devblogs.microsoft.com Open in urlscan Pro
2a02:26f0:fb:5b4::2f1e  Public Scan

Submitted URL: https://comm.microsoft.com/PoliteMail257/default.aspx?page=r6iXA_3ZTEOSeoCUootWpA&ref_id=lV0dfqeODEeQp1nMY0sf3Q
Effective URL: https://devblogs.microsoft.com/dotnet/early-peek-at-csharp-11-features/
Submission: On March 09 via api from US — Scanned from DE

Form analysis 3 forms found in the DOM

Name: searchFormGET /search

<form class="c-search" autocomplete="off" id="searchForm" name="searchForm" role="search" action="/search" method="GET"
  data-seautosuggest="{&quot;queryParams&quot;:{&quot;market&quot;:&quot;en-us&quot;,&quot;clientId&quot;:&quot;7F27B536-CF6B-4C65-8638-A0F8CBDFCA65&quot;,&quot;sources&quot;:&quot;Microsoft-Terms,Iris-Products,DCatAll-Products&quot;,&quot;filter&quot;:&quot;+ClientType:StoreWeb&quot;,&quot;counts&quot;:&quot;5,1,5&quot;},&quot;familyNames&quot;:{&quot;Apps&quot;:&quot;App&quot;,&quot;Books&quot;:&quot;Book&quot;,&quot;Bundles&quot;:&quot;Bundle&quot;,&quot;Devices&quot;:&quot;Device&quot;,&quot;Fees&quot;:&quot;Fee&quot;,&quot;Games&quot;:&quot;Game&quot;,&quot;MusicAlbums&quot;:&quot;Album&quot;,&quot;MusicTracks&quot;:&quot;Song&quot;,&quot;MusicVideos&quot;:&quot;Video&quot;,&quot;MusicArtists&quot;:&quot;Artist&quot;,&quot;OperatingSystem&quot;:&quot;Operating System&quot;,&quot;Software&quot;:&quot;Software&quot;,&quot;Movies&quot;:&quot;Movie&quot;,&quot;TV&quot;:&quot;TV&quot;,&quot;CSV&quot;:&quot;Gift Card&quot;,&quot;VideoActor&quot;:&quot;Actor&quot;}}"
  data-seautosuggestapi="https://www.microsoft.com/services/api/v3/suggest"
  data-m="{&quot;cN&quot;:&quot;GlobalNav_Search_cont&quot;,&quot;cT&quot;:&quot;Container&quot;,&quot;id&quot;:&quot;c1c9c3m1r1a1&quot;,&quot;sN&quot;:1,&quot;aN&quot;:&quot;c9c3m1r1a1&quot;}" aria-expanded="false">
  <input id="cli_shellHeaderSearchInput" aria-label="Search Expanded" aria-controls="universal-header-search-auto-suggest-transparent" aria-owns="universal-header-search-auto-suggest-ul" type="search" name="query" role="text" placeholder="Search"
    data-m="{&quot;cN&quot;:&quot;SearchBox_nav&quot;,&quot;id&quot;:&quot;n1c1c9c3m1r1a1&quot;,&quot;sN&quot;:1,&quot;aN&quot;:&quot;c1c9c3m1r1a1&quot;}" data-toggle="tooltip" data-placement="right" title="" data-original-title="Search">
  <input type="hidden" name="blog" value="/dotnet/" data-m="{&quot;cN&quot;:&quot;HiddenInput_nav&quot;,&quot;id&quot;:&quot;n2c1c9c3m1r1a1&quot;,&quot;sN&quot;:2,&quot;aN&quot;:&quot;c1c9c3m1r1a1&quot;}">
  <button id="search" aria-label="Search" class="c-glyph" data-m="{&quot;cN&quot;:&quot;Search_nav&quot;,&quot;id&quot;:&quot;n3c1c9c3m1r1a1&quot;,&quot;sN&quot;:3,&quot;aN&quot;:&quot;c1c9c3m1r1a1&quot;}" data-bi-dnt="true" data-bi-mto="true"
    aria-expanded="false">
    <span role="presentation">Search</span>
    <span role="tooltip" class="c-uhf-tooltip c-uhf-search-tooltip">Search</span>
  </button>
  <div class="m-auto-suggest" id="universal-header-search-auto-suggest-transparent" role="group">
    <ul class="c-menu" id="universal-header-search-auto-suggest-ul" aria-label="Search Suggestions" aria-hidden="true" data-bi-dnt="true" data-bi-mto="true" data-js-auto-suggest-position="default" role="listbox" data-tel="jsll"
      data-m="{&quot;cN&quot;:&quot;search suggestions_cont&quot;,&quot;cT&quot;:&quot;Container&quot;,&quot;id&quot;:&quot;c4c1c9c3m1r1a1&quot;,&quot;sN&quot;:4,&quot;aN&quot;:&quot;c1c9c3m1r1a1&quot;}"></ul>
  </div>
</form>

