<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: neil445</title>
    <description>The latest articles on DEV Community by neil445 (@neil445).</description>
    <link>https://dev.to/neil445</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F331666%2F2595737c-3809-46bc-9ad0-5d1b18457fba.jpg</url>
      <title>DEV Community: neil445</title>
      <link>https://dev.to/neil445</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/neil445"/>
    <language>en</language>
    <item>
      <title>I got called out for using IEnumerable on methods</title>
      <dc:creator>neil445</dc:creator>
      <pubDate>Fri, 02 Apr 2021 04:01:39 +0000</pubDate>
      <link>https://dev.to/neil445/i-got-called-out-for-using-ienumerable-on-methods-4e0f</link>
      <guid>https://dev.to/neil445/i-got-called-out-for-using-ienumerable-on-methods-4e0f</guid>
      <description>&lt;p&gt;I've always used &lt;code&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/code&gt; as the return value type and input value type for methods; currently, I'm working with a team with a standard of using array (T[]) or &lt;code&gt;List&amp;lt;T&amp;gt;&lt;/code&gt;. I did try to sneak up a few methods at first with &lt;code&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/code&gt;, until I was told to not use it and use the "lightest" implementation (what?) instead; and Resharper complains about possible multiple enumeration on LINQ methods called on an &lt;code&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/code&gt;. Since then I've been thinking to dig from memory what I know, and write it down.&lt;/p&gt;

&lt;dd&gt;&lt;br&gt;&lt;/dd&gt;

&lt;h3&gt;
  
  
  Why do I prefer to use &lt;code&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/code&gt;?
&lt;/h3&gt;

&lt;h5&gt;
  
  
  I want the flexibility using interfaces bring.
&lt;/h5&gt;

&lt;p&gt;Say I have this method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;DoTasks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I can pass in an array, a List, or whatever that inherits &lt;code&gt;IEnumerable&lt;/code&gt;, without having to bother converting it as opposed to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;DoTasks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;DoTasks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Immutability of the collection.
&lt;/h5&gt;

&lt;p&gt;Most of the time you don't really add/remove anything from the collection, you'd just play with the contents of a list. I know, it sounds trivial but the key here is intent. You don't want to leave code that's tempting the next developer to do something hacky.&lt;/p&gt;

&lt;h5&gt;
  
  
  Deferred execution
&lt;/h5&gt;

&lt;p&gt;&lt;code&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/code&gt; gives you the delicate art of deferred execution. There's already a lot out there explaining what all it is about, I'll just put it simply. Let's just say that &lt;code&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/code&gt; is not really there until you needed it, a familiar term that could give you the idea would be "lazy loading".&lt;br&gt;
Let's say we have&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;rooms&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_roomsService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetAllGuestRooms&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;vacantRooms&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rooms&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Vacant&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;foreach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;room&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;vacantRooms&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Room number: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;room&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Select expression is not yet executed here:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;vacantRooms&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rooms&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Vacant&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The point where Select expression is executed, or when the &lt;code&gt;IEnumerable&amp;lt;Room&amp;gt;&lt;/code&gt; result is "materialized", is here:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;foreach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;room&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;vacantRooms&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Room number: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;room&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;dd&gt;&lt;br&gt;&lt;/dd&gt;

&lt;h3&gt;
  
  
  What's the harm?
&lt;/h3&gt;

&lt;p&gt;It's all about avoiding the danger deferred execution can bring. &lt;a href="https://www.jetbrains.com/help/resharper/PossibleMultipleEnumeration.html"&gt;Here's&lt;/a&gt; Resharper's explanation why they warn about it, and they are correct about it.&lt;/p&gt;

&lt;p&gt;Going back to the previous sample code, let's say that &lt;strong&gt;_roomsService.GetAllGuestRooms()&lt;/strong&gt; looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Room&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;GetAllGuestRooms&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Room&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;rooms&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rooms&lt;/span&gt;
   &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"GUEST"&lt;/span&gt;
   &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;rooms&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;it returns an &lt;code&gt;IEnumerable&amp;lt;Room&amp;gt;&lt;/code&gt; and it makes a database query when it's called.&lt;br&gt;
We then add code to print all rooms&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;rooms&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_roomsService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetAllGuestRooms&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;foreach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;room&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;rooms&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Room: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;room&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;vacantRooms&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rooms&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Vacant&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;foreach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;vacantRoom&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;vacantRooms&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Vacant: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;vacantRoom&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Guess how many times it would make a database call? ONCE? No. TWICE. Despite reusing &lt;strong&gt;rooms&lt;/strong&gt;, the code above would make two database calls because &lt;strong&gt;rooms&lt;/strong&gt; was never materialized and stored in memory.&lt;/p&gt;

