<rss version="2.0">
  <channel>
    <title>Seb Nilsson</title>
    <link>https://feeds.feedburner.com/sebnilsson</link>
    <description>Seb Nilsson on Liquid Development</description>
    <item>
      <title>dotnet-ping: Ping URLs in the Terminal</title>
      <link>https://sebnilsson.com/blog/dotnet-ping-ping-urls-in-the-terminal/</link>
      <pubDate>Mon, 14 Oct 2024 06:44:00 GMT</pubDate>
      <description>&lt;p&gt;When working with the web development at a rapid pace, you need to constantly ensure that key parts of your website always work.
There are tools out there that offers advanced monitoring,
but what about when you just want to fire off quick ensuring tests on your local machine?&lt;/p&gt;
&lt;p&gt;This is the background to why I built &lt;code&gt;dotnet-ping&lt;/code&gt;,
which is easily installed as a &lt;a href="https://learn.microsoft.com/dotnet/core/tools/global-tools"&gt;.NET Global Tool&lt;/a&gt;
and makes pinging URLs via the terminal really easy.&lt;/p&gt;
&lt;h2 class="h1"&gt;Installation&lt;/h2&gt;
&lt;p&gt;Download &lt;a href="https://dotnet.microsoft.com/download"&gt;the latest version of .NET&lt;/a&gt;. Then install the &lt;a href="https://www.nuget.org/packages/dotnet-ping"&gt;&lt;code&gt;dotnet-ping&lt;/code&gt;&lt;/a&gt; .NET Tool, using the terminal:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dotnet tool install -g dotnet-ping
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Once installed, you can verify the tool is available by running &lt;code&gt;dotnet tool list -g&lt;/code&gt;.&lt;/p&gt;
&lt;h2 class="h1"&gt;Basic scenarios&lt;/h2&gt;
&lt;p&gt;To ping a single URL just supply the URL as the command argument:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;dotnet ping https://example.com/section/page&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;If you want to ping multiple URLs, you can supply multiple command arguments.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;dotnet ping example.com/page other.com/other-page&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;If a URL is missing the protocol (e.g., &lt;code&gt;http://&lt;/code&gt; or &lt;code&gt;https://&lt;/code&gt;), the tool will automatically assume &lt;code&gt;https://&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;You can use the &lt;code&gt;-s&lt;/code&gt; option to set the sleep time between requests
and the &lt;code&gt;-t&lt;/code&gt; option to set the timeout limit for a response from the pinged URL.&lt;/p&gt;
&lt;p&gt;If you want to ping multiple pages on the same website, you can supply a base-URL, using the &lt;code&gt;-b&lt;/code&gt; option:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;dotnet ping -b example.com /home /about /contact-us /products&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Pings expect, by default, a &lt;code&gt;200&lt;/code&gt; response as HTTP status. This can be modified with the &lt;code&gt;-e&lt;/code&gt; option.
The full list of documentation can be found by calling the tool with the &lt;code&gt;-h&lt;/code&gt; option or looking at the &lt;code&gt;README&lt;/code&gt; on
&lt;a href="https://github.com/sebnilsson/DotnetPing"&gt;GitHub&lt;/a&gt; or on &lt;a href="https://www.nuget.org/packages/dotnet-ping/"&gt;NuGet.org&lt;/a&gt;.&lt;/p&gt;
&lt;h2 class="h1"&gt;Advanced scenarios&lt;/h2&gt;
&lt;p&gt;For more advanced scenarios, where you want to have a better overview and more complex configuration for multiple URLs,
the tool supports configuration via a &lt;code&gt;.json&lt;/code&gt; file. If there is a &lt;code&gt;ping.json&lt;/code&gt; file in the directory that the tool is executed from,
and no URL is passed as a command argument, this file will be used.&lt;/p&gt;
&lt;p&gt;The basic structure of the file allows an array of URLs (&lt;code&gt;urls&lt;/code&gt;) and their configuration,
as well as an array of configuration group (&lt;code&gt;groups&lt;/code&gt;), which are applied to one or multiple URLs.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
    // Single URLs, with Single configurations
    "urls": [
        {
            "url": "test.com", // Required
            "method": "GET", // Default: GET
            "timeout": 15000, // Default: 5000ms
            "sleep": 100, // Default: 500ms
            "expect": [ 200, 201, 403 ] // Default: 200
        },
        {
            "url": "http://test2.com",
            "method": "DELETE",
            "timeout": 10000,
            "sleep": 200,
            "expect": [ 201, 202, 204 ]
        }
    ],
    // Groups of configurations, with single or multiple URLs
    "groups": [
        {
            "timeout": 20000,
            "sleep": 250,
            "expect": [ 301, 302 ],
            "urls": [ "test3.com/redirect", "test4.com/redirect" ]
        },
        {
            "timeout": 5000,
            "sleep": 550,
            "baseUrl": "https://test5.com/",
            "expect": [ 200, 201 ],
            "urls": [ "/", "/about", "/contact", "products" ]
        }
    ]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 class="h1"&gt;Usage Documentation&lt;/h2&gt;
&lt;p&gt;See the usage documentation of the tool by running &lt;code&gt;dotnet ping -h&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;USAGE:
    dotnet-ping [urls] [OPTIONS]

EXAMPLES:
    dotnet-ping https://example.com
    dotnet-ping https://example.com other.com -s 1000
    dotnet-ping https://example.com other.com -s 1000 -s 2000 -t 5000
    dotnet-ping /about /contact -b https://example.com
    dotnet-ping -c ping.json

ARGUMENTS:
    [urls]    The URLs to ping. If not specified, the URLs are read from the JSON config file

OPTIONS:
    -h, --help        Prints help information
    -b, --base-url    Sets the base-URL to use for requests
    -c, --config      The path to the JSON config file
    -d, --debug       Use debug console messaging
    -e, --expect      Sets the expected status code of requests. Default: 200
    -X, --request     Sets the request method. Default: GET
    -m, --minimal     Use minimal console messaging
    -s, --sleep       Sets the sleep wait time between requests in milliseconds. Default: 500ms
    -t, --timeout     Sets the timeout for requests in milliseconds. Default: 5000ms. If two values are provided, a
                      random number between the two numbers will be generated for each request
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 class="h1"&gt;Outro&lt;/h2&gt;
&lt;p&gt;Take it for a spin and feel free to give feedback on the tool.
If you find bugs or have suggestions,
feel free to &lt;a href="https://github.com/sebnilsson/DotnetPing"&gt;open an issue on GitHub or submit a pull request&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You can find the &lt;a href="https://github.com/sebnilsson/DotnetPing"&gt;source-code on GitHub&lt;/a&gt;
and the &lt;a href="https://www.nuget.org/packages/dotnet-ping/"&gt;package on Nuget&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>How to Understand Log Levels</title>
      <link>https://sebnilsson.com/blog/how-to-understand-log-levels/</link>
      <pubDate>Sun, 05 Sep 2021 12:27:00 GMT</pubDate>
      <description>&lt;p&gt;&lt;em&gt;&lt;strong&gt;Originally written and published for &lt;a href="https://lightrun.com/best-practices/how-to-understand-log-levels/"&gt;Lightrun's best practices&lt;/a&gt;&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;More than once, I've heard experienced software developers say that there are only two reasons to log: either you log &lt;code&gt;Information&lt;/code&gt; or you log an &lt;code&gt;Error&lt;/code&gt;. The implication here is that either you want to &lt;strong&gt;record something that happened&lt;/strong&gt; or you want to be able to &lt;strong&gt;react to something that went wrong&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;In this article, we'll take a closer look at logging and explore the fact that &lt;strong&gt;log levels are more than just black or red rows&lt;/strong&gt; in your main logging system. When used correctly, they let you filter certain types of data to be logged to different destinations, have different retention times, and can be searched more easily in different structures of the data.&lt;/p&gt;
