<?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: Sam Fields</title>
    <description>The latest articles on DEV Community by Sam Fields (@samfieldscc).</description>
    <link>https://dev.to/samfieldscc</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%2F464116%2F2fbd4466-6830-4911-a561-5f9e66a8fcbe.jpeg</url>
      <title>DEV Community: Sam Fields</title>
      <link>https://dev.to/samfieldscc</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/samfieldscc"/>
    <language>en</language>
    <item>
      <title>Things you need to know as a developer - Clean Coding</title>
      <dc:creator>Sam Fields</dc:creator>
      <pubDate>Tue, 26 Jan 2021 16:57:43 +0000</pubDate>
      <link>https://dev.to/samfieldscc/things-you-need-to-know-as-a-developer-clean-coding-part-1-3d8g</link>
      <guid>https://dev.to/samfieldscc/things-you-need-to-know-as-a-developer-clean-coding-part-1-3d8g</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;In this post, I will cover the things I find most important to know about writing clean code and why we should strive to achieve it. &lt;/p&gt;

&lt;h2&gt;
  
  
  Table Of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Why Clean Code?&lt;/li&gt;
&lt;li&gt;
&lt;a href=""&gt;Choosing the right tools&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;The email regex example&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;&lt;a href=""&gt;Keep things separated&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=""&gt;Code Metrics&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=""&gt;Things to avoid&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=""&gt;DRY Principle&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=""&gt;Implement good standards&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=""&gt;Self-documenting code&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Clean Code &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;It's important to understand that besides the compiler, we as programmers should also be able to easily read our code and others as well. Badly written code can create a bad development environment for you and your team, it can increase the number of bugs in your code, decrease flexibility, and increase code complexity and redundancy, which all contribute to increased technical debt.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why?
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. Reading code is harder than writing code!
&lt;/h4&gt;

&lt;p&gt;Reading old code is hard, sometimes it might even happen that you can't read your own code you wrote 1 month ago.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. "I will make this better later..."
&lt;/h4&gt;

&lt;p&gt;If you are telling yourself that, then there's probably more than a 50% chance you won't do it ever.&lt;/p&gt;

&lt;h4&gt;
  
  
  3. Technical Debt
&lt;/h4&gt;

&lt;p&gt;Badly written code creates technical debt, which is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Costly for the company;&lt;/li&gt;
&lt;li&gt;Cumbersome and boring for you to fix later.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  4. I'm a lazy programmer
&lt;/h4&gt;

&lt;p&gt;Although they say some of the best programmers are lazy, this should not apply for when you are writing your code. You can still be a lazy, good, creative, and fast programmer whilst writing clean code.&lt;/p&gt;

&lt;h4&gt;
  
  
  5. Clean code vs Development Speed
&lt;/h4&gt;

&lt;p&gt;Some might say that the required extra care can cripple their development speed. I don't think these two things are incompatible; if you know and practice your code standards and clean code practices beforehand, when you go to code they will naturally arise without you even thinking about them. &lt;/p&gt;

&lt;h3&gt;
  
  
  Choosing the right tools
&lt;/h3&gt;

&lt;p&gt;The first step for writing good code is having the right tools to do so. We should select the best tool for the job. This could be an IDE or programming approach to a problem. My favorite example is the validation of an email. &lt;/p&gt;

&lt;h4&gt;
  
  
  The email validation nightmare
&lt;/h4&gt;

&lt;p&gt;The most common approach I see is the use of a regex for this task. The problem is that the regex required to do this is awful and completely fallible if done wrong. &lt;/p&gt;

&lt;h5&gt;
  
  
  Example of a possible email regex in C\
&lt;/h5&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h5&gt;
  
  
  Example of an email regex in other languages
&lt;/h5&gt;

&lt;p&gt;And depending on the language it could be totally unreadable. Check &lt;a href="https://emailregex.com/"&gt;this website&lt;/a&gt; with the email regex for different languages. Just take a look at the Perl/Ruby implementation. 😱😱😱 What a nightmare!&lt;/p&gt;

&lt;h5&gt;
  
  
  An alternative for .NET developers
&lt;/h5&gt;

&lt;p&gt;If you are working with ASP.NET there might be a better alternative. This to make the case of finding the right tool for the job you could use the:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;System.ComponentModel.DataAnnotations&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;System.Net.Mail.MailAddress&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All these strategies have advantages and disadvantages and we must select the one that works for our requirements and that doesn't create unnecessary complexity or a potential source of bugs.&lt;/p&gt;

&lt;p&gt;If you want to go more in-depth about this email issue look at &lt;a href="https://stackoverflow.com/questions/1365407/c-sharp-code-to-validate-email-address"&gt;this StackOverflow question&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Keep things separated
&lt;/h3&gt;

&lt;p&gt;When dealing with a full-stack project it's a good idea to make sure that different code types are kept in different files. For instance, avoid having HTML, C#, and Javascript code in the same file (e.g., .cshtml files). Here are some reasons why:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;In general separating your code will possibly allow for &lt;strong&gt;code highlighting&lt;/strong&gt; and &lt;strong&gt;syntax verification&lt;/strong&gt;, which makes for better readability and prematurely catches silly syntax errors. Although this might not be the case for every language and project.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When dealing with javascript, having the code in a separate file allows you to potentially &lt;strong&gt;cache the code&lt;/strong&gt; and perform other optimizations like modification and compression, which might not happen if the code is on an HTML file.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Separating the code into different files will possibly promote the practice of separation of concerns and also make it &lt;strong&gt;reusable&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Code metrics
&lt;/h3&gt;

&lt;p&gt;Nowadays we have several ways of measuring different code metrics that allow us to learn several properties about our code. Some metrics include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cyclomatic complexity&lt;/li&gt;
&lt;li&gt;Maintainability Index&lt;/li&gt;
&lt;li&gt;Depth of Inheritance&lt;/li&gt;
&lt;li&gt;Class Coupling&lt;/li&gt;
&lt;li&gt;Lines of code metrics&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These metrics can be automatically measured from your IDE using built-in functionality or a plugin. For instance,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Visual Studio 2019 - Offers built-in capabilities for &lt;a href="https://docs.microsoft.com/en-us/visualstudio/code-quality/how-to-generate-code-metrics-data?view=vs-2019"&gt;generating code metrics&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.jetbrains.com/resharper"&gt;Resharper for VS2019&lt;/a&gt; - Offers continuous code quality analysis, code smell, and error detection, and standard enforcement.&lt;/li&gt;
&lt;li&gt;Visual Studio Code - Offers different plugins well, check them out &lt;a href="https://marketplace.visualstudio.com/search?term=code%20metrics&amp;amp;target=VSCode&amp;amp;category=Other&amp;amp;sortBy=Relevance"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Another way of getting code metrics analysis would be static code analysis tools, e.g. the open-source tool &lt;a href="https://docs.sonarqube.org/latest/user-guide/metric-definitions/#:~:text=Complexity,-Complexity%20(%20complexity%20)&amp;amp;text=It%20is%20the%20Cyclomatic%20Complexity,a%20minimum%20complexity%20of%201."&gt;SonarQube&lt;/a&gt; to perform static code analysis allowing you to detected bugs, code smells, and even security vulnerabilities. This can mainly be useful when added as a step in your CI/CD pipelines to ensure that standards and metrics are maintained.&lt;/p&gt;

