<?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: G.L Solaria</title>
    <description>The latest articles on DEV Community by G.L Solaria (@glsolaria).</description>
    <link>https://dev.to/glsolaria</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%2F229706%2F689efcae-08e3-4177-ab5e-c980e20d6bb6.png</url>
      <title>DEV Community: G.L Solaria</title>
      <link>https://dev.to/glsolaria</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/glsolaria"/>
    <language>en</language>
    <item>
      <title>.NET Aspire and WSL Docker</title>
      <dc:creator>G.L Solaria</dc:creator>
      <pubDate>Sat, 15 Nov 2025 04:26:10 +0000</pubDate>
      <link>https://dev.to/glsolaria/net-aspire-and-wsl-docker-21k4</link>
      <guid>https://dev.to/glsolaria/net-aspire-and-wsl-docker-21k4</guid>
      <description>&lt;p&gt;So you have probably heard how great &lt;a href="https://learn.microsoft.com/en-us/dotnet/aspire/get-started/aspire-overview" rel="noopener noreferrer"&gt;.NET Aspire&lt;/a&gt; is. If you aren't convinced, take the time to watch this video &lt;a href="https://youtu.be/41PD08tSH4E?si=kWcGM7IlbaKiphUq" rel="noopener noreferrer"&gt;.NET Aspire Tutorial For Beginners&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Currently, the &lt;a href="https://learn.microsoft.com/en-us/dotnet/aspire/fundamentals/setup-tooling?tabs=windows&amp;amp;pivots=vscode#container-runtime" rel="noopener noreferrer"&gt;only supported way&lt;/a&gt; to use Aspire on Windows requires either &lt;a href="https://podman.io/" rel="noopener noreferrer"&gt;Podman&lt;/a&gt; or &lt;a href="https://www.docker.com/products/docker-desktop/" rel="noopener noreferrer"&gt;Docker Desktop&lt;/a&gt; to be installed. If, for whatever reason, you can't use either of these 2 options, there is another way to connect .NET Aspire directly to Docker running on WSL. But be warned - setting up this option isn't simple, isn't supported, and has some limitations. If you need something that is simple and supported, use Podman or Docker Desktop. &lt;/p&gt;

&lt;p&gt;The solution I have posted below is not ideal and I am keen to hear from anyone who has managed to find a better solution. Creating a &lt;code&gt;docker.cmd&lt;/code&gt; file with &lt;code&gt;wsl.exe docker %*&lt;/code&gt; no longer works on the latest version of Aspire. Creating a wrapper application that correctly handles the complex argument escaping required to work with Aspire will probably end up blocked by &lt;a href="https://learn.microsoft.com/en-us/windows/apps/develop/smart-app-control/overview" rel="noopener noreferrer"&gt;Smart App Control&lt;/a&gt; unless you sign the application. So please post a comment if you have found a better solution that doesn't use Docker Desktop or Podman.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install WSL
&lt;/h2&gt;

&lt;p&gt;If you are not familiar with Windows Subsystem for Linux (WSL) then you have a steep learning curve and this approach may not be right for you. If you want to go ahead any way you can start to learn by going &lt;a href="https://code.visualstudio.com/docs/remote/wsl" rel="noopener noreferrer"&gt;here&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;To install WSL, open a powershell command prompt as Administrator and type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;wsl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--install&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-d&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Ubuntu-24.04&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Follow the instructions to create a WSL user/password and reboot Windows.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install Visual Studio Code
&lt;/h2&gt;

&lt;p&gt;Next &lt;a href="https://code.visualstudio.com/docs/setup/windows#_install-vs-code-on-windows" rel="noopener noreferrer"&gt;install VS Code&lt;/a&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  Install Docker in WSL
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Start a WSL Session from VS Code
&lt;/h3&gt;

&lt;p&gt;Start VS Code and select &lt;code&gt;Open a Remote Window&lt;/code&gt; in the bottom left of the window. &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe08w6ynrekrgt6a3arqc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe08w6ynrekrgt6a3arqc.png" alt=" " width="800" height="640"&gt;&lt;/a&gt;&lt;br&gt;
Then select &lt;code&gt;Connect to WSL&lt;/code&gt;.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu5ojf4iyj1xjfqtjrirx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu5ojf4iyj1xjfqtjrirx.png" alt=" " width="596" height="249"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Install Docker on WSL
&lt;/h3&gt;

&lt;p&gt;From a terminal in VS Code connected to WSL, install Docker on your instance of Ubuntu by following &lt;a href="https://docs.docker.com/engine/install/ubuntu/" rel="noopener noreferrer"&gt;these instructions&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Allow Docker Commands to Run as Non-Root User
&lt;/h3&gt;

&lt;p&gt;To be able to run docker commands on WSL without needing to run with &lt;code&gt;sudo&lt;/code&gt; you will need to &lt;a href="https://docs.docker.com/engine/install/linux-postinstall/#manage-docker-as-a-non-root-user" rel="noopener noreferrer"&gt;follow these instructions&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Install the Container Tools Microsoft Extension in VS Code
&lt;/h3&gt;

&lt;p&gt;From the Extensions tab in VS Code connected to WSL, search for &lt;code&gt;Container Tools&lt;/code&gt; and verify you have the found &lt;a href="https://code.visualstudio.com/docs/containers/overview" rel="noopener noreferrer"&gt;official Microsoft extension&lt;/a&gt; then install it.&lt;/p&gt;
&lt;h3&gt;
  
  
  Verify the Installation of Docker on WSL
&lt;/h3&gt;

&lt;p&gt;Click on the container icon in VS Code connected to WSL and confirm the Container Tools extension can connect to the Docker daemon. If it is connected you should see &lt;code&gt;No items found&lt;/code&gt; in the Images and Containers panel.&lt;/p&gt;

&lt;p&gt;From a terminal in VS Code connected to WSL, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run hello-world
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should now see something like this:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm4bzbd0n51z2md3d1t48.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm4bzbd0n51z2md3d1t48.png" alt=" " width="325" height="564"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Modify Docker Configuration to Listen on TCP
&lt;/h3&gt;

&lt;p&gt;In a terminal opened in VS Code connected to WSL, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;nano /etc/docker/daemon.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Enter the following text and save:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"hosts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"unix:///var/run/docker.sock"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"tcp://0.0.0.0:2375"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next override the Docker daemon startup to use this new daemon.json configuration file by:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo mkdir -p /etc/systemd/system/docker.service.d
sudo nano /etc/systemd/system/docker.service.d/override.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Enter the following text and save:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Service]
ExecStart=
ExecStart=/usr/bin/dockerd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Reload and restart Docker:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo systemctl daemon-reload
sudo systemctl restart docker
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next allow the port through the Ubuntu firewall:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo iptables -I INPUT -p tcp --dport 2375 -j ACCEPT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally note down the IP address of the WSL Ubuntu instance:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ip addr show eth0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Add DOCKER_HOST Windows Environment Variable
&lt;/h3&gt;

&lt;p&gt;We need to create an environment variable that will be used on the Windows side to communicate with Docker running in WSL. &lt;/p&gt;

&lt;p&gt;To do this create a new user environment variable in Windows called &lt;code&gt;DOCKER_HOST&lt;/code&gt; and set it to &lt;code&gt;tcp://wslip:2375&lt;/code&gt; where &lt;code&gt;wslip&lt;/code&gt; is the IP address you noted down from the WSL command &lt;code&gt;ip addr show eth0&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Download Docker CLI for Windows
&lt;/h2&gt;

&lt;p&gt;Next we need the &lt;code&gt;docker.exe&lt;/code&gt; that will run on Windows. The official builds of just the CLI are &lt;a href="https://download.docker.com/win/static/stable/x86_64/" rel="noopener noreferrer"&gt;here&lt;/a&gt;. Download the latest and extract the zip file to some location.&lt;/p&gt;

&lt;p&gt;Add the path to &lt;code&gt;docker.exe&lt;/code&gt; to your Windows &lt;code&gt;PATH&lt;/code&gt; environment variable.&lt;/p&gt;

&lt;p&gt;Finally, verify you can now run docker commands that connect to your WSL docker engine by opening a powershell prompt and running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker image ls
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see the &lt;code&gt;hello-world&lt;/code&gt; image in the output.&lt;/p&gt;

&lt;h2&gt;
  
  
  Limitations
&lt;/h2&gt;

&lt;p&gt;You should now be able to run your .NET Aspire App Host project that manages containers but there are limitations.&lt;/p&gt;

&lt;p&gt;You will need to keep your VS Code window to WSL open while you want to run your Aspire application. This is because Windows will automatically shut WSL down after a period of inactivity. &lt;/p&gt;

&lt;p&gt;Also Windows may decide to change the IP address of your WSL instance. If it does, you will need to edit the &lt;code&gt;DOCKER_HOST&lt;/code&gt; environment variable and restart your IDE. If this bothers you, you could look in to setting up a static IP address for WSL but this is also not straight forward.&lt;/p&gt;

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

&lt;p&gt;I warned you it wasn't simple! If you know of a better way that does not involve installing another Windows application like Podman or Docker Desktop, then please leave a comment.  &lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>docker</category>
    </item>
    <item>
      <title>Assessing Security Risks of Open Source Repos</title>
      <dc:creator>G.L Solaria</dc:creator>
      <pubDate>Mon, 16 Jun 2025 03:20:11 +0000</pubDate>
      <link>https://dev.to/glsolaria/assessing-security-risks-of-open-source-repos-293m</link>
      <guid>https://dev.to/glsolaria/assessing-security-risks-of-open-source-repos-293m</guid>
      <description>&lt;p&gt;So you want to use software from a GitHub or GitLab repository. But how can you assess the security risks associated with the repo? &lt;/p&gt;

&lt;p&gt;Thankfully there is a utility from &lt;a href="https://openssf.org/" rel="noopener noreferrer"&gt;OpenSSF&lt;/a&gt; called &lt;a href="https://github.com/ossf/scorecard" rel="noopener noreferrer"&gt;scorecard&lt;/a&gt; you can use to help you understand the risks involved with using the software from a public repo. &lt;/p&gt;

&lt;h2&gt;
  
  
  OpenSSF
&lt;/h2&gt;

&lt;p&gt;The Open Source Security Foundation is part of the Linux Foundation and was formed in 2020 to help improve the security of open source software. The &lt;a href="https://openssf.org/about/members/" rel="noopener noreferrer"&gt;premier members&lt;/a&gt; of the foundation include Google, GitHub, Microsoft, Apple, and Intel.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scorecard viewer
&lt;/h2&gt;