&lt;h3 class="h2"&gt;Why Logging?&lt;/h3&gt;
&lt;p&gt;While developing software, hopefully you write unit tests to validate isolated functionality in your code, add some integration tests, and maybe do some manual testing on top of that. But when your code is running in production, you need a way to get information about what code is being executed inside your software and have that accessible from the outside.&lt;/p&gt;
&lt;p&gt;The most common way to do this is to add logging to your code. Usually, this code will then write to a destination, which can be a local file, a database, or a centrally controlled more advanced log solution. You can then access this information to get technical insights into what's going on in the running code.&lt;/p&gt;
&lt;p&gt;Log entries, depending on configuration, usually contain a time stamp, a severity level, a message entered in the code, sometimes which class/file is doing the logging, sometimes a stack trace from an error in the code, and other metadata about the execution context. When done right, this can help developers follow the flow of logic through the software.&lt;/p&gt;
&lt;p&gt;Many use logging to log key events in the system, like orders completed, users registered, reviews written, and so on. &lt;strong&gt;With correctly structured data, you can pipe this data into different analysis tools to get more business insights.&lt;/strong&gt; For example, usually, you turn to your logs when something goes wrong in the software. If logging is set up correctly, you'll be able to figure out where the problem comes from and from which line of code.&lt;/p&gt;
&lt;p&gt;If there's not enough information in your logs, you might want to ensure that a lower level of logging is written to your logs, so you can get more details about what's going on in your software. You can usually achieve this by using different log levels.&lt;/p&gt;
&lt;h3 class="h2"&gt;Understanding The Different Log Levels&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Log levels convey the intention of the specific content of what's being logged. This can help you filter different levels of log data into different destinations, enabling you to focus on the log level relevant to the current issue you're facing.&lt;/strong&gt; Logging to different destinations also allows you to have different retention levels for different logged content.&lt;/p&gt;
&lt;p&gt;These are the most common log levels for logging libraries:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Critical&lt;/code&gt;&lt;em&gt;*&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Error&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Warn&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Info&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Debug&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Trace&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;* Sometimes under other names, such as &lt;strong&gt;Fatal&lt;/strong&gt; or &lt;strong&gt;Fault&lt;/strong&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Different languages and platforms, and their most popular logging libraries, actually support different log levels, even if the core functionality is there across them all.&lt;/p&gt;
&lt;div class="table-responsive"&gt;&lt;table class="table table-sm table-bordered table-striped table-hover"&gt;
&lt;thead class="thead-dark"&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;Trace&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;Debug&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;Info&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;Warn&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;Error&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;Critical&lt;/code&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://docs.microsoft.com/dotnet/api/microsoft.extensions.logging.loglevel"&gt;C#/.NET&lt;/a&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;&lt;a href="https://logging.apache.org/log4j/2.x/manual/customloglevels.html"&gt;Java&lt;/a&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;✔️ (as &lt;code&gt;Fatal&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://docs.python.org/3/library/logging.html#levels"&gt;Python&lt;/a&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;&lt;a href="https://docs.rs/log/0.4.14/log/"&gt;Rust&lt;/a&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;&lt;a href="https://developer.apple.com/documentation/os/oslogtype"&gt;Swift&lt;/a&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;✔️ (as &lt;code&gt;Fault&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/MicroUtils/kotlin-logging/blob/master/src/jvmMain/kotlin/mu/KLogger.kt"&gt;Kotlin&lt;/a&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;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;p&gt;Many logging libraries allow you to also handle an &lt;code&gt;All&lt;/code&gt; scenario, where all the levels are written to the configured destinations. The &lt;code&gt;None&lt;/code&gt; scenario, then, turns off all the logging. Some libraries also support a &lt;code&gt;Custom&lt;/code&gt; scenario, where you can specify exactly which log levels to include.&lt;/p&gt;
&lt;h3 class="h2"&gt;Picking the Right Log Level&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;There is no right or wrong when it comes to picking a level of logging, but it's important to set the same expectations throughout a project and maybe throughout an entire organization.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Here are a few best-practice suggestions as a starting point that any team should be able to build upon:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Critical&lt;/code&gt;: Used when your application is in an unrecoverable state. It crashes during startup configuration, or a framework-level component is not working as expected.&lt;br&gt;
&lt;em&gt;Example: Your app cannot start up correctly or your DI setup fails.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Error&lt;/code&gt;: Used for errors that stop the flow of the execution. Usually used for unknown and unexpected errors in a central catch-all scenario for an application.&lt;br&gt;
&lt;em&gt;Example: Routing in your web app fails, or code in an MVC controller throws an exception.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Warn&lt;/code&gt;: Used for errors that don't stop the flow of execution. Usually, these errors are somewhat expected, since the logging code is added manually to these points in the code.&lt;br&gt;
&lt;em&gt;Example: Calling an external service, which you know can fail and you can silently recover from.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Info&lt;/code&gt;: Used to log events in the normal flow of the code. Can be used for only system key events, to keep the volume of log data down.&lt;br&gt;
&lt;em&gt;Example: User clicked a call-to-action button or new user registered.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Debug&lt;/code&gt;: Used for scenarios where the information in higher levels is not enough to &lt;a href="https://lightrun.com/debugging/debugging-microservices-the-ultimate-guide/"&gt;debug a problem&lt;/a&gt;. Should record the flow through the system.&lt;br&gt;
&lt;em&gt;Example: Method X was called in class/object Y, to track different flows.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Trace&lt;/code&gt;: Used to get as much detail as possible, tracking the flow of data through the system. Can contain sensitive data. Should probably never be activated in production.&lt;br&gt;
&lt;em&gt;Example: Method X was called with parameter values Y and Z.&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Usually, &lt;code&gt;Critical&lt;/code&gt;, &lt;code&gt;Error&lt;/code&gt;, and sometimes &lt;code&gt;Warn&lt;/code&gt; levels contain a &lt;strong&gt;full stack trace&lt;/strong&gt; for full analysis of the technical context of the problem.&lt;/p&gt;
&lt;p&gt;You will probably want different configurations for your logging between your local development environment, your testing environment, and your production environment. It's worth noting that, with most logging libraries, configuring for one level includes the levels above it. For example, if you configure for the &lt;code&gt;Info&lt;/code&gt; level, it'll include all levels above it, too, in the logging. So you'll also get &lt;code&gt;Info&lt;/code&gt;, &lt;code&gt;Warn&lt;/code&gt; (where available), &lt;code&gt;Error&lt;/code&gt;, and &lt;code&gt;Critical&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Some libraries allow you to set an upper limit as well, but this is for very specific scenarios, since you would rarely want to see &lt;code&gt;Error&lt;/code&gt; logs but not &lt;code&gt;Critical&lt;/code&gt; logs, for example.&lt;/p&gt;
&lt;p&gt;However, all solutions have different needs, and these needs can change depending on what problem occurs when. Let’s glance through some examples of various setups.&lt;/p&gt;
&lt;h4 class="h3"&gt;Local Development Environment&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;In a development environment on your local machine, you probably want to start off with the &lt;code&gt;Debug&lt;/code&gt; level of logging.&lt;/strong&gt; You can lower it to &lt;code&gt;Trace&lt;/code&gt; if more detailed issues need diagnosed, or increase it to &lt;code&gt;Info&lt;/code&gt; if it gets too noisy.&lt;/p&gt;
&lt;p&gt;You'll probably always want to write to local files on your file system for quick access, and avoid writing to any central logging destination, unless you're explicitly testing the integration itself. This is because it can generate a lot of data over time, even with a small team, which usually increases cost quite a lot.&lt;/p&gt;
&lt;h4 class="h3"&gt;Testing Environment&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;In a testing environment, which is not on your local machine, you probably want to set the logging level to &lt;code&gt;Info&lt;/code&gt; and then temporarily turn the level down to &lt;code&gt;Debug&lt;/code&gt; and &lt;code&gt;Trace&lt;/code&gt; as needed for the moment.&lt;/strong&gt; If you're not interested in the normal flow of the app and only want to catch errors, you can actually set the logging level to &lt;code&gt;Error&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;As it's a test environment, you should only have test data logging here, so lower logging levels should not be logging sensitive production data. You don't have to worry about that aspect here, even if you should always be vigilant of it.&lt;/p&gt;
&lt;p&gt;Since this is not a local machine, you probably don't have (and maybe shouldn't have) easy access to the machine's local disk. This is a good opportunity to use a central logging solution (there are plenty of those on the market at the moment at various pricing levels).&lt;/p&gt;
&lt;h4 class="h3"&gt;Production Environment&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;In a production environment, you could start out by configuring your logging to write &lt;code&gt;Info&lt;/code&gt; and higher to a centralized logging service, such as a SaaS solution in the cloud. You should consider writing the &lt;code&gt;Error&lt;/code&gt; level and higher to local disk files, in case the SaaS has any technical issues.&lt;/strong&gt; Remember to manage the retention of these local logs to avoid being incompliant with data privacy rules and to keep costs down.&lt;/p&gt;
&lt;p&gt;For the very complicated and hard-to-solve bugs, you need to be able to activate &lt;code&gt;Debug&lt;/code&gt; and &lt;code&gt;Trace&lt;/code&gt; level logging. To comply with data privacy rules without too much hassle, consider writing only these two low levels to local files, which can easily be deleted, and set a very short retention time for them. &lt;strong&gt;Always consider using a &lt;em&gt;staging environment&lt;/em&gt; first, when using the &lt;code&gt;Trace&lt;/code&gt; level&lt;/strong&gt; and only use the production environment as the last way out.&lt;/p&gt;
&lt;p&gt;You can also consider forwarding just the &lt;code&gt;Info&lt;/code&gt; entries to an analysis tool of choice, to analyze key business events being triggered in your system. Some logging libraries support sending additional data in their entries, which can make this scenario more powerful.&lt;/p&gt;
&lt;p&gt;If needed, you can also configure &lt;code&gt;Error&lt;/code&gt; and &lt;code&gt;Critical&lt;/code&gt; to log to another external system, maybe another SaaS, that sends out alerts for these log entries. Many existing SaaSes for logging have this functionality built-in, so there's usually not a need for this configuration, but it's good to know it's an option.&lt;/p&gt;
&lt;p&gt;This would then mean that you're double-logging between two systems, but since you hopefully won't have a large volume of this kind of log entry, you don't have to worry too much about cost and you're only using the right tool for the right job.&lt;/p&gt;
&lt;h3 class="h2"&gt;The Caveats of Logging&lt;/h3&gt;
&lt;p&gt;Logging a lot of data might be the only way to solve some of the craziest bugs created out there, but there are some downsides of logging too much.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Depending on the solution you choose for logging data, too much data could make it very hard to easily search through your logs.&lt;/strong&gt; If the logging is split into different files for different days (or hours), it's hard to analyze a trend over time.&lt;/p&gt;
&lt;p&gt;Normally, no matter what solution you have in place for logging, &lt;strong&gt;the more data you log, the higher the cost will be&lt;/strong&gt;. Even if you're logging to the local disk of the server, space can get used up quickly over time.&lt;/p&gt;
&lt;p&gt;There is also a major security risk of leaking sensitive data if you store too much data, with too detailed information, for too long. &lt;a href="https://en.wikipedia.org/wiki/Internet_privacy#Global_privacy_policies"&gt;With all the new privacy rules out there&lt;/a&gt;, you also risk being noncompliant for things like &lt;a href="https://en.wikipedia.org/wiki/General_Data_Protection_Regulation"&gt;GDPR&lt;/a&gt;, if you store personal information too long, even in local files.&lt;/p&gt;
&lt;h3 class="h2"&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Logging is something you should include in your workflow right from the beginning when writing your software. Setting it up, and with the right strategy, will enable you to produce well-running software, &lt;a href="https://lightrun.com/debugging/complete-agility-extend-your-ci-cd-pipelines-with-continuous-debugging-and-continuous-observability/"&gt;monitor it in a robust way&lt;/a&gt;, and quickly access details about any problems that occur. Just keep the potential pitfalls in mind, such as cost, searchability, and security.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Having a solid strategy for which log level to use for what scenario is crucial for a long-term path growth path for your software. This will allow you to extend your logging in the future, making use of more refined and mature logging tools, as your software grows and the need inevitably shows itself.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Best 20 C# &amp; .NET Blogs</title>
      <link>https://sebnilsson.com/blog/best-csharp-dotnet-blogs/</link>
      <pubDate>Mon, 21 Dec 2020 14:44:00 GMT</pubDate>
      <description>&lt;p&gt;&lt;em&gt;&lt;strong&gt;Originally written for and published on &lt;a href="https://draft.dev/learn/technical-blogs/c-sharp-blogs"&gt;the Draft.dev blog&lt;/a&gt;&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;C# is a language loved by its users for being versatile, productive, and keeping up with