&lt;h3&gt;
  
  
  Things to avoid when writing code
&lt;/h3&gt;

&lt;h4&gt;
  
  
  High Cyclomatic complexity
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Cyclomatic_complexity"&gt;Cyclomatic complexity&lt;/a&gt; is a software metric used to indicate the complexity of a program.&lt;/p&gt;

&lt;p&gt;High cyclomatic complexity is an indicator of complex and hard to follow code. It might be an indication, for instance of nested if-else statements and method calls. Try to avoid this when possible.&lt;/p&gt;

&lt;h4&gt;
  
  
  Zombie Code
&lt;/h4&gt;

&lt;p&gt;This is code that you might find in your projects that are not being used at all or is deprecated but not properly identified as such. Over time this can amount to larger binaries, longer code to go through, and more testing required where it might not even be necessary. It can manifest in the form of unreferenced methods or functions or even blocks of commented code.&lt;/p&gt;

&lt;p&gt;If you ever see this in your codebase, it might be a good idea to ask someone more knowledgeable about the project if it could be removed. Another strategy is to implement QA tasks in your projects to periodically tackle the technical debt of the code.&lt;/p&gt;

&lt;h4&gt;
  
  
  Excessive indentation and no whitespaces
&lt;/h4&gt;

&lt;p&gt;The use of excessive indentation or the lack of it can create hard to follow code, sometimes the reader having to indent the code himself. Nowadays most IDEs offer some way of fixing indentation automatically and others even enforce and fix code standards. These standards can usually be customized for the developer's needs.&lt;/p&gt;

&lt;h4&gt;
  
  
  Long classes and methods
&lt;/h4&gt;

&lt;p&gt;The rule of 7 is based on the idea that humans can only remember up to 7 things at a time. Therefore, if you create anything with more than 7 parameters it will be very difficult to manage and go through.&lt;/p&gt;

&lt;p&gt;One thing I remember from university when studying processors is that they have something called &lt;a href="https://en.wikipedia.org/wiki/Processor_register"&gt;registers&lt;/a&gt; and they come in a limited number. Putting it very simply and general: &lt;/p&gt;

&lt;p&gt;For some architectures, when invoking a function, the processor uses those registers to hold those variables, because it makes the operation extremely fast. If the number of passing parameters exceeds the number of available registers then the processor needs to store the remaining parameters elsewhere, which leads to a lot more work and maybe small performance penalties. &lt;/p&gt;

&lt;p&gt;Therefore I always try to keep the number of parameters to less than 7, usually 4 or 5.&lt;/p&gt;

&lt;p&gt;This rule usually applies at:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The number of parameters in a method&lt;/li&gt;
&lt;li&gt;The number of variables in a method&lt;/li&gt;
&lt;li&gt;The number of methods in a class&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Unnecessary comments
&lt;/h4&gt;

&lt;p&gt;All I have to say about this is, avoid doing commentaries like this:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;In my opinion, we should only add comments when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On a property when we want to explain what it does in the given context and the name in itself is not enough.&lt;/li&gt;
&lt;li&gt;To explain some obscure algorithm that performs a very specific thing that isn't clear given the context where it's found.&lt;/li&gt;
&lt;li&gt;To justify a decision on why something was done a certain way and to avoid possible "corrections".&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Poorly named data structures and variables
&lt;/h4&gt;

&lt;p&gt;Poorly named variables and data structures can have a very significant negative impact on the readability of our code. In some cases, even a simple code snippet can become frustrating to decipher because of badly chosen variable names.&lt;/p&gt;

&lt;p&gt;Another bad consequence of badly naming things is that it can misguide the reader to what the class, method, or variable are doing. This can lead to bad usage of the code and resulting in unexpected behavior.&lt;/p&gt;

&lt;p&gt;In the second part of this post, I'll go into more detail on naming classes, variables, and much more.&lt;/p&gt;

&lt;h4&gt;
  
  
  Overly verbose names
&lt;/h4&gt;

&lt;p&gt;That being said we should also try and avoid being too explicit on what a class or method is doing and avoid overly verbose names!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ValidatePaymentAndSendEventMessageToPipeline()&lt;/li&gt;
&lt;li&gt;ValidateInputProcessDataAndReturnResult()&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There's no reason why we need to be so descriptive about what's happening in those methods. Sure we can kind of guess what's happening just from the name, but we can probably also guess what's happening by looking at the code. There's no added advantage in being so descriptive. Something like this should be enough:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ValidatePayment()&lt;/li&gt;
&lt;li&gt;ValidateAndProcessData()&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And if it's not consider adding a //summary section above the method giving some further information about the method.&lt;/p&gt;

&lt;h3&gt;
  
  
  DRY principle´
&lt;/h3&gt;

&lt;p&gt;The DRY principle stands for:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;D&lt;/strong&gt;on't &lt;strong&gt;R&lt;/strong&gt;epeat &lt;strong&gt;Y&lt;/strong&gt;ourself.&lt;/p&gt;

&lt;p&gt;As a developer this tells that we should try to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Decrease the amount of unnecessary code in the codebase.&lt;/li&gt;
&lt;li&gt;Decrease the number of lines of code and not have more of them.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;"Measuring programming progress by lines of code is like measuring aircraft building progress by weight" - Bill Gates&lt;/p&gt;

&lt;p&gt;3.Try to detect patterns that are repeating in your code and refactor them into one cohesive code block shared by the entire code base, when applicable.&lt;/p&gt;

&lt;h3&gt;
  
  
  Self-documenting code
&lt;/h3&gt;

&lt;p&gt;In general, the code should be self-documenting, meaning that for the most part, a developer should be able to understand what it's happening in there. And to make sure that happens we should make sure we write clean code! This is not to say we should have comments describing the code, but try to be clear with your code before adding commentary on it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;These things I've talked about here I believe to be for the most part of general application. Do you disagree on something? Please let everyone know your experience on the matter!&lt;/p&gt;

&lt;p&gt;So happy to being back to writing! Almost after 5 months, I started a new job in London and I am still in the process of trying to move there! Quite an adventure that unfortunately didn't leave me with much time for writing. But I'm back :D &lt;/p&gt;

</description>
      <category>csharp</category>
      <category>cleancode</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>LINQ: Caveats and pitfalls</title>
      <dc:creator>Sam Fields</dc:creator>
      <pubDate>Mon, 21 Sep 2020 16:31:57 +0000</pubDate>
      <link>https://dev.to/samfieldscc/linq-37k3</link>
      <guid>https://dev.to/samfieldscc/linq-37k3</guid>
      <description>&lt;p&gt;In the third installment of the "Things you need to know as a C# developer" series, I want to look at some &lt;strong&gt;caveats and pitfalls of deferred execution in LINQ&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This concept can sometimes cause some confusion and can create performance problems and create super annoying bugs when misused.&lt;/p&gt;

&lt;p&gt;This post expects that the reader has some working knowledge of LINQ. This post is a practical overview of how LINQ runs in the background and how it can affect your program. 😁&lt;/p&gt;

&lt;h2&gt;
  
  
  Table Of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
