<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Polysharp on Nicola Iarocci</title>
    <link>https://nicolaiarocci.com/tags/polysharp/</link>
    <description>Recent content in Polysharp on Nicola Iarocci</description>
    <generator>Hugo -- 0.143.1</generator>
    <language>en</language>
    <copyright>Produced / Written / Maintained by Nicola Iarocci since 2010</copyright>
    <lastBuildDate>Sat, 04 Feb 2023 07:05:25 +0100</lastBuildDate>
    <atom:link href="https://nicolaiarocci.com/tags/polysharp/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Making the latest C# language features available in older .NET versions</title>
      <link>https://nicolaiarocci.com/making-the-latest-csharp-language-features-available-in-older-dotnet-versions/</link>
      <pubDate>Sat, 04 Feb 2023 07:05:25 +0100</pubDate>
      <guid>https://nicolaiarocci.com/making-the-latest-csharp-language-features-available-in-older-dotnet-versions/</guid>
      <description>&lt;p&gt;In a C# library I&amp;rsquo;ve been working on, I wanted to use C# 9.0&amp;rsquo;s &lt;code&gt;init&lt;/code&gt; keyword.
Quoting the &lt;a href=&#34;https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/init&#34;&gt;documentation&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The init keyword defines an accessor method in a property or indexer. An
init-only setter assigns a value to the property or the indexer element
&lt;strong&gt;only&lt;/strong&gt; during object construction. This enforces immutability so that once
the object is initialized, it can&amp;rsquo;t be changed again.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Consider the following class:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    public class Person
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        public string FirstName { get; init; }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You can initialize it like this:&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>In a C# library I&rsquo;ve been working on, I wanted to use C# 9.0&rsquo;s <code>init</code> keyword.
Quoting the <a href="https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/init">documentation</a>:</p>
<blockquote>
<p>The init keyword defines an accessor method in a property or indexer. An
init-only setter assigns a value to the property or the indexer element
<strong>only</strong> during object construction. This enforces immutability so that once
the object is initialized, it can&rsquo;t be changed again.</p></blockquote>
<p>Consider the following class:</p>
<div class="highlight"><pre tabindex="0" style="background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>    public class Person
</span></span><span style="display:flex;"><span>    {
</span></span><span style="display:flex;"><span>        public string FirstName { get; init; }
</span></span><span style="display:flex;"><span>    }
</span></span></code></pre></div><p>You can initialize it like this:</p>
<div class="highlight"><pre tabindex="0" style="background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-gdscript3" data-lang="gdscript3"><span style="display:flex;"><span>    <span style="font-weight:bold">var</span> person = new Person { FirstName = <span style="font-style:italic">&#34;John&#34;</span> };
</span></span></code></pre></div><p>But this will fail:</p>
<div class="highlight"><pre tabindex="0" style="background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-gdscript3" data-lang="gdscript3"><span style="display:flex;"><span>    <span style="font-weight:bold">var</span> person = new Person();
</span></span><span style="display:flex;"><span>    person.FirstName = <span style="font-style:italic">&#34;John&#34;</span>;  //Not allowed
</span></span></code></pre></div><p>For my project, which is a .NET Standard 2.0 library, I thought this approach
might be preferable to a parameter-enforced class constructor alternative.</p>
<p>To my surprise, however, when I tried the above, I got the following error:</p>
<div class="highlight"><pre tabindex="0" style="background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>The predefined type &#39;System.Runtime.CompilerServices.IsExternalInit&#39; must be
</span></span><span style="display:flex;"><span>defined or imported in order to declare init-only setter
</span></span></code></pre></div><p>As it <a href="https://developercommunity.visualstudio.com/t/error-cs0518-predefined-type-systemruntimecompiler/1244809#TPIN-N1249582">turns out</a>, The <code>IsExternalInit</code> type is only included in the net5.0
(and subsequent) target frameworks, so one cannot use it right away in a
NetStandard 2.0 (or 2.1, for that matter) library.</p>
<p>In the dotnet world, when I encounter <em>&ldquo;type is not defined in version X&rdquo;</em>
scenario, I know I can get around the issue by making up the type on my own. A
quick lookup confirmed that this was the case, and the workaround is to add
the following somewhere in my source code:</p>
<div class="highlight"><pre tabindex="0" style="background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>    namespace System.Runtime.CompilerServices
</span></span><span style="display:flex;"><span>    {
</span></span><span style="display:flex;"><span>        internal static class IsExternalInit {}
</span></span><span style="display:flex;"><span>    }
</span></span></code></pre></div><p>And presto, the <code>init</code> keyword is now fully available to my library.</p>
<p>While researching this matter, I stumbled into <a href="https://github.com/Sergio0694/PolySharp">PolySharp</a>,  a lovely
package that takes this workaround approach to new heights. What is it?</p>
<blockquote>
<p>PolySharp provides generated, source-only polyfills for C# language features,
to easily use all runtime-agnostic features downlevel. The package is
distributed as a source generator, so that it will automatically detect which
polyfills are needed depending on the target framework and project in use:
just add a reference to PolySharp, set your C# language version to latest,
and have fun!</p></blockquote>
<p>And it works! Just add a PolySharp reference, and almost all modern C# language
features become automagically available to your project, with no tricks around
polluting your code. What&rsquo;s also nice about PolySharp, is that it isn&rsquo;t a
dependency for your library; it only needs to be there at compile time.</p>
<p>Do you know what&rsquo;s funny? After all, I took a different route; no <code>init</code>
keyword is used anymore in my library, but that&rsquo;s for another story.</p>
]]></content:encoded>
    </item>
  </channel>
</rss>