the current problems programmers need to solve. For example, maintainers have added
functional programming concepts to the primarily imperative C# language, adding the powerful
query-functionality in LINQ, and smoother handling of asynchronous programming with the &lt;code&gt;async&lt;/code&gt; / &lt;code&gt;await&lt;/code&gt;-syntax.&lt;/p&gt;
&lt;p&gt;The unification of all versions of .NET into .NET 5 has given C# and .NET future-safety,
no matter which platform you use to develop or which platform you develop for: desktop, web, cloud, mobile, or other.&lt;/p&gt;
&lt;p&gt;Whether you're getting into C# with the launch of .NET 5 or if you're a long-time C# developer,
there are a lot of great blogs out there. Based on writing quality, consistency, longevity,
technical depth, and usefulness, I've put together &lt;strong&gt;this comprehensive list of the 20 best C# blogs publishing today&lt;/strong&gt;.&lt;/p&gt;
&lt;h4 class="h3"&gt;&lt;a href="https://devblogs.microsoft.com/dotnet/"&gt;.NET Blog&lt;/a&gt;&lt;/h4&gt;
&lt;p class="text-center mb-3"&gt;&lt;img src="https://files.sebnilsson.com/web/images/top-csharp-blogs/dotnet-blog.jpg" alt="Screenshot of the .NET Blog" class="img-fluid fancybox-img" loading="lazy"&gt;&lt;/p&gt;
&lt;p&gt;Maybe a bit obvious, but the .NET blog from Microsoft should probably your first place to check
for new updates on C# and .NET. They consistently publish updates about everything related to C# and .NET
but also dives deep into different subjects, such as functionality deep within .NET or the details
about the performance improvements being made there.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Writing Quality: 5&lt;/li&gt;
&lt;li&gt;Consistency: 5&lt;/li&gt;
&lt;li&gt;Longevity: 5&lt;/li&gt;
&lt;li&gt;Technical Depth: 5&lt;/li&gt;
&lt;li&gt;Broad Usefulness: 5&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 class="h3"&gt;&lt;a href="https://www.hanselman.com/blog"&gt;Scott Hanselman's Blog&lt;/a&gt;&lt;/h4&gt;
&lt;p class="text-center mb-3"&gt;&lt;img src="https://files.sebnilsson.com/web/images/top-csharp-blogs/hanselman.jpg" alt="Screenshot of Scott Hanselman's blog" class="img-fluid fancybox-img" loading="lazy"&gt;&lt;/p&gt;
&lt;p&gt;Sometimes, I'm unsure if you're allowed to use .NET if you're not reading Scott Hanselman's blog.
There might be something in EULA about that. 😉&lt;/p&gt;
&lt;p&gt;Jokes aside, Hanselman has been blogging about C# and .NET from the very start and has inspired
many people with the content on his blog, his conference-talks, his podcast, his YouTube-channel, and more.
He mixes high-level articles with some technical deep-dives, and his posts seem to be driven by his passion
for learning and solving problems.&lt;/p&gt;
&lt;p&gt;Hanselman has become quite a household name in the .NET-world and is often featured in Microsoft's keynotes.
This is well deserved, given his unparalleled professional approach to quality content, interesting topics,
and entertaining delivery.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Writing Quality: 5&lt;/li&gt;
&lt;li&gt;Consistency: 5&lt;/li&gt;
&lt;li&gt;Longevity: 5&lt;/li&gt;
&lt;li&gt;Technical Depth: 5&lt;/li&gt;
&lt;li&gt;Broad Usefulness: 5&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 class="h3"&gt;&lt;a href="https://ardalis.com/blog"&gt;Ardalis: Steve Smith's Blog&lt;/a&gt;&lt;/h4&gt;
&lt;p class="text-center mb-3"&gt;&lt;img src="https://files.sebnilsson.com/web/images/top-csharp-blogs/ardalis.jpg" alt="Screenshot of Ardalis: Steve Smith's Blog" class="img-fluid fancybox-img" loading="lazy"&gt;&lt;/p&gt;
&lt;p&gt;Steve Smith (aka Ardalis) is a strong proponent of producing content instead of consuming it,
which is quite obviously something he lives by when you look at his output. If you are a person
wanting to build your own brand, Steve is a role-model. He continually puts out qualitative information
on his blog, on Twitter, on Twitch, his newsletter, his Pluralsight-courses, and he now also is
building his own developer coaching-community.&lt;/p&gt;
&lt;p&gt;Lately, Steve has been focusing on a lot of content around Domain-Driven Design (DDD) and the SOLID-principles.
Much of this can be found on his blog and on some great Pluralsight-courses.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Writing Quality: 5&lt;/li&gt;
&lt;li&gt;Consistency: 5&lt;/li&gt;
&lt;li&gt;Longevity: 5&lt;/li&gt;
&lt;li&gt;Technical Depth: 5&lt;/li&gt;
&lt;li&gt;Broad Usefulness: 4&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 class="h3"&gt;&lt;a href="https://www.alvinashcraft.com/"&gt;Alvin Ashcraft's Morning Dew&lt;/a&gt;&lt;/h4&gt;
&lt;p class="text-center mb-3"&gt;&lt;img src="https://files.sebnilsson.com/web/images/top-csharp-blogs/morning-dew.jpg" alt="Screenshot of Alvin Ashcraft's Morning Dew" class="img-fluid fancybox-img" loading="lazy"&gt;&lt;/p&gt;
&lt;p&gt;Want to see basically every new article the community puts out every single day? Well, then Alvin Ashcraft's
&lt;em&gt;Morning Dew&lt;/em&gt; has you covered when it comes to the subjects of C#, .NET, and the Microsoft-ecosystem.&lt;/p&gt;
&lt;p&gt;Alvin Ashcraft is a longtime Microsoft MVP. From what you can tell from comments on his website,
Morning Dew is the result of Alvin reading through over 1,600 feeds daily. Any interesting articles found
are categorized and published on the blog.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Writing Quality: N/A&lt;/li&gt;
&lt;li&gt;Consistency: 5&lt;/li&gt;
&lt;li&gt;Longevity: 5&lt;/li&gt;
&lt;li&gt;Technical Depth: N/A&lt;/li&gt;
&lt;li&gt;Broad Usefulness: 5&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 class="h3"&gt;&lt;a href="https://www.troyhunt.com/"&gt;Troy Hunt&lt;/a&gt;&lt;/h4&gt;
&lt;p class="text-center mb-3"&gt;&lt;img src="https://files.sebnilsson.com/web/images/top-csharp-blogs/troy-hunt.jpg" alt="Screenshot of Troy Hunt's blog" class="img-fluid fancybox-img" loading="lazy"&gt;&lt;/p&gt;
&lt;p&gt;One of the most influential voices on the topic of security within the Microsoft-ecosystem is Troy Hunt.
He is the creator of the service &lt;a href="https://haveibeenpwned.com/"&gt;Have I Been Pwned (HIBP)&lt;/a&gt;, which helps users
identify if and how they've been affected by data breaches and other malicious activity on the internet.&lt;/p&gt;
&lt;p&gt;Since Troy has Microsoft MVP for developer-security for a longer time, this is a subject that is often covered on his blog.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Writing Quality: 5&lt;/li&gt;
&lt;li&gt;Consistency: 5&lt;/li&gt;
&lt;li&gt;Longevity: 5&lt;/li&gt;
&lt;li&gt;Technical Depth: 4&lt;/li&gt;
&lt;li&gt;Broad Usefulness: 3&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 class="h3"&gt;&lt;a href="https://timheuer.com/blog"&gt;Tim Heuer&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Tim Heuer has worked at Microsoft since 2005, currently with a focus on .NET, Visual Studio, and Azure.
This gives him a lot of insight, which you can tell by the in-depth content and a great variety of technologies covered on his blog.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Writing Quality: 5&lt;/li&gt;
&lt;li&gt;Consistency: 4&lt;/li&gt;
&lt;li&gt;Longevity: 5&lt;/li&gt;
&lt;li&gt;Technical Depth: 5&lt;/li&gt;
&lt;li&gt;Broad Usefulness: 4&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 class="h3"&gt;&lt;a href="https://thedatafarm.com/blog/"&gt;The Data Farm: Julie Lerman's World of Data&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Julie Lerman is the absolute authority on &lt;a href="https://docs.microsoft.com/en-us/ef/"&gt;Entity Framework&lt;/a&gt;, including EF Core.
No matter if you're looking for a detailed, low-level problem within EF, or if you're looking for
a solid guide to walk you through various aspects of Entity Framework, there is a real chance that you'll find
material around it produced by Julie Lerman.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Writing Quality: 5&lt;/li&gt;
&lt;li&gt;Consistency: 4&lt;/li&gt;
&lt;li&gt;Longevity: 5&lt;/li&gt;
&lt;li&gt;Technical Depth: 5&lt;/li&gt;
&lt;li&gt;Broad Usefulness: 4&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 class="h3"&gt;&lt;a href="https://haacked.com/"&gt;You've Been Haacked&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Phil Haack was an integral part of helping Microsoft make many of its development-software open-source,
along with Scott Hanselman, Scott Guthrie, and Rob Connery. Since then, Phil has moved on from Microsoft
but still consistently blogs about technologies in the Microsoft-ecosystem.&lt;/p&gt;
&lt;p&gt;With his experience inside Microsoft during their exciting transformation, there is usually something interesting
for developers to learn in his posts.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Writing Quality: 5&lt;/li&gt;
&lt;li&gt;Consistency: 4&lt;/li&gt;
&lt;li&gt;Longevity: 5&lt;/li&gt;
&lt;li&gt;Technical Depth: 4&lt;/li&gt;
&lt;li&gt;Broad Usefulness: 4&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 class="h3"&gt;&lt;a href="https://blog.ploeh.dk/"&gt;ploeh: Mark Seemann&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;If you feel completely bulletproof in your coding-skills, go check out Mark Seemann's blog and
get a glimpse of the endless things you could be doing better.&lt;/p&gt;
&lt;p&gt;Writing good software is an art, so you can have endless opinions on other peoples' opinions,
but there is almost always something new to learn from Mark's deep-diving and well-thought-through posts.
Each article walks you through a complicated concept and helps you understand it and become a better developer
who writes better, more maintainable code.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Writing Quality: 5&lt;/li&gt;
&lt;li&gt;Consistency: 5&lt;/li&gt;
&lt;li&gt;Longevity: 5&lt;/li&gt;
&lt;li&gt;Technical Depth: 5&lt;/li&gt;
&lt;li&gt;Broad Usefulness: 3&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 class="h3"&gt;&lt;a href="https://www.cazzulino.com/"&gt;Daniel Cazzulino's Blog&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Daniel Cazzulino (aka 'kzu') is the creator of the most popular mocking framework for C# and
.NET, called &lt;a href="https://github.com/moq/moq4"&gt;Moq&lt;/a&gt;, which is used for testing the source-code behind .NET.&lt;/p&gt;
&lt;p&gt;Kzu writes about all different kinds of technologies related to the Microsoft-ecosystem and mixes
high-level guides with technical deep dives into non-mainstream topics.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Writing Quality: 5&lt;/li&gt;
&lt;li&gt;Consistency: 4&lt;/li&gt;
&lt;li&gt;Longevity: 4&lt;/li&gt;
&lt;li&gt;Technical Depth: 5&lt;/li&gt;
&lt;li&gt;Broad Usefulness: 4&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 class="h3"&gt;&lt;a href="https://devblogs.microsoft.com/visualstudio/"&gt;Visual Studio Blog&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;The blog for the Visual Studio Engineering Team, of course, covers everything related to Visual Studio,
but it also includes adjacent technologies, which can contribute to great inspiration. They cover topics
like Unity, Visual Studio for Mac, GitHub-integrations, debugging with memory-dumping, and much more.&lt;/p&gt;
&lt;p&gt;For anyone interested in productivity in your Visual Studio-editor, it's worth noting that
&lt;a href="https://www.madskristensen.net/"&gt;Mads Kristensen&lt;/a&gt; writes posts on the subject on the Visual Studio Blog.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Writing Quality: 5&lt;/li&gt;
&lt;li&gt;Consistency: 5&lt;/li&gt;
&lt;li&gt;Longevity: 4&lt;/li&gt;
&lt;li&gt;Technical Depth: 4&lt;/li&gt;
&lt;li&gt;Broad Usefulness: 4&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 class="h3"&gt;&lt;a href="https://blog.maartenballiauw.be/"&gt;Maarten Balliauw&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Maarten has a focus on web and cloud-apps, but he was also the founder of &lt;a href="https://www.myget.org/"&gt;MyGet&lt;/a&gt; and
is a frequent speaker at conferences. He brings a unique mix of experiences and knowledge to his blog,
which covers many different technologies within the Microsoft-ecosystem.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Writing Quality: 5&lt;/li&gt;
&lt;li&gt;Consistency: 4&lt;/li&gt;
&lt;li&gt;Longevity: 5&lt;/li&gt;
&lt;li&gt;Technical Depth: 4&lt;/li&gt;
&lt;li&gt;Broad Usefulness: 4&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 class="h3"&gt;&lt;a href="https://codeblog.jonskeet.uk/"&gt;Jon Skeet&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;If you have ever searched for a C# question, there's a 99% chance that you have, at least once,
landed on an answer on Stack Overflow by Jon Skeet.&lt;/p&gt;
&lt;p&gt;He's been &lt;strong&gt;the number one contributor to Stack Overflow&lt;/strong&gt; for many years and usually with a focus
on .NET and C#. It is said that he’s read the whole C# specification (maybe more than once),
and he regularly blogs about some of the deepest subjects around C#.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Writing Quality: 5&lt;/li&gt;
&lt;li&gt;Consistency: 4&lt;/li&gt;
&lt;li&gt;Longevity: 4&lt;/li&gt;
&lt;li&gt;Technical Depth: 5&lt;/li&gt;
&lt;li&gt;Broad Usefulness: 3&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 class="h3"&gt;&lt;a href="https://jimmybogard.com/"&gt;Jimmy Bogard&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Jimmy is the man behind some of the most productivity-boosting frameworks for C# and .NET developers:
AutoMapper and MediatR. These frameworks help you write isolated and more easily maintainable code and
his blog-posts revolve around these frameworks, but also these topics in general.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Writing Quality: 4&lt;/li&gt;
&lt;li&gt;Consistency: 4&lt;/li&gt;
&lt;li&gt;Longevity: 4&lt;/li&gt;
&lt;li&gt;Technical Depth: 5&lt;/li&gt;
&lt;li&gt;Broad Usefulness: 4&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 class="h3"&gt;&lt;a href="https://weblog.west-wind.com/"&gt;Rick Strahl's Web Log&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;If you've worked with C# and .NET since its early days, especially with a focus on ASP.NET and the web,
you will most probably have run into more than one of Rick Strahl's blog-posts.&lt;/p&gt;
&lt;p&gt;In the course of working hands-on solving problems for clients, Rick has documented many solutions to
real-world problems on his blog. The topics often coincide with what other people are looking to answer,
so you can often find one of Rick's articles linked in answers on Stack Overflow.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Writing Quality: 4&lt;/li&gt;
&lt;li&gt;Consistency: 4&lt;/li&gt;
&lt;li&gt;Longevity: 5&lt;/li&gt;
&lt;li&gt;Technical Depth: 4&lt;/li&gt;
&lt;li&gt;Broad Usefulness: 5&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 class="h3"&gt;&lt;a href="https://blog.jetbrains.com/dotnet/"&gt;.NET Tools Blog - JetBrains&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;JetBrain's blog for .NET covers very useful topics, whether you use their tools or not. They have specific posts
about the popular tools ReSharper and Rider, but also great articles about a broad range of topics related to C# and .NET.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Writing Quality: 5&lt;/li&gt;
&lt;li&gt;Consistency: 5&lt;/li&gt;
&lt;li&gt;Longevity: N/A&lt;/li&gt;
&lt;li&gt;Technical Depth: 4&lt;/li&gt;
&lt;li&gt;Broad Usefulness: 4&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 class="h3"&gt;&lt;a href="http://wildermuth.com/"&gt;Shawn Wildermuth&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Shawn has been a prolific creator of content around C#, .NET, and the Microsoft-ecosystem since the
earliest days of .NET. Focusing mainly on the web-aspect of .NET, and recently, with a lot of Vue.js content,
he now describes himself as an author, teacher, and filmmaker.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Writing Quality: 4&lt;/li&gt;
&lt;li&gt;Consistency: 4&lt;/li&gt;
&lt;li&gt;Longevity: 5&lt;/li&gt;
&lt;li&gt;Technical Depth: 4&lt;/li&gt;
&lt;li&gt;Broad Usefulness: 3&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 class="h3"&gt;&lt;a href="https://ericlippert.com/"&gt;Fabulous Adventures in Coding - Eric Lippert's Blog&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Eric Lippert used to work on the C# language design team, which is clear based on his superhuman
rate of answering questions on Stack Overflow. On his blog, he deep-dives into language-design
with a focus on "making developers' lives better and having fun doing it".&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Writing Quality: 5&lt;/li&gt;
&lt;li&gt;Consistency: 3&lt;/li&gt;
&lt;li&gt;Longevity: 5&lt;/li&gt;
&lt;li&gt;Technical Depth: 5&lt;/li&gt;
&lt;li&gt;Broad Usefulness: 2&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 class="h3"&gt;&lt;a href="https://www.strathweb.com/"&gt;StrathWeb - Filip W.&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;When searching for various intricate technical issues related to the Microsoft-ecosystem,
it is not uncommon to end up on an in-depth article written by Filip. Recently, the topic of
quantum computing has been a big focus, to add to the long archive of articles focused on C# and .NET.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Writing Quality: 4&lt;/li&gt;
&lt;li&gt;Consistency: 4&lt;/li&gt;
&lt;li&gt;Longevity: 4&lt;/li&gt;
&lt;li&gt;Technical Depth: 5&lt;/li&gt;
&lt;li&gt;Broad Usefulness: 3&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 class="h3"&gt;&lt;a href="http://dontcodetired.com/blog"&gt;Don't Code Tired - Jason Roberts&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Jason Roberts is a former Microsoft MVP who blogs on different topics around the Microsoft-ecosystem.
Lately, he’s been focused on testing with posts about approval tests, feature-flags, and optimizing various testing frameworks.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Writing Quality: 4&lt;/li&gt;
&lt;li&gt;Consistency: 4&lt;/li&gt;
&lt;li&gt;Longevity: 5&lt;/li&gt;
&lt;li&gt;Technical Depth: 4&lt;/li&gt;
&lt;li&gt;Broad Usefulness: 2&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 class="h2"&gt;Final Words&lt;/h3&gt;
&lt;p&gt;While researching this post, I went through every single account I subscribe to on Twitter to pick out
the best blogs from the best people I've been following for many years - often over a decade.
I was surprised to recognize so many names I had associated with quality content and learned so much from,
but what surprised me even more was how many of these people had stopped blogging or switched focus away from C# and .NET.&lt;/p&gt;
&lt;p&gt;Scott Guthrie is probably a perfect example. He used to be one of the top bloggers within our field before he
was promoted to the fancy title of &lt;em&gt;Executive Vice President&lt;/em&gt; at Microsoft, where the blog no longer seemed to be a priority.
So subscribe to these blogs while you can. You never know when things will change.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>From C# to Rust: Code Basics</title>
      <link>https://sebnilsson.com/blog/from-csharp-to-rust-code-basics/</link>
      <pubDate>Tue, 28 Jul 2020 13:47:00 GMT</pubDate>
      <description>&lt;p&gt;Now that we've gotten the &lt;a href="/blog/from-csharp-to-rust-fundamentals/"&gt;fundamentals&lt;/a&gt; out of the way, we can finally get into the basics of Rust-code.&lt;/p&gt;