LINQ &lt;/li&gt;
&lt;li&gt;Imediate Execution&lt;/li&gt;
&lt;li&gt;
Deferred Execution

&lt;ul&gt;
&lt;li&gt;Deferred Streaming Execution&lt;/li&gt;
&lt;li&gt;Deferred Non-Streaming Execution&lt;/li&gt;
&lt;li&gt;What is query evaluation?&lt;/li&gt;
&lt;li&gt;Things that force query evaluation&lt;/li&gt;
&lt;li&gt;Comparing how deferred and imediate execution works&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;The dangers of deferred execution&lt;/li&gt;

&lt;li&gt;Things to remember&lt;/li&gt;

&lt;/ul&gt;

&lt;h1&gt;
  
  
  LINQ &lt;a&gt;&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;In the past, to access different data sources, we would require different API's to work with them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Memory Data with generics and algorithms&lt;/li&gt;
&lt;li&gt;Relational Data with ADO.NET and SQL&lt;/li&gt;
&lt;li&gt;XML Data with XmlDocument&lt;/li&gt;
&lt;li&gt;And many others&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;LINQ offers a consistent way of working with all the data sources referred above using a single interface. It allows us to &lt;strong&gt;write less and more expressive code&lt;/strong&gt;, which is fantastic! :D&lt;/p&gt;

&lt;p&gt;LINQ functionality is available when we include the "System.Linq" namespace in our code. Its usage comes in two flavors:&lt;/p&gt;

&lt;h4&gt;
  
  
  Extension method syntax
&lt;/h4&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h4&gt;
  
  
  Query method syntax
&lt;/h4&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;These lines are called LINQ queries that can contain expressions that create more specific results. The queries can be evaluated immediately or at a later time to produce an output.&lt;/p&gt;

&lt;h1&gt;
  
  
  Execution types &lt;a&gt;&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;LINQ methods or query operator methods exist in 3 flavors of execution: Immediate execution or deferred execution, which then classifies as (streaming or non-streaming). Let's now take a quick look at each of them. &lt;/p&gt;

&lt;h2&gt;
  
  
  Imediate execution &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Immediate execution &lt;strong&gt;(IE)&lt;/strong&gt; means that the LINQ method executes in the same line as you see it. A method that uses IE evaluates the LINQ query and produces a concrete result by accessing a data source or a memory location; this is a program flow that we all know.&lt;/p&gt;

&lt;p&gt;Some LINQ methods that have immediate execution are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;.All()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.Any()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.Average()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.First()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.ToList()&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Deferred execution &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;To defer something means to &lt;em&gt;"put off (an action or event) to a later time; postpone"&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Deferred execution means that no work happens (no data source is accessed) until we "force the LINQ query to be evaluated," creating a result to be "available" (I will make this clearer in a later section). For fun, I also like to call this type of execution one of the following terms:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;"I will only do it if I have to"&lt;/em&gt; execution or;&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;"I will only do the bare amount of work possible"&lt;/em&gt; execution or;&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;"I will wait until the last moment to do it"&lt;/em&gt; execution or;&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;"I might not even do it"&lt;/em&gt; execution.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Deferred execution is available in C# by using the two keywords &lt;em&gt;yield return&lt;/em&gt;. We will see an example of this in the next sections.&lt;/p&gt;

&lt;p&gt;Some LINQ methods that use deferred execution:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;.Where()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.Skip()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.Take()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.Select()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.OrderBy()&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🔥 &lt;strong&gt;Hot Tip&lt;/strong&gt; 🔥&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;As a rule of thumb, if the LINQ method returns an abstract type (e.g., IEnumerable), it's probably using deferred execution.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;➡️ When in doubt, you can use &lt;a href="https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/linq/classification-of-standard-query-operators-by-manner-of-execution" rel="noopener noreferrer"&gt;this table&lt;/a&gt; as a reference.&lt;/p&gt;

&lt;h3&gt;
  
  
  Deferred Streaming Execution &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Deferred streaming execution means that the method uses a process known as &lt;em&gt;lazy evaluation&lt;/em&gt;  when iterating through a collection; this means that only one element of the collection is read and used each time an iterator asks for a new element of the set. A method with this type of execution almost always returns in the form of an &lt;code&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/code&gt; or &lt;code&gt;IOrderedEnumearble&amp;lt;T&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Examples of these methods using deferred streaming execution in LINQ are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;.Where()&lt;/code&gt; - Used to create a filter over a collection.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.Skip()&lt;/code&gt; - Used to skip the first available N elements of a collection.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.Take()&lt;/code&gt; - Used to retrieve the first available N elements of a collection.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Deferred Non-Streaming Execution &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;On the other side, we have deferred non-streaming execution, which means that the method uses what is sometimes called "eager evaluation"; the first time an iterator goes through the collection, reading it entirely. The non-streaming execution might require temporary variables to store the original collection (e.g., when ordering a collection).&lt;/p&gt;

&lt;p&gt;Examples of this type of execution in LINQ are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;.OrderBy()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.GroupBy()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.Join()&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What is query evaluation? &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;So one question you might be asking is: What does it mean to "evaluate" a LINQ query that ultimately produces a result? &lt;/p&gt;

&lt;p&gt;1 On a very, very general way, when an expression is created, for instance, something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F3qw3glkfb3r6q6u0r80q.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F3qw3glkfb3r6q6u0r80q.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;2 When the query evaluation happens, it gets converted into expression trees. Which can look something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fj2ewuz6puc9leatcj727.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fj2ewuz6puc9leatcj727.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;3 Then those expression trees get translated into other types of queries, e.g., LINQ query translated into a SQL Query when using LINQ with Entity Framework.&lt;/p&gt;

&lt;p&gt;4 The translated queries are executed against their data sources, followed by creating the desired result objects using the results of those translated queries.&lt;/p&gt;

&lt;p&gt;5 Creates a happy programmer because LINQ is awesome to use, and our code stays very clean. Clean code, Happy coder? 😅😁&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Query evaluation can happen in the client-side (e.g., your program) or the server-side (e.g., in a database);&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Things that force query evaluation &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Enumerating with a foreach; &lt;a&gt;&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;One of the things that force a deferred method to evaluate is iterating through the resulting collection from a LINQ operation. That happens, for instance, when we use a foreach loop to iterate through a collection:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h4&gt;
  
  
  Chaining to deferred extension methods a method that does not implement deferred execution &lt;a&gt;&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;Another way of accomplishing the method to do work is to chain a query method operator that requires access to the data such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;.ToList() - forces immediate query evaluation and returns a List
*.First() - forces immediate query evaluation and returns the first entry of type T in the IEnumerable&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  Comparing how deferred and imediate execution works &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;One way of understanding what deferred execution does it to compare it against the immediate execution implementation of a method does the same thing. Next, I show two custom filter methods that perform the same task; one implements a method that uses &lt;br&gt;
 a deferred execution strategy and the other an immediate execution strategy.&lt;/p&gt;
&lt;h4&gt;
  
  
  Custom filter method using immediate execution &lt;a&gt;&lt;/a&gt;