&lt;h5&gt;
  
  
  Getting around it
&lt;/h5&gt;

&lt;p&gt;The simple way of getting around is materialize the IEnumerable and store it memory. Use .ToList().&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;rooms&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_roomsService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetAllGuestRooms&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;ToList&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or, you may do this if the db query isn't expensive and doesn't take too long; your call.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Room&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;GetAllGuestRooms&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Room&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;rooms&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rooms&lt;/span&gt;
   &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"GUEST"&lt;/span&gt;
   &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;rooms&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToList&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above will have the method's return value have an underlying type of &lt;code&gt;List&amp;lt;Room&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So it's simply using .ToList() to materialize the &lt;code&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/code&gt;? Yes and no. I've seen this getting abused, other people put .ToList() left and right just to make sure &lt;code&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/code&gt; is materialized. However, it would allocate memory unnecessarily, sure GC would take care of it, but; don't make things work harder, make things work smarter. With that in mind, you have to be smart on what point you want &lt;code&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/code&gt; materialized, and use it when only necessary.&lt;/p&gt;

&lt;dd&gt;&lt;br&gt;&lt;/dd&gt;

&lt;h3&gt;
  
  
  Small things that Count
&lt;/h3&gt;

&lt;p&gt;Let's check &lt;strong&gt;IEnumerable.Count()&lt;/strong&gt;. Does it materialize the collection? Should I materialize it first? It depends on the underlying type.&lt;/p&gt;