&lt;p&gt;&lt;a href="/blog/from-csharp-to-rust-introduction/"&gt;This series&lt;/a&gt; is written from the perspective of getting to know Rust from knowing C#. There are already many good &lt;em&gt;getting-started-guides&lt;/em&gt; out there for Rust, but &lt;strong&gt;this series tries to leverage your existing .NET/C#-knowledge&lt;/strong&gt; to fast-track you into understanding Rust, by relating the concepts to what you already know.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Disclaimer&lt;/strong&gt;: This series is being written while I'm learning Rust, so I'm by no means an expert and maybe this might be reflected in some of the example code. If you find any blatant errors, feel free to add some feedback in the comments.&lt;/em&gt;&lt;/p&gt;
&lt;h2 class="h1"&gt;Setup&lt;/h2&gt;
&lt;p&gt;In the post about &lt;a href="/blog/from-csharp-to-rust-fundamentals/"&gt;Rust fundamentals&lt;/a&gt;, we could read about how &lt;strong&gt;Rust provides a complete toolchain&lt;/strong&gt; for development, which is made available by installing &lt;a href="https://www.rust-lang.org/tools/install"&gt;Rustup, the recommended way of installing Rust&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Create a new project in a command-line by running: &lt;code&gt;cargo new example_project&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The file &lt;strong&gt;&lt;code&gt;src/main.rs&lt;/code&gt; is your application's entry point&lt;/strong&gt;, which will be run when you execute &lt;code&gt;cargo run&lt;/code&gt;. So this is a good file to start with, to &lt;strong&gt;follow along in your code-editor&lt;/strong&gt;. This file will only contain a function called &lt;code&gt;main&lt;/code&gt;, with a simple &lt;em&gt;Hello World&lt;/em&gt;, when generated by Cargo:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;fn main() {
    println!("Hello, world!");
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 class="h1"&gt;Code Basics&lt;/h2&gt;
&lt;p&gt;Let's start looking at some basic example-code, to go through some basic concepts in Rust. Since Rust is a C-style language, &lt;strong&gt;you will probably recognize much of the syntax&lt;/strong&gt; you see in this code-snippet, as a C#-developer.&lt;/p&gt;
&lt;p&gt;You can always find the full code for this series in the &lt;a href="https://github.com/sebnilsson/from-csharp-to-rust"&gt;&lt;code&gt;from-csharp-to-rust&lt;/code&gt;-project on GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;h2 class="h1"&gt;Variables&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://doc.rust-lang.org/reference/variables.html"&gt;Variables in Rust&lt;/a&gt; are created by using the &lt;code&gt;let&lt;/code&gt;-keyword, in a very similar way to the use of the &lt;code&gt;var&lt;/code&gt;-keyword in C#.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let title = "Ghost Buster";
let year: u16 = 1984;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href="https://doc.rust-lang.org/stable/rust-by-example/types/inference.html"&gt;Types are inferred&lt;/a&gt; in Rust, as you can see with the &lt;code&gt;title&lt;/code&gt;-variable. You can also specify the type, as we do with the &lt;code&gt;year&lt;/code&gt;-variable, where we want to use a smaller number-type than what is inferred by default.&lt;/p&gt;
&lt;p&gt;One important difference between Rust and C# is that &lt;strong&gt;variables are immutable by default in Rust&lt;/strong&gt;. If you want a variable to be mutable, you have to add &lt;code&gt;mut&lt;/code&gt; to the variable declaration:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let mut rating_avg = 7.8;

// Someone rated the movie
rating_avg = 7.9;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Variables can be created as &lt;a href="https://doc.rust-lang.org/std/keyword.const.html"&gt;constants in Rust&lt;/a&gt;, by using the &lt;code&gt;const&lt;/code&gt;-keyword, just like in C#. These variables &lt;strong&gt;have to have their types specified&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const GOOD_MOVIE_LIMIT: f32 = 7.5;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 class="h2"&gt;Naming Conventions&lt;/h3&gt;
&lt;p&gt;As you may have noticed, &lt;a href="https://doc.rust-lang.org/1.0.0/style/style/naming/README.html"&gt;Rust naming conventions&lt;/a&gt; use &lt;a href="https://en.wikipedia.org/wiki/Snake_case"&gt;&lt;em&gt;Snake case&lt;/em&gt;&lt;/a&gt; (&lt;code&gt;example_variable_name&lt;/code&gt;) for its variables. Unlike C# which usually uses &lt;a href="https://en.wikipedia.org/wiki/Camel_case"&gt;Camel case&lt;/a&gt; (&lt;code&gt;exampleVariableName&lt;/code&gt;) or Pascal case (&lt;code&gt;ExampleVariableName&lt;/code&gt;) for most of its variables, fields, and properties.&lt;/p&gt;
&lt;p&gt;The Rust-compiler will even warn you about using the wrong conventions for different namings.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;At the moment of writing, Rust-developers also seems to prefer shorter names for variables and functions, than we usually see in C# and .NET.&lt;/em&gt;&lt;/p&gt;
&lt;h2 class="h1"&gt;Strings&lt;/h2&gt;
&lt;p&gt;In C#, we only have one string-type for all types of strings. &lt;strong&gt;In Rust, there are two different string-types&lt;/strong&gt; you learn about at first. The primitive &lt;a href="https://doc.rust-lang.org/std/str/"&gt;&lt;code&gt;str&lt;/code&gt;-type&lt;/a&gt;, which is immutable and fixed length, as well as the &lt;a href="https://doc.rust-lang.org/std/string/struct.String.html"&gt;&lt;code&gt;String&lt;/code&gt;-type&lt;/a&gt;, which can be modified and grow in size.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let mut value = String::default();
for x in 65..68 {
    value.push(x as u8 as char);
}
// value: "ABC"
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;On Stack Overflow, a question called &lt;a href="https://stackoverflow.com/questions/24158114/what-are-the-differences-between-rusts-string-and-str/24159933#24159933"&gt;&lt;em&gt;What are the differences between Rust's &lt;code&gt;String&lt;/code&gt; and &lt;code&gt;str&lt;/code&gt;?&lt;/em&gt;&lt;/a&gt; the most popular answer, by far, summarizes:&lt;/p&gt;
&lt;blockquote class="blockquote"&gt;
&lt;p&gt;Use &lt;code&gt;String&lt;/code&gt; if you need owned string data (like passing strings to other threads, or building them at runtime), and use &lt;code&gt;str&lt;/code&gt; if you only need a view of a string.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Conversion between the two types is quite straight forward:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let title = "Ghostbusters";
// From str to String
let title_string = String::from(title);
// From String to str
let title_str = title_string.as_str();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In practical use, you can see Rust's &lt;code&gt;String&lt;/code&gt;-type as the equivalent of &lt;code&gt;StringBuilder&lt;/code&gt; in C#, while Rust's &lt;code&gt;str&lt;/code&gt; is the equivalent of &lt;code&gt;ReadOnlySpan&amp;lt;char&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;h2 class="h1"&gt;Collections&lt;/h2&gt;
&lt;p&gt;In Rust, the two most common types used to create collections are &lt;a href="https://doc.rust-lang.org/std/primitive.array.html"&gt;&lt;code&gt;array&lt;/code&gt;&lt;/a&gt; and &lt;a href="https://doc.rust-lang.org/std/vec/struct.Vec.html"&gt;&lt;code&gt;Vec&lt;/code&gt; (vector)&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;array&lt;/code&gt;-type is a fixed-size collection and is compared to an array of a type in C# and .NET, like &lt;code&gt;string[]&lt;/code&gt;, &lt;code&gt;int[]&lt;/code&gt;, &lt;code&gt;char[]&lt;/code&gt;, and so on. The &lt;code&gt;Vec&lt;/code&gt;-type can change in size and can be compared to &lt;code&gt;List&amp;lt;T&amp;gt;&lt;/code&gt; in C# and .NET.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Both types can be mutated&lt;/strong&gt; if the variable has the &lt;code&gt;mut&lt;/code&gt;-keyword. They can also easily be converted between each other.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let mut arr = [1, 2, 3];
arr[0] = 0;

let mut vec = vec![1, 2];
vec.push(3);
vec[0] = 0;

let arr_from_vec = &amp;amp;vec[0.. 2];
let vec_from_arr = arr.to_vec();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Rust also has the &lt;a href="https://doc.rust-lang.org/std/collections/struct.HashMap.html"&gt;&lt;code&gt;HashMap&lt;/code&gt;-type&lt;/a&gt;, which is the equivalent of &lt;code&gt;Dictionary&amp;lt;TKey, TValue&amp;gt;&lt;/code&gt; in C# and .NET.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let mut map = HashMap::new();
map.insert("key", 123);
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 class="h2"&gt;Generics&lt;/h3&gt;
&lt;p&gt;Rust has &lt;a href="https://doc.rust-lang.org/book/ch10-00-generics.html"&gt;support for generics&lt;/a&gt;, just like C# does, but with a little bit more smart functionality built into the compiler. In C#, you don't always have to specify the exact generics used in some contexts, since it can be inferred. Rust has some additional functionality for this.&lt;/p&gt;
&lt;p&gt;For both &lt;code&gt;Vec&lt;/code&gt; and &lt;code&gt;HashMap&lt;/code&gt;, &lt;strong&gt;you don't have to specify the type explicitly&lt;/strong&gt; when creating the object. It will be &lt;strong&gt;inferred by the first items added&lt;/strong&gt; and enforced to the following added items.&lt;/p&gt;
&lt;h2 class="h1"&gt;Logic Flow&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;if&lt;/code&gt;-statements in Rust are very similar to the ones in C#, except &lt;strong&gt;you don't need parenthesis around the condition&lt;/strong&gt;, but it's possible to use it if you want to.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let mut info = String::from(title);