&lt;/h4&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;This implementation uses a temporary variable to hold the results, which increases the auxiliary space complexity of the method;&lt;/li&gt;
&lt;li&gt;To return a result, the method must access the entire collection.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Custom filter method using deferred execution &lt;a&gt;&lt;/a&gt;
&lt;/h4&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;This implementation doesn't use any temporary variables;&lt;/li&gt;
&lt;li&gt;Once there's a match with the predicate, a result is immediately returned to the caller as it accesses the entire collection.&lt;/li&gt;
&lt;li&gt;This is not apparent here but, the caller might not end up iterating through all the results. For instance, if a cancelation token is issued, a condition is met that stops the enumeration, or an exception is thrown. Which means we might avoid iterating throw the entire collection unnecessarily.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;✔️ &lt;strong&gt;Just Do It!&lt;/strong&gt; ✔️ &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I advise you to &lt;strong&gt;copy, edit and debug the snippet bellow step by step&lt;/strong&gt; to see how the program flows and compare both execution types. This way, I assure you that you will understand how deferred execution works!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This next snippet shows you, with some funny dialog, at least that is what I was going for: deferred and immediate execution at work. Please run the code in➡️ &lt;a href="https://dotnetfiddle.net/OkinpG" rel="noopener noreferrer"&gt;this fiddle&lt;/a&gt; ⬅️ to see the comparison between both types of execution, or copy and run it locally.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dangers with deferred execution &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;So, as with everything, there are good things, but there's also bad things, things that happen when we don't know what we are doing. &lt;br&gt;
As this proverb says, "The road to hell is paved with good intentions." so yeah... Let's take a look at some things to be aware when using LINQ:&lt;/p&gt;
&lt;h4&gt;
  
  
  Deferred exception execution &lt;a&gt;&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;Take a look at the following code snippet:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;This piece of code is inside a try-catch block because we want to make sure our code handles an IEnumerable object that could potentially be null. (Ignore the fact that we could apply several other strategies here; this is to make a point with an easily understandable example).&lt;/p&gt;

&lt;p&gt;I now ask: Which line of code throws an "ArgumentNullException" exception?&lt;/p&gt;

&lt;p&gt;If you said line 14, then I'm sorry, but your program just crashed! If you told line 21, then you are correct! Why? &lt;/p&gt;

&lt;p&gt;The &lt;em&gt;.Where()&lt;/em&gt; method uses deferred execution, which means it evaluates the query to execute when a value is requested. In this example, the requested value is in line 21, which triggers the query evaluation and subsequently throwing an exception. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;t =&amp;gt; !valuesToRemove.All(x =&amp;gt; x == t)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;But notice that it stands inconveniently outside our try-catch block! Therefore because we are performing work outside the scope of the try-catch block, our code throws an exception, and the program crashes. &lt;/p&gt;

&lt;p&gt;A sneaky and hazardous situation! But now you know to be aware of this.&lt;/p&gt;

&lt;h4&gt;
  
  
  Multiple enumerations
&lt;/h4&gt;

&lt;h5&gt;
  
  
  The performance problem &lt;a&gt;&lt;/a&gt;
&lt;/h5&gt;

&lt;p&gt;So deferred execution is great. IEnumerable is great. It saves us from unnecessary data fetches and processing time, but there's a bad side to all this flexibility. If the users don't know how to use it, they can unknowingly write bad code.&lt;/p&gt;

&lt;p&gt;Sometimes, our code performs several method calls, passing the same parameter between those calls, or maybe we have a pipeline that's executing several computations on a particular dataset. There is a problem that can occur when one of those parameters is an IEnumerable. Take a look at the following code snippets that implement two pipelines that perform the same tasks.&lt;/p&gt;

&lt;h5&gt;
  
  
  Pipeline A
&lt;/h5&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h5&gt;
  
  
  Pipeline B
&lt;/h5&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Can you see what the problem between these two pipelines is?&lt;/p&gt;

&lt;p&gt;Because of the use of methods that cause immediate execution between pipeline A, we are doing something called &lt;strong&gt;multiple enumerations the IEnumerable&lt;/strong&gt;, which means that the data is retrieved numerous times from the data source.&lt;/p&gt;

&lt;p&gt;If your data source is a List or any other source in memory, this is not a problem; if your data source is something like a file or a database, we can potentially come to face a significant performance problem.&lt;/p&gt;

&lt;p&gt;As the size of the data returned by the data-source increases, the execution time increments very fast for the multiple enumerations scenario, but its constants for pipeline B were methods that only used deferred execution until the last step where the data is necessary.&lt;/p&gt;

&lt;p&gt;In contrast, pipeline B deferred all execution inside the pipeline, which is the preferred solution. Although sometimes we might not be able to avoid it, and that's fine. The purpose should always be to have clean and performant code.&lt;/p&gt;

&lt;p&gt;Please take at this complete [code snippet] where the pipelines are an analogy for a stack that spans several method calls (&lt;a href="https://dotnetfiddle.net/rlcHoN" rel="noopener noreferrer"&gt;https://dotnetfiddle.net/rlcHoN&lt;/a&gt;); you will see that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pipeline without multiple enumerations takes &lt;strong&gt;approx. 0.001 ms&lt;/strong&gt; to execute.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pipeline with multiple enumerations takes &lt;strong&gt;approx. 4 ms&lt;/strong&gt; to execute&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;As we increase the number of elements in the file, the processing time also increases. Now test this code against a database with millions of records, you see where this is going.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🔥 &lt;strong&gt;Hot Tip&lt;/strong&gt; 🔥&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A tool like Resharper can be a great option to warn you about multiple enumerations in your code.&lt;/li&gt;
&lt;li&gt;Try to avoid query evaluation if possible unless there is some clear advantage not to do it; &lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  The consistency problem &lt;a&gt;&lt;/a&gt;
&lt;/h5&gt;

&lt;p&gt;In this section, you will see why sometimes you might need to force query evaluation after fetching data from a data source.&lt;/p&gt;

&lt;p&gt;As if the performance problem wasn't bad, I think this one is equally bad or worse. &lt;/p&gt;

&lt;p&gt;Imagine that your data source is a database. If you have multiple enumerations, that results in numerous calls to the database to retrieve data at different moments in time. Can you think of anything that could happen to the database in between calls?&lt;/p&gt;

&lt;p&gt;Well, if you are performing operations on a particular set of records, it could happen that in one of the &lt;strong&gt;calls to the data source will return different results because between requests, someone may have updated the data source&lt;/strong&gt;!! Someone could perform an update to the same dataset you are working with, which results in you manipulating different datasets where you thought it was always the same. This unexpected consequence can create a very sneaky bug 🐞 to find.&lt;/p&gt;

&lt;p&gt;✔️🧠 Remember&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you can't be sure that someone will perform an operation that will force query evaluation more than once, it might be a good idea to use &lt;code&gt;.ToList()&lt;/code&gt; before sending the collection to another part of your code so to avoid these two situations.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🧠🤔 &lt;strong&gt;Things to remember&lt;/strong&gt;:
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;A call to a method that uses IE can be wasteful because we might not even use the work it has done for us.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A call to a method that uses deferred execution does not do any work internally until it's required to "produce" a result, this means &lt;strong&gt;potentially saving resources and time on doing useless work&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Given a method using a deferred execution (streaming), the processing scenario would be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A value that matches a predicate is found.&lt;/li&gt;
&lt;li&gt;The method returns a value and yields (gives control) to the caller.&lt;/li&gt;
&lt;li&gt;The next time the caller asks for another value, the program will continue execution from where he exited the scope before, right after a yield statement &lt;a href="https://dotnetfiddle.net/OkinpG" rel="noopener noreferrer"&gt;(as shown in this the code snippet)&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When the deferred execution method only looks at one element from the data source before yielding a result, we say it's a &lt;strong&gt;streaming deferred execution&lt;/strong&gt;, e.g., the &lt;em&gt;.Where()&lt;/em&gt; method.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When the deferred execution method looks at the entire data source before yielding a result, we say it's a &lt;strong&gt;non-streaming deferred execution&lt;/strong&gt;, e.g., the.OrderBy() method.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We should usually avoid using the &lt;em&gt;.ToList()&lt;/em&gt; method or any other methods that force query evaluation (or immediate execution) prematurely but at the same time, we should take into consideration it's dangers:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The IEnumerable interface is handy; we should use it carefully to avoid performance problems caused by multiple enumerations. In the worst-case scenarios, this could mean calling and querying our data source (e.g., a database) several times, wasting valuable time and network resources.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The use of the IEnumerable interface can bring immense flexibility and performance benefits to your codebase. Still, at the same time, if not designed correctly, it could introduce costly mistakes in both performance and data consistency.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I hope you found this post informative. If you have any doubts, knowledge you would like to share, or any questions, please put them bellow as the community members, and I will be glad to interact with you!&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
      <category>linq</category>
    </item>
    <item>
      <title>Algorithms Every Developer Should Know -  Binary Search</title>
      <dc:creator>Sam Fields</dc:creator>
      <pubDate>Tue, 15 Sep 2020 15:34:49 +0000</pubDate>
      <link>https://dev.to/samfieldscc/algorithms-in-c-sorting-with-binary-search-3gj</link>
      <guid>https://dev.to/samfieldscc/algorithms-in-c-sorting-with-binary-search-3gj</guid>
      <description>&lt;p&gt;In this new series &lt;strong&gt;"Algorithms Every Developer Should Know"&lt;/strong&gt;, I'm going to explore the implementation of algorithms everyone should know (if you need them, otherwise it's fine) using C#. For the first post, we will take a look at Binary Search, a search algorithm used to find the position of a specific value in a sorted array.&lt;/p&gt;