&lt;p&gt;(Reference source code)[&lt;a href="https://source.dot.net/#System.Linq/System/Linq/Count.cs"&gt;https://source.dot.net/#System.Linq/System/Linq/Count.cs&lt;/a&gt;] for .Count():&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;Count&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;TSource&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;TSource&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="p"&gt;{&lt;/span&gt;

 &lt;span class="n"&gt;ThrowHelper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ThrowArgumentNullException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ExceptionArgument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;

   &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="n"&gt;ICollection&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;TSource&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;collectionoft&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;collectionoft&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Count&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;

   &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="n"&gt;IIListProvider&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;TSource&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;listProv&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;listProv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;onlyIfCheap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;

   &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="n"&gt;ICollection&lt;/span&gt; &lt;span class="n"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Count&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;

   &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IEnumerator&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;TSource&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetEnumerator&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
   &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;checked&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;MoveNext&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
         &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;++;&lt;/span&gt;
         &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;

   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's not forget:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/code&gt; is inherited by &lt;code&gt;ICollection&amp;lt;T&amp;gt;&lt;/code&gt;&lt;br&gt;
&lt;code&gt;ICollection&amp;lt;T&amp;gt;&lt;/code&gt; is inherited by &lt;code&gt;IList&amp;lt;T&amp;gt;&lt;/code&gt;&lt;br&gt;
&lt;code&gt;IList&amp;lt;T&amp;gt;&lt;/code&gt; is inherited by &lt;code&gt;List&amp;lt;T&amp;gt;&lt;/code&gt;&lt;br&gt;
&lt;code&gt;IList&amp;lt;T&amp;gt;&lt;/code&gt; is also inherited by &lt;code&gt;T[]&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;.Count()&lt;/strong&gt; checks if the underlying type is an &lt;code&gt;ICollection&amp;lt;TSource&amp;gt;&lt;/code&gt;, &lt;code&gt;ICollection&lt;/code&gt;, or an &lt;code&gt;IListProvider&amp;lt;TSource&amp;gt;&lt;/code&gt;; if not, it would enumerate through the &lt;code&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/code&gt; to count the items.&lt;/p&gt;

&lt;dd&gt;&lt;br&gt;&lt;/dd&gt;

&lt;h3&gt;
  
  
  How about IQueryable?
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;IQueryable&amp;lt;T&amp;gt;&lt;/code&gt; inherits from &lt;code&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/code&gt;. I've seen this go bad personally. There was another team's project using Azure CosmosDB. They returned &lt;code&gt;IQueryable&lt;/code&gt; from their repository layer and they did not materialize them properly. The result is a nightmare utilization of Request Units (RU) and a huge bill that what was it supposedly.&lt;/p&gt;




&lt;p&gt;Got it refreshed on my memory again. Let me know if I'm wrong, point me to right path.&lt;/p&gt;

&lt;p&gt;If you can't find why your code is taking too long to execute or your database requests are off the charts, you may want to revisit how &lt;code&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/code&gt; is used on your code.&lt;/p&gt;

&lt;p&gt;That's it. Happy Coding!&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>We used CosmosDB instead of a relational database, here's what we went through and learned.</title>
      <dc:creator>neil445</dc:creator>
      <pubDate>Wed, 13 May 2020 06:37:48 +0000</pubDate>
      <link>https://dev.to/neil445/we-used-cosmosdb-instead-of-a-relational-database-here-s-what-went-through-and-learned-40k3</link>
      <guid>https://dev.to/neil445/we-used-cosmosdb-instead-of-a-relational-database-here-s-what-went-through-and-learned-40k3</guid>
      <description>&lt;p&gt;Almost two years ago, we took on a pretty sizable project. We're talking about a potential of users from everywhere in the world, if all goes well, and; a brilliantly complex domain that makes a lot of sense to the aim of the product.&lt;/p&gt;

&lt;p&gt;I was involved on designing the solution architecture, everything was agreed upon except with the database. Taking to consideration the complexity of the relationships of the entities, I proposed to use Azure SQL and find a way with Elastic Database tools to scale it horizontally. On the other side of the table, it was decided to use CosmosDB, why? mainly for these reasons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;FAST. We're guaranteed that some queries would be faster than 10ms.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CosmosDB offers an almost painless scaling. Set a partition key, write a few lines of code to handle partitioning, and there you go.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Since we're dealing with multi-tenancy, we found that CosmosDB's partitioning could help us to properly segregate data for each tenant.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I've worked on CosmosDB back when it was still called DocumentDB. I was never sold that you could totally replace a relational database with a NoSQL database, though, you can still pull it off if you do it properly or the complexity permits. The key is modelling your entities correctly, you should identify when you need to reference or embed, it's all about how volatile the data is. I was given a sandwich for my idea and told me that we would go with CosmosDB. We did the dirty work, and here's what we went through:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Stored procedures run on their own transaction. You can't write a transaction that would run multiple stored procedures and sweetly roll back all the changes if something went wrong.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The SQL engine isn't really all your familiar SQL. SQL statements are very limited, and JOIN doesn't work like the JOIN you know from relational databases. You can't do cross collection queries.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Back then, the SDK doesn't support that much LINQ statements. We had a hard time implementing pagination. Currently, more LINQ statements are supported and OFFSET LIMIT statements was introduced to the SQL engine.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Partitioning can get in the way of your queries. We had a lot of filters in our application. There were times we need to restructure the partitions to accommodate filters or totally say we can't do that filters since the partitioning forbids us.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You have to deal with error 429's. I wouldn't go deep about it, it needs another wall of text. It basically means that your collection is getting overloaded with requests and you have to handle this error and retry the request. The SDK can help you handle it automatically or just pay more for more request units.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Hot partitions. We tried the auto-scale feature for the request units (RU's). The idea is when we hit the threshold, more RU's will be automatically allocated and will go back down if there's no need. Still we're getting a lot of error 429's, we found out that we're experiencing hot partitions. The partition keys developers set are the logical partitions, which are then mapped to physical partitions, these physical partitions take up a definite amount of RU's; if the physical partition's RU's are used up, all requests for all the logical partitions mapped to it will result to error 429.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I am personally convinced that you cannot live without error 429's, unless you are filthy rich and willing to pay the price. We optimized our code, did caching, and implemented automatic scaling. We still get error 429's and the cost didn't really go down.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I was never convinced that CosmosDB is the right way to go. We're spending way too much and we can't do so much about it. We hopelessly combed through the diagnostic logs to find some light, and even bothered support to give us answers for our questions that doesn't even make sense. Up until the day I left, we're still trying to make do with CosmosDB and bled our pockets for it. Through the experience, here's what we realized:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;CosmosDB really does offer painless scaling through partitioning.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It would really shine for you if you are not doing fancy things with your data. If you have data that you would store as you display it or display it as store it, you could really benefit from the speed CosmosDB promised.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If you have huge amount of data that you just need to store outright, you'll could take advantage on how easy you can scale storage through partitioning. We had other projects where CosmosDB really paid-off. We have an IoT project that used CosmosDB to save tons of telemetry. The team was able to scale for terabytes of data without breaking a sweat and worrying for storage.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You could create collection triggers and have a change feed processor if you need to something event-driven.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You couldn't totally replace a relational database with a NoSQL Database for a domain with business logic relying heavily on entity relationship.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's all. I do believe that CosmosDB is a great product. On the right design and with proper documentation, developers could really benefit with the speed and almost painless storage scaling. Let me know if I missed something, you agree or disagree with my thoughts, discussion is well appreciated.&lt;/p&gt;




&lt;p&gt;DISCLAIMER: This post is not meant to criticize CosmosDB negatively or convince developers to stay away from it. CosmosDB is a really good NoSQL database and gives a lot of benefits on proper implementation.&lt;/p&gt;

</description>
      <category>database</category>
      <category>nosql</category>
      <category>sql</category>
    </item>
    <item>
      <title>I got caught in between during this recession brought by the pandemic; I lost my job. A very humbling experience.</title>
      <dc:creator>neil445</dc:creator>
      <pubDate>Wed, 29 Apr 2020 07:32:23 +0000</pubDate>
      <link>https://dev.to/neil445/i-got-caught-in-between-during-this-recession-brought-by-the-pandemic-i-lost-my-job-a-very-humbling-experience-2ha3</link>
      <guid>https://dev.to/neil445/i-got-caught-in-between-during-this-recession-brought-by-the-pandemic-i-lost-my-job-a-very-humbling-experience-2ha3</guid>
      <description>&lt;p&gt;I looked for greener pastures and made careful preparations before leaving my previous company, I signed the contract to a new employer and properly waived everyone goodbye. I was already out of my previous employer, taking sweet time learning React and .NET Core before my start date for my new employer. Ten days before my start date, while I was having breakfast, the recruiter sent me an  email that the contract I signed was rescinded and my employment is therefore terminated before I could even start. I got caught in between.&lt;/p&gt;

&lt;p&gt;I didn't take time to let it sink in, I immediately fired up my laptop, updated my resume and sent it to 26 job vacancies. I posted on LinkedIn and got sympathy and help. I got much appreciated messages from my previous CEO, manager, and client hoping me well and are open to help me. Three days after, I started receiving invites to interviews and I entertained where I believed I am qualified. Out of 26, I got processed up to the final interview for 3 of them, 1 immediately said that they would consider other candidates, the other two I never heard back from them.&lt;/p&gt;

&lt;p&gt;Through the interviews, I learned a lot. The things I thought I was doing right and some practices got exposed. I was wrong on several things and I could say that I'm going outdated with the recent developments in the software development.&lt;/p&gt;

&lt;p&gt;Here's what I've learned so far going through the experience.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;I've worked on my recent project for quite a while and I unconsciously limited myself from learning other things. I've been interested on React and ReactNative for quite a while and I didn't manage to find time to actually learn it, instead I confined myself on my subpar skills in Angular and that didn't help me through the interview. My point is, make time to learn things that stray from your comfort zone and what you're working on.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Read the job description on what is offered to you. You might end up applying to a position you're not qualified. Also, you'll get an idea how other organizations do the same job you're doing. For example, I've seen a lot of DevOps engineer positions looking for people with experience on Test Automation. You might want to touch base with your previous colleagues and suggest things you've seen so they can keep themselves up to date.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Some recruiters don't know exactly what they are looking for, and it is not their fault. I've been invited for DevOps engineer, Java Developer, Node.JS Developer, and many others; despite it was clear on my resume that my experience is on C# and Angular. Be patient and understanding, and it helps to give the recruiters an idea what to look for for those positions. Have the conversation end well for both of you, at the end of the day we're throwing ourselves at the mercy of the recruiters during initial contact.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Keep your resume clean and concise. I had feedback that my one page resume is clean and inviting to take a look on. Most recruiters on initial contact would only ask about your recent experience or a gist of your experience related to the position you're applying for. The rest of your selling point will be discussed when you face technical interview, that's when you should do the talking about your experience.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When talking during the interview, don't dig your own grave. Do not rush answering questions. I've done interview myself before and there are times we follow up on things that came out of the applicant's mouth. Be honest and admit what you don't know, it's better to come clean rather than have a hard time catching up on the job if you get hired.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sell yourself on things you know you excel, but not too much so you don't toot your horn. When talking about things you aren't good enough, follow up on what you think you can do to improve it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Lastly, there is no harm keeping professional relationships from your previous employment. They do come handy in times of need. So don't burn bridges!&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's it. I'm still going through this unfortunate circumstance and I know there's a lot of people on the same boat. I hope we get to learn more and get through this as soon as possible. I wish everyone good health and safety during these trying times.&lt;/p&gt;

</description>
      <category>career</category>
      <category>hiring</category>
    </item>
  </channel>
</rss>