&lt;p&gt;So how can you get a quick overview of the security risks associated with using a GitHub or GitLab repo? Well the repo may already have been indexed by OpenSSF. Simply replace the placeholders in the following URL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://scorecard.dev/viewer/?uri=&amp;lt;github_or_gitlab&amp;gt;.com/&amp;lt;user_name_or_org&amp;gt;/&amp;lt;repository_name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example, to view a report on the scorecard repo go to &lt;a href="https://scorecard.dev/viewer/?uri=github.com/ossf/scorecard" rel="noopener noreferrer"&gt;https://scorecard.dev/viewer/?uri=github.com/ossf/scorecard&lt;/a&gt; and you will see something like this:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcydejvtvlgm1pdtu44su.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcydejvtvlgm1pdtu44su.png" alt="Image description" width="800" height="788"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Scorecard command line utility
&lt;/h2&gt;

&lt;p&gt;If the GitHub repo isn't already indexed by OpenSSF, you will need to generate a GitHub personal access token to run the utility from the command line. This is because GitHub imposes API rate limits on unauthenticated requests. Instructions on how to set up the token are documented &lt;a href="https://github.com/ossf/scorecard/tree/main?tab=readme-ov-file#scorecard-command-line-interface" rel="noopener noreferrer"&gt;here&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;You can install the utility standalone but the easiest way to run it is via a docker container:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run -e GITHUB_AUTH_TOKEN=&amp;lt;your_access_token&amp;gt; gcr.io/openssf/scorecard:stable  --repo=&amp;lt;url_of_repo_to_audit&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will output an ASCII table that looks something like:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvhloo8m8isviwqyu49ix.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvhloo8m8isviwqyu49ix.png" alt="Image description" width="571" height="432"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Probing for security vulnerabilities
&lt;/h2&gt;

&lt;p&gt;You can also use the command line utility to &lt;a href="https://openssf.org/blog/2024/04/17/beyond-scores-with-openssf-scorecard-granular-structured-results-for-custom-policy-enforcement/" rel="noopener noreferrer"&gt;get more detailed information on the security vulnerabilities&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run -e GITHUB_AUTH_TOKEN=&amp;lt;your_access_token&amp;gt; gcr.io/openssf/scorecard:stable  --repo=&amp;lt;url_of_repo_to_audit&amp;gt; --probes=hasOSVVulnerabilities --format=probe
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will output a JSON file with the known security vulnerabilities. &lt;/p&gt;

&lt;h2&gt;
  
  
  More details
&lt;/h2&gt;

&lt;p&gt;Read the &lt;a href="https://github.com/ossf/scorecard" rel="noopener noreferrer"&gt;docs&lt;/a&gt; for more details on how to use this utility, use it in your CI/CD pipeline, or make use of it as a repo maintainer. &lt;/p&gt;

</description>
      <category>security</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Decompiling and Debugging with Ghidra</title>
      <dc:creator>G.L Solaria</dc:creator>
      <pubDate>Sat, 01 Feb 2025 03:55:28 +0000</pubDate>
      <link>https://dev.to/glsolaria/decompiling-and-debugging-with-ghidra-15k3</link>
      <guid>https://dev.to/glsolaria/decompiling-and-debugging-with-ghidra-15k3</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/NationalSecurityAgency/ghidra" rel="noopener noreferrer"&gt;Ghidra&lt;/a&gt; is an open source tool developed by the U.S. National Security Agency (NSA) for reverse engineering binaries when you don't have access to the source code. It can be used to assist in capture the flag cyber security challenges. Among its many features is that it can convert binaries into C code. Ghidra can run headless or through a Java GUI. This post will focus on using the GUI to decompile and debug a C program given just the binary. &lt;/p&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;p&gt;This installation guide assumes you are installing to a Debian based Linux distribution.&lt;/p&gt;

&lt;h3&gt;
  
  
  Install JDK
&lt;/h3&gt;

&lt;p&gt;Ghidra requires the Java Development Kit (currently uses JDK 21) to run. Eclipse Termurin is a free, open-source JDK provided by the Eclipse Adoptium project. It is a build of OpenJDK that is widely used as an alternative to Oracle JDK. Depending on the Linux distribution, you may be able to install the JDK using the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;temurin-21-jdk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If your distribution doesn't distribute a Temurin JDK, then you can download the version for your hardware architecture from &lt;a href="https://adoptium.net/temurin/releases/" rel="noopener noreferrer"&gt;Adoptium&lt;/a&gt;. Follow the installation instructions for &lt;a href="https://adoptium.net/installation/archives/" rel="noopener noreferrer"&gt;archives&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Install GBD
&lt;/h3&gt;

&lt;p&gt;Run the following command to install GDB (the GNU debugger) if you want to be able to use Ghidra's debugging features:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;gdb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will need gdb compiled with Python version of at least 3.7. Verify the version of Python supported by GDB by running the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;gdb
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; python import sys
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; python print&lt;span class="o"&gt;(&lt;/span&gt;sys.version&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;gdb&lt;span class="o"&gt;)&lt;/span&gt; quit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make sure the version is 3.7 or higher.&lt;/p&gt;

&lt;h3&gt;
  
  
  Install psutil and protobuf Python Modules
&lt;/h3&gt;

&lt;p&gt;To use the GDB debugger in Ghidra, you need the psutil and protobuf Python modules to be installed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;python3-psutil python3-protobuf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Install Ghidra
&lt;/h3&gt;

&lt;p&gt;Download the appropriate zip file from the &lt;a href="https://github.com/NationalSecurityAgency/ghidra/releases" rel="noopener noreferrer"&gt;GitHub repo&lt;/a&gt;. Unzip it to a directory then find the "ghidraRun" script and run it. &lt;/p&gt;

&lt;h2&gt;
  
  
  Create a Sample C Program
&lt;/h2&gt;

&lt;p&gt;You can skip this step if you already have a binary you want to decompile but when learning I think it is best to start with something where you already know the code being decompiled. This code comes from the leetcode solution for the simple two sum problem. Create a main.c file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;twoSum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;nums&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;numsSize&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;target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;returnSize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&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="o"&gt;=&lt;/span&gt; &lt;span class="mi"&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="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;numsSize&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&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;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;j&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;numsSize&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&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;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;nums&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="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;malloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&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;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;returnSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&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;result&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="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;returnSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&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;malloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;0&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="nf"&gt;main&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;nums&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;22&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;returnSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;twoSumResult&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;twoSum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;returnSize&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;returnSize&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&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="o"&gt;=&lt;/span&gt; &lt;span class="mi"&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="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;returnSize&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="o"&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;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"twoSumResult[%d]: %d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&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;twoSumResult&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="n"&gt;free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;twoSumResult&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"No result&lt;/span&gt;&lt;span class="se"&gt;\n&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Compile an executable by running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;gcc &lt;span class="nt"&gt;-o&lt;/span&gt; main main.c
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note you may have to install the gcc compiler if you haven't already done so.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a Project in Ghidra
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Go to "File" then "New Project" and select "Non-shared Project". &lt;/li&gt;
&lt;li&gt;Select the directory and give the project a name (in our case TwoSum). &lt;/li&gt;
&lt;li&gt;Drag and drop the main executable from a file explorer window to the newly created project pane. &lt;/li&gt;
&lt;li&gt;A pop-up should appear. Have a look around at the options and languages then click "OK" and then "OK" again when the next popup appears.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Browsing the Code
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Select "main" in the Active Project pane and drag it to the dragon button (i.e. Code browser) in the Tool Chest set of buttons.&lt;/li&gt;
&lt;li&gt;Click "Yes" on the analyze popup then click "Analyze" on the next popup keeping all options set to the defaults.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Finding the TwoSum Function
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Select "Search" then "Program Text" from the menu. &lt;/li&gt;
&lt;li&gt;Select the "All Fields" button then click "Search All". &lt;/li&gt;
&lt;li&gt;&lt;p&gt;A popup should appear. Select "twoSum" and the listing window should auto navigate to the disassembly listing.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fep43lb2tmpfq4kgo2dgf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fep43lb2tmpfq4kgo2dgf.png" alt="Image description" width="589" height="372"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Next select "Window" then "Decompiler" from the menu. A pane should appear with the decompiled code.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqym07hnmovq7shkxg2jb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqym07hnmovq7shkxg2jb.png" alt="Image description" width="740" height="551"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can see that the decompiled code differs from the original code we wrote. This is because Ghidra reverse engineers C code from the compiler generated instructions in the binary file.&lt;/p&gt;

&lt;h2&gt;
  
  
  Debugging the Code
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Close the Code Browser window and return to the Ghidra project window. &lt;/li&gt;
&lt;li&gt;Select "main" and drag it to the button with a bug on it (the debugger tool). &lt;/li&gt;
&lt;li&gt;Click "Yes" to analyze then click "Analyze". &lt;/li&gt;
&lt;li&gt;From the "Debugger" menu item click "Configure and Launch main using...". &lt;/li&gt;
&lt;li&gt;Then select "gdb" then click "Launch" on the popup keeping the defaults selected. &lt;/li&gt;
&lt;li&gt;The launch of GDB should be successful and you should see a message in the GDB pane:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Connected to Ghidra 11.2.1 at 127.0.0.1:36921
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Next click on "Window" then "Decompile: main" from the menu. You should see a pane that now shows the decompiled main code. &lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Setting a Breakpoint
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;In the decompiled code pane, right click on the line you want to break at and select "Toggle Breakpoint". &lt;/li&gt;
&lt;li&gt;Leave the defaults as selected (specifically ensure "SW_EXECUTE" is selected) and click "OK".&lt;/li&gt;
&lt;li&gt;Click on the the green arrow button on the main debugger window to start debugging. &lt;/li&gt;
&lt;li&gt;You should see the debugger stop at the breakpoint. &lt;/li&gt;
&lt;li&gt;You can then step using the arrow buttons on the debugger menu:
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0gbczg43b7nab1a21bxz.png" alt="Image description" width="206" height="27"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note you can see the values of various variables as you step by hovering over them.&lt;/p&gt;

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

&lt;p&gt;This was a brief introduction to installing and using Ghidra. It has many more features to explore so take your time. Or you could join a capture the flag challenge and see how you go using it on unfamiliar code. There are also lots of YouTube videos showing how it can be used in capture the flag challenges too.&lt;/p&gt;