&lt;p&gt;Using an iterative or recursive approach, we can implement the binary search algorithm, and we'll take a look at both of them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Table Of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
Binary Search Algorithm 

&lt;ul&gt;
&lt;li&gt;Definition&lt;/li&gt;
&lt;li&gt;Time Complexity&lt;/li&gt;
&lt;li&gt;Auxiliary Space&lt;/li&gt;
&lt;li&gt;Step by Step pseudo-code&lt;/li&gt;
&lt;li&gt;Edge Cases&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Implementation of the Binary Search Algorithm using an iterative approach&lt;/li&gt;
&lt;li&gt;Implementation of the Binary Search Algorithm using an iterative approach&lt;/li&gt;
&lt;li&gt;Generic implementation of the binary search algorithm in C#&lt;/li&gt;
&lt;li&gt;Explore the code&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Binary Search Algorithm &lt;a&gt;&lt;/a&gt;
&lt;/h1&gt;

&lt;h3&gt;
  
  
  Definition &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Search a &lt;em&gt;sorted array&lt;/em&gt; by repeatedly dividing the search interval in half. This algorithm is useful in finding the position of a specific value in a sorted array.&lt;/p&gt;

&lt;h3&gt;
  
  
  Time Complexity &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;O(logN)&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt;Not going into detail but, but this tells us that for an array with N = 8, the output of logN is 3, which means we can split the array 3 times, so the number of steps (at most) to find the target value will be (3 + 1) = 4. Where 1 is the first attempt and also the best-case scenario in which the middle element of the array is our target value.&lt;/p&gt;

&lt;h3&gt;
  
  
  Auxiliary Space &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;O(1)&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;The constant space of 1 tells us that the algorithm does not require temporary additional memory allocations to do its work.&lt;/p&gt;

&lt;h3&gt;
  
  
  A step by step look at the algorithm &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Starting with the middle element:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;1.&lt;/strong&gt; If the target value is equal to the middle element of the array, then return the index of the middle element -&amp;gt; &lt;strong&gt;[goto 3]&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;2.&lt;/strong&gt; If not, then compare the middle element with the target value;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;2.1&lt;/strong&gt; If the target value is greater than the number in the middle index, then pick the elements to the right of the middle index, and -&amp;gt;  &lt;strong&gt;[goto 1]&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;2.2.&lt;/strong&gt; If the target value is less than the number in the middle index, then pick the elements to the left of the middle index, and -&amp;gt;  &lt;strong&gt;[goto 1]&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;3.&lt;/strong&gt; Found a match, then &lt;strong&gt;{return the index}&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;4.&lt;/strong&gt; Did not found a match, then &lt;strong&gt;{return -1}&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Edge Cases &lt;a&gt;&lt;/a&gt;&lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;There are some edge cases we must be aware:&lt;/p&gt;

&lt;h4&gt;
  
  
  1. The element might not exist in the array
&lt;/h4&gt;

&lt;p&gt;If the element does not exist in the array we must make sure that the search does not get out of bounds and consequently creating an exception because of it trying to access an invalid index.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. The target value could be in the rightmost or left most side of the array
&lt;/h4&gt;

&lt;h4&gt;
  
  
  3. The target value could be the initial, middle element
&lt;/h4&gt;

&lt;h4&gt;
  
  
  4. Duplicate entries could exist in the array
&lt;/h4&gt;

&lt;p&gt;Using this algorithm to deal with duplicates is not appropriate, but it will return the position for the first element that it finds.&lt;/p&gt;

&lt;h1&gt;
  
  
  Implementation of the Binary Search algorithm using an iterative approach &lt;a&gt;&lt;/a&gt;
&lt;/h1&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h1&gt;
  
  
  Implementation of the Binary Search algorithm using a recursive approach &lt;a&gt;&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;I find this approach the most natural when I start to write this algorithm. It doesn't make it better or worse than the iterative version.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h1&gt;
  
  
  Generic implementation of the binary search algorithm in C# &lt;a&gt;&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;This algorithm is not necessarily used to only sort integers or numbers. You can use it to sort anything as long you can provide a way for the computer to know how to classify different objects. To see that in action, you can see &lt;a href="https://dotnetfiddle.net/6xmER0"&gt;this fiddle&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For this, you can use different strategies:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The generic type you are using implements an &lt;a href="https://docs.microsoft.com/en-us/dotnet/api/system.icomparable-1?view=netcore-3.1"&gt;IComparable&lt;/a&gt; and/or &lt;a href="https://docs.microsoft.com/en-us/dotnet/api/system.iequatable-1?view=netcore-3.1"&gt;IEquatable&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Add parameter to the method that executes the algorithm and passes a &lt;a href="https://docs.microsoft.com/en-us/dotnet/api/system.comparison-1?view=netcore-3.1"&gt;IComparison&lt;/a&gt; parameter.&lt;/li&gt;