<form id="wp-link" tabindex="-1">
  <input type="hidden" id="_ajax_linking_nonce" name="_ajax_linking_nonce" value="c3079b854c">
  <h1 id="link-modal-title">Insert/edit link</h1>
  <button type="button" id="wp-link-close"><span class="screen-reader-text">Close</span></button>
  <div id="link-selector">
    <div id="link-options">
      <p class="howto" id="wplink-enter-url">Enter the destination URL</p>
      <div>
        <label><span>URL</span>
          <input id="wp-link-url" type="text" aria-describedby="wplink-enter-url"></label>
      </div>
      <div class="wp-link-text-field">
        <label><span>Link Text</span>
          <input id="wp-link-text" type="text"></label>
      </div>
      <div class="link-target">
        <label><span></span>
          <input type="checkbox" id="wp-link-target"> Open link in a new tab</label>
      </div>
    </div>
    <p class="howto" id="wplink-link-existing-content">Or link to existing content</p>
    <div id="search-panel">
      <div class="link-search-wrapper">
        <label>
          <span class="search-label">Search</span>
          <input type="search" id="wp-link-search" class="link-search-field" autocomplete="off" aria-describedby="wplink-link-existing-content">
          <span class="spinner"></span>
        </label>
      </div>
      <div id="search-results" class="query-results" tabindex="0">
        <ul></ul>
        <div class="river-waiting">
          <span class="spinner"></span>
        </div>
      </div>
      <div id="most-recent-results" class="query-results" tabindex="0">
        <div class="query-notice" id="query-notice-message">
          <em class="query-notice-default">No search term specified. Showing recent items.</em>
          <em class="query-notice-hint screen-reader-text">Search or use up and down arrow keys to select an item.</em>
        </div>
        <ul></ul>
        <div class="river-waiting">
          <span class="spinner"></span>
        </div>
      </div>
    </div>
  </div>
  <div class="submitbox">
    <div id="wp-link-cancel">
      <button type="button" class="button">Cancel</button>
    </div>
    <div id="wp-link-update">
      <input type="submit" value="Add Link" class="button button-primary" id="wp-link-submit" name="wp-link-submit">
    </div>
  </div>
</form>

#

<form id="myForm" action="#">
  <div class="modal-body">
    <div class="form-group">
      <label for="code-text">Paste your code snippet</label>
      <textarea class="form-control" id="code-text" style="height: 150px;"></textarea>
    </div>
  </div>
</form>

Text Content

We use optional cookies to improve your experience on our websites, such as
through social media connections, and to display personalized advertising based
on your online activity. If you reject optional cookies, only cookies necessary
to provide you the services will be used. You may change your selection by
clicking “Manage Cookies” at the bottom of the page. Privacy Statement
Third-Party Cookies

Accept Reject Manage cookies

Skip to main content
Microsoft
.NET Blog
.NET Blog
.NET Blog
 * Home
 * DevBlogs
 * Developer
    * Visual Studio
    * Visual Studio Code
    * Visual Studio for Mac
    * DevOps
    * Developer support
    * CSE Developer
    * Engineering@Microsoft
    * Azure SDK
    * IoT
    * Command Line
    * Perf and Diagnostics
    * Dr. International
    * Notification Hubs
    * Math in Office

 * Technology
    * DirectX
    * PIX
    * SurfaceDuo
    * Startups
    * Sustainable Engineering
    * Windows AI Platform

 * Languages
    * C++
    * C#
    * F#
    * Visual Basic
    * TypeScript
    * PowerShell Community
    * PowerShell Team
    * Python
    * Q#
    * JavaScript
    * Java
    * Java Blog in Chinese

 * .NET
    * .NET
    * .NET MAUI
    * Blazor
    * ASP.NET
    * NuGet
    * Xamarin

 * Platform Development
    * #ifdef Windows
    * Apps for Windows
    * Azure Depth Platform
    * Azure Government
    * Bing Dev Center
    * Microsoft Edge Dev
    * Microsoft Azure
    * Microsoft 365 Developer
    * Old New Thing
    * Windows MIDI and Music dev
    * Windows Search Platform

 * Data Development
    * Azure Cosmos DB
    * Azure Data Studio
    * Azure SQL
    * OData
    * Revolutions R
    * SQL Server Data Tools

 * More

Login
Search Search

Cancel


EARLY PEEK AT C# 11 FEATURES

Kathleen



February 22nd, 202278



Visual Studio 17.1 (Visual Studio 2022 Update 1) and .NET SDK 6.0.200 include
preview features for C# 11! You can update Visual Studio or download the latest
.NET SDK to get these features.

Check out the post Visual Studio 2022 17.1 is now available! to find out what’s
new in Visual Studio and the post Announcing .NET 7 Preview 1 to learn about
more .NET 7 preview features.


DESIGNING C# 11

We love designing and developing in the open! You can find proposals for future
C# features and notes from language design meetings in the CSharpLang repo. The
main page explains our design process and you can listen to Mads Torgersen on
the .NET Community Runtime and Languages Standup where he talks about the design
process.

Once work for a feature is planned, work and tracking shifts to the Roslyn repo.
You can find the status of upcoming features on the Feature Status page. You can
see what we are working on and what’s merged into each preview. You can also
look back at previous versions to check out features you may have overlooked.

For this post I’ve distilled these sometimes complex and technical discussions
to what each feature means in your code.

We hope you will try out these new preview features and let us know what you
think. To try out the C# 11 preview features, create a C# project and set the
LangVersion to Preview. Your .csproj file might look like:

<Project Sdk="Microsoft.NET.Sdk">
    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>net6.0</TargetFramework>
        <ImplicitUsings>enable</ImplicitUsings>
        <Nullable>enable</Nullable>
        <LangVersion>preview</LangVersion>
    </PropertyGroup>
</Project>


C# 11 PREVIEW: ALLOW NEWLINES IN THE “HOLES” OF INTERPOLATED STRINGS

Read more about this change in the proposal Remove restriction that
interpolations within a non-verbatim interpolated string cannot contain
new-lines. #4935

C# supports two styles of interpolated strings: verbatim and non-verbatim
interpolated strings ($@"" and $"" respectively). A key difference between these
is that a non-verbatim interpolated strings cannot contain newlines in its text
segments, and must instead use escapes (like \r\n). A verbatim interpolated
string can contain newlines in its text segments, and doesn’t escape newlines or
other character (except for “” to escape a quote itself). All of this behavior
remains the same.

Previously, these restrictions extended to the holes of non-verbatim
interpolated strings. Holes is a shorthand way of saying interpolation
expressions and are the portions inside the curly braces that supply runtime
values. The holes themselves are not text, and shouldn’t be held to the
escaping/newline rules of the interpolated string text segments.

For example, the following would have resulted in a compiler error in C# 10 and
is legal in this C# 11 preview:

var v = $"Count ist: { this.Is.Really.Something()
                            .That.I.Should(
                                be + able)[
                                    to.Wrap()] }.";


C# 11 PREVIEW: LIST PATTERNS

Read more about this change in the proposal List patterns.

The new list pattern allows you to match against lists and arrays. You can match
elements and optionally include a slice pattern that matches zero or more
elements. Using slice patterns you can discard or capture zero or more elements.

The syntax for list patterns are values surrounded by square brackets and for
the slice pattern it is two dots. The slice pattern can be followed by another
list pattern, such as the var pattern to capture the contents of the slice.

The pattern [1, 2, .., 10] matches all of the following:

int[] arr1 = { 1, 2, 10 };
int[] arr1 = { 1, 2, 5, 10 };
int[] arr1 = { 1, 2, 5, 6, 7, 8, 9, 10 };

To explore list patterns consider:

public static int CheckSwitch(int[] values)
    => values switch
    {
        [1, 2, .., 10] => 1,
        [1, 2] => 2,
        [1, _] => 3,
        [1, ..] => 4,
        [..] => 50
    };

When it is passed the following arrays, the results are as indicated:

WriteLine(CheckSwitch(new[] { 1, 2, 10 }));          // prints 1
WriteLine(CheckSwitch(new[] { 1, 2, 7, 3, 3, 10 })); // prints 1
WriteLine(CheckSwitch(new[] { 1, 2 }));              // prints 2
WriteLine(CheckSwitch(new[] { 1, 3 }));              // prints 3
WriteLine(CheckSwitch(new[] { 1, 3, 5 }));           // prints 4
WriteLine(CheckSwitch(new[] { 2, 5, 6, 7 }));        // prints 50

You can also capture the results of a slice pattern:

public static string CaptureSlice(int[] values)
    => values switch
    {
        [1, .. var middle, _] => $"Middle {String.Join(", ", middle)}",
        [.. var all] => $"All {String.Join(", ", all)}"
    };

List patterns work with any type that is countable and indexable — which means
it has an accessible Length or Count property and with an indexer an int or
System.Index parameter. Slice patterns work with any type that is countable and
sliceable — which means it has an accessible indexer that takes a Range as an
argument or has an accessible Slice method with two int parameters.

We’re considering adding support for list patterns on IEnumerable types. If you
have a chance to play with this feature, let us know your thoughts on it.


C# 11 PREVIEW: PARAMETER NULL-CHECKING

Read more about this change in the proposal Parameter null checking.

We are putting this feature into this early preview to ensure we have time to
get feedback. There have been discussions on a very succinct syntax vs. a more
verbose one. We want to get customer feedback and from users that have had a
chance to experiment with this feature.

It is quite common to validate whether method arguments are null with variations
of boilerplate code like:

public static void M(string s)
{
    if (s is null)
    {
        throw new ArgumentNullException(nameof(s));
    }
    // Body of the method
}

With Parameter null checking, you can abbreviate your intent by adding !! to the
parameter name:

public static void M(string s!!)
{
    // Body of the method
}

Code will be generated to perform the null check. The generated null check will
execute before any of the code within the method. For constructors, the null
check occurs before field initialization, calls to base constructors, and calls
to this constructors.

This features is independent of Nullable Reference Types (NRT), although they
work well together. NRT helps you know at design time whether a null is
possible. Parameter null-checking makes it easier to check at runtime whether
nulls have been passed to your code. This is particularly important when your
code is interacting with external code that might not have NRT enabled.

The check is equivalent if (param is null) throw new ArgumentNullException(...).
When multiple parameters contain the !! operator then the checks will occur in
the same order as the parameters are declared.

There are a few guidelines limiting where !! can be used:

 * Null-checks can only be applied to parameters when there is an
   implementation. For example, an abstract method parameter cannot use !!.
   Other cases where it cannot be used include:
   * extern method parameters.
   * Delegate parameters.
   * Interface method parameters when the method is not a Default Interface
     Method (DIM).
 * Null checking can only be applied to parameters that can be checked.

An example of scenarios that are excluded based on the second rule are discards
and out parameters. Null-checking can be done on ref and in parameters.

Null-checking is allowed on indexer parameters, and the check is added to the
get and set accessor. For example:

public string this[string key!!] { get { ... } set { ... } }

Null-checks can be used on lambda parameters, whether or not they are surrounded
by parentheses:

// An identity lambda which throws on a null input
Func<string, string> s = x!! => x;

async methods can have null-checked parameters. The null check occurs when the
method is invoked.

The syntax is also valid on parameters to iterator methods. The null-check will
occur when the iterator method is invoked, not when the underlying enumerator is
walked. This is true for traditional or async iterators:

class Iterators {
    IEnumerable<char> GetCharacters(string s!!) {
        foreach (var c in s) {
            yield return c;
        }
    }

    void Use() {
        // The invocation of GetCharacters will throw
        IEnumerable<char> e = GetCharacters(null);
    }
}


INTERACTION WITH NULLABLE REFERENCE TYPES

Any parameter which has a !! operator applied to its name will start with the
nullable state being not-null. This is true even if the type of the parameter
itself is potentially null. That can occur with an explicitly nullable type,
such as say string?, or with an unconstrained type parameter.

When !! syntax on parameters is combined with an explicitly nullable type on the
parameter, the compiler will issue a warning:

void WarnCase<T>(
    string? name!!,     // CS8995   Nullable type 'string?' is null-checked and will throw if null. 
    T value1!!        // Okay
)


CONSTRUCTORS

There is a small, but observable change when you change from explicit
null-checks in your code to null-checks using the null validation syntax (!!).
Your explicit validation occurs after field initializers, base class
constructors, and constructors called using this. Null-checks performed with the
parameter null-check syntax will occur before any of these execute. Early
testers found this order to be helpful and we think it will be very rare that
this difference will adversely affect code. But check that it will not impact
your program before shifting from explicit null-checks to the new syntax.