</description>
      <category>cybersecurity</category>
      <category>c</category>
    </item>
    <item>
      <title>C# devs need to know about sharplab.io</title>
      <dc:creator>G.L Solaria</dc:creator>
      <pubDate>Tue, 15 Oct 2024 05:34:14 +0000</pubDate>
      <link>https://dev.to/glsolaria/c-devs-need-to-know-about-sharplabio-3hm2</link>
      <guid>https://dev.to/glsolaria/c-devs-need-to-know-about-sharplabio-3hm2</guid>
      <description>&lt;p&gt;It is not just practice that will help you master C#. Using tools to look under the hood will accelerate your understanding of various language features and helps you write better, more efficient code. &lt;a href="https://sharplab.io/" rel="noopener noreferrer"&gt;Sharplab.io&lt;/a&gt; is one such tool that will help you to quickly learn and understand certain C# language features. You can use this tool to show you "lowered" C# code.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Lowering?
&lt;/h2&gt;

&lt;p&gt;Lowering is where the compiler converts high-level language features into simpler, low-level features. Lowering has the added benefit for compiler writers in that they can implement new language features without needing to change the underlying CIL or Common Intermediate Language (It is the CIL that is executed by the CLR or Common Language Runtime).&lt;/p&gt;

&lt;h2&gt;
  
  
  String Concatenation Operator
&lt;/h2&gt;

&lt;p&gt;Let's look at a simple example of the use of &lt;code&gt;+=&lt;/code&gt; on a string to start with. &lt;/p&gt;

&lt;p&gt;Below is an image from the &lt;a href="https://sharplab.io/" rel="noopener noreferrer"&gt;sharplab.io&lt;/a&gt; site. In the left pane is the code I wrote and the right pane shows the lowered code. As you can see, the &lt;code&gt;+=&lt;/code&gt; operator is lowered to use &lt;code&gt;string.Concat&lt;/code&gt;.&lt;br&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%2Fuploads%2Farticles%2F46f8ek1ov751k87wejco.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%2Fuploads%2Farticles%2F46f8ek1ov751k87wejco.png" alt="Image description" width="800" height="353"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Below is the same code but lowered in release mode. Notice how the compiler has eliminated use of the &lt;code&gt;text&lt;/code&gt; variable.&lt;br&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%2Fuploads%2Farticles%2Ff2gt4z3igmpmyt5zplid.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%2Fuploads%2Farticles%2Ff2gt4z3igmpmyt5zplid.png" alt="Image description" width="800" height="353"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  List versus Span Iteration
&lt;/h2&gt;

&lt;p&gt;Let's now look at a more complex example using List and Span.&lt;/p&gt;

&lt;p&gt;Below is some code using a List. Notice how the foreach is converted to a while loop using an Enumerator.&lt;br&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%2Fuploads%2Farticles%2Fcexh1f1jm157isv3nliq.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%2Fuploads%2Farticles%2Fcexh1f1jm157isv3nliq.png" alt="Image description" width="800" height="258"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Below is similar code using Span. Which do you think will perform faster?&lt;br&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%2Fuploads%2Farticles%2Fetusv48e7bl3s9beyxkd.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%2Fuploads%2Farticles%2Fetusv48e7bl3s9beyxkd.png" alt="Image description" width="800" height="364"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Understanding Records
&lt;/h2&gt;

&lt;p&gt;As an exercise for you, use the site to look at the lowered code for records. Copy the following into the left pane on &lt;a href="https://sharplab.io/" rel="noopener noreferrer"&gt;sharplab.io&lt;/a&gt;.&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;rec1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;RecordClass&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;21&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"hello"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Lowered to use the compiler generated Deconstruct method.&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rec1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  

&lt;span class="c1"&gt;// Lowered to use the compiler generated Clone method.&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;rec2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rec1&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Num&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;42&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt; 

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;record&lt;/span&gt; &lt;span class="nc"&gt;RecordClass&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;Num&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Str&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you do you will see all the automatically generated properties and methods you get for free when using records:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It makes the record class immutable by providing read-only/init properties.&lt;/li&gt;
&lt;li&gt;It generates Equals() and the equals/not equals operators.&lt;/li&gt;
&lt;li&gt;It generates a ToString() implementation.&lt;/li&gt;
&lt;li&gt;It generates a GetHashCode() method so you can use the record in hashing data structures like Dictionary.&lt;/li&gt;
&lt;li&gt;It generates a Descontruct() method used when deconstructing the record.&lt;/li&gt;
&lt;li&gt;It generates a Clone() method which is used in this case when using the &lt;code&gt;with&lt;/code&gt; keyword.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  More Exercises For You to Try
&lt;/h2&gt;

&lt;p&gt;So keep exploring using this tool and see what you can learn. See how the &lt;code&gt;using&lt;/code&gt; statement is lowered. Try some LINQ using the query syntax. Try a &lt;code&gt;switch&lt;/code&gt; statement switching on strings. If you are feeling brave, try &lt;code&gt;async&lt;/code&gt; methods. You can even start exploring the CIL generated to get a sense of the performance of different implementations.&lt;/p&gt;

</description>
      <category>csharp</category>
    </item>
    <item>
      <title>How to setup a free, self-hosted AI model for use with VS Code</title>
      <dc:creator>G.L Solaria</dc:creator>
      <pubDate>Tue, 04 Jun 2024 07:34:31 +0000</pubDate>
      <link>https://dev.to/glsolaria/how-to-setup-a-free-self-hosted-ai-model-for-use-with-vs-code-4704</link>
      <guid>https://dev.to/glsolaria/how-to-setup-a-free-self-hosted-ai-model-for-use-with-vs-code-4704</guid>
      <description>&lt;p&gt;You have probably heard about GitHub &lt;a href="https://github.com/features/copilot" rel="noopener noreferrer"&gt;Co-pilot&lt;/a&gt;. It's an AI assistant that helps you code. There are a few AI coding assistants out there but most cost money to access from an IDE. But did you know you can run self-hosted AI models for free on your own hardware? All you need is a machine with a supported GPU.&lt;/p&gt;

&lt;h2&gt;
  
  
  Before we begin
&lt;/h2&gt;

&lt;p&gt;We are going to use an &lt;a href="https://hub.docker.com/r/ollama/ollama" rel="noopener noreferrer"&gt;ollama docker image&lt;/a&gt; to host &lt;a href="https://ollama.com/library" rel="noopener noreferrer"&gt;AI models&lt;/a&gt; that have been pre-trained for assisting with coding tasks. We are going to use the VS Code extension &lt;a href="https://marketplace.visualstudio.com/items?itemName=Continue.continue" rel="noopener noreferrer"&gt;Continue&lt;/a&gt; to integrate with VS Code. If you are running VS Code on the same machine as you are hosting ollama, you could try &lt;a href="https://marketplace.visualstudio.com/items?itemName=DanielSanMedium.dscodegpt" rel="noopener noreferrer"&gt;CodeGPT&lt;/a&gt; but I could not get it to work when ollama is self-hosted on a machine remote to where I was running VS Code (well not without modifying the extension files). There are currently open issues on &lt;a href="https://github.com/davila7/code-gpt-docs" rel="noopener noreferrer"&gt;GitHub with CodeGPT&lt;/a&gt; which may have fixed the problem now.&lt;/p&gt;

&lt;h2&gt;
  
  
  System requirements
&lt;/h2&gt;

&lt;p&gt;This guide assumes you have a &lt;a href="https://github.com/ollama/ollama/blob/main/docs/gpu.md" rel="noopener noreferrer"&gt;supported NVIDIA GPU&lt;/a&gt; and have installed Ubuntu 22.04 on the machine that will host the ollama docker image. &lt;a href="https://ollama.com/blog/amd-preview" rel="noopener noreferrer"&gt;AMD is now supported&lt;/a&gt; with ollama but this guide does not cover this type of setup.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing the NVIDIA CUDA drivers
&lt;/h2&gt;

&lt;p&gt;The NVIDIA CUDA drivers need to be installed so we can get the best response times when chatting with the AI models. On the machine you want to host the AI models...&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;nvidia-cuda-toolkit


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now check the status of the CUDA drivers by running ...&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

nvidia-smi


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;You should see something like this ...&lt;br&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%2Fuploads%2Farticles%2Fe7q2fnprvdi350bud6h4.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%2Fuploads%2Farticles%2Fe7q2fnprvdi350bud6h4.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
Next run a check to ensure the CUDA drivers are available to for use ...&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

nvcc &lt;span class="nt"&gt;--version&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;You should see something like this ...&lt;br&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%2Fuploads%2Farticles%2Fwqei00s0dq7ovylq6rl4.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%2Fuploads%2Farticles%2Fwqei00s0dq7ovylq6rl4.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Install Docker and enable Docker images to access the GPU
&lt;/h2&gt;

&lt;p&gt;Follow the instructions to install &lt;a href="https://docs.docker.com/engine/install/ubuntu/" rel="noopener noreferrer"&gt;Docker on Ubuntu&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Now we install and configure the NVIDIA Container Toolkit by following &lt;a href="https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html#installation" rel="noopener noreferrer"&gt;these instructions&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Next we double check that any docker images can access the NVIDI GPU...&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

docker run &lt;span class="nt"&gt;--runtime&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;nvidia &lt;span class="nt"&gt;--gpus&lt;/span&gt; all &lt;span class="nt"&gt;--rm&lt;/span&gt; nvidia/cuda:12.2.0-base-ubuntu22.04 nvidia-smi


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Note you should select the NVIDIA Docker image that matches your &lt;a href="https://hub.docker.com/r/nvidia/cuda" rel="noopener noreferrer"&gt;CUDA driver version&lt;/a&gt;. Look in the &lt;a href="https://gitlab.com/nvidia/container-images/cuda/blob/master/doc/unsupported-tags.md" rel="noopener noreferrer"&gt;unsupported list&lt;/a&gt; if your driver version is older.&lt;/p&gt;

&lt;h2&gt;
  
  
  Run the ollama Docker image
&lt;/h2&gt;

&lt;p&gt;Now we are ready to start hosting some AI models.&lt;/p&gt;

&lt;p&gt;First, download and run the &lt;a href="https://hub.docker.com/r/ollama/ollama" rel="noopener noreferrer"&gt;ollama Docker image&lt;/a&gt;...&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;--gpus&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;all &lt;span class="nt"&gt;-v&lt;/span&gt; ollama:/root/.ollama &lt;span class="nt"&gt;-p&lt;/span&gt; 11434:11434 &lt;span class="nt"&gt;--name&lt;/span&gt; ollama ollama/ollama


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Next check ollama is running by...&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