&lt;li&gt;Add parameter to the method that executes the algorithm and passes a &lt;a href="https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.icomparer-1?view=netcore-3.1"&gt;ICompararer&lt;/a&gt; parameter.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Explore the code &lt;a&gt;&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;I have added the code in &lt;a href="https://dotnetfiddle.net/OkinpG"&gt;this fiddle&lt;/a&gt;, so you can test the variations and play with the code at will to make it easier to understand the concepts.&lt;/p&gt;

</description>
      <category>algorithms</category>
      <category>csharp</category>
      <category>sorting</category>
      <category>binarysearch</category>
    </item>
    <item>
      <title>Things you need to know as a C# developer - Collections</title>
      <dc:creator>Sam Fields</dc:creator>
      <pubDate>Mon, 14 Sep 2020 17:17:39 +0000</pubDate>
      <link>https://dev.to/samfieldscc/things-you-need-to-know-as-a-c-developer-collections-md6</link>
      <guid>https://dev.to/samfieldscc/things-you-need-to-know-as-a-c-developer-collections-md6</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fo7d36cg3ex36hqudbo5j.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fo7d36cg3ex36hqudbo5j.jpg" alt="Magnetic Memory Array"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this post, we will take a look at the main C# collections, summarize their main features, and quickly bring to attention some sneaky things about them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Table Of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
Arrays

&lt;ul&gt;
&lt;li&gt;Features of an array&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

Collections

&lt;ul&gt;
&lt;li&gt;Common features of almost all collections&lt;/li&gt;
&lt;li&gt;Selecting the best collection for the job&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

Lists

&lt;ul&gt;
&lt;li&gt;List add operations can be costly&lt;/li&gt;
&lt;li&gt;Example of an O(n) operation using RemoveAt(0) with a List&lt;/li&gt;
&lt;li&gt;Do not perform O(n) operations inside a loop!&lt;/li&gt;
&lt;li&gt;Sorted List&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;LinkedList&lt;/li&gt;

&lt;li&gt;

Dictionary and related types

&lt;ul&gt;
&lt;li&gt;Features of a Dictionary&lt;/li&gt;
&lt;li&gt;Sorted Dictionary&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Stack&lt;/li&gt;

&lt;li&gt;Queue&lt;/li&gt;

&lt;li&gt;

HashSet

&lt;ul&gt;
&lt;li&gt;The best solution for dealing with duplicates&lt;/li&gt;
&lt;li&gt;Comparison between Dictionary and HashSet&lt;/li&gt;
&lt;li&gt;SortedSet&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

Read-Only Collection

&lt;ul&gt;
&lt;li&gt;Caution ReadOnlyDictionary it's not really read-only&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Immutable Collections&lt;/li&gt;

&lt;li&gt;Some examples of time complexity in collections&lt;/li&gt;

&lt;/ul&gt;

&lt;h1&gt;
  
  
  Arrays &lt;a&gt;&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;An array is a reference type that contains a fixed-size list of elements that can be accessed using a positional index number. They are available through the &lt;a href="https://docs.microsoft.com/en-us/dotnet/api/system.array?view=netcore-3.1" rel="noopener noreferrer"&gt;System.Array&lt;/a&gt; namespace.&lt;/p&gt;

&lt;h3&gt;
  
  
  Features of an Array &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Strongly typed&lt;/li&gt;
&lt;li&gt;Useful when an array size can in known at design time.&lt;/li&gt;
&lt;li&gt;No ability to add or remove elements.&lt;/li&gt;
&lt;li&gt;Allows for multiple dimensions (array of an array)&lt;/li&gt;
&lt;li&gt;Using an array might allow you to squeeze out a bit more performance with large datasets.&lt;/li&gt;
&lt;li&gt;Two similar arrays are not equal when compared (arr1 == arr2) because they are reference types. The memory location is what's compared and not the content of the array.&lt;/li&gt;
&lt;li&gt;To compare the content of the array, we can use the possibly expensive SequenceEqual() method.&lt;/li&gt;
&lt;li&gt;When assigning array X to array Y, the equality of (x == y) equates to true.&lt;/li&gt;
&lt;li&gt;An array occupies a single continuous block of memory.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Collections &lt;a&gt;&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;A collection is a class that provides in-memory management of groups of items; by providing methods for adding, removing, or finding things in the collection. The items can be similar (strongly typed) or different from each other.&lt;/p&gt;