NOTES ON DESIGN

You can hear Jared Parsons in the .NET Languages and Runtime Community Standup
on Feb. 9th, 2022. This clip starts about 45 minutes into the stream when Jared
joins us to talk more about the decisions made to get this feature into preview,
and responds to some of the common feedback.

Some folks learned about this feature when they saw PRs using this feature in
the .NET Runtime. Other teams at Microsoft provide important dogfooding feedback
on C#. It was exciting to learn that the .NET Runtime removed nearly 20,000
lines of code using this new null-check syntax.

The syntax is !! on the parameter name. It is on the name, not the type, because
this is a feature of how that specific parameter will be treated in your code.
We decided against attributes because of how it would impact code readability
and because attributes very rarely impact how your program executes in the way
this feature does.

We considered and rejected making a global setting that there would be
null-checks on all nullable parameters. Parameter null checking forces a design
choice about how null will be handled. There are many methods where a null
argument is a valid value. Doing this everywhere a type is not null would be
excessive and have a performance impact. It would be extremely difficult to
limit only to methods that were vulnerable to nulls (such as public interfaces).
We also know from the .NET Runtime work that there are many places the check is
not appropriate, so a per parameter opt-out mechanism would be needed. We do not
currently think that a global approach to runtime null checks is likely to be
appropriate, and if we ever consider a global approach, it would be a different
feature.


SUMMARY

Visual Studio 17.1 and .NET SDK 6.0.200 offer an early peek into C# 11. You can
play with parameter null-checking, list patterns, and new lines within curly
braces (the holes) of interpolated strings.

We hope you’ll check out the C# 11 Preview features by updating Visual Studio or
downloading the latest .NET SDK, and then setting the LangVersion to preview.

We look forward to hearing what you think, here or via discussions in the
CSharpLang repo on GitHub!




KATHLEEN DOLLARD

Principal Program Manager, .NET

Follow


Posted in .NET C# Visual StudioTagged C# C# 11 language features null parameter
null safety Preview

READ NEXT

.NET 💜 GitHub Actions: Intro to GitHub Actions for .NET
Use GitHub Actions to automate common .NET build, test, and deploy tasks.
David Pine February 25, 2022
1 comment
Training a ML.NET Model with Azure ML
Learn how to create a training pipeline for ML.NET using Azure ML and Azure
Devops.
Becca McHenry February 28, 2022
1 comment


78 COMMENTS


LEAVE A COMMENTCANCEL REPLY