curl http://localhost:11434


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;You should see the output "Ollama is running".&lt;/p&gt;

&lt;p&gt;We can now download and run any model easily by running ...&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; ollama ollama run deepseek-coder:6.7b


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This version of deepseek-coder is a 6.7 billon parameter model. The model will be automatically downloaded the first time it is used then it will be run. After it has finished downloading you should end up with a chat prompt when you run this command.&lt;/p&gt;

&lt;p&gt;While it responds to a prompt, use a command like &lt;a href="https://packages.ubuntu.com/noble/btop" rel="noopener noreferrer"&gt;btop&lt;/a&gt; to check if the GPU is being used successfully. Also note if you do not have enough VRAM for the size model you are using, you may find using the model actually ends up using CPU and swap.&lt;/p&gt;

&lt;h2&gt;
  
  
  Picking a pre-trained coding model
&lt;/h2&gt;

&lt;p&gt;You may have to have a play around with this one. The best model will vary but you can check out the &lt;a href="https://huggingface.co/spaces/bigcode/bigcode-models-leaderboard" rel="noopener noreferrer"&gt;Hugging Face Big Code Models leaderboard&lt;/a&gt; for some guidance. You will also need to be careful to pick a model that will be responsive using your GPU and that will depend greatly on the specs of your GPU. &lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up VS Code
&lt;/h2&gt;

&lt;p&gt;On the machine you want to run VS Code on, check you can see the ollama API address (note x.x.x.x is the IP address of your machine that is hosting the Docker image)...&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

curl http://x.x.x.x:11434


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;You should get the output "Ollama is running". &lt;/p&gt;

&lt;p&gt;Next &lt;a href="https://code.visualstudio.com/download" rel="noopener noreferrer"&gt;Download and install VS Code&lt;/a&gt; on your developer machine.&lt;/p&gt;

&lt;p&gt;Now we need the &lt;a href="https://marketplace.visualstudio.com/items?itemName=Continue.continue" rel="noopener noreferrer"&gt;Continue VS Code extension&lt;/a&gt;. &lt;br&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%2Fuploads%2Farticles%2Fertfj4vwk9fs5h77xjvc.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%2Fuploads%2Farticles%2Fertfj4vwk9fs5h77xjvc.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
Make sure you only install the official Continue extension. &lt;/p&gt;

&lt;p&gt;Click cancel if it asks you to sign in to GitHub. &lt;/p&gt;