&lt;p&gt;There are four main types of collections: generic collections and non-generic collections, concurrent and immutable. These are the following namespaces:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Not Strongly typed &amp;amp; Strongly typed &lt;a href="(https://docs.microsoft.com/en-us/dotnet/api/system.collections?view=netcore-3.1)"&gt;System.Collections&lt;/a&gt; &amp;amp;(&lt;a href="https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic?view=dotnet-plat-ext-3.1" rel="noopener noreferrer"&gt;System.Collections.Generic&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Concurrent (&lt;a href="https://docs.microsoft.com/en-us/dotnet/api/system.collections.concurrent?view=netcore-3.1" rel="noopener noreferrer"&gt;System.Collections.Concurrent&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Immutable (&lt;a href="https://docs.microsoft.com/en-us/dotnet/api/system.collections.immutable?view=netcore-3.1" rel="noopener noreferrer"&gt;System.Collections.Immutable&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Common features of almost all collections &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Used when the number of elements is unknown at design time, or it's required to have the ability to add and remove elements.&lt;/li&gt;
&lt;li&gt;The ability to iterate through the collection (implements the IEnumerable interface).&lt;/li&gt;
&lt;li&gt;A method to copy it's elements to an array with CopyTo().&lt;/li&gt;
&lt;li&gt;Provide information about the capacity of the collection and the number of elements currently in it.&lt;/li&gt;
&lt;li&gt;They are 0-indexed, meaning the first element is always at [0].&lt;/li&gt;
&lt;li&gt;Two similar collections are not equal when comparing (arrayX == arrayZ) because they are reference types. The memory location (reference) of the object is what's compared and not the content of the collection.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Selecting the best collection for the job &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;In general, avoid using non-generic collections. I recommend using the generic and concurrent versions of the collections because of their greater type safety and other improvements.&lt;/p&gt;

&lt;p&gt;To learn how to choose the appropriate collection, check &lt;a href="https://dev.tothis%20table"&gt;https://docs.microsoft.com/en-us/dotnet/standard/collections/#choose-a-collection&lt;/a&gt; and &lt;a href="https://dev.tothis%20article"&gt;https://docs.microsoft.com/en-us/dotnet/standard/collections/selecting-a-collection-class&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Taking a look at the .NET collections
&lt;/h3&gt;

&lt;p&gt;Next, I will quickly introduce the properties and make some observations of some of the .NET collections.&lt;/p&gt;

&lt;h1&gt;
  
  
  Lists &lt;a&gt;&lt;/a&gt;
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Occupies a single continuous block of memory.&lt;/li&gt;
&lt;li&gt;Optimized for fast lookups&lt;/li&gt;
&lt;li&gt;To look up an element using the List .[] index access is an O(1) operation.&lt;/li&gt;
&lt;li&gt;To lookup an element using a method like List.Find(x =&amp;gt; x == y) the operation will be O(n).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  List add operations can be costly &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;When a new List is created; Internally, an array, of a specific size, int[] is created with an initial capacity of N;&lt;/li&gt;
&lt;li&gt;After N add operations, the array is not big enough. A new array with more capacity is created, the contents of the current array are copied, the previous array gets discarded, and the new element is added.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;An operation to add an element to a List can be costly because it can cause memory relocations, which makes the operation possibly slow. Usually, the List is allocated with enough space, but attention should be given to this for a list where large datasets are being inserted.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example of an O(n) operation using RemoveAt(0) with a List &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;It's important to note that we cannot have empty spaces in memory.&lt;br&gt;
When removing the first element in a list, all its elements must be moved (-1 positions) in memory. This means that removing an element at for a list of n elements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;At [0] position of an array is an O(1) operation&lt;/li&gt;
&lt;li&gt;At [x] position of an array is an O(n-x) operation&lt;/li&gt;
&lt;li&gt;At [n-1] position of an array is an O(n) operation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Or we can say that the RemoveAt() method is an O(n) operations where n is (Count - index).&lt;/p&gt;
&lt;h3&gt;
  
  
  Do not perform O(n) operations inside a loop! &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Look at the following piece of code:&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;for&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;i&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lst&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="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="err"&gt;≥&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="err"&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="nf"&gt;isPair&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;anotherList&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;])){&lt;/span&gt;
      &lt;span class="n"&gt;lst&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RemoveAt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The RemoveAt() is O(n), and the entire loop could be in the worst case also O(n), which creates a complexity of O(n²), which should be avoided whenever possible; this is even a bigger problem for large datasets. In general, we should avoid O(n) operations inside loops. An alternative to this is using LINQ method RemoveAll():&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="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RemoveAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;isPair&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  SortedList &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Functionally a dictionary&lt;/li&gt;
&lt;li&gt;Internally uses a list&lt;/li&gt;
&lt;li&gt;Uses less memory than SortedDictionary&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  LinkedList &lt;a&gt;&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;This is a very well known data structure where it's data elements order is not given by their physical placement in memory. Instead, each element points to the next. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Optimized for fast changes (adding and removing is fast). Very scalable.&lt;/li&gt;
&lt;li&gt;Contrary to a List, when removing an element in the middle of the LinkedList, there is no need for memory relocations. Only update the references in the previous and next node.&lt;/li&gt;
&lt;li&gt;The lookup is slow (because we have to jump from one place to another).&lt;/li&gt;
&lt;li&gt;Under the hood, the data is saved to a LinkedListNode.&lt;/li&gt;
&lt;li&gt;No direct indexed element access.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because of its optimization for changes, a LinkedList could be used as a temporary working set for operations that are performing a large number of changes to it; it can then be copied to another collection when done with editing the List.&lt;/p&gt;

&lt;h1&gt;
  
  
  Dictionary and related types &lt;a&gt;&lt;/a&gt;
&lt;/h1&gt;

&lt;h3&gt;
  
  
  Features of a Dictionary &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Lists are not suitable for lookups in large data sets; the Dictionary fetches an element for the cost of O(1) when trying to get an element from it!&lt;/li&gt;
&lt;li&gt;The Dictionary uses keys to index its elements; they can be of any data type, some better than others.
The keys are case sensitive, and we must specify a StringComparer when using string keys to avoid problems.&lt;/li&gt;
&lt;li&gt;The Dictionary returns a key-value pair and not just the value.&lt;/li&gt;
&lt;li&gt;The items in a dictionary are not ordered.&lt;/li&gt;
&lt;li&gt;When using custom types for the key, we must implement an IEquatable interface and specify an override to the following methods: "bool Equals(object obj)" method, and the "GetHashCode(…)" method.

&lt;ul&gt;
&lt;li&gt;Optionally, you can also specify the "bool operator==" operator.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Make sure to have consistency between the Equality comparator and the HashCode generator. Take advantage of existing MS implementations.&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  SortedDictionary &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Keyed access to items&lt;/li&gt;
&lt;li&gt;Sorts items only by key&lt;/li&gt;
&lt;li&gt;Guaranteed sort order when enumerating&lt;/li&gt;
&lt;li&gt;Modifications scale better&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Stack &lt;a&gt;&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;We pop the last item in the collection and push items to it.&lt;br&gt;
Useful when we have items (or tasks) to be processed. New items are added to the collection; Items are removed as they are processed.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An Undo operation is a good use case of this data structure.&lt;/li&gt;
&lt;li&gt;Items are stored in order (like List ).&lt;/li&gt;
&lt;li&gt;Retrieving an item removes it.&lt;/li&gt;
&lt;li&gt;No direct element lookup.&lt;/li&gt;
&lt;li&gt;Provides the most recent item in the collection.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Queue &lt;a&gt;&lt;/a&gt;
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Behaves like a real queue; the first item in is the first item out (FIFO).&lt;/li&gt;
&lt;li&gt;Retrieving an item with "Dequeue()" removes it from the queue, but we can use "Peek()" to see the next item in the queue without removing it.&lt;/li&gt;
&lt;li&gt;No direct element lookup but supports enumeration with the foreach loop.&lt;/li&gt;
&lt;li&gt;Provides the item waiting the longest time in the queue.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  HashSet &lt;a&gt;&lt;/a&gt;
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Useful to enforce uniqueness out of the box.&lt;/li&gt;
&lt;li&gt;Allows for set operations (unions and intersections).&lt;/li&gt;
&lt;li&gt;Similar to dictionaries (But lack keys and don't support lookups).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  HashSet for dealing with duplicates &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;There are two ways to deal with unwanted duplicates: the native way and the better away (just kidding, kind of).&lt;/p&gt;

&lt;h4&gt;
  
  
  The naive way:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var uniqueListOfNumbers = listOfNumbers.Distinct().ToList();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This strategy works fine for small collections but is not ideal for extensive collections.&lt;/p&gt;

&lt;h4&gt;
  
  
  The better way
&lt;/h4&gt;

&lt;p&gt;Another strategy is to use a HashSet; this way, when we are adding elements to the HashSet, it will ignore duplicate values when adding them to the set! It's very scalable and efficient at enforcing uniqueness.&lt;/p&gt;

&lt;h3&gt;
  
  
  Comparison between Dictionary and HashSet &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;They are both unordered bags of objects and use similar data structures internally.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dictionaries&lt;/strong&gt; have keys and use them to perform lookups | &lt;strong&gt;HashSet&lt;/strong&gt; does not have keys and does not support lookup (only enumeration).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dictionaries&lt;/strong&gt; have unique keys | &lt;strong&gt;HashSet&lt;/strong&gt; has unique values.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dictionaries&lt;/strong&gt; throw an exception when adding duplicates | &lt;strong&gt;HashSet&lt;/strong&gt; ignores when adding duplicates.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  SortedSet &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Used to order a set as you add elements to it.&lt;/li&gt;
&lt;li&gt;Requires that an implementation of IComparer is provided so that the sorted set can use it to compare elements when sorting. * We are the ones that decide how the sorting happens.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Read-Only Collections &lt;a&gt;&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;Read-only collections only allow reading of the collection (pretty self-explanatory). This is useful if you have a collection that you want to be able to modify internally, but you want it to be read-only to external users of your library or application.&lt;/p&gt;

&lt;h3&gt;
  
  
  Caution ReadOnlyDictionary it's not really read-only &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;When we update a standard Dictionary , and we then create a new ReadOnlyDictionary based on the standard dictionary  Dictionary  the changes will also be reflected in the ReadOnlyDictionary, maybe defeating our initial goal. To avoid this, we use ImmutableDictionary, which will guarantee that no changes are made to the collection.&lt;/p&gt;

&lt;p&gt;This happens because the ReadOnlyDictionary adds a read-only wrapper around the original collection reference! This is true to all ReadOnly collections.&lt;/p&gt;

&lt;h2&gt;
  
  
  Immutable Collections &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;An immutable collection prevents any changes to the collection. It's useful to enforce that a dataset should not be tampered with, possibly avoiding other programmers to introduce bugs in your code.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Although immutable collections cannot be modified by "normal" C# code, they could be manipulated with reflection or unmanaged code.&lt;/li&gt;
&lt;li&gt;Immutable collections are guaranteed to be thread-safe because of their immutable nature.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Some notes about time complexity in collections &lt;a&gt;&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;As you should know, the time complexity of any piece of code is an approximation of the time (it's not an absolute measure) that piece of code takes to execute. With collections, it will tell you how the performance scales as the collection size increases.&lt;/p&gt;

&lt;h3&gt;
  
  
  O(1)
&lt;/h3&gt;

&lt;p&gt;Represents a constant time to execute the operation, independent of the size of the collection.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It's the lookup time for an indexed lookup in an array or List.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  O(n)
&lt;/h3&gt;

&lt;p&gt;Represents a time that scales linearly with the size of the collection&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Removing the nth item from a list.&lt;/li&gt;
&lt;li&gt;The time to enumerate a collection with n items.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  O(n²)
&lt;/h3&gt;

&lt;p&gt;Represents a time that scales in a non-linear way.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Very slow for extensive collections&lt;/li&gt;
&lt;li&gt;Rare in .NET, unless we do something like putting an O(n) operation inside a loop.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  O(log n) &amp;amp; O(n log n)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Found in some collections that use more complex algorithms than just arrays under the hood.&lt;/li&gt;
&lt;li&gt;For huge collections, O(log n) performs as good as O(1).&lt;/li&gt;
&lt;li&gt;For huge collections, O(n log n) performs as good as O(n).&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  References
&lt;/h1&gt;

&lt;p&gt;[1]. &lt;a href="https://docs.microsoft.com/en-us/dotnet/api/system.array?view=netcore-3.1" rel="noopener noreferrer"&gt;Arrays - https://docs.microsoft.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>Things you need to know as a C# developer - Build types</title>
      <dc:creator>Sam Fields</dc:creator>
      <pubDate>Sat, 05 Sep 2020 20:37:33 +0000</pubDate>
      <link>https://dev.to/samfieldscc/things-you-need-to-know-as-a-c-developer-build-types-2igl</link>
      <guid>https://dev.to/samfieldscc/things-you-need-to-know-as-a-c-developer-build-types-2igl</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UIS7IzE0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/a1lwlgbue9dzd8awqdpd.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UIS7IzE0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/a1lwlgbue9dzd8awqdpd.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This post is part of a series of posts that I'm using to compile the most significant bits and tips about several things in C#. The purpose of this post is to be used as a way of review or quickly learn something new about C#.&lt;/p&gt;

&lt;p&gt;In the first post of this series, we will summarize the C# build types, where every variable type is either a value type or a reference type.&lt;/p&gt;

&lt;h1&gt;
  
  
  Value Types
&lt;/h1&gt;

&lt;p&gt;Variables that are value types contain their data, meaning value types are the value themselves. Below are some of the properties of this type:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Types like a struct, int, float are value types.&lt;/li&gt;
&lt;li&gt;Each variable holds an independent instance or copy of the type.&lt;/li&gt;
&lt;li&gt;Value changes to the variable do not affect other copies.&lt;/li&gt;
&lt;li&gt;The value in the variable is the information.&lt;/li&gt;
&lt;li&gt;Because it is not a reference, it cannot be null.&lt;/li&gt;
&lt;li&gt;You might have to check the variable for null.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Passing Value Types by Value
&lt;/h2&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h2&gt;
  
  
  Passing Value Types by Reference
&lt;/h2&gt;

&lt;p&gt;In some cases, passing value types by value can create a performance bottleneck because the value passed (and copied) can be a complex data structure. Therefore, it can be a good idea to pass those data structures by reference. Bellow, a more straightforward example, shows how this works:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h1&gt;
  
  
  Reference Type
&lt;/h1&gt;

&lt;p&gt;Variables of reference types store references to their data (objects), meaning that reference types reference something. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;All C# classes are reference types.&lt;/li&gt;
&lt;li&gt;The object instance shares its data, amongst other copies.&lt;/li&gt;
&lt;li&gt;Value change affects all the references pointing to it.&lt;/li&gt;
&lt;li&gt;The variable can point to nothing =&amp;gt; it can be null.&lt;/li&gt;
&lt;li&gt;Null checking may be required.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Passing Reference Types by Value
&lt;/h2&gt;

&lt;p&gt;This example displays all the ways a reference can behave:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h2&gt;
  
  
  Passing Reference Types by Reference (using the ref keyword)
&lt;/h2&gt;

&lt;p&gt;Reference types behave slightly differently when you use the ref keyword. The example below displays how the ref keyword can affect a variable when passed to a method:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h1&gt;
  
  
  Important Notes
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;The CLR can store objects in three locations: registers, stack, or the managed heap.&lt;/li&gt;
&lt;li&gt;A value type does not exist exclusively in the stack! It can exist in any of those three locations.&lt;/li&gt;
&lt;li&gt;A reference type can exist either on the managed heap or the stack. The location of the variable in memory depends on many factors. It's scope, the lifetime of the variable, and the implementation of the CLR.&lt;/li&gt;
&lt;li&gt;Use the ref keyword to avoid copies of complex value type data structures.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Quiz
&lt;/h1&gt;

&lt;p&gt;1 &lt;strong&gt;What's the main difference between a value type and a reference type?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A value type holds the value itself, and a reference type holds a reference "memory address" to the value.&lt;/p&gt;

&lt;p&gt;2 &lt;strong&gt;How do you pass a value type variable by reference to a method?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To pass a value type parameter by reference, we can use the "ref" keyword available since C# 7.0.&lt;/p&gt;

&lt;p&gt;3 &lt;strong&gt;Value type variables are stored wherein the memory landscape?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Contrary to popular belief, value types can either be stored in the stack or the managed heap. In some cases, depending on the variable lifetime, it might even be stored in a register. It's difficult to pinpoint the precise location at any given point since the CLR implementation must also be taken into consideration.&lt;/p&gt;

&lt;h1&gt;
  
  
  References
&lt;/h1&gt;

&lt;p&gt;[1]. &lt;a href="https://dev.toPassing%20Reference-Type%20Parameters"&gt;https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/passing-reference-type-parameters&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[2]. &lt;a href="https://dev.toPassing%20Value-Type%20Parameters"&gt;https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/passing-value-type-parameters&lt;/a&gt;&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
    </item>
  </channel>
</rss>