Log in to join the discussion.

 * Page 1of comments
 * Page 2of comments
 * Page 3of comments
 * Page 4of comments
 * Next comment

 * Денис Оболенский February 22, 2022 11:33 am
   collapse this comment
   
   
   I don’t like parameter null checking feature. It doesn’t feels like a nice
   addition to the language and have already caused a lot of holywars. Why does
   you introduce a new syntax for this? Why you can’t use existing notnull
   keyword on the type, not on the parameter name? Why do you use !! on the
   parameter name? It even contradicts with NRT feature, where strict null’s
   validation can be added.
   
   Log in to Reply
   * JesperTreetop February 22, 2022 1:15 pm
     collapse this comment
     
     
     Putting the !! on the parameter rather than the type is fitting here since
     it’s the value of the parameter that’s being checked. Things that go with
     the type should only be there if they describe something about the type.
     There’s no type anywhere else that can be string!! or string?!!.
     
     That said, it feels a bit ridiculous and out-of-place that a special
     two-punctuation-character incantation is introduced just to throw a certain
     exception.
     
     Log in to Reply
     * Kathleen Dollard February 23, 2022 7:36 am
       collapse this comment
       
       
       We’d love any feedback with alternate syntax suggestions!
       
       Log in to Reply
       * hitesh davey February 23, 2022 11:56 pm
         collapse this comment
         
         
         notnull keyword on the right is a much better option than !! notation.
         
         public void DoSomething(string first notnull, string second notnull ) { // code }
         
         having notnull, on the left, may hinder the practice of writing the
         code as C# developers are now used to writing and reading the code as
         “datatype followed by variable name”.
         
         Log in to Reply
         * Richard Valdivieso February 24, 2022 7:25 am
           collapse this comment
           
           
           I think we can try both and using data it is possible to remove the
           one that is less used?
           
           
           
         * Joey . February 26, 2022 2:53 am
           collapse this comment
           
           
           Technically it’d be a modifier for the parameter, like ref or out and
           thus should come to the left. But agreed, a (contextual) keyword
           would be more sensible than more sigils.
           
           
           
         
       * Paul Hughes February 25, 2022 12:20 pm
         collapse this comment
         
         
         There is a lot of double symbols popping up now, ??, !!. If I was a
         beginner and knew a bit of digital logic i would assume !! was
         true(which it is, but not understanding it was not null). I prefer when
         it is written in English what it is I am looking at, I pick up the code
         faster. I get it though learn new concepts and shorter code. I hope we
         don’t end up with too many symbols though rather than readable code,
         one of the reasons I took to C# over languages like Python with no
         types when going over variables in the code and global and local mess.
         Maybe I’m just getting old.
         
         Log in to Reply
         
       
     
   * Charles Roddie February 22, 2022 3:34 pm
     collapse this comment
     
     
     I agree. The NRT project is a success so this feature is not needed. If any
     consuming project has NRT turned off then that is its problem.
     
     > We considered and rejected making a global setting that there would be
     > null-checks on all nullable parameters.
     
     Then this code can be generated only in consuming projects with NRTs
     disabled. This contains the performance impact.
     
     Log in to Reply
     * Kathleen Dollard February 23, 2022 7:38 am
       collapse this comment
       
       
       If the code you are calling may have nulls, you still need null checks.
       
       Log in to Reply
       * Ladislav Burkovsky February 24, 2022 3:41 am
         collapse this comment
         
         
         We can have the bang bang implicit in NRT projects and optional
         outside. Additionally we should have the option to activate/deactivate
         in code.
         
         Log in to Reply
         
       
     
   * Jonatas Hudler February 23, 2022 6:15 am
     collapse this comment
     
     
     I agree !! syntax is ugly as hell. It adds noise to the code, it is not
     self explanatory, and makes newcomers overwhelmed (like F#, that contains
     lots of syntax gotchas and has one of the most ugly syntax ever produced).
     
     Log in to Reply
     
   * Kathleen Dollard February 23, 2022 7:33 am
     collapse this comment
     
     
     @Денис Оболенский
     
     I want to be sure I understand, can you give a code sample of what your
     notnull suggestion would look like. I want to check that it is one of the
     alternatives we have.
     
     We use this on the parameter because it is a feature of that parameter.
     
     Null Reference Type checking is not strict null validation. It is design
     time and things can happen at runtime that NRT does not consider.
     
     Log in to Reply
     * Денис Оболенский February 23, 2022 8:49 am
       collapse this comment
       
       
       Sure, I can provide some alternatives:
       
       1) Using notnull because this keyword is in the language already
       
       public void DoSomething(notnull string first, notnull string second) { // code }
       
       2) Using new NRT option here with strict validation (for example, as
       implemented in typescript, angularc, etc).
       
        strict 
       
       3) Using [NotNull] attribute
       
       public void DoSomething([NotNull] string arg) { //code }
       
       For me !! seems like an ugly syntax. Yeah, with this feature it’s much
       easier to write the code, but 80% of the time developers read the code.
       For me, it’s the same ugly feature, just like
       
       Type array[]
       
       declarations in Java.
       
       Options 1 and 3 will need to write more characters for developers, but
       they are in billion times easier to understand. And all losses to write
       more characters could be zeroed by using IDE features for code
       generation. Option 2 may be less intuitive, but with strict NRT
       validation it also makes sence.
       
       Log in to Reply
       * Oscar Järgren February 23, 2022 12:29 pm
         collapse this comment
         
         
         I approve of this, seems a way better option to handle it.
         
         Reading code should be easy, not writing it.
         
         Writing code has never been the hard part, it’s figuring out what you
         want to do and then understanding it later.
         
         Log in to Reply
         * hitesh davey February 24, 2022 12:09 am
           collapse this comment
           
           
           Well said. You just echoed my views.
           Reading and understanding code is more critical than writing since
           nowadays we have good AI code completion features.
           
           
           
         
       * AlseinX February 24, 2022 2:29 am
         collapse this comment
         
         
         I am strongly against them.
         
          1. notnull keyword is a contextual keyword, which means adding extra
             available context for it is also adding new keyword.
         
          2. It is a keyword at the beginning of code to opt in or out some
             language feature that is the really ugly design failure.
         
          3. An attribute to directly change the logical behavior (at managed
             level) of a statically compiled code, is not what C# was previously
             designed to be.
         
         And, as for that example
         
         Type array[]
         
         , I agree with that it is certian to be ugly, but it is because of that
         modern laguanges turn to use “type expression”, which is a syntax tree
         to express complexed structural parameterized types, instead of the old
         C-style (array is not a type but a way of declaring a bunch of
         variables).
         
         But parameter null checking is not a type but a sugar that attaches
         checking behavior to A PARAMETER that is declared as some nullable
         type, which is not itself a wrapper type. Thus the java array example
         does not apply.
         
         Log in to Reply
         
       
     
   * Y Zhang March 7, 2022 11:35 pm
     collapse this comment
     
     
     I don’t like it either. Besides, it’s also not a good practice if we are
     talking about “a static method should be thread-safe”
     
     Log in to Reply
     
   
 * JesperTreetop February 22, 2022 1:16 pm
   collapse this comment
   
   
   “and must instead use escapes (like rn)”
   
   I think WordPress is being WordPress and ate the backslashes.
   
   Log in to Reply
   * Kathleen Dollard February 23, 2022 7:35 am
     collapse this comment
     
     
     Thank you! It is now fixed.
     
     Log in to Reply
     
   
 * Evgeny Muryshkin February 22, 2022 2:20 pm
   collapse this comment
   
   
   Why !! at all? If parameter is nullable, and there is no explicit
   check/branch for null in code, exception generation can be implied.
   
   Advanced mode can check that all calls for this private/internal member
   already have checked for null and skip it to reduce amount of checks.
   
   Log in to Reply
   * Michael Taylor February 23, 2022 8:12 am
     collapse this comment
     
     
     Auto-generating such code would be a very bad idea. Therefore this really
     isn’t an option. I can think of several cases where auto-generating such
     code without prompting from the dev would not work well.
     
      * Some methods shouldn’t throw an ANE on null but NRE. The use case here
        is an extension method as they should behave like instance members.
        Instance members do not throw ANE but NRE. But you should not throw an
        NRE yourself so the only way to get this to work properly is to
        reference the instance.
      * In many cases higher level methods already validate arguments and
        therefore lower level methods should not auto-check as well. This is
        wasteful and there is no way to know whether such a case exists or not
        given just a method declaration.
      * Accessibility doesn’t matter in terms of “already checked”. If you could
        even do such analysis (what if there are cases where the args are
        checked and others aren’t) it still isn’t reliable. For example a
        method, irrelevant of accessibility, can be passed as a delegate to
        other code. There is no way to do code analysis and detect this. Hence
        you’d have to come up with heuristics to determine when to
        enable/disable such a feature (e.g. accessibility) and that just makes
        it a lot harder to understand. It would also then be a breaking change
        to change the accessibility of a method (currently it generally isn’t if
        you go from more restrictive to less).
      * Finally, it would be a breaking change to suddenly start throwing ANE in
        code that didn’t previously. Somebody somewhere could be wrapping that
        code in typed exception handlers and would suddenly see different
        behavior.
     
     Auto-generation of code without a programmer indicating they want it is
     almost always a bad idea. It must always be opt in.
     
     Log in to Reply
     
   
 * Mark Adamson February 22, 2022 3:30 pm
   collapse this comment
   
   
   > Slice patterns work with any type that is countable and sliceable
   
   I was surprised to find recently that ImmutableArray doesn’t support Slicing
   in .net 6. Will that be resolved so that we can use this feature with
   ImmutableArray and others which I use as standard now?
   
   Log in to Reply
   * anonymous February 22, 2022 3:35 pm
     collapse this comment
     
     
     this comment has been deleted.
     
     Log in to Reply
     
   * Fred Silberberg February 22, 2022 6:35 pm
     collapse this comment
     
     
     Yes, the PR for adding the new APIs was merged a couple of weeks ago:
     https://github.com/dotnet/runtime/pull/61196
     
     Log in to Reply
     
   
 * Arturo Torres Sánchez February 22, 2022 3:33 pm
   collapse this comment
   
   
   After all this I still hate the !! feature, because it essentially means that
   a plain string input is useless.
   
   For a method public void Process(string input) now we have three options:
   
    1. string? input: input can be null. OK.
    2. string input!!: input can never be null. OK.
    3. string input: input shouldn’t be null, but who knows? This last one is
       essentially deprecated since either 1 or 2 is the one you actually want.
   
   It’s still vexing to me why this functionality wasn’t included in the
   existing NRT feature.
   
   Log in to Reply
   * Kathleen Dollard February 23, 2022 7:45 am
     collapse this comment
     
     
     Your #3 is a good option where NRT is sufficiently protecting your code.
     This feature is to add a check where you think it is needed in your code.
     
     There is also a great deal of code that does not yet use NRT. This feature
     avoids that code being visible and will allow us to do the fastest possible
     check. However, there is still a performance hit of the null check.
     
     NRT is strictly design time. Null-checks is the sister runtime feature.
     
     Log in to Reply
     * Arturo Torres Sánchez February 23, 2022 8:35 am
       collapse this comment
       
       
       > Your #3 is a good option where NRT is sufficiently protecting your
       > code.
       
       I mean, if NRT was sufficiently protecting my code, this feature wouldn’t
       be necessary, would it?
       
       > This feature is to add a check where you think it is needed in your
       > code.
       
       I think it’s needed in all public methods. Having a plain string input on
       a public method is now an error. If only there was a way to add the
       validation without me having to manually add it…
       
       > There is also a great deal of code that does not yet use NRT.
       
       But code that doesn’t use NRT already is throwing exceptions on nulls
       everywhere. I don’t see the point of this feature to replace one syntax
       with another while not solving the underlying issue at all.
       
       > NRT is strictly design time. Null-checks is the sister runtime feature.
       
       Yes, this is exactly my complaint. NRT being strictly design time is a
       bad decision in my opinion, and shouldn’t need a “sister” runtime
       feature.
       
       Log in to Reply
       * Kathleen Dollard February 23, 2022 1:04 pm
         collapse this comment
         
         
         > Your #3 is a good option where NRT is sufficiently protecting your
         > code.
         
         I said that in relation to scenarios where the author of the method
         understands enough of the context where it is used that they think NRT
         is sufficient.
         
         Log in to Reply
         
       
     
   
 * WDS_ACCOUNT® February 22, 2022 7:09 pm
   collapse this comment
   
   
   the though is a situation on which the scope retain value of method;
   
   if( TestMethod(parameters...) ){
    //perform the scope of returning value;
    //value keyword
    x=a+value;
   } else { //[...] }
   
   is there such a thing? then using the !! null checking (aka: Scope Tuple)…
   
   if( !!TestMethod(parameters...) ){
    //the !! indicate the feature of null checking; like a tuple
    //scopex keyword
    x=a+scope0;
   
   if( !!TestMethod(parameters...) ){
    //scopex tuple in action;
    x2=a+scope0+scope1;
   } 
   
   } else { //[...] }
   
   just illustration of idea feature; could avoid boiler plate variables
   declarations;
   
   oh and the TestMethod declaration
   
   dynamic TestMethod(parameters...){}
   
   Log in to Reply
   * Kathleen Dollard February 23, 2022 7:52 am
     collapse this comment
     
     
     I’m having trouble following this. If it is a new feature, I’d suggest an
     issue in CSharplang
     
     Log in to Reply
     * WDS_ACCOUNT® February 23, 2022 8:04 am
       collapse this comment
       
       
       C# 11 Preview: Parameter null-checking
       had only followed illustrating the idea with featured sample codes;
       thanks;
       
       also the github is too complicated then just commenting it;
       
       Log in to Reply
       
     
   
 * artemis ravel February 22, 2022 8:38 pm
   collapse this comment
   
   
   I think NRT is good enough for most scenarios
   
   Log in to Reply
   * Oleg Mikhailov February 26, 2022 4:17 am
     collapse this comment
     
     
     First, NRT is dead, nobody uses it; second, this feature is for run-time,
     not for compile-time like NRT.
     
     Log in to Reply
     * Olivier Spinelli March 9, 2022 1:29 am
       collapse this comment
       
       
       Funny. I use it everywhere in my code base. At start I had to use ! at
       too many places. Nowadays I have nearly none of them.
       I also use them “deeply”, for instance a List<int> will not be serialized
       like a List<int?> and a List<Person> will not be serialized as a
       List<Person?> (where Person is a reference type). Really using it’s a
       real gain.
       
       Saying “NRT is dead” sounds like saying “You don’t need GC”… LOL.
       
       Log in to Reply
       
     
   
 * hitesh davey February 22, 2022 9:05 pm
   collapse this comment
   
   
   Pl, explain why two !! instead of just one ! ?
   
   Also, I realized that in the last 6yrs or so, too many features are added
   aggressively to C# lanaguage. Pl control the language release cycle for the
   major Dotnet release versions only. Give enough time to the developer
   community around the world to get hold of the new features and take advantage
   of them. My observation is that by adding too many features it looks like I
   am writing assembly code, not human-understandable code.
   
   Log in to Reply
   * Kathleen Dollard February 23, 2022 8:23 am
     collapse this comment
     
     
     C# 11 will be released with .NET 7, so we do align the language release
     cycled for C# with major .NET releases. These are preview features we are
     including for those people that want to experiment with the new features,
     and so we can get feedback on these issues.
     
     Log in to Reply
     
   * Julien Couvreur February 23, 2022 1:22 pm
     collapse this comment
     
     
     Re: “Pl, explain why two !! instead of just one ! ?”
     
     In short because we may want to support the same null-checking syntax on
     expressions and the meaning is opposite of !. More details in Jared’s
     write-up:
     https://github.com/dotnet/csharplang/discussions/5735#discussioncomment-2152891
     
     Log in to Reply
     
   
 * Thorsten Sommer February 22, 2022 11:40 pm
   collapse this comment
   
   
   Thank you Kathleen for this article. Since many other commenters do not like
   this feature, I would like to speak up for the silent mass of .NET
   developers. In our enterprise code, parameter null checking will save many
   thousands of lines of code. This feature complements NRT usefully, in our
   opinion. We also don’t agree with the opinion that new features have been
   added too quickly and aggressively in recent years. Each developer can decide
   for himself how fast or slow to adopt new features in his own code. After
   all, there are also the long term versions of the SDK (e.g. .NET Core 3.1,
   .NET 6). In particular, the changes and new language features in recent years
   have clearly improved C# code for us. Modern C# code is easier to read and
   understand and is now closer to Python 3 code. We see this as very positive:
   new employees often have a Python background and thus get into C# code more
   easily. Over the last 12 months, we have seen an interesting development in
   our applicants: There are more and more young developers who apply to us
   explicitly because we write modern C# code. Their motivation? They want to
   learn modern C# to develop games in Unity or Godot later on. This suits us
   and we get motivated employees.
   
   Log in to Reply
   * Gábor Szabó February 23, 2022 12:23 am
     collapse this comment
     
     
     I came to second this opinion. The C# language is one of the most rapidly
     improving languages out there. The only thing that I can argue maybe is
     there are too many language features which are superseded by vastly
     superior ones, and they should be deprecated. Most of these have code fixes
     implemented anyways, so migration shouldn’t be an issue.
     
     I don’t fully support the idea that we cannot set our null checks to be
     applied by default. Arturo before said it well, with the nullable ref types
     feature, the “plain” mode of defining a parameter will be essentially
     obsolete. I think it should be controlled on a project level, as you
     shouldn’t have too huge projects anyways, and opt-in/opt-out is always a
     possible solution. Also, the feature is opinionated enough that it maybe
     won’t be a good fit for all solutions out of the box, maybe not even new
     projects. I myself would like it if there was a way to generate opinionated
     code too for checks. I understand you discarded the idea of using attribute
     to don’t bloat the code, but maybe you could think about a nice way to
     bring in something like more typesafe type aliases? Like I could define my
     own String-like type that is convertible to and from normal strings without
     issue, but would throw in cases I could explicitly define in code. These
     should be special “alias” types, that wouldn’t allocate and would behave
     exactly like the type they alias.
     
     public alias MyString : string
     {
       public MyString(string!! value) { }
     } 
     
     I feel a solution like this would benefit the most and would stay closest
     to what the spirit of C# is and has embraced ever since it was introduced.
     
     Log in to Reply
     
   * Олег Нечитайло February 23, 2022 2:41 am
     collapse this comment
     
     
     Did you look at something like Fody.NullGuard?
     
     It solves parameter null checking and integrates seamlessly with NRT.
     
     Log in to Reply
     
   * Ian Marteens February 23, 2022 3:23 am
     collapse this comment
     
     
     Is “closer to Python 3” a good thing? Python is the worst thing that has
     happened to IT since the previous century.
     
     Log in to Reply
     
   * Cole Brand February 23, 2022 6:33 pm
     collapse this comment
     
     
     I’m here to third Thorsten’s comment. I get that there are a lot of vocal
     devs who would love to just remain on C# 1.0, and the truth is, they can.
     It’s just not a very good experience.
     
     There was a comment about “how can new developers ever learn all these
     things” and the answer to that is the same as it has always been:
     mentorship. If you are complaining about features like these but not
     helping to mentor new developers, then you are not really creating a very
     conducive environment for programming, and that is a problem. We should all
     work together to make development more fun and engaging for everyone.
     
     As to the comments of “but this feature is garbage, I would never use this”
     I have only to say to those developers “please don’t use it. You are free
     to write as many lines of code as you would like. The runtime that you are
     running on will still use this feature and you will never know that they
     didn’t write as many lines of code as you did, and that’s ok too.”
     
     I for one am excited about this feature and looking forward to using it.
     Saving 20k lines of code is enough of a blessing for me to take it as a
     good sign.
     
     I love the new upcoming features. Haters gonna hate. Y’all keep inspiring
     us! We look forward to it!
     
     Log in to Reply
     
   * Brad Bodily February 24, 2022 11:29 am
     collapse this comment
     
     
     There are many considerations that go beyond my typical use cases, I’m
     sure. However, I think of the many, many times I’ve written the same code
     at the beginning of so many methods, and then I see this statement, “It was
     exciting to learn that the .NET Runtime removed nearly 20,000 lines of code
     using this new null-check syntax,” and I picture how many lines of code I
     could remove, and that makes me look forward to the option of this new
     syntax.
     
     Log in to Reply
     
   
 * JinShil February 23, 2022 2:19 am
   collapse this comment
   
   
   I don’t find these features to be very valuable. I’d prefer if resources were
   instead dedicated to fixing holes in existing features such as calling base()
   in default interface implementations. See
   https://github.com/dotnet/csharplang/issues/2337 and
   https://github.com/dotnet/csharplang/blob/main/meetings/2019/LDM-2019-04-29.md#conclusion
   
   Log in to Reply
   * Kathleen Dollard February 23, 2022 8:06 am
     collapse this comment
     
     
     I suggest that you ping that issue explaining your continuing need, perhaps
     with an example.
     
     Log in to Reply
     
   

 * Page 1of comments
 * Page 2of comments
 * Page 3of comments
 * Page 4of comments
 * Next comment

RELEVANT LINKS

.NET Download

.NET Hello World

.NET Meetup Events

.NET Documentation

.NET API Browser

.NET SDKs

.NET APPLICATION ARCHITECTURE GUIDES

Web apps with ASP.NET Core

Mobile apps with Xamarin.Forms

Microservices with Docker Containers

Modernizing existing .NET apps to the cloud

ARCHIVE

March 2022 February 2022 January 2022 December 2021 November 2021 October 2021
September 2021 August 2021 July 2021 June 2021 May 2021 April 2021 March 2021
February 2021 January 2021 December 2020 November 2020 October 2020 September
2020 August 2020 July 2020 June 2020 May 2020 April 2020 March 2020 February
2020 January 2020 December 2019 November 2019 October 2019 September 2019 August
2019 July 2019 June 2019 May 2019 April 2019 March 2019 February 2019 January
2019 December 2018 November 2018 October 2018 September 2018 August 2018 July
2018 June 2018 May 2018 April 2018 March 2018 February 2018 January 2018
December 2017 November 2017 October 2017 September 2017 August 2017 July 2017
June 2017 May 2017 April 2017 March 2017 February 2017 January 2017 December
2016 November 2016 October 2016 September 2016 August 2016 July 2016 June 2016
May 2016 April 2016 March 2016 February 2016 January 2016 December 2015 November
2015 October 2015 September 2015 August 2015 July 2015 June 2015 May 2015 April
2015 March 2015 February 2015 January 2015 December 2014 November 2014 October
2014 September 2014 August 2014 July 2014 June 2014 May 2014 April 2014 March
2014 February 2014 January 2014 December 2013 November 2013 October 2013
September 2013 August 2013 July 2013 June 2013 May 2013 April 2013 March 2013
February 2013 January 2013 December 2012 November 2012 October 2012 September
2012 August 2012 July 2012 June 2012 May 2012 April 2012 March 2012 February
2012 January 2012 October 2011 September 2011 August 2011 June 2011 April 2011
March 2011 February 2011 January 2011 December 2010 November 2010 October 2010
September 2010 August 2010 July 2010 June 2010 May 2010 April 2010 March 2010
February 2010 December 2009 November 2009 October 2009 September 2009 August
2009 July 2009 June 2009 May 2009 April 2009 March 2009 February 2009 January
2009 December 2008 November 2008 October 2008 September 2008 August 2008 July
2008 June 2008 May 2008 April 2008 March 2008 February 2008 January 2008
December 2007 November 2007 October 2007 September 2007 August 2007 July 2007
June 2007 May 2007 April 2007 March 2007 February 2007 January 2007 December
2006 November 2006 October 2006 September 2006 August 2006 July 2006 June 2006
May 2006 April 2006 March 2006 February 2006 January 2006 October 2005 July 2005
May 2005 December 2004 November 2004 September 2004 June 2004

TOPICS

.NET ASP.NET .NET Core ASP.NET Core .NET Framework Blazor Entity Framework C#
Azure Visual Studio WPF ML.NET Performance Machine Learning F# .NET MAUI
WinForms AI Machine Learning Security SignalR Containers Community Standup .NET
Internals Conversations Game Development Cloud Show dotnet WCF Lifecycle
Debugging Docker WebHooks Networking Maoni Async Concurrency GC TPL Visual Basic
Static Analysis Featured Apache Big Data Spark for .NET IoT Orchard Core SQL
Server GitHub Actions Maintenance & Updates LOH XAML


STAY INFORMED






INSERT/EDIT LINK

Close

Enter the destination URL

URL
Link Text
Open link in a new tab

Or link to existing content

Search

No search term specified. Showing recent items. Search or use up and down arrow
keys to select an item.

Cancel


CODE BLOCK

×
Paste your code snippet
Cancel Ok
What's new
 * Surface Pro 8
 * Surface Laptop Studio
 * Surface Pro X
 * Surface Go 3
 * Surface Duo 2
 * Surface Pro 7+
 * Windows 11 apps
 * HoloLens 2

Microsoft Store
 * Account profile
 * Download Center
 * Microsoft Store support
 * Returns
 * Order tracking
 * Virtual workshops and training
 * Microsoft Store Promise
 * Flexible Payments

Education
 * Microsoft in education
 * Office for students
 * Office 365 for schools
 * Deals for students & parents
 * Microsoft Azure in education
 * Education consultation appointment

Business
 * Azure
 * AppSource
 * Automotive
 * Government
 * Healthcare
 * Manufacturing
 * Financial services
 * Retail

Developer & IT
 * Microsoft Visual Studio
 * Windows Dev Center
 * Developer Center
 * Microsoft developer program
 * Channel 9
 * Microsoft 365 Dev Center
 * Microsoft 365 Developer Program
 * Microsoft Garage

Company
 * Careers
 * About Microsoft
 * Company news
 * Privacy at Microsoft
 * Investors
 * Diversity and inclusion
 * Accessibility
 * Security

English (United States)
 * Sitemap
 * Contact Microsoft
 * Privacy
 * Manage cookies
 * Terms of use
 * Trademarks
 * Safety & eco
 * About our ads
 * © Microsoft 2022

Notifications