&lt;p&gt;Now configure Continue by opening the command palette (you can select "View" from the menu then "Command Palette" if you don't know the keyboard shortcut). Type "Continue: Open config.json" &lt;br&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%2Fuploads%2Farticles%2Fqvhq7q3to6wasvypp647.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%2Fuploads%2Farticles%2Fqvhq7q3to6wasvypp647.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Open the config file and modify it to be like what I have entered below:&lt;br&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%2Fuploads%2Farticles%2F0kostbbp071jwdnv0zsu.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%2Fuploads%2Farticles%2F0kostbbp071jwdnv0zsu.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
Note again that x.x.x.x is the IP of your machine hosting the ollama docker container. &lt;/p&gt;

&lt;p&gt;Save the file and click on the Continue icon in the left side-bar and you should be ready to go. Note you can toggle tab code completion off/on by clicking on the continue text in the lower right status bar. Also note that if the model is too slow, you might want to try a smaller model like "deepseek-coder:latest". Refer to the &lt;a href="https://marketplace.visualstudio.com/items?itemName=Continue.continue" rel="noopener noreferrer"&gt;Continue VS Code page&lt;/a&gt; for details on how to use the extension.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>vscode</category>
    </item>
    <item>
      <title>C# Async/Await Mistakes: Resuming in the Wrong Context</title>
      <dc:creator>G.L Solaria</dc:creator>
      <pubDate>Mon, 06 Nov 2023 03:48:06 +0000</pubDate>
      <link>https://dev.to/glsolaria/c-asyncawait-mistakes-resuming-in-the-wrong-context-3oa0</link>
      <guid>https://dev.to/glsolaria/c-asyncawait-mistakes-resuming-in-the-wrong-context-3oa0</guid>
      <description>&lt;p&gt;Using async/await in C# is generally straight forward but when you start to use it in more advanced ways, you need to understand a bit more about what is happening to make sure you are not making mistakes.&lt;/p&gt;

&lt;p&gt;Let's look at one common mistake: resuming in the wrong context. &lt;/p&gt;

&lt;p&gt;The code below implements a class that uses HTTP Client to load some JSON. The LoadToDosAsync method however has a potential problem. Can you spot it?&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="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Getter&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;HttpClient&lt;/span&gt; &lt;span class="n"&gt;_Client&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;BaseAddress&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; 
      &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Uri&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"https://jsonplaceholder.typicode.com/"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;LoadToDosAsync&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_Client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"todos/1"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;EnsureSuccessStatusCode&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;json&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ReadAsStringAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

      &lt;span class="c1"&gt;// This is a CPU intensive operation...&lt;/span&gt;
      &lt;span class="nf"&gt;LoadData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&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;When LoadToDosAsync is called, the calling thread returns when it hits the first await. A thread from the &lt;a href="https://dev.to/glsolaria/c-async-await-eventually-thread-pools-jng"&gt;threadpool&lt;/a&gt; will then be selected by the threadpool scheduler and this thread will perform the work to call out over the network to get the data. &lt;/p&gt;

&lt;p&gt;If LoadToDosAsync is called from a main UI thread and when GetAsync returns, execution will resume on the main UI thread until it reaches the next await. &lt;/p&gt;

&lt;p&gt;If LoadToDosAsync is called from the main of a console application and when GetAsync returns, execution will resume in the context of the threadpool scheduler. The threadpool scheduler will then select a thread from the threadpool that will execute until it hits the next await. &lt;/p&gt;

&lt;p&gt;A similar process is then repeated when awaiting ReadAsStringAsync. &lt;/p&gt;

&lt;p&gt;So LoadData ends up being executed in the same context as LoadToDosAsync started executing before the first await. The context will be the main UI thread if LoadToDosAsync is called from the main UI thread. The context will be the threadpool scheduler if called from the main of a console application.&lt;/p&gt;

&lt;p&gt;What's the potential problem here? The problem shows up when LoadToDosAsync is called from a main UI thread. Execution resumes on the main UI thread when ReadAsStringAsync returns hence LoadData will execute on the main UI thread. LoadData is a CPU intensive call that will block the main UI thread until it completes. This means the UI will freeze until LoadData completes. So the UI will be unresponsive while LoadData is executing.&lt;/p&gt;

&lt;p&gt;To fix this problem, you can use ConfigureAwait(false) to indicate that execution can resume in the threadpool scheduler context. The threadpool scheduler will then select a thread from the threadpool to continue execution of LoadData instead of executing it in the main UI thread.&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="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Getter&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;HttpClient&lt;/span&gt; &lt;span class="n"&gt;_Client&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;BaseAddress&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; 
            &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Uri&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"https://jsonplaceholder.typicode.com/"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;GetToDosAsync&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_Client&lt;/span&gt;
          &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"todos/1"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ConfigureAwait&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="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;EnsureSuccessStatusCode&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;json&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Content&lt;/span&gt;
          &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ReadAsStringAsync&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
          &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ConfigureAwait&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="c1"&gt;// This is a CPU intensive operation...&lt;/span&gt;
        &lt;span class="nf"&gt;LoadData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&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;Using ConfigureAwait(false) is especially important when writing general-purpose libraries. You should get in the habit of using it almost everywhere unless you know you want to resume in the caller's context.&lt;/p&gt;

&lt;p&gt;It must be noted that if the calling context is the threadpool scheduler, you may or may not resume on the same calling thread. Take the example of a console application below...&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;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;true&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;callingThread&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Environment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CurrentManagedThreadId&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TimeSpan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromSeconds&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="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;resumingThread&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Environment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CurrentManagedThreadId&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;$"Calling &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;callingThread&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;, Resumed &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;resumingThread&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;Run this console application and you will see that sometimes execution resumes on the calling thread but sometimes it does not.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Calling 1, Resumed 5.
Calling 5, Resumed 5.
Calling 5, Resumed 5.
Calling 5, Resumed 7.
Calling 7, Resumed 7.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It should be noted that the above is a simple explanation of when is going on. To read a technically correct explanation of the behaviour of ConfigureAwait(false) refer to &lt;a href="https://devblogs.microsoft.com/dotnet/configureawait-faq/"&gt;Stephen Toub's article on the subject&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>programming</category>
      <category>csharp</category>
    </item>
    <item>
      <title>A word of warning when writing C# benchmarks</title>
      <dc:creator>G.L Solaria</dc:creator>
      <pubDate>Wed, 21 Sep 2022 21:57:39 +0000</pubDate>
      <link>https://dev.to/glsolaria/a-word-of-warning-when-writing-c-benchmarks-g13</link>
      <guid>https://dev.to/glsolaria/a-word-of-warning-when-writing-c-benchmarks-g13</guid>
      <description>&lt;p&gt;I wrote &lt;a href="https://dev.to/glsolaria/you-need-to-know-about-benchmarkdotnet-kok"&gt;a post on the free, open source tool BenchmarkDotNet&lt;/a&gt; but I wanted to mention a common pitfall that you might fall in to if you are not careful.&lt;/p&gt;

&lt;p&gt;The warning is simple: when writing benchmarks, always use the results of your calculations. &lt;/p&gt;

&lt;p&gt;Consider these benchmarks ...&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="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;Benchmark&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Baseline&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Sqrt1&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&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;ii&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="n"&gt;ii&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;++&lt;/span&gt;&lt;span class="n"&gt;ii&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Sqrt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ii&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="n"&gt;Benchmark&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="nf"&gt;Sqrt2&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;result&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;for&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;ii&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="n"&gt;ii&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;++&lt;/span&gt;&lt;span class="n"&gt;ii&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Sqrt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ii&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;result&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;If we look at the results of the above benchmarks ...&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;N&lt;/th&gt;
&lt;th&gt;Mean&lt;/th&gt;
&lt;th&gt;Error&lt;/th&gt;
&lt;th&gt;StdDev&lt;/th&gt;
&lt;th&gt;Ratio&lt;/th&gt;
&lt;th&gt;RatioSD&lt;/th&gt;
&lt;th&gt;Rank&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Sqrt1&lt;/td&gt;
&lt;td&gt;1000000&lt;/td&gt;
&lt;td&gt;291.8 us&lt;/td&gt;
&lt;td&gt;5.79 us&lt;/td&gt;
&lt;td&gt;6.66 us&lt;/td&gt;
&lt;td&gt;1.00&lt;/td&gt;
&lt;td&gt;0.00&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sqrt2&lt;/td&gt;
&lt;td&gt;1000000&lt;/td&gt;
&lt;td&gt;4,006.9 us&lt;/td&gt;
&lt;td&gt;55.00 us&lt;/td&gt;
&lt;td&gt;51.45 us&lt;/td&gt;
&lt;td&gt;13.64&lt;/td&gt;
&lt;td&gt;0.29&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;How can &lt;code&gt;Sqrt2&lt;/code&gt; be almost 14 times slower than &lt;code&gt;Sqrt1&lt;/code&gt;? The answer lies with the JIT compiler ...&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%2Fuploads%2Farticles%2Fqme74b7n51jppjy8ybje.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%2Fuploads%2Farticles%2Fqme74b7n51jppjy8ybje.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://sharplab.io/" rel="noopener noreferrer"&gt;SharpLab&lt;/a&gt; is another great tool that will show you what the JIT compiler will do initially. In the case of &lt;code&gt;Sqrt1&lt;/code&gt;, it will compile out dead code because the result of the square root isn't used so it doesn't need to run the instructions to perform the square root. &lt;/p&gt;

&lt;p&gt;So be careful with how you write your benchmarks otherwise you may not be measuring what you think you are measuring!&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
    <item>
      <title>You need to know about BenchmarkDotNet</title>
      <dc:creator>G.L Solaria</dc:creator>
      <pubDate>Tue, 20 Sep 2022 10:10:05 +0000</pubDate>
      <link>https://dev.to/glsolaria/you-need-to-know-about-benchmarkdotnet-kok</link>
      <guid>https://dev.to/glsolaria/you-need-to-know-about-benchmarkdotnet-kok</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/dotnet/BenchmarkDotNet"&gt;BenchmarkDotNet&lt;/a&gt; is one of those free, open source tools that all .NET developers need to know how to use. This tool is useful if you want to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;compare the performance of multiple ways of doing the same thing,&lt;/li&gt;
&lt;li&gt;decide which 3rd party library provides the fastest and most memory efficient implementation,&lt;/li&gt;
&lt;li&gt;compare the performance of code running on different versions of the .NET platform,&lt;/li&gt;
&lt;li&gt;monitor changes to your code base for changes that degrade performance.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What is a benchmark?
&lt;/h2&gt;

&lt;p&gt;A benchmark is a program that measures the performance characteristics of some code (or hardware though this is not the focus of this article). Benchmarking is often used to compare the performance of different implementations but can also be used to show that you have achieved some performance goal (e.g. processing 1,000,000 operations per second). &lt;/p&gt;

&lt;h2&gt;
  
  
  Why use BenchmarkDotNet?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Don't use DateTime.Now
&lt;/h3&gt;

&lt;p&gt;Hopefully you know not to use DateTime.Now for measuring the execution time of code. It isn't good for measuring sub-millisecond execution time and it can sometimes be affected by time synchronisation activities.&lt;/p&gt;

&lt;h3&gt;
  
  
  The pitfalls of using Stopwatch
&lt;/h3&gt;

&lt;p&gt;You have probably used Stopwatch to measure execution times. However, taking a one shot value of one implementation and comparing it to another one shot value is unreliable. You will probably observe that if you do 5 runs of the same code, you will get 5 different results that vary wildly. So how can you compare multiple implementations that do the same thing? Using only the arithmetic mean might not be meaningful if there are &lt;a href="https://en.wikipedia.org/wiki/Outlier"&gt;outliers&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  The JIT compiler can cause problems
&lt;/h3&gt;

&lt;p&gt;Have you considered that the JIT compiler can dynamically re-compile code over time? It can do this to optimise hot paths of execution. The JIT compiler can also vary its optimisations based on the code it executed before the code you want to benchmark. How can you ensure the JIT compiler has done its optimisations and ensure isolation of the benchmarked code?&lt;/p&gt;

&lt;h3&gt;
  
  
  The overhead of running the benchmark can also cause problems
&lt;/h3&gt;

&lt;p&gt;If you do realise that you need to do many iterations and perform some sort of statistical analysis, have you discounted the overhead in executing the benchmark? How many iterations do you need to do to get a stable result?&lt;/p&gt;

&lt;h2&gt;
  
  
  Enter BenchmarkDotNet
&lt;/h2&gt;

&lt;p&gt;BenchmarkDotNet is a project supported by the &lt;a href="https://dotnetfoundation.org/"&gt;.NET Foundation&lt;/a&gt;. It is used by many .NET projects (including those run by Microsoft) to analyse the performance of various libraries and detect regressions in performance as modifications are made. &lt;/p&gt;

&lt;p&gt;It takes care of handling common pitfalls for you. It will:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;run your code multiple times and automatically detect when the results have stabilised,&lt;/li&gt;
&lt;li&gt;take into consideration the overhead used to run the benchmark and ensure the overhead does not interfere with the results,&lt;/li&gt;
&lt;li&gt;calculate all the statistics for you,&lt;/li&gt;
&lt;li&gt;produce nice graphs to help you visualise the results,&lt;/li&gt;
&lt;li&gt;warn you of potential issues when trying to reach conclusions based on the statistics (e.g. if it detects a &lt;a href="https://en.wikipedia.org/wiki/Multimodal_distribution"&gt;bi-modal distribution&lt;/a&gt;, or if it detects and eliminates outliers). &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Installing BenchmarkDotNet
&lt;/h2&gt;

&lt;p&gt;Installation is simple ...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;dotnet add package BenchmarkDotNet
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  C# Example
&lt;/h2&gt;

&lt;p&gt;The main that runs the benchmark in this example is simple too ...&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;BenchmarkRunner&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;MyBenchmark&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's look at the code to be benchmarked. Let's compare which is faster to look through a list - LINQ or a "for each" loop ...&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="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;RankColumn&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;Orderer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BenchmarkDotNet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SummaryOrderPolicy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FastestToSlowest&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyBenchmark&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;Params&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="n"&gt;_000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="n"&gt;_000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;_000_000&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;N&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;private&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;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_list&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;GlobalSetup&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Setup&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_list&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Enumerable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Range&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="n"&gt;N&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;span class="n"&gt;Benchmark&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;LinqQuery&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;First&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ii&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ii&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;N&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="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;Benchmark&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Baseline&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;ForEachLoop&lt;/span&gt;&lt;span class="p"&gt;()&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;ii&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;_list&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;ii&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;N&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="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ii&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;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Not found"&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 &lt;code&gt;[RankColumn]&lt;/code&gt; and &lt;code&gt;[Orderer]&lt;/code&gt; will rank and order the code according to what you configure in your &lt;code&gt;Orderer&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;[Params]&lt;/code&gt; attribute will instruct the benchmarker to perform a benchmark run with (in this case) &lt;code&gt;N&lt;/code&gt; set to that value. It will run the &lt;code&gt;[GlobalSetup]&lt;/code&gt; once for each value of &lt;code&gt;N&lt;/code&gt; before it runs a number of iterations of each of the benchmarks. &lt;/p&gt;

&lt;p&gt;Using the &lt;code&gt;Baseline&lt;/code&gt; attribute parameter will more clearly show how many times faster/slower the code is compared to a baseline.&lt;/p&gt;

&lt;p&gt;The result summary from this example console application is shown below. Note that 1us is 1 microsecond. Also note that the Error is half of the &lt;a href="https://en.wikipedia.org/wiki/Confidence_interval"&gt;99.9% confidence interval&lt;/a&gt; (Note that I am not a statistician but I think of it as highly likely that the real mean is within the interval defined by the sampled Mean ± Error) ...&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;N&lt;/th&gt;
&lt;th&gt;Mean&lt;/th&gt;
&lt;th&gt;Error&lt;/th&gt;
&lt;th&gt;StdDev&lt;/th&gt;
&lt;th&gt;Ratio&lt;/th&gt;
&lt;th&gt;RatioSD&lt;/th&gt;
&lt;th&gt;Rank&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;ForEachLoop&lt;/td&gt;
&lt;td&gt;10000&lt;/td&gt;
&lt;td&gt;11.80 us&lt;/td&gt;
&lt;td&gt;0.229 us&lt;/td&gt;
&lt;td&gt;0.225 us&lt;/td&gt;
&lt;td&gt;1.00&lt;/td&gt;
&lt;td&gt;0.00&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LinqQuery&lt;/td&gt;
&lt;td&gt;10000&lt;/td&gt;
&lt;td&gt;86.12 us&lt;/td&gt;
&lt;td&gt;1.568 us&lt;/td&gt;
&lt;td&gt;1.466 us&lt;/td&gt;
&lt;td&gt;7.30&lt;/td&gt;
&lt;td&gt;0.13&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ForEachLoop&lt;/td&gt;
&lt;td&gt;100000&lt;/td&gt;
&lt;td&gt;114.91 us&lt;/td&gt;
&lt;td&gt;1.628 us&lt;/td&gt;
&lt;td&gt;1.444 us&lt;/td&gt;
&lt;td&gt;1.00&lt;/td&gt;
&lt;td&gt;0.00&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LinqQuery&lt;/td&gt;
&lt;td&gt;100000&lt;/td&gt;
&lt;td&gt;835.23 us&lt;/td&gt;
&lt;td&gt;11.179 us&lt;/td&gt;
&lt;td&gt;9.910 us&lt;/td&gt;
&lt;td&gt;7.27&lt;/td&gt;
&lt;td&gt;0.14&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ForEachLoop&lt;/td&gt;
&lt;td&gt;1000000&lt;/td&gt;
&lt;td&gt;1,172.17 us&lt;/td&gt;
&lt;td&gt;20.658 us&lt;/td&gt;
&lt;td&gt;19.323 us&lt;/td&gt;
&lt;td&gt;1.00&lt;/td&gt;
&lt;td&gt;0.00&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LinqQuery&lt;/td&gt;
&lt;td&gt;1000000&lt;/td&gt;
&lt;td&gt;8,446.51 us&lt;/td&gt;
&lt;td&gt;166.337 us&lt;/td&gt;
&lt;td&gt;163.366 us&lt;/td&gt;
&lt;td&gt;7.21&lt;/td&gt;
&lt;td&gt;0.16&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;So we can see that on my machine, &lt;code&gt;LinqQuery&lt;/code&gt; is around 7 times slower (looking at the Ratio column) than the baseline &lt;code&gt;ForEachLoop&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Other useful attributes
&lt;/h2&gt;

&lt;p&gt;The attribute &lt;code&gt;[RPlotExplorer]&lt;/code&gt; will create nice plots for you but you will need &lt;a href="https://www.r-project.org/"&gt;R&lt;/a&gt; and the rplotengine package installed on the machine running the benchmark.&lt;/p&gt;

&lt;p&gt;The attribute &lt;code&gt;[MemoryDiagnoser]&lt;/code&gt; will show the allocated memory so it can be useful for showing code that may be fast but uses more memory.&lt;/p&gt;

&lt;p&gt;The attribute &lt;code&gt;[SimpleJob(runtimeMoniker: RuntimeMoniker.Net70]&lt;/code&gt; will run each of the benchmarks with .NET 7. You can specify multiple platforms if you want to compare performance against other versions of .NET.&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Where to start with regular expressions?</title>
      <dc:creator>G.L Solaria</dc:creator>
      <pubDate>Sat, 07 May 2022 02:11:24 +0000</pubDate>
      <link>https://dev.to/glsolaria/where-to-start-with-regular-expressions-4b16</link>
      <guid>https://dev.to/glsolaria/where-to-start-with-regular-expressions-4b16</guid>
      <description>&lt;p&gt;Recently I was asked where a novice would start learning how to read and write regular expressions. Below are two sites that I think would be useful.&lt;/p&gt;

&lt;h1&gt;
  
  
  Reading regular expressions
&lt;/h1&gt;

&lt;p&gt;I think &lt;a href="https://regexr.com/"&gt;RegExr&lt;/a&gt; is a good site for explaining regular expressions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nf4GeyEk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w2k9iemrgnz2na36u4fr.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nf4GeyEk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w2k9iemrgnz2na36u4fr.gif" alt="RegExr" width="800" height="760"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Writing regular expressions
&lt;/h1&gt;

&lt;p&gt;Learning to write regular expressions is quite hard. &lt;a href="https://regexone.com/"&gt;RegexOne&lt;/a&gt; provides a very good beginners tutorial to help people learn how to write regular expressions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KpsTMgUM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c9xb9b5rf64ovysnmzcy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KpsTMgUM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c9xb9b5rf64ovysnmzcy.gif" alt="RegexOne" width="800" height="760"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What resources have helped you to learn how to read/write regular expressions?&lt;/p&gt;

</description>
      <category>regex</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Fail-fast Programming?</title>
      <dc:creator>G.L Solaria</dc:creator>
      <pubDate>Sat, 26 Mar 2022 06:33:33 +0000</pubDate>
      <link>https://dev.to/glsolaria/fail-fast-programming-2p7a</link>
      <guid>https://dev.to/glsolaria/fail-fast-programming-2p7a</guid>
      <description>&lt;p&gt;I have an existing code base for which I need to replace a low-level layer and I want to think about an error handling strategy for this new layer. &lt;/p&gt;

&lt;p&gt;For handling interfaces to external systems, it makes sense to reject unexpected inputs and carry on. I think it also makes sense that errors in inputs from a high-layer to a lower layer are thrown as exceptions upward from the lower layer. But what about &lt;em&gt;internal&lt;/em&gt; inputs/outputs that are passed between code &lt;em&gt;within&lt;/em&gt; a layer? &lt;/p&gt;

&lt;p&gt;Before I go into what I think fail-fast programming is, I need to cover design by contract.&lt;/p&gt;

&lt;h1&gt;
  
  
  Design by Contract
&lt;/h1&gt;

&lt;p&gt;Design by contract is an approach to reducing the number of bugs in code. The idea is to specify pre-conditions, post-conditions, and invariants that must hold for the code to execute correctly. Below I define these terms and give a code example. Note that the code examples are a bit silly and certainly don't represent best coding practices but hopefully explain the concept simply.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pre-conditions
&lt;/h2&gt;

&lt;p&gt;A pre-condition is a condition that must be true before executing a code block. The code block won't execute as expected if the pre-conditions are false. A pre-condition can express what is required of the inputs or expectations about the internal state of a class.&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;class&lt;/span&gt; &lt;span class="nc"&gt;Haystack&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;Objects&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Needle&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="n"&gt;Pen&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;Pencil&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;private&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="n"&gt;Objects&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_buried&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="nf"&gt;Haystack&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_buried&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&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="n"&gt;Objects&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Needle&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;FindAndRemove&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;obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Pre-condition: obj must be 0, 1, 2        &lt;/span&gt;
        &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;found&lt;/span&gt; &lt;span class="p"&gt;=&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="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;ii&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="n"&gt;ii&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;_buried&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="n"&gt;ii&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="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;_buried&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ii&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;found&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="k"&gt;break&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="c1"&gt;// Needles are too dangerous to remove!&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;found&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;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;obj&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="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Needle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;_buried&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Remove&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;Objects&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;obj&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;found&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;h2&gt;
  
  
  Post-conditions
&lt;/h2&gt;

&lt;p&gt;A post-condition is something that must be true once a code block has executed.&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;class&lt;/span&gt; &lt;span class="nc"&gt;Haystack&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;Objects&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Needle&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="n"&gt;Pen&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;Pencil&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;private&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="n"&gt;Objects&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_buried&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="nf"&gt;Haystack&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_buried&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&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="n"&gt;Objects&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Needle&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;FindAndRemove&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;obj&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;found&lt;/span&gt; &lt;span class="p"&gt;=&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="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;ii&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="n"&gt;ii&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;_buried&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="n"&gt;ii&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="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;_buried&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ii&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;found&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="k"&gt;break&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="c1"&gt;// Needles are too dangerous to remove!&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;found&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;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;obj&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="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Needle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;_buried&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Remove&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;Objects&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// Post-condition: found is either 1 or -1&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;found&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;h2&gt;
  
  
  Invariants
&lt;/h2&gt;

&lt;p&gt;An invariant always holds true after a certain point in the code (typically after initialisation code is executed).&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;class&lt;/span&gt; &lt;span class="nc"&gt;Haystack&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;Objects&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Needle&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="n"&gt;Pen&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;Pencil&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;private&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="n"&gt;Objects&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_buried&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="nf"&gt;Haystack&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_buried&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&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="n"&gt;Objects&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Needle&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
        &lt;span class="c1"&gt;// Invariant: _buried is not null&lt;/span&gt;
        &lt;span class="c1"&gt;// Invariant: a needle is always buried&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;FindAndRemove&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;obj&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;found&lt;/span&gt; &lt;span class="p"&gt;=&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="c1"&gt;// Invariant: _buried is not null&lt;/span&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;ii&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="n"&gt;ii&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;_buried&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="n"&gt;ii&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Invariant: ii is less than the length of _buried&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;_buried&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ii&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;found&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="k"&gt;break&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="c1"&gt;// Needles are too dangerous to remove!&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;found&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;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;obj&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="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Needle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;_buried&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Remove&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;Objects&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="c1"&gt;// Invariant: a needle is always buried&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;found&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;h1&gt;
  
  
  Fail-fast Strategy
&lt;/h1&gt;

&lt;p&gt;A fail-fast strategy means the program crashes immediately when a pre-condition, post-condition or invariant is false. Instead of using comments to document the condition, "asserts" are used to crash the program. For example, a condition can be tested ...&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;Trace&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_buried&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="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;$"obj is &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;obj&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="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;$"obj is &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;obj&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;... which crashes the program with a stack trace and a helpful line number. If a message is included, the message is output.&lt;/p&gt;

&lt;p&gt;I have seen this strategy create very reliable code in a very large code base that has run 24/7 for over 10 years. &lt;/p&gt;

&lt;p&gt;There are some pretty big commitments that need to be made for this to result in reliable code - namely extensive testing. Automated test cases are the ideal but they need to be of a good quality and properly maintained. Code coverage metrics must be collected and analysed to ensure adequate code coverage.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pros
&lt;/h2&gt;

&lt;p&gt;It's hard to ignore a crash. &lt;/p&gt;

&lt;p&gt;Developers implicitly become testers of all fail-fast code. A sufficiently trained developer with adequate time will at least raise a bug, if not investigate it.&lt;/p&gt;

&lt;p&gt;Traces of crashes help developers zero in as close as possible to the cause of the crash.&lt;/p&gt;

&lt;p&gt;Code is simpler because the code to check conditions is often less verbose than using try/catch blocks.&lt;/p&gt;

&lt;p&gt;Code is better documented and actively enforced. The documentation can't become out of date because if it does, it crashes the program.&lt;/p&gt;

&lt;p&gt;Code that has pre-conditions, post-conditions, and invariants leads to less bugs getting introduced when code is later modified. This is especially true when developers only read a fragment of code before making a change.  &lt;/p&gt;

&lt;p&gt;There is no error recovery code. Ideally if the system is critical, there is a fault-tolerance mechanism at the system level that triggers to recover from the fault.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cons
&lt;/h2&gt;

&lt;p&gt;It's hard to ignore a crash.&lt;/p&gt;

&lt;p&gt;Under pressure, developers may choose to remove pre-conditions, post-conditions, and invariants if a root cause for a crash cannot be found. &lt;/p&gt;

&lt;p&gt;Testing may be inadequate leading to more bugs getting through to production. This is obviously a very big con because crashes in production are generally considered bad!&lt;/p&gt;

&lt;h1&gt;
  
  
  Catch-all Strategy
&lt;/h1&gt;

&lt;p&gt;A catch-all strategy tries to continue on in the face of fault conditions. This usually involves surrounding all code blocks with try/catch statements. &lt;/p&gt;

&lt;h2&gt;
  
  
  Pros
&lt;/h2&gt;

&lt;p&gt;The system is unlikely to crash in production.&lt;/p&gt;

&lt;p&gt;Error conditions can be recovered if exceptions are handled and do more than simply log an error message.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cons
&lt;/h2&gt;

&lt;p&gt;The system can silently malfunction in production. When the system silently malfunctions in test and in development environments, it is a lost opportunity to catch and fix bugs.&lt;/p&gt;

&lt;p&gt;It is harder to track down the cause of a malfunction without good log messages. If the bugs cannot be re-produced, turning on tracing will not help. &lt;/p&gt;

&lt;p&gt;Most developers will only look at their own log messages and not look for other error messages. Unless developers are very disciplined, log files become very noisy with lots of errors even though the system looks like it is behaving leading to what I like to call "log-error-blindness".&lt;/p&gt;

&lt;p&gt;Testing error recovery code littered throughout the code base is difficult. &lt;/p&gt;

&lt;h1&gt;
  
  
  Optional Fail-Fast
&lt;/h1&gt;

&lt;p&gt;Another possibility is that fail-fast can be optionally switched on or off either at build time or at runtime.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pros
&lt;/h2&gt;

&lt;p&gt;Fail-fast can be disabled in critical production environments.&lt;/p&gt;

&lt;p&gt;Fail-fast can be enabled in internal or external test environments and developer environments. &lt;/p&gt;

&lt;p&gt;Most of the benefits of fail-fast can be realised without risking stability in production.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cons
&lt;/h2&gt;

&lt;p&gt;Running different code in production compared to test and development potentially introduces the risk of error conditions emerging in production that don't occur in development and test. For example, side-effects in condition testing could lead to faults when condition testing is turned off.&lt;/p&gt;

&lt;h1&gt;
  
  
  Fail-fast with Error Recovery
&lt;/h1&gt;

&lt;p&gt;Fail-fast can be implemented with special exceptions thrown up to a level that can handle and try to recover from the error. Helper methods can be implemented to more succinctly document and enforce detection of internal error conditions. &lt;/p&gt;

&lt;h2&gt;
  
  
  Pros
&lt;/h2&gt;

&lt;p&gt;The dream is that you get the best of all strategies. &lt;/p&gt;

&lt;h2&gt;
  
  
  Cons
&lt;/h2&gt;

&lt;p&gt;Testing error recovery in code is difficult. The system could become even more unreliable if a fault occurs in the error recovery code.&lt;/p&gt;

&lt;p&gt;Testing error recovery code at the system level can be difficult unless an error can be triggered in some way. This con can be mitigated if there is a system-level fault-tolerance mechanism (rather than trying to handle the error in code) that is easily testable. But this can also become a con again if the error condition persists leading frequent engagement of the fault-tolerance mechanism which itself can cause instability.&lt;/p&gt;

&lt;h1&gt;
  
  
  Discussion
&lt;/h1&gt;

&lt;p&gt;There are probably other approaches. If you can think of any others, please let me know in the comments. &lt;/p&gt;

&lt;p&gt;I don't think there is a one-size-fits-all implementation strategy for design by contract. I think in my case, the new layer will use a strategy of throwing exceptions up to higher layers when pre-conditions, post-conditions and invariants are violated. It will then be up to the higher layers to decide what to do.&lt;/p&gt;

</description>
      <category>computerscience</category>
      <category>programming</category>
    </item>
    <item>
      <title>How to Create a .NET 6.0 SDK Linux Docker Container</title>
      <dc:creator>G.L Solaria</dc:creator>
      <pubDate>Fri, 12 Nov 2021 23:58:18 +0000</pubDate>
      <link>https://dev.to/glsolaria/how-to-create-a-net-60-sdk-linux-docker-container-589l</link>
      <guid>https://dev.to/glsolaria/how-to-create-a-net-60-sdk-linux-docker-container-589l</guid>
      <description>&lt;p&gt;This post describes the steps I took to create a .NET 6.0 SDK Docker container running Ubuntu 20.04. I should note that my host machine is also running Ubuntu 20.04. Here is a more detailed explanation on how to &lt;a href="https://github.com/dotnet/dotnet-docker/blob/main/samples/README.md" rel="noopener noreferrer"&gt;setup Docker .NET images on GitHub&lt;/a&gt;.  &lt;/p&gt;

&lt;h1&gt;
  
  
  Install Docker on Ubuntu 20.04
&lt;/h1&gt;

&lt;p&gt;I quite like the &lt;a href="https://docs.docker.com" rel="noopener noreferrer"&gt;Docker documentation&lt;/a&gt; on &lt;a href="https://docs.docker.com/engine/install/ubuntu/" rel="noopener noreferrer"&gt;how to install Docker on Ubuntu&lt;/a&gt; so I am not going to repeat the steps here.&lt;/p&gt;

&lt;h1&gt;
  
  
  Note the .NET 6.0 Dockerhub Image Tag
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://hub.docker.com/" rel="noopener noreferrer"&gt;Dockerhub&lt;/a&gt; is the biggest and most well-known repository of pre-built docker images. It hosts the .NET 6.0 &lt;a href="https://hub.docker.com/_/microsoft-dotnet-runtime" rel="noopener noreferrer"&gt;runtime&lt;/a&gt; and &lt;a href="https://hub.docker.com/_/microsoft-dotnet-sdk" rel="noopener noreferrer"&gt;SDK&lt;/a&gt; images built by Microsoft.&lt;/p&gt;

&lt;p&gt;Say you want to install the .NET 6.0 SDK on Ubuntu 20.04.&lt;/p&gt;

&lt;p&gt;First you need to know the path. If you look at the "Featured Tag" section of the page, you will see something like the following ...&lt;br&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%2Fuploads%2Farticles%2Fcg92zi9qbljl5qvpu39e.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%2Fuploads%2Farticles%2Fcg92zi9qbljl5qvpu39e.png" alt=".NET 6.0 featured tag"&gt;&lt;/a&gt;&lt;br&gt;
More information on the featured tag can be found on the &lt;a href="https://github.com/dotnet/dotnet-docker/blob/main/samples/dotnetapp/README.md" rel="noopener noreferrer"&gt;samples page&lt;/a&gt; ...&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The sdk:6.0 and runtime:6.0 tags are both multi-arch tags that will result in an image that is compatible for the given chip and OS. These simple tags (only contain a version number) are great to get started with Docker because they adapt to your environment.&lt;br&gt;
They do mention that for production systems, you should specify an OS-specific tag. So we need to extract the image path from the tag. In this case, the path is "mcr.microsoft.com/dotnet/sdk".&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now if you navigate to the "Full Tag Listing" on the &lt;a href="https://hub.docker.com/_/microsoft-dotnet-sdk" rel="noopener noreferrer"&gt;.NET SDK dockerhub page&lt;/a&gt;, you will see something like the following ...&lt;br&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%2Fuploads%2Farticles%2Fbivmiumlw68mzuk3r4xi.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%2Fuploads%2Farticles%2Fbivmiumlw68mzuk3r4xi.png" alt=".NET SDK dockerhub page"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Say I want the latest Ubuntu 20.04 image, then the tag will be "6.0-focal" and the full path will be "mcr.microsoft.com/dotnet/sdk:6.0-focal". But you can use any Linux image tag. For example to build an Alpine image, use "mcr.microsoft.com/dotnet/sdk:6.0-alpine".&lt;/p&gt;

&lt;h1&gt;
  
  
  Create a Dockerfile
&lt;/h1&gt;

&lt;p&gt;So now we know the path and tag of the image we want to base our image on, we can create a a file called "Dockerfile" in an empty directory ...&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;

&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;mcr.microsoft.com/dotnet/sdk:6.0-focal&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;build&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h1&gt;
  
  
  Build the Docker Image
&lt;/h1&gt;

&lt;p&gt;To create the image we run the following command in the same directory as the "Dockerfile" ...&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nb"&gt;sudo &lt;/span&gt;docker build &lt;span class="nt"&gt;-t&lt;/span&gt; example-image &lt;span class="nb"&gt;.&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The "-t" option specifies a tag name and the "." tells it which directory to find the "Dockerfile".&lt;/p&gt;

&lt;p&gt;To see that the image has been successfully created, run ...&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nb"&gt;sudo &lt;/span&gt;docker image &lt;span class="nb"&gt;ls&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h1&gt;
  
  
  Create and Run a Command in a Container
&lt;/h1&gt;

&lt;p&gt;To create and run a command in a new container based on the image we just built, we run the following command ...&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;docker run &lt;span class="nt"&gt;--name&lt;/span&gt; example-server &lt;span class="nt"&gt;-it&lt;/span&gt; &lt;span class="nt"&gt;--rm&lt;/span&gt; example-image bash


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The "-it" will run the bash command interactively and allocates a &lt;a href="https://en.wikipedia.org/wiki/Pseudoterminal" rel="noopener noreferrer"&gt;pseudo TTY&lt;/a&gt; to allow us to effectively run a bash shell in our current shell. The "--rm" will automatically remove the container that gets created. If we did not use the "--rm" option, each time we run the command, a new container would be created. From the bash terminal running in the container, list out the supported SDKs and exit ...&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

root@2dc636974d10:/# dotnet &lt;span class="nt"&gt;--list-sdks&lt;/span&gt;
6.0.100 &lt;span class="o"&gt;[&lt;/span&gt;/usr/share/dotnet/sdk]
root@2dc636974d10:/# &lt;span class="nb"&gt;exit&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The "exit" command will exit the bash shell running in the container and the container will get deleted because of the "--rm" option we specified in the run command.&lt;/p&gt;

</description>
      <category>docker</category>
      <category>csharp</category>
    </item>
    <item>
      <title>What's new in C# 10.0</title>
      <dc:creator>G.L Solaria</dc:creator>
      <pubDate>Sat, 06 Nov 2021 03:35:42 +0000</pubDate>
      <link>https://dev.to/glsolaria/whats-new-in-c-100-4l3n</link>
      <guid>https://dev.to/glsolaria/whats-new-in-c-100-4l3n</guid>
      <description>&lt;p&gt;C# was first released around 20 years ago and recently the pace of releases has increased with new releases being unveiled every year for the past 4 years.&lt;/p&gt;

&lt;p&gt;C# 10.0 is likely to be launched with .NET 6.0 at &lt;a href="https://www.dotnetconf.net/"&gt;.NET Conf 2021&lt;/a&gt; coming up on November 9 (with the conference concluding on November 11). So I thought I would summarise some of the new features introduced in C# 10.0. But first a bit of history ...&lt;/p&gt;

&lt;h1&gt;
  
  
  Language Evolution
&lt;/h1&gt;

&lt;p&gt;Initially C# was released every few years. Each release typically included a signature feature that required significant thought in how to use it. For example, C# 2.0 introduced Generics, C# 3.0 introduced LINQ, C# 5.0 introduced async/await for asynchronous programming. &lt;/p&gt;

&lt;p&gt;With the latest releases now happening every year, they are focusing more on code simplification with smaller updates. Big new features, however, are now likely to evolve over a few releases. For example, pattern matching continues to evolve now spanning 4 releases. Records is another example of this evolutionary approach. &lt;/p&gt;

&lt;p&gt;The C# language design also moved from a closed, secret development model to an open development model around 2013. Now you can even contribute to the &lt;a href="https://github.com/dotnet/csharplang"&gt;C# language design forum hosted on GitHub&lt;/a&gt; to help further evolve the language. Design meetings and road-maps are published on the site publicly to enable open discussions and feedback.&lt;/p&gt;

&lt;h1&gt;
  
  
  New Features
&lt;/h1&gt;

&lt;p&gt;I have chosen not to describe all proposed features of C# 10.0 because this would be a very long post (it's very long already!). If you are interested in the full list of proposals, see the &lt;a href="https://github.com/dotnet/csharplang/blob/main/Language-Version-History.md"&gt;C# Language Version History&lt;/a&gt;. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;File scoped namespace declarations which is a dispenses with the wasteful indentation and braces that comes with namespace declarations thereby removing one level of indentation and braces for all C# files.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Global using directives which allow you to define using directives centrally so that they do not need to be defined in every file.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Constant interpolated strings which allows interpolated strings to be able to be declared constant where possible.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Extended property patterns which simplifies the use of nested properties in pattern matching statements.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Lambda improvements which include the ability for attributes to be defined on lambdas, ability to use var when defining lambdas, and the ability to specify the return type of a lambda.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Caller argument expression which adds a new attribute to help identify expression information at compile time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Record structs which evolves the C# 9.0 record class reference-type to add a new record struct value-type to manipulate small records efficiently.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Incremental generators which takes source code generators to the next level allowing for generation of not just source code. It also allows for improved generation performance.  &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Improved definite assignment analysis which fixes a few obscure cases where the compiler would complain that a variable had not been initialised.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  File scoped namespace declarations
&lt;/h1&gt;

&lt;p&gt;Instead of ...&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;namespace&lt;/span&gt; &lt;span class="nn"&gt;WhatsNew10&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Foo&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;... you can dispense with the top level braces by declaring the namespace using the following ...&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;namespace&lt;/span&gt; &lt;span class="nn"&gt;WhatsNew10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Foo&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;h1&gt;
  
  
  Global using directives
&lt;/h1&gt;

&lt;p&gt;The using directive imports all types from the specified namespace.&lt;/p&gt;

&lt;p&gt;Adding the keyword "global" to the directive in any code file will import those namespace types and make the types available to all code in the project.&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;global&lt;/span&gt; &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Implicit global using directives are also created by the compiler depending on the .NET 6.0 project SDK type. The implicit usings for 2 of the major project types are shown below ...&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
  &lt;tr&gt;
    &lt;th&gt;Project SDK Type&lt;/th&gt;
    &lt;th&gt;Implicit Global Usings&lt;/th&gt;
  &lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
  &lt;tr&gt;
    &lt;td rowspan="7"&gt;Microsoft.NET.Sdk&lt;/td&gt;
    &lt;td&gt;System&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;System&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;System.IO&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;System.Net.Linq&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;System.Net.Http&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;System.Threading&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;System.Threading.Tasks&lt;/td&gt;&lt;/tr&gt;

  &lt;tr&gt;
    &lt;td rowspan="10"&gt;Microsoft.NET.Sdk.Web&lt;/td&gt;
    &lt;td&gt;System&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;System.Net.Http.Json&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Microsoft.AspNetCore.Builder&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Microsoft.AspNetCore.Hosting&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Microsoft.AspNetCore.Http&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Microsoft.AspNetCore.Routing&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Microsoft.Extensions.Configuration&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Microsoft.Extensions.DependencyInjection&lt;/td&gt;&lt;/tr&gt; 
  &lt;tr&gt;&lt;td&gt;Microsoft.Extensions.Hosting&lt;/td&gt;&lt;/tr&gt; 
  &lt;tr&gt;&lt;td&gt;Microsoft.Extensions.Logging&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;So together with the C# 9.0 &lt;a href="https://github.com/dotnet/csharplang/blob/main/proposals/csharp-9.0/top-level-statements.md"&gt;Top Level Statements&lt;/a&gt; feature, the complete code file for a Program.cs can look 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="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;"Hello, World!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Constant interpolated strings
&lt;/h1&gt;

&lt;p&gt;The following use of the constant keyword is now permitted for interpolated strings where previously a compile error would be generated ...&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;const&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;s1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;$"Hello world"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;s3&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="n"&gt;s1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; C#10"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Extended property patterns
&lt;/h1&gt;

&lt;p&gt;Consider the following ...&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;aa&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;A&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Property1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"foo"&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;bb&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Property2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;aa&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;A&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Property1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&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;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;B&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;A&lt;/span&gt; &lt;span class="n"&gt;Property2&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&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;To use pattern matching on an instance of B you previously had 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="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;isFoo&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bb&lt;/span&gt; &lt;span class="k"&gt;switch&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Property2&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Property1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"foo"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;... but you can do this more simply now by ...&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;bool&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bb&lt;/span&gt; &lt;span class="k"&gt;switch&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Property2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Property1&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"foo"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Lambda improvements
&lt;/h1&gt;

&lt;p&gt;Automatic inference of the type of a lambda is a nice simplification introduced in C# 10.0.&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;Func&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;,&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;isFooInC9&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ss&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ss&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"foo"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// C# 9.0&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;isFooIn10&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;ss&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ss&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"foo"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;       &lt;span class="c1"&gt;// C# 10.0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lambdas can also have attributes defined on them so instead of ...&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="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;HttpGet&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="n"&gt;Foo&lt;/span&gt; &lt;span class="nf"&gt;GetFoo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&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="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Name"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;MapAction&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;Func&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;)&lt;/span&gt;&lt;span class="n"&gt;GetFoo&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;... you can now write ...&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;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;MapAction&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nf"&gt;HttpGet&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="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Foo&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="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Name"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The return type of a lambda can also now be explicitly specified ...&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;foo&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;        &lt;span class="c1"&gt;// foo is type Func&amp;lt;Int32&amp;gt;&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;bar&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;long&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="c1"&gt;// bar is type Func&amp;lt;Int64&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are a few other improvements including direct lambda invocation and enhanced overload resolution that can be reviewed in the &lt;a href="https://github.com/dotnet/csharplang/blob/main/proposals/csharp-10.0/lambda-improvements.md"&gt;proposal for lambda improvements&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Caller Argument Expression
&lt;/h1&gt;

&lt;p&gt;You can now get an expression as a string by ...&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="c1"&gt;// Writes "(1 == 2 ? true : false) is False" to the console.&lt;/span&gt;
&lt;span class="nf"&gt;Print&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="m"&gt;2&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="k"&gt;true&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="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;CallerArgumentExpression&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"result"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;expr&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;default&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;$"(&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;expr&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;) is &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;result&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;h1&gt;
  
  
  Record Structs
&lt;/h1&gt;

&lt;p&gt;Record classes introduced in C# 9.0 are useful because it makes it easier to create immutable objects that are thread-safe (by using the init keyword instead of the set keyword). Record classes are also helpful because the compiler creates some nice value-like built-in methods like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;equality operators, &lt;/li&gt;
&lt;li&gt;a numeric hash code based on the property values (so you can use the record in a hash-based collections for fast look-ups), and &lt;/li&gt;
&lt;li&gt;a way to convert the values of the record properties to a string.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Record structs also provide those compiler generated record built-ins (unlike plain structs which only generate getters and setters). Record classes, however, are reference types so instances of the type are allocated within the heap. Record structs, on the other hand, are value types so they are allocated on the stack. This means record structs can be manipulated efficiently. &lt;/p&gt;

&lt;p&gt;So now we can create an immutable record struct in one nice line 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;public&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Fiz&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Faz&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;... and use it ...&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;foo1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Foo&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Fiz&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Fizzy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Faz&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Fazzy"&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;foo2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Foo&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Fiz&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Fizzy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Faz&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Fazzy"&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;foo3&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;foo1&lt;/span&gt; &lt;span class="n"&gt;with&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Faz&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Zazzy"&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;$"&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;foo1&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="c1"&gt;// Foo { Fiz = Fizzy, Faz = Fazzy }&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;$"&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;foo2&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="c1"&gt;// Foo { Fiz = Fizzy, Faz = Fazzy }&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;$"&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;foo3&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="c1"&gt;// Foo { Fiz = Fizzy, Faz = Zazzy }&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;$"&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;foo1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetHashCode&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="c1"&gt;// 129686175&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;$"&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;foo2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetHashCode&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="c1"&gt;// 129686175&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;$"&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;foo3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetHashCode&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="c1"&gt;// 784730341&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;$"&lt;/span&gt;&lt;span class="p"&gt;{(&lt;/span&gt;&lt;span class="n"&gt;foo1&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;foo2&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="c1"&gt;// True&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;$"&lt;/span&gt;&lt;span class="p"&gt;{(&lt;/span&gt;&lt;span class="n"&gt;foo1&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;foo3&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="c1"&gt;// False&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Incremental generators
&lt;/h1&gt;

&lt;p&gt;Source generators were introduced in .NET 5 which lets ...&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;C# developers inspect user code and generate new C# source files that can be added to a compilation. This is done via a new kind of component that we’re calling a Source Generator. (&lt;a href="https://devblogs.microsoft.com/dotnet/introducing-c-source-generators/"&gt;Introducing C# Source Generators&lt;/a&gt;)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Incremental generators are a new feature that allows for the generation of source code, artefacts and embedded files. Pipelines can be implemented that use cached data to perform further transformations thereby improving performance. &lt;/p&gt;

&lt;p&gt;I admit I don't fully understand how to use this feature and I will be looking forward to .NET Conf for some simple explanations and examples.&lt;/p&gt;

&lt;h1&gt;
  
  
  Improved definite assignment analysis
&lt;/h1&gt;

&lt;p&gt;Definite assignment analysis is the static analysis done by the compiler to ensure that variables are assigned before they are used. C and C++ don't have this feature although Java does.&lt;/p&gt;

&lt;p&gt;There were a few interesting cases that previously gave an error and are now okay with C# 10.0. The cases are obscure but if you are really interested, you can &lt;a href="https://github.com/dotnet/csharplang/blob/main/proposals/csharp-10.0/improved-definite-assignment.md"&gt;delve into the cases&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;So there have been some nice simplifications proposed for C# 10.0. They are continuing to evolve features such as pattern matching and records in response to developer feedback which I think is good to see. C# might even survive another 20 years!&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=JOdGFLNDbBs"&gt;Chat with Mads Torgersen who has worked on the language for over 16 years&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/csharplang/blob/main/Language-Version-History.md"&gt;Features added in C# language versions&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

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