if rating_avg &amp;gt;= GOOD_MOVIE_LIMIT {
    info += " - You're in for a good movie";
} else if rating_avg &amp;lt; GOOD_MOVIE_LIMIT &amp;amp;&amp;amp; year &amp;lt;= 1995 {
    info += "- Could be a classic...";
} else {
    info += "... Do you want to look for another movie?";
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;if&lt;/code&gt;-statement is in itself an expression, from which you can catch the result. This means that you can &lt;strong&gt;use an &lt;code&gt;if&lt;/code&gt;-statement to assign a variable&lt;/strong&gt;. You can catch the value resulting from the &lt;code&gt;if&lt;/code&gt;, the &lt;code&gt;if else&lt;/code&gt;, or the &lt;code&gt;else&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This can be used to create a &lt;em&gt;shorthand if&lt;/em&gt;. This is a good replacement for the &lt;em&gt;ternary conditional operator&lt;/em&gt; (In C#: &lt;code&gt;var a = true ? b : c&lt;/code&gt;), since it's not supported in Rust.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let classic = year &amp;lt;= 1995 &amp;amp;&amp;amp; !title.ends_with(" II");
let text = if classic { "Potential classic" } else { "We'll see..." };
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 class="h2"&gt;Pattern Matching&lt;/h3&gt;
&lt;p&gt;Rust also has very appreciated &lt;a href="https://doc.rust-lang.org/book/ch18-03-pattern-syntax.html"&gt;pattern-matching-functionality&lt;/a&gt;. This is something that &lt;a href="https://docs.microsoft.com/en-us/dotnet/csharp/pattern-matching"&gt;C# has implemented&lt;/a&gt; and seems to keep on improving it with every version.&lt;/p&gt;
&lt;p&gt;Pattern-matching in Rust can do a lot more than just replace simple &lt;code&gt;if&lt;/code&gt;-statements. It can also, among other things, be used to assign the result to variables. More sophisticated usages will be shown as this series goes on.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let info = match rating_avg {
    x if x &amp;gt; GOOD_MOVIE_LIMIT =&amp;gt;
        format!("{} - You're in for a good movie", x),
    x if x &amp;lt; GOOD_MOVIE_LIMIT &amp;amp;&amp;amp; year &amp;lt;= 1995 =&amp;gt;
        format!("{} - Could be a classic...", x),
    _ =&amp;gt; String::from("... Do you want to look for another movie?"),
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 class="h1"&gt;Standard Output&lt;/h2&gt;
&lt;p&gt;To write to the standard output, in the equivalent way of &lt;code&gt;Console.WriteLine&lt;/code&gt; in C# and .NET, you use &lt;a href="https://doc.rust-lang.org/std/macro.println.html"&gt;the function &lt;code&gt;println!&lt;/code&gt;&lt;/a&gt; in Rust.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let hello = "Hello";
let world = "World";
println!("{} {}!", hello, world);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In .NET, we specify the indexes inside the placeholder-curly brackes like this: &lt;code&gt;Console.WriteLine("{1} {0}!", world, hello)&lt;/code&gt;. These explicit indexes can also be used in Rust like this &lt;code&gt;println!("{1} {0}!", world, hello)&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If you don't specify the index In Rust and just use the empty placeholder &lt;code&gt;{}&lt;/code&gt;, as in the above example, &lt;strong&gt;the index will be inferred&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Just like in C# and .NET, you can &lt;a href="https://doc.rust-lang.org/stable/rust-by-example/hello/print/fmt.html"&gt;add formatting&lt;/a&gt; to a parameter by adding a colon-character (&lt;code&gt;:&lt;/code&gt;) after it and a specific flag. For debugging, it's very useful to use the &lt;a href="https://doc.rust-lang.org/rust-by-example/hello/print/print_debug.html"&gt;debug-formatting&lt;/a&gt;, which &lt;strong&gt;shows the whole content of the object&lt;/strong&gt; in the console.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let obj = complex_obj();
println!("Debug: {:?}", obj);
println!("Debug pretty: {:#?}", obj);
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 class="h2"&gt;Command-Line Arguments&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;Standard input&lt;/em&gt; is not as straight forward as &lt;em&gt;Standard output&lt;/em&gt; and not a one-liner like in C# and .NET with &lt;code&gt;Console.ReadLine&lt;/code&gt;. So we will get more into that in future articles.&lt;/p&gt;
&lt;p&gt;Getting access to the &lt;strong&gt;command-line arguments passed to the application&lt;/strong&gt; is a lot easier. This can be used to quickly build a CLI-type application.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Execute: cargo run "The Shawshank Redemption"

let args: Vec&amp;lt;String&amp;gt; = env::args().collect();
let first_arg =
    if args.len() &amp;gt; 1 { args[1].clone() } else { String::default() };
// first_arg: "The Shawshank Redemption"
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 class="h1"&gt;Functions&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://doc.rust-lang.org/book/ch03-03-how-functions-work.html"&gt;Functions in Rust&lt;/a&gt; work just like in C#, except you declare it using the &lt;code&gt;fn&lt;/code&gt;-keyword. &lt;strong&gt;You can specify a return-type&lt;/strong&gt;, but if you don't the function will just act like a &lt;code&gt;void&lt;/code&gt; in C#.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;fn is_sequel(title: &amp;amp;str) -&amp;gt; bool {
    if title.is_empty() {
        return false;
    }
    let sequel_title = title.ends_with("II");

    sequel_title
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice the &lt;strong&gt;lack of a trailing semicolon&lt;/strong&gt; (&lt;code&gt;;&lt;/code&gt;) behind the &lt;code&gt;sequel_title&lt;/code&gt;-variable at the end of the method. This makes the statement into an "expression" and Rust will &lt;strong&gt;implicitly accept this as a return statement&lt;/strong&gt;, as long as it's the &lt;strong&gt;final expression of the method&lt;/strong&gt;. This is why a &lt;code&gt;return&lt;/code&gt; is needed in the body of the early returning &lt;code&gt;if&lt;/code&gt;-statement.&lt;/p&gt;
&lt;p&gt;This is a &lt;strong&gt;feature that might look weird&lt;/strong&gt; when you're coming from another C-style language, but that you will see all over the place in Rust-code.&lt;/p&gt;
&lt;p&gt;Functions are then called with their names and parameters, just like in C#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;fn main() {
    let sequel = is_sequel("Ghostbusters");
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 class="h2"&gt;Macros&lt;/h3&gt;
&lt;p&gt;In this article, you've seen the use of the &lt;code&gt;println!&lt;/code&gt;-function, with the unusually looking exclamation-point (&lt;code&gt;!&lt;/code&gt;) at the end. This annotation makes this a &lt;em&gt;macro&lt;/em&gt;. This is a too advanced of a topic to go into in this part about basic code, so I'll just point to official &lt;a href="https://doc.rust-lang.org/book/ch19-06-macros.html"&gt;Rust Programming Language Book's section on macros&lt;/a&gt;, which summarizes:&lt;/p&gt;
&lt;blockquote class="blockquote"&gt;
&lt;p&gt;Macros are a way of writing code that writes other code, which is known as &lt;em&gt;metaprogramming&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 class="h1"&gt;Null-Values&lt;/h2&gt;
&lt;p&gt;The notorious &lt;a href="https://en.wikipedia.org/wiki/Tony_Hoare#Apologies_and_retractions"&gt;&lt;em&gt;Billion dollar mistake&lt;/em&gt;&lt;/a&gt; of allowing &lt;code&gt;null&lt;/code&gt;-values into programming languages seems to be a &lt;strong&gt;problem tackled only recently&lt;/strong&gt;. C# got &lt;em&gt;Nullable reference types&lt;/em&gt; with C# 8.0 in late 2019 and F# doesn't have nulls built-in at all (even if there are ways to get around it).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Rust does not support null values.&lt;/strong&gt; Instead, it uses patterns to wrap around types, to help indicate if there was a value or not. The most commonly used such type is the &lt;a href="https://doc.rust-lang.org/std/option/"&gt;&lt;code&gt;Option&lt;/code&gt;-type&lt;/a&gt;. It will return either a &lt;code&gt;Some&lt;/code&gt;, carrying the value, or a &lt;code&gt;None&lt;/code&gt;, indicating there was no object.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;fn main() {
    let quotient = divide(123, divisor);
    match quotient {
        Some(x) if x &amp;gt; 10 =&amp;gt; println!("Big division result: {}", x),
        Some(x) =&amp;gt; println!("Division result: {}", x),
        None =&amp;gt; println!("Division failed")
    }
}

fn divide(dividend: i32, divisor: i32) -&amp;gt; Option&amp;lt;i32&amp;gt; {
    if divisor == 0 {
        return None;
    }
    Some(dividend / divisor)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 class="h1"&gt;Object-Orientation&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://doc.rust-lang.org/book/ch17-00-oop.html"&gt;Object-orientation in Rust&lt;/a&gt; is a point in the code-basics where &lt;strong&gt;things get a bit strange&lt;/strong&gt; for the regular C#-developer. In C#, we are used to having a &lt;code&gt;class&lt;/code&gt; that owns its fields, properties, and methods. The class is then a template for creating an &lt;em&gt;instance&lt;/em&gt; of an object.&lt;/p&gt;
&lt;p&gt;Rust uses what they call a &lt;code&gt;struct&lt;/code&gt; instead of classes, which is just a "dumb" data-structure, which contains fields, but &lt;strong&gt;they do not (directly) contain properties or methods&lt;/strong&gt;. Instead, Rust provides the possibility to add functions to a &lt;code&gt;struct&lt;/code&gt; through the &lt;code&gt;impl&lt;/code&gt;-keyword.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pub struct Movie {
    pub title: String,
    release_year: u16,
}

impl Movie {
    // Constructor - Associated method
    pub fn new(title: &amp;amp;str, release_year: u16) -&amp;gt; Self {
        Self { title: String::from(title), release_year }
    }
    // Method
    pub fn display_title(&amp;amp;self) -&amp;gt; String {
        format!("{} ({})", self.title, self.release_year)
    }
    // Method with mutability
    pub fn update_release_year(&amp;amp;mut self, year: u16) {
        self.release_year = year;
    }
}

fn main() {
    let movie = Movie::new("Ghostbusters", 1984);
    println!("Movie: {}", movie.display_title());
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;First, we define the &lt;code&gt;struct&lt;/code&gt; and its fields, where we add the &lt;code&gt;pub&lt;/code&gt;-keyword to the &lt;code&gt;struct&lt;/code&gt; itself and its field &lt;code&gt;title&lt;/code&gt;. &lt;strong&gt;All public fields are mutable&lt;/strong&gt; in Rust if used with the &lt;code&gt;mut&lt;/code&gt;-keyword by other code. If you want to protect a field, use methods, like the &lt;code&gt;update_release_year&lt;/code&gt;-function in this example.&lt;/p&gt;
&lt;p&gt;In the &lt;code&gt;impl&lt;/code&gt;-block, we have the &lt;code&gt;new&lt;/code&gt;-function, which acts as a constructor. It's an associated method to the type, which is the equivalent of a &lt;code&gt;static&lt;/code&gt; method in C#. It returns a new instance of the implementing type, which in this case is a &lt;code&gt;Movie&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The function &lt;code&gt;display_title&lt;/code&gt; is a &lt;strong&gt;method on the instance of the object&lt;/strong&gt; and through the &lt;code&gt;self&lt;/code&gt;-keyword in the first parameter, it can access fields and methods on the object, even non-public ones. It's the equivalent to the &lt;code&gt;this&lt;/code&gt;-keyword in C#.&lt;/p&gt;
&lt;h3 class="h2"&gt;Inheritance&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Rust doesn't have inheritance&lt;/strong&gt;. At least not in the way a C#-developer is used to it. This seems to be a very &lt;a href="https://doc.rust-lang.org/book/ch17-01-what-is-oo.html"&gt;conscious decision&lt;/a&gt; by the Rust-team.&lt;/p&gt;
&lt;p&gt;Instead of inheritance, Rust provides the very powerful &lt;a href="https://doc.rust-lang.org/1.9.0/book/traits.html"&gt;concept of traits&lt;/a&gt;, which allows you to extend any type, no matter if you've created the type or not. As a C#-developer it acts like of mixture of interfaces and extension-methods. We will look closer at traits in upcoming articles in the series.&lt;/p&gt;
&lt;h2 class="h1"&gt;Ownership &amp;amp; Borrowing&lt;/h2&gt;
&lt;p&gt;You've seen the use of the ampersand (&lt;code&gt;&amp;amp;&lt;/code&gt;) character in some places of the example-code. These indicate that the use of an object is done by reference. This is something you normally very rarely need to deal with in C# and .NET.&lt;/p&gt;
&lt;p&gt;This relates to the unique concept in Rust of &lt;a href="https://doc.rust-lang.org/1.8.0/book/references-and-borrowing.html"&gt;References and Borrowing&lt;/a&gt;. This is &lt;strong&gt;the foundational concept which enables the language's memory-safety, performance, and "&lt;a href="https://doc.rust-lang.org/book/ch16-00-concurrency.html"&gt;fearless concurrency&lt;/a&gt;"&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;This is also one of &lt;strong&gt;the hardest parts of Rust to master&lt;/strong&gt;. It's usually the number one complaint about the language from newcomers and a very frequent topic on Stack Overflow and other Q&amp;amp;A-forums.&lt;/p&gt;
&lt;h2 class="h1"&gt;Primitives Comparison Table&lt;/h2&gt;
&lt;p&gt;Rust has a set of primitives that overlap quite well with the ones we're used to in C# and .NET. They are listed for reference:&lt;/p&gt;
&lt;div class="table-responsive"&gt;&lt;table class="table table-sm table-bordered table-striped table-hover"&gt;
&lt;thead class="thead-dark"&gt;
&lt;tr&gt;
&lt;th&gt;Rust&lt;/th&gt;
&lt;th&gt;C#&lt;/th&gt;
&lt;th&gt;Comments&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;bool&lt;/td&gt;
&lt;td&gt;bool&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;char&lt;/td&gt;
&lt;td&gt;char&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;i8, i16, i32, i64, i128&lt;/td&gt;
&lt;td&gt;sbyte, short, int, long, (N/A)&lt;/td&gt;
&lt;td&gt;Signed 128-bit integer not available in .NET&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;u8, u16, u32, u64, u128&lt;/td&gt;
&lt;td&gt;byte, ushort, uint, ulong, (N/A)&lt;/td&gt;
&lt;td&gt;Unsigned 128-bit integer not available in .NET&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;isize, usize&lt;/td&gt;
&lt;td&gt;(N/A)&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;f32, f64&lt;/td&gt;
&lt;td&gt;float, double&lt;/td&gt;
&lt;td&gt;.NET has the 128-bit floating-point number &lt;code&gt;decimal&lt;/code&gt;, which is not available in Rust out-of-the-box&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Array&lt;/td&gt;
&lt;td&gt;Array&lt;/td&gt;
&lt;td&gt;Not a primitive type in .NET. Fixed size.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tuple&lt;/td&gt;
&lt;td&gt;System.ValueTuple / System.Tuple&lt;/td&gt;
&lt;td&gt;Not a primitive type in .NET&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Slice&lt;/td&gt;
&lt;td&gt;Span&amp;lt;T&amp;gt;&lt;/td&gt;
&lt;td&gt;Not a primitive type in .NET&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;str&lt;/td&gt;
&lt;td&gt;string&lt;/td&gt;
&lt;td&gt;&lt;code&gt;str&lt;/code&gt; is immutable and fixed length in Rust, but not in .NET&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Function&lt;/td&gt;
&lt;td&gt;Func&amp;lt;T&amp;gt;&lt;/td&gt;
&lt;td&gt;Not a primitive type in .NET&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h2 class="h1"&gt;Learn More&lt;/h2&gt;
&lt;p&gt;If you want to learn more about Rust, unrelated to its equivalent functionality in C# and .NET, you can check out the &lt;a href="https://www.rust-lang.org/learn"&gt;&lt;em&gt;Learn Rust&lt;/em&gt;-section&lt;/a&gt; of the official website, which points to multiple resources, including the &lt;a href="https://doc.rust-lang.org/book/"&gt;&lt;em&gt;Rust Programming Language&lt;/em&gt;-book&lt;/a&gt; and the &lt;a href="https://doc.rust-lang.org/stable/rust-by-example/"&gt;&lt;em&gt;Rust by Example&lt;/em&gt;-book&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I also found the guide &lt;a href="https://github.com/Dhghomon/easy_rust"&gt;&lt;em&gt;Writing Easy Rust&lt;/em&gt;&lt;/a&gt; very helpful, because it helps to explain the more complicated Rust-concepts in easier terms.&lt;/p&gt;
&lt;h2 class="h1"&gt;Summary&lt;/h2&gt;
&lt;p&gt;This article tried to lead you into the Rust-language by &lt;strong&gt;relating concepts to the ones you already know in C#&lt;/strong&gt; and .NET.&lt;/p&gt;
&lt;p&gt;Rust is very &lt;strong&gt;similar syntactically&lt;/strong&gt; to other C-style languages, including C#. There are some concepts in Rust that are relatively different from what you're used to, but this can be a great way to be &lt;strong&gt;inspired to solve things in new ways&lt;/strong&gt;. I've actually heard multiple people say that they've &lt;strong&gt;rediscovered their love for programming by learning Rust&lt;/strong&gt;.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>From C# to Rust: Fundamentals</title>
      <link>https://sebnilsson.com/blog/from-csharp-to-rust-fundamentals/</link>
      <pubDate>Thu, 16 Jul 2020 13:43:00 GMT</pubDate>
      <description>&lt;p&gt;There are some &lt;strong&gt;fundamental tools and concepts which we should understand&lt;/strong&gt; before we get into actually coding Rust.&lt;/p&gt;
&lt;p&gt;Since this series focuses on Rust from &lt;strong&gt;the perspective of a C#-developer&lt;/strong&gt;, we will try to &lt;strong&gt;relate the Rust-concepts to the equivalent concepts in C#&lt;/strong&gt; and .NET.&lt;/p&gt;
&lt;h2 class="h1"&gt;Modern Toolchain&lt;/h2&gt;
&lt;p&gt;Rust comes with a complete toolchain of &lt;strong&gt;everything you need to compile and run your Rust-code&lt;/strong&gt;. All the way from the compiler, to package-management, testing, code-formatting, linting, documentation-generation, and more.&lt;/p&gt;
&lt;h2 class="h1"&gt;The Rust Compiler&lt;/h2&gt;
&lt;p&gt;The compiler for Rust &lt;strong&gt;can&lt;/strong&gt; be executed by using the command &lt;a href="https://doc.rust-lang.org/rustc/what-is-rustc.html"&gt;&lt;code&gt;rustc&lt;/code&gt;&lt;/a&gt;. &lt;strong&gt;This is usually not done&lt;/strong&gt; by Rust-developers, but instead, it's done through the Cargo-tool.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;.NET equivalent&lt;/strong&gt;: &lt;a href="https://docs.microsoft.com/visualstudio/msbuild/msbuild"&gt;MSBuild&lt;/a&gt; / &lt;a href="https://docs.microsoft.com/dotnet/csharp/language-reference/compiler-options/command-line-building-with-csc-exe"&gt;The C#-compiler (csc.exe)&lt;/a&gt;&lt;/p&gt;
&lt;h2 class="h1"&gt;Cargo: Build System &amp;amp; Package Manager&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://doc.rust-lang.org/cargo/"&gt;Cargo&lt;/a&gt; is used by Rust-developers to manage, build, test, and document their projects. This is done by using various &lt;a href="https://doc.rust-lang.org/stable/cargo/commands/"&gt;cargo-commands&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;.NET equivalent&lt;/strong&gt;: &lt;a href="https://docs.microsoft.com/dotnet/core/tools/"&gt;.NET CLI&lt;/a&gt; and &lt;a href="https://docs.microsoft.com/nuget/"&gt;NuGet&lt;/a&gt;&lt;/p&gt;
&lt;h3 class="h2"&gt;Cargo-Commands&lt;/h3&gt;
&lt;p&gt;Cargo can be used to &lt;a href="https://doc.rust-lang.org/cargo/guide/creating-a-new-project.html"&gt;create a new project&lt;/a&gt; by running, for example, &lt;code&gt;cargo new example_project&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;.NET equivalent&lt;/strong&gt;: &lt;code&gt;dotnet new&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;As mentioned above, Cargo &lt;a href="https://doc.rust-lang.org/cargo/guide/working-on-an-existing-project.html"&gt;builds the project&lt;/a&gt; and this is done by running the command &lt;code&gt;cargo build&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;.NET equivalent&lt;/strong&gt;: &lt;code&gt;dotnet build&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Cargo is the Rust-equivalent of .NET's NuGet, so it's also used to &lt;a href="https://doc.rust-lang.org/cargo/guide/dependencies.html"&gt;resolve and download libraries&lt;/a&gt;, which it does automatically when you run the &lt;code&gt;cargo build&lt;/code&gt;-command.&lt;/p&gt;
&lt;p&gt;Now that your code has been built, you can run the code, given that it's a binary. This is done by using &lt;code&gt;cargo run&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;.NET equivalent&lt;/strong&gt;: &lt;code&gt;dotnet run&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;To just &lt;a href="https://doc.rust-lang.org/edition-guide/rust-2018/cargo-and-crates-io/cargo-check-for-faster-checking.html"&gt;check that the code is valid&lt;/a&gt; and if that it can build, but not actually do a full build, there is a more lightweight command in Rust, which is &lt;code&gt;cargo check&lt;/code&gt;.&lt;/p&gt;
&lt;h2 class="h1"&gt;Rustup: Rust Toolchain Installer&lt;/h2&gt;
&lt;p&gt;To easily get access to the &lt;a href="https://stackoverflow.com/a/62419829/2429"&gt;complete toolchain&lt;/a&gt;, we use &lt;a href="https://rustup.rs/"&gt;&lt;code&gt;rustup&lt;/code&gt;, the Rust toolchain installer&lt;/a&gt;, which installs &lt;code&gt;rustc&lt;/code&gt;, &lt;code&gt;cargo&lt;/code&gt;, the &lt;a href="https://github.com/rust-lang/rustup"&gt;&lt;code&gt;rustup&lt;/code&gt;-CLI&lt;/a&gt;, and other Rust-tools.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;.NET equivalent&lt;/strong&gt;: .NET Core SDK&lt;/p&gt;
&lt;p&gt;&lt;a href="https://doc.rust-lang.org/edition-guide/rust-2018/rustup-for-managing-rust-versions.html"&gt;With Rustup&lt;/a&gt;, you can change which version of Rust is used, install different platforms for cross-compiling, and installing various other components.&lt;/p&gt;
&lt;h3 class="h2"&gt;Rust on Windows&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;For Rust and Rustup to work on Windows&lt;/strong&gt;, you need to &lt;a href="https://visualstudio.microsoft.com/downloads/"&gt;install Visual Studio&lt;/a&gt;, or the &lt;a href="https://visualstudio.microsoft.com/visual-cpp-build-tools/"&gt;C++ Build Tools&lt;/a&gt; and the &lt;a href="https://developer.microsoft.com/windows/downloads/windows-10-sdk"&gt;Windows 10 SDK&lt;/a&gt; separately. Details on this can be found on &lt;a href="https://github.com/rust-lang/rustup#working-with-rust-on-windows"&gt;Rustup's GitHub-page&lt;/a&gt;.&lt;/p&gt;
&lt;h2 class="h1"&gt;Package Manifest&lt;/h2&gt;
&lt;p&gt;When you run &lt;code&gt;cargo new&lt;/code&gt;, your new project will get a &lt;a href="https://doc.rust-lang.org/cargo/reference/manifest.html"&gt;&lt;code&gt;Cargo.toml&lt;/code&gt;-file&lt;/a&gt;, which is the manifest that contains the meta-data about your project.&lt;/p&gt;
&lt;p&gt;An example-version of the file, with the &lt;strong&gt;added dependency to the &lt;em&gt;regex&lt;/em&gt;-package&lt;/strong&gt;, looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[package]
name = "example_project"
version = "0.1.0"
authors = ["Seb Nilsson"]
edition = "2018"

[dependencies]
regex = "1.3.9"
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;.NET equivalent&lt;/strong&gt;: The &lt;code&gt;.csproj&lt;/code&gt;-file (or the formerly used &lt;code&gt;packages.config&lt;/code&gt;-file).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Node.js equivalent&lt;/strong&gt;: The &lt;code&gt;package.json&lt;/code&gt;-file.&lt;/p&gt;
&lt;h2 class="h1"&gt;Crates&lt;/h2&gt;
&lt;p&gt;In Rust, the term &lt;a href="https://doc.rust-lang.org/book/ch07-01-packages-and-crates.html"&gt;&lt;em&gt;crate&lt;/em&gt;&lt;/a&gt; is used for a package. It can be either an executable binary or a library.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;.NET equivalent&lt;/strong&gt;: NuGet-packages&lt;/p&gt;
&lt;h3 class="h2"&gt;Crates.io&lt;/h3&gt;
&lt;p&gt;To find useful packages/crates to include in your Rust-projects, the registry-site &lt;a href="https://crates.io/"&gt;Crates.io&lt;/a&gt; is used.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;.NET equivalent&lt;/strong&gt;: &lt;a href="http://nuget.org/"&gt;NuGet.org&lt;/a&gt;&lt;/p&gt;
&lt;h2 class="h1"&gt;Formatting Rust-code&lt;/h2&gt;
&lt;p&gt;Cargo contains a command which can automatically format all the Rust-code in your project. It's called &lt;a href="https://github.com/rust-lang/rustfmt"&gt;&lt;em&gt;rustfmt&lt;/em&gt;&lt;/a&gt; and can be executed by running &lt;code&gt;cargo fmt&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://rust-lang.github.io/rustfmt/"&gt;Customizing the rules applied when formatting&lt;/a&gt; is done by adding a &lt;code&gt;rustfmt.toml&lt;/code&gt;-file to the project, which &lt;em&gt;rustfmt&lt;/em&gt; then will follow.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;.NET equivalent&lt;/strong&gt;: There is no built-in way to do this in the .NET CLI, but there is .NET Global Tool from the .NET-team called &lt;a href="https://github.com/dotnet/format"&gt;&lt;em&gt;dotnet-format&lt;/em&gt;&lt;/a&gt;, which allows you to run &lt;code&gt;dotnet format&lt;/code&gt; on your project.&lt;/p&gt;
&lt;h2 class="h1"&gt;Testing&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://doc.rust-lang.org/cargo/guide/tests.html"&gt;Running the tests in a project&lt;/a&gt; is also done through Cargo, by running &lt;code&gt;cargo test&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;.NET equivalent&lt;/strong&gt;: &lt;code&gt;dotnet test&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://doc.rust-lang.org/book/ch11-00-testing.html"&gt;Testing is built into Rust&lt;/a&gt;, so you do not need to add any external testing-package.&lt;/p&gt;
&lt;h2 class="h1"&gt;VS Code Setup&lt;/h2&gt;
&lt;p&gt;First, make sure you've &lt;a href="https://rustup.rs/"&gt;installed Rustup&lt;/a&gt;. You can verify that you have it installed by running the command &lt;code&gt;rustup --version&lt;/code&gt;, which should show you a version-number.&lt;/p&gt;
&lt;p&gt;To get started developing in Rust, with features such as syntax highlighting, auto-complete, code-formatting, refactoring, debugging, and much more, you can install &lt;a href="https://code.visualstudio.com/"&gt;Visual Studio Code&lt;/a&gt;, with the &lt;a href="https://marketplace.visualstudio.com/items?itemName=rust-lang.rust"&gt;&lt;em&gt;Rust&lt;/em&gt;&lt;/a&gt;-extension and the &lt;a href="https://marketplace.visualstudio.com/items?itemName=vadimcn.vscode-lldb"&gt;&lt;em&gt;CodeLLDB&lt;/em&gt;&lt;/a&gt;-extension.&lt;/p&gt;
&lt;p&gt;Consider evaluating the extension &lt;a href="https://marketplace.visualstudio.com/items?itemName=matklad.rust-analyzer"&gt;&lt;em&gt;rust-analyzer&lt;/em&gt;&lt;/a&gt; as an alternative to the &lt;em&gt;Rust&lt;/em&gt;-extension. It's not as well &lt;a href="https://rust-analyzer.github.io/"&gt;documented&lt;/a&gt;, but it seems to have more features, including the showing of type inference.&lt;/p&gt;
&lt;p&gt;Next, create a new Rust-project by running &lt;code&gt;cargo new&lt;/code&gt;. Now, all you have to do now is press &lt;kbd&gt;F5&lt;/kbd&gt; in VS Code and it will automatically create a &lt;code&gt;launch.json&lt;/code&gt; for you, which allows you to debug your Rust-code.&lt;/p&gt;
&lt;h2 class="h1"&gt;Summary&lt;/h2&gt;
&lt;p&gt;By just installing &lt;a href="https://rustup.rs/"&gt;&lt;code&gt;rustup&lt;/code&gt;&lt;/a&gt;, we get access to the complete Rust-toolchain. This includes, among other things, &lt;a href="https://doc.rust-lang.org/cargo/"&gt;Cargo&lt;/a&gt;, which lets us &lt;strong&gt;work through the full development-cycle&lt;/strong&gt; with our projects, like: &lt;strong&gt;create new&lt;/strong&gt; projects, &lt;strong&gt;compile&lt;/strong&gt; the code, &lt;strong&gt;run the code&lt;/strong&gt;, &lt;strong&gt;format&lt;/strong&gt; the code, and &lt;strong&gt;run the tests&lt;/strong&gt; in our projects.&lt;/p&gt;
&lt;p&gt;Add VS Code with a few Rust-extensions, and you'll have a great developer-experience to get started with.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>From C# to Rust: Introduction</title>
      <link>https://sebnilsson.com/blog/from-csharp-to-rust-introduction/</link>
      <pubDate>Mon, 06 Jul 2020 13:49:00 GMT</pubDate>
      <description>&lt;p&gt;&lt;a href="https://www.rust-lang.org/"&gt;Rust&lt;/a&gt; has been the &lt;strong&gt;&lt;a href="https://stackoverflow.blog/2020/01/20/what-is-rust-and-why-is-it-so-popular/"&gt;most loved programming language&lt;/a&gt; for the last 5 years&lt;/strong&gt;. This, and many other factors, made me interested in learning more about Rust, especially &lt;strong&gt;from the perspective of a C#-developer&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 class="h1"&gt;Why Rust?&lt;/h2&gt;
&lt;p&gt;In early 2019, a Microsoft engineer revealed that about &lt;a href="https://www.zdnet.com/article/microsoft-70-percent-of-all-security-bugs-are-memory-safety-issues/"&gt;70% of all vulnerabilities in their products are due to memory safety issues&lt;/a&gt;. Memory &lt;strong&gt;safety is something you get for free with C# and .NET&lt;/strong&gt;. But sometimes, you need more tools to squeeze out every last drop of performance.&lt;/p&gt;
&lt;p&gt;It's also generally very beneficial to &lt;strong&gt;learn new languages&lt;/strong&gt;, which could inspire us to find &lt;strong&gt;new ways of solving problems&lt;/strong&gt;. To specifically do so with a modern language, which could replace C/C++ over time and has a &lt;strong&gt;focus on both performance and productivity&lt;/strong&gt;, could bring a very &lt;strong&gt;valuable tool&lt;/strong&gt; to any developer's toolbox.&lt;/p&gt;
&lt;p&gt;Rust has actually been the most loved language every single year, from the &lt;a href="https://insights.stackoverflow.com/survey/2016#technology-most-loved-dreaded-and-wanted"&gt;2016 survey&lt;/a&gt;, all the way to this year's &lt;a href="https://insights.stackoverflow.com/survey/2020#technology-most-loved-dreaded-and-wanted-languages-loved"&gt;2020 survey&lt;/a&gt;.&lt;/p&gt;
&lt;h2 class="h1"&gt;Rust Overview&lt;/h2&gt;
&lt;p&gt;Rust is a C-style language, similar to C# or C++, and even has &lt;a href="https://doc.rust-lang.org/reference/influences.html"&gt;influences from C#&lt;/a&gt; (among others), with a focus on &lt;strong&gt;memory safety and performance&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;The slogan on &lt;a href="https://www.rust-lang.org/"&gt;Rust's official website&lt;/a&gt; is:&lt;/p&gt;
&lt;blockquote class="blockquote"&gt;
&lt;p&gt;A language empowering everyone to build reliable and efficient software.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The language is &lt;a href="https://en.wikipedia.org/wiki/Static_typing"&gt;statically typed&lt;/a&gt; and is primarily &lt;a href="https://en.wikipedia.org/wiki/Imperative_programming"&gt;imperative&lt;/a&gt; but also has &lt;a href="https://en.wikipedia.org/wiki/Functional_programming"&gt;functional&lt;/a&gt; aspects, &lt;strong&gt;similar to C#&lt;/strong&gt;. It's an open-source language &lt;a href="https://research.mozilla.org/rust/"&gt;initially developed by Mozilla&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Wikipedia describes the &lt;a href="https://en.wikipedia.org/wiki/Rust_(programming_language)"&gt;Rust programming language&lt;/a&gt; in the following way:&lt;/p&gt;
&lt;blockquote class="blockquote"&gt;
&lt;p&gt;Rust is a multi-paradigm programming language focused on performance and safety, especially safe concurrency. Rust is syntactically similar to C++ but provides memory safety without using garbage collection.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;As a C#-developer, you'll find the syntax familiar, with the &lt;em&gt;"Hello World!"&lt;/em&gt; for Rust looking like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;fn main() {
    println!("Hello World!");
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Rust was announced in 2010, with version 1.0 released in 2015. In comparison, C# was released in the year 2000, Java in 1995, C++ in 1985, and C in 1972. So it's quite a modern language, which has been &lt;a href="https://doc.rust-lang.org/reference/influences.html"&gt;influenced by many other languages&lt;/a&gt; and has hopefully used many lessons learned from these.&lt;/p&gt;
&lt;h3 class="h2"&gt;Performance&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Rust can be as fast as C and C++&lt;/strong&gt; and in some cases, it might be even faster. The code &lt;a href="https://rustc-dev-guide.rust-lang.org/overview.html"&gt;compiles to machine code&lt;/a&gt;, instead of compiling to an &lt;a href="https://docs.microsoft.com/en-us/dotnet/standard/managed-code"&gt;intermediate language (IL), like with C#&lt;/a&gt; or being &lt;a href="https://en.wikipedia.org/wiki/Interpreted_language"&gt;interpreted on the fly&lt;/a&gt;, like with JavaScript or Ruby.&lt;/p&gt;
&lt;p&gt;The memory management is not provided by using automated garbage collection (like in .NET/Java) or automatic reference counting (like in Swift/Objective C). The &lt;strong&gt;memory safety-guarantees&lt;/strong&gt; are provided by Rust's &lt;strong&gt;key concept called &lt;em&gt;&lt;a href="https://doc.rust-lang.org/1.8.0/book/ownership.html"&gt;Ownership&lt;/a&gt;&lt;/em&gt;&lt;/strong&gt;. By enforcing &lt;a href="https://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization"&gt;Resource Acquisition Is Initialization (RAII)&lt;/a&gt;, Rust makes sure that any objects which go out of scope get deconstructed and its resources are freed up.&lt;/p&gt;
&lt;h2 class="h1"&gt;Systems &amp;amp; Application Programming Language&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;Systems programming languages&lt;/em&gt; typically are more &lt;em&gt;close to the metal&lt;/em&gt; and have more direct access to the physical hardware of the machine it is running on, which &lt;strong&gt;enables writing performant software&lt;/strong&gt;, such as operating systems, drivers, embedded systems, game-engines, network services, and more. Assembly language, C, and C++ are examples of traditional systems programming languages.&lt;/p&gt;
&lt;p&gt;C# is considered as an &lt;em&gt;application programming language&lt;/em&gt;, which usually prioritizes &lt;strong&gt;productive ways of building software&lt;/strong&gt; which gives functionality to end-users. They are usually &lt;strong&gt;not intended to compete on performance&lt;/strong&gt; with systems programming languages.&lt;/p&gt;
&lt;p&gt;Rust is a language that tries to &lt;strong&gt;&lt;a href="https://doc.rust-lang.org/book/foreword.html"&gt;straddle both&lt;/a&gt; systems and application programming&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 class="h1"&gt;Industry Adoption&lt;/h2&gt;
&lt;p&gt;The 2020 &lt;em&gt;&lt;a href="https://insights.stackoverflow.com/survey/2020"&gt;Stack Overflow Developer Survey&lt;/a&gt;&lt;/em&gt; shows that when it comes to &lt;strong&gt;the most professionally used programming language&lt;/strong&gt;, &lt;a href="https://insights.stackoverflow.com/survey/2020#most-popular-technologies"&gt;C# has a 32,3% popularity, while Rust only has 4,8%&lt;/a&gt;. Comparing these numbers to JavaScript's 69,7% popularity might indicate that &lt;strong&gt;Rust is in an early phase of its widespread professional adoption&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;The adoption of Rust does seem to be ramping up though, for good reasons. In a 2020 virtual talk about &lt;a href="https://youtu.be/NQBVUjdkLAA?t=580"&gt;Rust at Microsoft&lt;/a&gt;, one of their &lt;em&gt;cloud developer advocates&lt;/em&gt; said:&lt;/p&gt;
&lt;blockquote class="blockquote"&gt;
&lt;p&gt;Rust is the industry’s &lt;strong&gt;best chance&lt;/strong&gt; at safe systems programming&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It does seem like &lt;a href="https://thenewstack.io/microsoft-rust-is-the-industrys-best-chance-at-safe-systems-programming/"&gt;Microsoft is exploring gradually switching to Rust&lt;/a&gt; from C and C++. These languages are not memory safe, which has &lt;strong&gt;caused a lot of costly errors&lt;/strong&gt;, as mentioned before, with Microsoft's having around 70% of all their security bugs related to memory safety issues.&lt;/p&gt;
&lt;p&gt;In 2019, Microsoft experimented with rewriting a &lt;a href="https://www.zdnet.com/article/microsofts-rust-experiments-are-going-well-but-some-features-are-missing/"&gt;low-level component in Windows with Rust&lt;/a&gt;, with a reported generally positive experience.&lt;/p&gt;
&lt;p&gt;It's said that Amazon Web Services (AWS) uses Rust to power the deployment of the Lambda serverless runtime and some parts of EC2.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.rust-lang.org/production/users"&gt;Many other companies are adopting Rust&lt;/a&gt;, including big players like &lt;a href="https://www.youtube.com/watch?v=kylqq8pEgRs"&gt;Facebook&lt;/a&gt; (also with &lt;a href="https://developers.libra.org/docs/community/coding-guidelines"&gt;Libra&lt;/a&gt;), &lt;a href="https://twitter.com/benwilliamson/status/1240113606374686721"&gt;Apple&lt;/a&gt;, Google (with &lt;a href="https://en.wikipedia.org/wiki/Google_Fuchsia"&gt;Fuchsia&lt;/a&gt;), and &lt;a href="https://blog.cloudflare.com/tag/rust/"&gt;Cloudflare&lt;/a&gt;.&lt;/p&gt;
&lt;h2 class="h1"&gt;&lt;em&gt;"From C# to Rust"&lt;/em&gt;-Series&lt;/h2&gt;
&lt;p&gt;Given that I'm learning Rust as I'm going, the goals of this series might change over time. But at this time, some topics I aim to cover are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="/blog/from-csharp-to-rust-fundamentals/"&gt;&lt;strong&gt;Fundamentals&lt;/strong&gt;&lt;/a&gt;: Tools and concepts we need to understand&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Code basics&lt;/strong&gt;: Learning the basics of Rust-code and how the concepts relate to C#&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Advanced code&lt;/strong&gt;: Diving deeper into more advanced code and concepts in Rust&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rust specific functionality&lt;/strong&gt;: Functionality and concepts which exists in Rust, but not in C#&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rust's drawbacks&lt;/strong&gt;: Exploring what the reasons are behind the perceived steeper learning curve of Rust&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There will probably be more subjects discovered along the way. Feel free to &lt;strong&gt;write in the comments&lt;/strong&gt; if there are any specific subjects you're interested in, especially coming in as a C#-developer.&lt;/p&gt;
&lt;h2 class="h1"&gt;Summary&lt;/h2&gt;
&lt;p&gt;Some points that &lt;strong&gt;make me quite excited about Rust&lt;/strong&gt; and motivated me to start this exploration are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Modern C-style language, like C#, should give familiarity&lt;/li&gt;
&lt;li&gt;The most loved language for half a decade&lt;/li&gt;
&lt;li&gt;Enables both high-level productivity and low-level performance&lt;/li&gt;
&lt;li&gt;Growing industry adoption, even by many of the giants&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    <item>
      <title>Deno: The Official Node.js-Successor?</title>
      <link>https://sebnilsson.com/blog/deno-the-official-nodejs-successor/</link>
      <pubDate>Mon, 18 May 2020 12:38:00 GMT</pubDate>
      <description>&lt;p&gt;Why is &lt;a href="https://deno.land/v1"&gt;the announcement of Deno 1.0&lt;/a&gt; possibly &lt;strong&gt;very exciting&lt;/strong&gt;? Are there &lt;strong&gt;enough upsides to warrant a switch&lt;/strong&gt; from Node.js to &lt;a href="https://github.com/denoland/deno"&gt;Deno&lt;/a&gt;?&lt;/p&gt;
&lt;p&gt;The announcement of 1.0 was done middle of May 2020, but the initial announcement came in a presentation named &lt;a href="https://youtu.be/M3BM9TB-8yA"&gt;&lt;em&gt;10 Things I Regret About Node.js&lt;/em&gt; by Ryan Dahl&lt;/a&gt; in mid-2018.&lt;/p&gt;
&lt;p&gt;Deno is not just a rearrangement of the first two and the last two letters of "Node". It's built on top of more than &lt;strong&gt;11 years of experience from Node.js&lt;/strong&gt; running in production all over the world, &lt;strong&gt;by the original creator of Node.js&lt;/strong&gt;. So this does not seem like another case of &lt;em&gt;"I don't like how this project is handled, &lt;a href="https://www.infoworld.com/article/2855057/why-iojs-decided-to-fork-nodejs.html"&gt;so I'm making my own fork&lt;/a&gt;"&lt;/em&gt;, it's a completely new implementation.&lt;/p&gt;
&lt;h2 class="h1"&gt;10 Regrets about Node.js&lt;/h2&gt;
&lt;p&gt;The 10 things Ryan Dahl regretted about Node.js, which he acknowledges are &lt;strong&gt;impossible to change now&lt;/strong&gt;, seem to be &lt;strong&gt;large motivators for the creation of Deno&lt;/strong&gt;. It's worth noting that JavaScript has changed a lot during its 11 years of existence and Node has driven a lot of those changes.&lt;/p&gt;
&lt;p&gt;The numbered &lt;a href="https://youtu.be/M3BM9TB-8yA"&gt;regrets brought up in the talk&lt;/a&gt; were:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Not sticking with promises&lt;/strong&gt;: Promises allow the usage of &lt;code&gt;async&lt;/code&gt;/&lt;code&gt;await&lt;/code&gt; and avoids "&lt;a href="http://callbackhell.com/"&gt;Callback Hell&lt;/a&gt;".&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Security&lt;/strong&gt;: Your linter shouldn't get complete access to your computer and network.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The Build System (GYP)&lt;/strong&gt;: Awful experience for users. It's a non-JSON, Python adaptation of JSON.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;package.json&lt;/code&gt;&lt;/strong&gt;: Not a strictly necessary abstraction and doesn't exist on the web. Includes all sorts of unnecessary information.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;node_modules&lt;/code&gt;&lt;/strong&gt;: Massively complicates the module resolution. Deviates greatly from browser semantics.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;require("module")&lt;/code&gt; without the extension "&lt;code&gt;.js&lt;/code&gt;"&lt;/strong&gt;: Needlessly less explicit. Module loader has to query the file system at multiple locations.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;index.js&lt;/code&gt;&lt;/strong&gt;: Needlessly complicated the module loading system.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;It was also mentioned that Deno supports the following things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Unhandled promises should die immediately&lt;/li&gt;
&lt;li&gt;Support top-level &lt;code&gt;await&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Browser compatible where functionality overlaps&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 class="h1"&gt;Introducing Deno&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://deno.land/"&gt;Deno&lt;/a&gt; is a runtime for both JavaScript and &lt;a href="https://www.typescriptlang.org/"&gt;TypeScript&lt;/a&gt;, built on the &lt;a href="https://v8.dev/"&gt;V8 JavaScript engine&lt;/a&gt; and &lt;a href="https://www.rust-lang.org/"&gt;Rust&lt;/a&gt;, with the asynchronous runtime &lt;a href="https://tokio.rs/"&gt;Tokio&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;a href="https://deno.land/manual#feature-highlights"&gt;feature highlights&lt;/a&gt;, as of version 1.0, are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Secure by default&lt;/strong&gt;: Access to files, network or environment must be &lt;strong&gt;&lt;a href="https://deno.land/manual/getting_started/permissions"&gt;explicitly enabled&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Supports TypeScript out of the box&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ships a single executable&lt;/strong&gt;: No separate package-manager, like &lt;em&gt;npm&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Built-in utilities&lt;/strong&gt;: &lt;a href="https://deno.land/manual/testing"&gt;test runner&lt;/a&gt;, &lt;a href="https://deno.land/manual/tools/formatter"&gt;code formatter&lt;/a&gt;, built in &lt;a href="https://deno.land/manual/tools/debugger"&gt;debugger&lt;/a&gt;, dependency inspector and &lt;a href="https://deno.land/manual/tools"&gt;more&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bundling&lt;/strong&gt;: Scripts can be &lt;a href="https://deno.land/manual/tools/bundler"&gt;bundled&lt;/a&gt; into a single JavaScript file&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Standard modules&lt;/strong&gt;: Audited and &lt;a href="https://github.com/denoland/deno/tree/master/std"&gt;guaranteed to work with Deno&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 class="h1"&gt;Executing JavaScript/TypeScript&lt;/h2&gt;
&lt;p&gt;Deno being a single executable file, not needing a separate package-manager or &lt;code&gt;package.json&lt;/code&gt;-file, an example of a &lt;strong&gt;working HTTP server application&lt;/strong&gt; looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import { serve } from "https://deno.land/std@0.50.0/http/server.ts";
for await (const req of serve({ port: 8000 })) {
  req.respond({ body: "Hello World\n" });
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There is &lt;strong&gt;no need to install anything&lt;/strong&gt; beforehand or add any configuration-files. &lt;strong&gt;All you need to run is&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;deno run example.js
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Since the code is executed in a sandbox, which is secure by default, the &lt;strong&gt;explicit access must be granted&lt;/strong&gt; for the fetching the remote dependency, by adding the flag &lt;code&gt;--allow-net&lt;/code&gt; to the command-line.&lt;/p&gt;
&lt;p&gt;The remote dependency is &lt;strong&gt;cached locally&lt;/strong&gt; and only reloaded if the script is executed with the flag &lt;code&gt;--reload&lt;/code&gt;.&lt;/p&gt;
&lt;h2 class="h1"&gt;Limitations&lt;/h2&gt;
&lt;p&gt;Deno 1.0 &lt;a href="https://deno.land/v1#limitations"&gt;has some known limitations&lt;/a&gt;, which include things like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;No automatic compatibility with existing npm-packages&lt;/li&gt;
&lt;li&gt;HTTP server performance is not as good as Node.js, even if it's not too far away&lt;/li&gt;
&lt;li&gt;TypeScript performance issues&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Since Deno uses ECMAScript modules, which uses &lt;code&gt;import&lt;/code&gt; instead of &lt;code&gt;require&lt;/code&gt;, any module using &lt;code&gt;require&lt;/code&gt; has to be converted.&lt;/p&gt;
&lt;h2 class="h1"&gt;Summary&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;I'm surprised at how excited I am about the potential of Deno.&lt;/strong&gt; For me, to have the creator of Node.js use a decade of learning to start over with a blank slate is what makes this a rare situation of high potential.&lt;/p&gt;
&lt;p&gt;Some things I look forward to from Deno are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A fresh take on a JavaScript/TypeScript runtime&lt;/li&gt;
&lt;li&gt;First Class TypeScript Support&lt;/li&gt;
&lt;li&gt;Skipping &lt;code&gt;package.json&lt;/code&gt; and &lt;code&gt;npm install&lt;/code&gt; when you just want to get started fast&lt;/li&gt;
&lt;li&gt;Promises as default: Avoiding callback hell and mixed concepts between different parts of the code&lt;/li&gt;
&lt;li&gt;Not having to deal with the &lt;code&gt;node_modules&lt;/code&gt;-folder&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    <item>
      <title>C# Nullable Reference Types: IntelliSense Confusion</title>
      <link>https://sebnilsson.com/blog/c-nullable-reference-types-intellisense-confusion/</link>
      <pubDate>Thu, 13 Feb 2020 16:49:00 GMT</pubDate>
      <description>&lt;p&gt;The feature and concept of &lt;em&gt;&lt;a href="https://docs.microsoft.com/en-us/dotnet/csharp/nullable-references"&gt;Nullable reference types&lt;/a&gt;&lt;/em&gt; were introduced in C# 8.0 and it basically &lt;strong&gt;made all types non-nullable by default&lt;/strong&gt; and ensured that these types could never be assigned the value &lt;code&gt;null&lt;/code&gt;. This is one of my favorite features in C# recently, but there are scenarios where &lt;strong&gt;a mixed nullable environment could cause confusion&lt;/strong&gt;.&lt;/p&gt;
&lt;p class="text-center mb-3"&gt;&lt;img src="https://files.sebnilsson.com/web/images/nullable-confusion/confusion2.jpg" alt="Confusion" class="img-fluid fancybox-img" loading="lazy"&gt;&lt;/p&gt;
&lt;p&gt;To enable the assignment of the value &lt;code&gt;null&lt;/code&gt; to a type, &lt;strong&gt;you have to explicitly mark that type&lt;/strong&gt;. This uses the same concept of nullable as introduced in C# 2.0, where you, for example, make an &lt;code&gt;int&lt;/code&gt; nullable by adding a question mark after it: &lt;code&gt;int?&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;When we look at a regular example service-class, we can see which benefits can be had from &lt;em&gt;Nullable reference types&lt;/em&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class ProductService
{
    // This method accepts a non-null string for 'productId'
    // and always returns a string
    public string FormatProductId(string productId)
    {
        // ...
    }

    // This method accepts a nullable 'formattedProductId'
    // and returns a string or null
    public string? TryGetProductName(string? formattedProductId)
    {
        // ...
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This makes things all fine and clear. We know that the method &lt;code&gt;FormatProductId&lt;/code&gt; never returns &lt;code&gt;null&lt;/code&gt; and that it doesn't accept &lt;code&gt;null&lt;/code&gt; in its parameter. We also know that the method &lt;code&gt;TryGetProductName&lt;/code&gt; returns a &lt;code&gt;string&lt;/code&gt; which could be &lt;code&gt;null&lt;/code&gt; and that the parameter accepts a &lt;code&gt;string&lt;/code&gt; which could be &lt;code&gt;null&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This is great, this means that &lt;strong&gt;we don't have to perform a &lt;code&gt;null&lt;/code&gt;-check&lt;/strong&gt; on &lt;code&gt;productId&lt;/code&gt;-parameter of the &lt;code&gt;FormatProductId&lt;/code&gt;-method, right? &lt;strong&gt;Well, not exactly&lt;/strong&gt;...&lt;/p&gt;
&lt;h2 class="h1"&gt;Confusion: Mixed nullable environments&lt;/h2&gt;
&lt;p&gt;In an environment where all your code has &lt;em&gt;Nullable reference types&lt;/em&gt; enabled, you can trust the output of a method and the input to its parameters. &lt;strong&gt;In a mixed nullable environment, things are not as straight forward&lt;/strong&gt;, especially when you look at how IntelliSense in Visual Studio signals &lt;strong&gt;what to expect from the code&lt;/strong&gt;.&lt;/p&gt;
&lt;h3 class="h2"&gt;Scenario 1: Modern app &amp;amp; legacy library&lt;/h3&gt;
&lt;p&gt;Imagine that your new modern app has &lt;em&gt;Nullable reference types&lt;/em&gt; enabled, but you're using an external library that is legacy and does not have this enabled. This external library can be your own old library or something you've included from NuGet.&lt;/p&gt;
&lt;p&gt;The problem now becomes that the external library is signaling, for example, that it has a method that returns a &lt;code&gt;string&lt;/code&gt; and not a &lt;code&gt;string?&lt;/code&gt;, so you should be able to trust that it is not &lt;code&gt;null&lt;/code&gt;, right? &lt;strong&gt;Unfortunately not&lt;/strong&gt;. Even with a local non-nullable project, &lt;strong&gt;IntelliSense tells me that the returned &lt;code&gt;string&lt;/code&gt; is not &lt;code&gt;null&lt;/code&gt;, even when it is&lt;/strong&gt;.&lt;/p&gt;
&lt;p class="text-center mb-3"&gt;&lt;img src="https://files.sebnilsson.com/web/images/nullable-confusion/value-is-not-null.png" alt="Value is not null" class="img-fluid fancybox-img" loading="lazy"&gt;&lt;/p&gt;
&lt;h3 class="h2"&gt;Scenario 2: Legacy app &amp;amp; modern library&lt;/h3&gt;
&lt;p&gt;Imagine that you have just put together a nice library that you want others to use, either in your project, organization or publicly through NuGet. One of the best parts about using &lt;em&gt;Nullable reference types&lt;/em&gt; is that &lt;strong&gt;the compiler will warn you if you try to send in a &lt;code&gt;null&lt;/code&gt; value as a parameter&lt;/strong&gt; to a method that explicitly states that it doesn't support &lt;code&gt;null&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Nice, now you can clean out all those noisy &lt;code&gt;null&lt;/code&gt;-checks at the top of all the methods, right? &lt;strong&gt;Unfortunately not&lt;/strong&gt;. Your code might be used by another assembly (or an older version of Visual Studio), which &lt;strong&gt;doesn't detect the non-nullability&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;In a way, this means you have to reverse the way you do &lt;code&gt;null&lt;/code&gt;-checks in your code.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class ProductService
{
    // This method does not accept a null-value
    // and if it does, it should throw an exception
    public string FormatProductId(string productId)
    {
        if (productId == null)
            throw new ArgumentNullException(productId);
        // ...
    }

    // This method accepts null-values
    // and should adjust its logic accordingly
    public string? TryGetProductName(string? formattedProductId)
    {
        return
            formattedProductId != null
            ? GetProductName(formattedProductId)
            : null;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 class="h1"&gt;Key takeaways&lt;/h2&gt;
&lt;p&gt;My own take-aways from exploring this aspect of &lt;em&gt;Nullable reference types&lt;/em&gt; are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;When building a library, always check for &lt;code&gt;null&lt;/code&gt; in incoming method-arguments, even when &lt;em&gt;Nullable reference types&lt;/em&gt; is enabled&lt;/li&gt;
&lt;li&gt;When consuming an external legacy library, don't trust the return-type to not be &lt;code&gt;null&lt;/code&gt; (even if it says it's not)&lt;/li&gt;
&lt;li&gt;In a mixed nullable environment, the feature to guard us against &lt;code&gt;NullReferenceException&lt;/code&gt;s is likely to mistakenly cause some more of them&lt;/li&gt;
&lt;li&gt;When this feature is fully adopted, there will be a reduction in a lot of the overhead in &lt;code&gt;null&lt;/code&gt;-handling code&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 class="h1"&gt;Thoughts&lt;/h2&gt;
&lt;p&gt;Hopefully, in .NET 5, this feature is enabled by default and these kinds of confusions, and described associated errors can be avoided.&lt;/p&gt;
&lt;p&gt;One idea for an improvement to the IntelliSense-behavior around assemblies that are not known to have &lt;em&gt;Nullable reference types&lt;/em&gt; enabled could be to &lt;strong&gt;show all these types as nullable&lt;/strong&gt;. Both because it makes things super-clear, but also because of the fact that they actually are nullable.&lt;/p&gt;
&lt;p&gt;This change would make &lt;strong&gt;everything in the whole .NET Core CLR light up as nullable&lt;/strong&gt;, but as of .NET Core 3.1, it all is nullable, by definition.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>PowerShell LINQ with Short Aliases</title>
      <link>https://sebnilsson.com/blog/powershell-linq-with-short-aliases/</link>
      <pubDate>Mon, 15 Jul 2019 17:04:00 GMT</pubDate>
      <description>&lt;p&gt;Most modern applications or code today deal with some kind of filtering or querying. In C# and .NET, we have &lt;a href="/blog/tag/?t=linq"&gt;Language Integrated Query (LINQ)&lt;/a&gt;, which we also have access to in PowerShell, because it's built on .NET.&lt;/p&gt;
&lt;p&gt;To list the top 10 largest files in the Windows temporary folder, which is larger than 1 Mb and starts with the letter W, skipping the first 5, ordering by size, the C#-code with LINQ would look somewhat like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;new System.IO.DirectoryInfo(@"C:\Windows\Temp")
    .GetFiles()
    .Where(x =&amp;gt; x.Length &amp;gt; 1024 &amp;amp;&amp;amp; x.Name.StartsWith("W"))
    .OrderByDescending(x =&amp;gt; x.Length)
    .Select(x =&amp;gt; new { x.Name, x.Length })
    .Skip(5)
    .Take(10)
    .ToList()
    .ForEach(x =&amp;gt; Console.WriteLine($"{x.Name} ({x.Length})"));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The equivalent logic in PowerShell has a bit of a more daunting syntax, especially if you're not used to it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Get-ChildItem "C:\Windows\Temp" `
| Where-Object {$_.Length -gt 1024 -and $_.Name.StartsWith("W")} `
| Sort-Object {$_.Length} -Descending `
| Select-Object -Property Name, Length -First 10 -Skip 5 `
| ForEach-Object {Write-Host "$($_.Name) ($($_.Length))"}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That's &lt;strong&gt;a bit explicit and verbose&lt;/strong&gt;, but if you use the command &lt;a href="https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/get-alias"&gt;&lt;code&gt;Get-Alias&lt;/code&gt;&lt;/a&gt; in PowerShell, you will see a lot of useful aliases, which make the syntax a bit terser and easier to get an overview of:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;gci "C:\Windows\Temp" `
| ?{$_.Length -gt 1024 -and $_.Name.StartsWith("W")} `
| sort{$_.Length} -Descending `
| select Name, Length -First 10 -Skip 5 `
| %{write "$($_.Name) ($($_.Length))"}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In a real scenario, you probably wouldn't write each result to the console, but let PowerShell present the result in its default grid format.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>HTML Encode TagHelper in ASP.NET Core</title>
      <link>https://sebnilsson.com/blog/html-encode-taghelper-in-asp-net-core/</link>
      <pubDate>Thu, 27 Jun 2019 14:31:00 GMT</pubDate>
      <description>&lt;p&gt;For a specific scenario recently, I wanted to display the HTML-encoded output of a &lt;a href="https://docs.microsoft.com/en-us/aspnet/core/mvc/views/tag-helpers/intro"&gt;TagHelper&lt;/a&gt; in ASP.NET Core. So I wanted to use the TagHelper, but not output its actual result, but see the &lt;strong&gt;raw HTML&lt;/strong&gt; which would have been included in my template.&lt;/p&gt;
&lt;p class="text-center mb-3"&gt;&lt;img src="https://files.sebnilsson.com/web/images/html-encode-aspnet-core/html.jpg" alt="HTML" class="img-fluid fancybox-img" loading="lazy"&gt;&lt;/p&gt;
&lt;p&gt;So I created another TagHelper, which allows me to &lt;strong&gt;wrap any HTML, inline code in ASP.NET Core and other TagHelpers&lt;/strong&gt;, and get all the content inside the TagHelper's tag to be HTML-encoded, like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;html-encode&amp;gt;
    &amp;lt;a href="@Url.Action("Index")"&amp;gt;Read More&amp;lt;/a&amp;gt;
    @Html.TextBox("No_Longer_Recommended-TagHelpers_Preferred")
    &amp;lt;my-other-tag-helper /&amp;gt;
&amp;lt;/html-encode&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;From this, I will get the raw HTML of the link with an UrlHelper-result, the result of the HTML-helper and the result of my other TagHelper.&lt;/p&gt;
&lt;p&gt;The source-code for the &lt;code&gt;html-encode&lt;/code&gt;-TagHelper is as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[HtmlTargetElement("html-encode", TagStructure = TagStructure.NormalOrSelfClosing)]
public class HtmlEncodeTagHelper : TagHelper
{
    public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
    {
        var childContent = output.Content.IsModified
            ? output.Content.GetContent()
            : (await output.GetChildContentAsync()).GetContent();

        string encodedChildContent = WebUtility.HtmlEncode(childContent ?? string.Empty);

        output.TagName = null;
        output.Content.SetHtmlContent(encodedChildContent);
    }
}
&lt;/code&gt;&lt;/pre&gt;
</description>
    </item>
  </channel>
</rss>