Looking Ahead to C# 7 with Mads Torgersen

Play Looking Ahead to C# 7 with Mads Torgersen

The Discussion

  • User profile image

    The generalized "is" statement at 31:19 is just like the ability to declare a variable in any statement that didn't seem to make it into C# 6. Why not just finish that feature and add this as a new use case for it?

    Touching at 49:43 on the commentary about how Swift is "harsh" about how it treats null. The biggest "harsh" parallel in C# for me is the ban on unsafe iterator and async methods. It is arbitrary and I have to write tons of boilerplate to get around it, which is what I'm using C# to avoid in the first place! If I'm daring enough to declare pointers, that should settle it.

  • User profile image

    Tuples, pattern matching, state machines, extension properties, ref returns/locals, array views/slices oh my!! Almost everything I want everyday in fluent scientific API design with C#. Throw in GADT's, move semantics, and C#/AMP and you're done with v7! :)

  • User profile image

    Although all that was discussed was inspired from from other languages, can't wait to have them in C#. Hats off to @Mads (Mads Torgersen) for enthusiastically comparing OO and functional paradigm - closed of operations vs closed set of types. That was good.

  • User profile image

    Well you learn something new everyday. I've been using the null conditional but didn't know you could use it to conditionally call a method (without an if)  e?.m(...). Good stuff.

  • User profile image

    Isn't ArraySegment<T> already implementing array slices? Or is it planned to put it into C# as a language feature? Or are there differences between ArraySegment and array slices I just dont know?

  • User profile image

    The reason I like tuples is for stuff that might fail.

    Let's suppose that you have a method which connects to a service of some sort, and can either succeed and bring back data, or fail and bring back an error. How can we represent that in C# today? I can think of 3 ways, all bad:

    1. Throw an exception, which is bad because it goes against the idea that exceptions are for exceptional circumstances.
    2. Return a value which indicates the status of the method (a la DateTime.TryParse(string input, out DateTime result)), and use an out parameters, which is bad because out parameters are ugliest monstrosity ever.
    3. Put a status property on the object which is returned (a la WebClient.GetResponse(....)) which is bad because the status of the request becomes conflated with the state of the object.

    Compare any of these with something like (excuse the psuedo-ish code)


       (Data d, Status s) GetDataFromService(....)
    // called like so
       (Data d, Status s) = GetDataFromService(....)
       if (s.Ok)

  • User profile image

    @electricninja33: Yes, the pattern version of the "is" operator is another way to introduce a variable inside an expression. We need to figure out all the same things as we did for "declaration expressions", such as what is the scope for the variables etc. They are not exactly the same feature, though, and I can actually imagine us adding both.

    @electricninja33: Some caution is warranted around unsafe and iterators/async. We may have erred too far on the side of caution, though, and blocking valid useful scenarios. Can you raise an issue with a bit more detail on github.com/dotnet/roslyn and maybe post the issue# back here to close the loop? Thanks a ton in advance!

    @dcuccia: whoa, wanna save some good stuff for C# 8, right? ;)

    @VivekRagunathan: glad you liked the duality bit. This has actually been a target of academic study for decades. Some good references may be found in this paper, written by some weirdo professor type I knew once.

    @mjjj: We didn't initially realize the utility of this for invoking delegates or void returning methods, and our first prototype didn't allow it. We started out calling it the "null propagating" operator, so if there was nowhere to propagate to, what would be the use? :). Luckily we got our minds on the right track, thanks in large part to community discussion on CodePlex, and tweaked the feature in the direction of "null conditional".

    @T_D: Yes, ArraySegment<T> is that. It is barely being used, and we wonder why. We want something that is a little more general and efficient, and can for instance serve as a window onto unmanaged memory. We may or may not add language syntax for the type, or for the slicing operation. We'll see when our thoughts are a little further along.

    @JohnLudlow: Great example! Especially when you think about writing the async version, right? At that point out parameters go from a bad option to not an option at all.

  • User profile image

    I may be a minority voice on this so I would appreciate it if others voiced their opinions here as well but I think "should (not) be null" is one of those things that would be a regret in the future. I do like the choice of `?`and `!` as flags but I feel that the "may be null" case should be implicit so it works with existing libraries. I predict that the concept of "should not be null but could maybe possibly be null I guess" is going to be problematic for many users and will likely be disabled by most users after a while. Consider the following example method:

    // in some other assembly
    class ThingWithStuff {
        public string Stuff;
        public void DoStuffToStuff(){ /* ... */ }
    class Program {
        void Main(){
            string! pleaseDontMakeMeNull = "test";
            var thing = new ThingWithStuff{
                Stuff = pleaseDontMakeMeNull
            pleaseDontMakeMeNull = thing.Stuff; // warning

    In this example I expect that I and many other users will get a compiler warning that we would interpret something like this:

    Warning 12345: Attempt to assign a value that may be null to a variable that would be pretty upset if you gave it null but it won't say anything about it at the time but will totally be passive aggressive from now on.

    This is an example scenario where I think the `#pragma warning disable 12345` would start to get littered around the code or we would disable that feature in the compiler/analyzer completely if possible.

    Instead I would much rather see the `?` behavior just be what we already have today and have the `!` behavior be "null is absolutely not permitted" so that you can not actually assign null. Converting from `string` to `string!` could possibly be a cast that would throw at run-time. I know there are lot of issues with this regarding initializing default values and possible run-time changes, so it is not an easy thing to do. That said I would much rather see this behavior in C# 8 and done right or at least better than rushed into C# 7. I also think that what is being discussed for C# 7, without an actual guarantee or restriction, would be better handled by Code Contracts .

  • User profile image

    @aarondandy: this is a great observation. We've had a lot of design discussion around interaction between existing code (compiled without the new null feature) and new code, and we have some ideas for how to avoid situations like you describe. The main idea is that operations involving existing types (which are in a sense both nullable and non-nullable) do not generate warnings. Your program above would not yield a warning on the assignment you indicate.

    This means that when it comes to interacting between todays null-unsafe code and tomorrow's somewhat-less-unsafe code we would sacrifice safety rather than yield spurious warnings.

  • User profile image

    The null checking is quite scary to me. The ! idea is sound but it is disgusting on syntax. The idea to make the default non-null would be cool if this was C# 1.0 but not now. You have to either skip some warnings, spit a lot of warnings or add a flag for old code. Option 1 is confusing for the user because he won't know when he can depend on the compiler to check the nulls. Option 2 is directly bad since warnings are not much different from introducing an error and that amount of warnings is just insane. Option 3 is bad because it turns perfectly fine code into legacy code in 1 second when C# 7.0 is released. I know I'd be quite annoyed by the feeling of guilt you will bring upon me. And what about all the learning materials out there? Suddenly newcomers can't even compile that code. I'd rather not have any null checking feature than have any of the current options.

    BTW pattern matching and tuple/record syntax have been my top requests for C# since C# 5.0. I am glad they are coming.

  • User profile image

    @Stilgar: Those are our worries too, and one of the reasons we haven't done this in the past. I agree that '!' everywhere is ugly. I'd rather not have the feature than recommend that! Here's the way that I think about it:

    I think nullable reference types is the most important part of the feature. Since this is new (and uncontroversial) syntax, it doesn't break anyone's existing code in and of itself - not even with a warning. They way we would make it work is, that if you dereference one of those - say a "string?" - we would give you a warning only if we can't see you checking for null. We will do a flow analysis similar to definite assignment, and if for instance you are inside an if-statement and have just checked that the thing is not null, then we're happy to let you dereference without warning.

    This means that if you add '?' to any member, for instance, you will get warnings in the places where that member is dereferenced without first being checked for null. You can then go and insert null checks, and we will probably also have syntax to let you easily override if you know it is not null. (In fact we would probably use '!' for that - as in 'p!.Name', where 'p!' means p assumed to be non-null. (I suspect it will be known as the "dammit!' operator).

    Non-null reference types are actually less important I think. They prevent fewer mistakes: they prevent assigning null into something. Ok. And they would prevent forgetting to initialize a member that's supposed to be non-null (but whose initial value is null) in a constructor. I don't think this warrants its own new syntax, especially due to the damage it would do to the beauty of code.

    I think a number of people will want to say: well I marked all my nullable types, I think. Can you please check that I use the rest in a non-nullable manner? If I don't, I may have forgotten to mark some, or I may have found a bug.

    I'm quite open to that check being opt-in - maybe it's even a Roslyn analyzer, not something the compiler does.

    There's a lot more subtlety still. The design notes etc. on GitHub, however messy and as-you-go, are the best source of the full discussion we've had.

  • User profile image

    @MadsTorgersen:Right! Forgot to raise that (you even mentioned async not supporting out parameters in the video).

    @aarondandy: If we forget backward compatibility for a second, defaulting to non-nullable for ref types is IMHO the right choice (with some sort of modifier like the ? suffix for switching on nullability) when you need it. It'd be nice to get to a point where I don't have to remember to put the ! on everything, because you just know I'll forget. It'd be nice if getting there didn't require a whole new language.

    The way to get there without a whole new language (which has probably been suggested in the discussions) is probably through some type of compile-time option. Mads talked about some sort of warning (which will often be ignored) or Roslyn checker (a la Dustin's C# Essentials). I think a code analysis rule (which can be made to trigger compiler warnings, errors, or just be ignored, on a project-by-project basis) probably gives the right semantics.


  • User profile image

    @MadsTorgensen So you think the nullable reference may be useful without the non-nullable part? It always seemed to me that it would be useless without it but I never gave it much thought. I do read the design notes from time to time and occasionally comment on them. The nullability tracking ones always scared me. The psychological aspect of declaring all code out there legacy even with a compiler flag is just too much. Now Roslyn analyzer is certainly less intrusive and may be a good idea but still would you put it in new projects by default? If you do it is not much different from a compiler flag, if you don't will people use it enough to justify the investment in this feature and the introduction of nullable reference types? And again what about all the courses and tutorials? I notice people in discussions about new features easily dismiss that last part. I think it is really serious since C# is already been criticized for becoming too large and complex and hard on beginners and for the long-term survival of the platform the community should not lose new members to stuff like Node and Go. Frustrating newcomers is not a non-issue.

  • User profile image

    @MadsTorgersen: What will happen with the existing APIs that use out parameters when tuples are introduced? Do you think it's possible for the compiler to make calls to these APIs look like the tupled versions? I think F# compiler does something like this

  • User profile image

    I'm curious, but when can we have metadata as a first class citizen in the language? I see an interface as a version of this. Just as you create an interface file, you create a metadata file, which states it's contract (interface) communication channels, type, parent, property constructs and type rules, so on and so on, etc. Config file for data. That way you can program effects logically because of the metadata using the data state, instead of the other way around.

    Something like this would help entity framework. Class is the data holder and it's metadata file holds it's indexes, alternative indexes, descriptions and history locations, etc.

    In the web, it would be awesome to have the metadata move along with the data. It would even enable binary data sent instead of json as the metadata tells you how to hydrate it.

    I'm a rectangle, not because my class name says so, but because my metadata says my label is such. Intellisense on what data you are allowed to list together instead of methods, no more null checks as metadata says it can't be null, rules on what (class, construct, type, etc) operations this is compatible with.

    So maybe not then, as I the more I think of what it could do, there is not much to say what it cannot do.

  • User profile image

    C# 7 is looking good! I do see a trend to borrow from Swift, which is good because swift is really awesome.

    Indeed, you should be careful about implementing "optional" variables (i.e. string? someString). Swift can step on a nerve or two due to it's restrictions.

  • User profile image

    @Stilgar: We won't do something that feels like a breaking change. If that's the best we can do, we won't do it. I'm not hell bent on the nullability feature. I'm determined on chasing it all the way to the best we can possibly do. If that's not good enough, then we'll put the feature to rest knowing that it just doesn't have a place in C#.

    @PurityControl: It's a great idea to allow functions with out parameters to be called as if they were tuple-returning, having the compiler do the magic like in F#. Another possible convenience is allowing a tuple to be passed to a function that can take the individual members of the tuple as arguments.

    @N2Cheval: Sounds like a big feature. We'd probably need to see a somewhat more fleshed out proposal to understand what you are getting at. But I have to say that reifying more metadata at runtime is not the direction I see us going. On the contrary, with native compilation we are challenged by the ubiquitous access to even the metadata that is there today. But maybe I'm misunderstanding the proposal.

    @Alex: I don't think it's borrowing from Swift as much as borrowing from the same places that Swift is borrowing from. :) However, I see Swift doing something we've also often done, which is to take concepts from less widely adopted languages and pulling them into the mainstream. Option types (or "optional types" as the Swift guys call them, which irks me because that used to mean something else) are a well known pattern from functional languages that Swift has - rather successfully I think - integrated into a more imperative setting, and found a way to blend with the legacy Objective-C libraries. That integration depends heavily on pattern matching to do the null checking (like in the functional languages it comes from). I don't think we have that option (no pun intended), because we already have established ways of checking for null in C#. Any feature we do here would have to recognize when folks are checking for null, rather than force them to do it in a new way. That would be a disaster!

  • User profile image

    Hi all, Mads,

    Have been watching Ch9 for years and years, but never found it necessary to post a comment so had no profile until now. This episode had something special, that is your 'duality' comments. Completely agree with vivekragunathan comments on this. Having watched many shows on functional programming, well, I just never got the point, like F#, who needs it? And WHY?

    Now I know, great, but still won't go there, it will come to me |-)

    Reading all your comments, I am sure you'll pick the right final imp here and love the other things coming.

    As for the dammit! operator, well, I've been using that for years:

    // Code checked but still has bugs!


    // Todo!



  • User profile image

    Ya I think to that not nullable type is a little bit scary, as @Stilgar said it would be cool for a new lenguage or stuff like that.

    I more see not nullable type be used for different think like, correct If I'm wrong, where used in slightly changed C# lenguage (Spec# ??), when singularity OS were made, in that scenrio not nullable type would have been a must to have.
    Any way have you never think of introducing a comcept of range variable? I mean a variable that can assume value in a range specified by the user, like with an attribute, that throw automatcly an exception if the bound are crossed?

    [InRange(0, 6)]
    int A = 5;
    I = 10 //Throw and exception

    I know it would require a CLR changes but for a new version of both for me seem a good idea!
    And I also read, are you still think to params in generic types like IEnumerable?It would simplify a lot of code.

  • User profile image

    Great video, this is a truly great time to be learning c# - so many awesome resources available for your study. I'm loving it.

  • User profile image

    I'm a big fan of Functional enhancements but I would put all them aside for the performance enhancements you speak of.  Much less copying, pointer returns, Native Buffers, all that sounds great.  I even wrote my own buffer wrapper around VirtualAlloc so I could get aligned memory that worked super fast with file system pinvokes.  Was working on a super fast .net persistent queue and write ahead log.  To be honest I would love to see tons more performance related enhancements to the language.

  • User profile image

    The discussion about nulls highlights how difficult it will be for C# to change some fundamental core characteristics. Every time I hear about what features C# 7.0 may have, I realise just damn good the design of F# is!

    Some C# developers tend to salivate when they think that features such as pattern matching or a simplified tuple syntax may be added to the language, but can't bear the thought of using F# where these features and a lot more are the norm. Just use both languages. They are both great languages and tend to complement each other.

  • User profile image

    Agree with @AceHack - bring on the performance enhancement features!

  • User profile image

    I just have to wonder how these features will play nicely with F# considering these features already exist there. It wouldn't be very nice if we have a period where I'm trying to interop with F# code via C# and vice versa and I have to "match" two different ways depending on where the type came from; or write workaround functions to match F# patterns in C# code and vice versa. If your allowing us to match on objects (such as DU's) it would be awesome if this syntax could interface with my F# types naturally especially since that language already has these features. If I can interop with patterns, tuples, etc both ways (i.e can match on F# unions and such and F# can do so on C# types) it would make life that much easier for developers that have their feet in both languages. Maybe it will yield some benefit to collaborate with the F# developers?

  • User profile image

    I want c# feature to automatically convert Singlecore-Processor program to Multicore-Processor program. Now there is quad core & 8 core processors available. These processors are even available on mobile. I want c# to go big, feature that has never been available, neither on c# nor on any other programming language.

  • User profile image

    @dcuccia: whoa, wanna save some good stuff for C# 8, right? ;)

    @MadsTorgersen, I suppose. ;) Maybe extension operators, then?

  • User profile image

    @AnilApex: There's no such thing as a "single core" or "multi-core" program. Any multi-threaded program will use as many cores as it can. And there's no magic a compiler can do to turn a single threaded program into a multi-threaded program.

    @MadsTorgersen What happened to the contract ideas? Are we going to go yet another release without DbC support in the language? Why? Even the C++ committee is looking into this. For others, yes I'm aware of the Code Contracts framework from the research group, but there are many reasons why that just doesn't cut it. Chief among them is that no "third party" or "add on" solution is going to work... we need contract usage to be pervasive, which means it must be part of the language. The IL rewriting solution is also problematic... we need contract's implemented at the compilation phase.

  • User profile image

    what about multiple return results like Go

  • User profile image

    Lots of great features discussed, but the one that got me most excited was the idea hinted at around 46:00 of being able to back .NET structs/arrays with unmanaged memory. This would be absolutely huge for interop heavy code, where you are constantly doing Marshal.PointerToStructure and back again. I'd love to be able to declare an unmanaged block of memory, and map various C# structs or arrays over various parts of it. This would give a big performance boost and code simplification in my NAudio library. Currently I am using rather hacky methods like this to eliminate copying between byte[] and float[] for example.

  • User profile image
    Michael Logutov

    @MadsTorgersen Why not just make some syntax directive that marks file as "reference as not null by default"? Like javascript "use strict".

  • User profile image
    Michael Logutov

    Or maybe use attributes like ReSharper's NotNull/CanBeNull? Attributes (there are far more than those two) actually helps a lot with proper static analysis - I wish it was the core feature of the language.

  • User profile image

    ;) What about optional semi-colons;

  • User profile image

    This is super exciting stuff for someone who really enjoys f# concepts, but writes c# at work like myself.

  • User profile image


Add Your 2 Cents