

C# 6: First reactions - yulaow
http://msmvps.com/blogs/jon_skeet/archive/2014/04/04/c-6-first-reactions.aspx

======
bruceboughton
I'm not sure of this direction. It looks like a rather large syntax explosion
to cover a bunch of corner cases. C# doesn't want to become Perl. That's my
initial gut feeling but perhaps that will change.

Does anyone know what the dollar syntax is? Similarly, the new dictionary
initialiser syntax? Fisnlly, what is private protected?

Edit: these are from
[https://roslyn.codeplex.com/wikipage?title=Language%20Featur...](https://roslyn.codeplex.com/wikipage?title=Language%20Feature%20Status&referringTitle=Documentation)

~~~
gambler
I feel the same way. Too many corner cases, not many I deal with very often.

So far null propagation seems like the most useful feature for cleaning up
cluttered code I'm used to dealing with.

Auto-property initializers are nice, but the syntax looks a bit ugly and I
don't see them making that big of a difference in readability. I would rather
see something that tackles the ugly-but-necessary construct I see the most:
lazy-loading getters. Generic memorization of methods and properties would be
even more useful. And yet even more useful would be something that could be
used for both memoization and transparent caching:

    
    
      [Cache(For = 1000 /*milliseconds*/)]
      public GetSomethingFromDB(){ ... }
    

That would be tough to implement well, though. Unless they added Python-like
attributes. Which would give us memoization, caching an a myriad other things.

~~~
bruceboughton
Lazy<T> is quite useful for lazy-loading/memoization.

~~~
gambler
Yes, but cleaner syntax for it would be nice. Right now it looks quite messy:

    
    
      private Lazy<string> _someVariable =new Lazy<string>(SomeClass.IOnlyWantToCallYouOnce);
      public string SomeVariable {
        get { return _someVariable.Value; }
      }
    

Imagine the same things with a long lambda inside.

------
Pxtl
I looked at this earlier - on the one hand, I like that they're directly
tackling known pain-points in the language. The declaration expression "out
var x" thing is, imho, great. The TryParse syntax has always been a problem
because you have to declare the variable the line before, which means no type
inferencing and whatnot. Also, good for casting as they show.

Using static is great - finally we've liberated the verbs in the kingdom of
nouns.

However, some of them have _really_ ugly syntax. I know they wanted to get rid
of the boilerplate problem of declaring and setting into a read-only member,
but the primary constructor syntax is monstrous - declaring local variables
_inside_ of your constructor? Really? I feel like just having a "readonly set"
access modifier on properties (both auto and explicit) would have been
sufficient.

The new dictionary accessor seems silly.

Exception filters seem just as pontless in C# as they did in VB (nesting an
"if/else throw" into a catch clause wasn't too hard).

The crazy null ?. operator I'm unsure about... that one I'll have to use. I've
run into the problem enough times to see why they did it, though.

~~~
theflagbug
Exception filters aren't pointless. They preserve the stacktrace, meaning the
debugger will break at the original throw and not the throw; in your catch
(I'm on mobile so I don't have a code sample, sorry, I hope you get what I
mean)

~~~
Pxtl
Throw in a catch block with no exception argument preserves stack-trace.

That is

catch(Exception ex) {throw;}

Rethrows without meddling with ex.

~~~
Locke1689
_Throw in a catch block with no exception argument preserves stack-trace._

No it doesn't. If you then let that exception fall out as unhandled, the stack
trace will be centered on the second throw, not on the original.

~~~
ColinDabritz
This case is confusing and a lot of people miss the subtle difference.

In one case you

try { Throws(); } catch(Exception ex) { DoHandling(); throw ex; } // BAD!

This one does lose the initial site of the first exception, and throws it as a
new exception at this location, centering the stack trace on this line.

This is what you want to do:

try { Throws(); } catch { DoHandling(); throw; }

Notice you do not name, or capture the exception. This causes your handling to
execute, but crucially it re-throws the original exception untouched, with the
original stack trace, centering on the original exception thrown location.

So you can easily lose that information if you re-throw naively. Good code
tools should yell at you for doing this most of the time. Note in some cases
you want to add information, so you can throw a new exception with new
information, but set the InnerException property to the original causing
exception.

See [http://msdn.microsoft.com/en-
us/library/system.exception.inn...](http://msdn.microsoft.com/en-
us/library/system.exception.innerexception.aspx)

~~~
Locke1689
This case _is_ confusing and both you and the documentation are wrong. :)

You're confusing the Exception.StackTrace with the actual CLR stack trace. The
minute you catch an exception in the CLR the accurate trace is destroyed. This
is pathological for crash dumps, where it's imperative that you have an
accurate trace for debugging.

If you don't believe me, go into VS and do the following.

1\. Throw an exception.

2\. Make sure that exception is not listed in exceptions to break on.

3\. Catch and rethrow that exception using "throw;".

4\. Let that exception filter out of the program unhandled.

5\. Run in debugger.

Notice where your stack trace is centered on -- the "throw;" call.

~~~
ColinDabritz
Well huh...

I appreciate the further information, I did try this myself, and the
difference is more clear now. The exception object had the StackTrace with the
right info, but the debugger highlights the throw; line.

If the Exception.StackTrace has all the juicy details, why on earth not break
there?

Yes, I was certainly thinking about the information available in the exception
object itself. It's odd that it's set up this way, but I get it makes sense
semantically, if other handler code has run, you need to trace things back
yourself probably with a debugging step-through session, or turn on 'first
chance exceptions' to get the most 'on the ground' information.

To break immediately on an exception before handlers are invoked:
[http://msdn.microsoft.com/en-
us/library/d14azbfh.aspx](http://msdn.microsoft.com/en-
us/library/d14azbfh.aspx)

In the spirit of learning, Thanks for your contribution!

~~~
Locke1689
Yup, as I said, the problem is crash dumps. If this only affected debugging it
would be a minor annoyance, but it destroys information in client crash dumps
which get delivered by Watson, effectively making dumps useless.

Exception filters run before the stack is unrolled, so if you crash your
process in an exception filter the stack is preserved.

------
Hominem
Seems like 6.0 is all about reducing boilerplate. Those default constructors
and null checking will probably save me hours of typing as the ctor that does
nothing but set stuff and null checking properties all the way down are such
common code patterns.

------
jksmith
Hjelsberg is continuing the tradition from Delphi that "less is less." Golang,
stay disciplined and focused my friend.

------
zwieback
Looks good but I don't know if I'll be able to keep these fresh enough in my
head to be able to use these things without looking them up. Trying to keep up
with the explosion of features in the curly brace languages starts getting
really hard. Moving between low level FW (C), desktop apps (C++/C#) and
Android (Java) something will have to give, my code will probably continue to
just look really 2005-ish.

I really like the what the monadic null checking does but aesthetically it
looks pretty ugly right now.

------
Locke1689
Thanks for the feedback, Jon!

FYI, we have discussion threads on
[http://roslyn.codeplex.com](http://roslyn.codeplex.com).

------
platz
This is perhaps a bit trollish but hopefully someone will get some enjoyment
out of it.

[http://tomasp.net/blog/2014/csharp-6-released/](http://tomasp.net/blog/2014/csharp-6-released/)

~~~
bananas
Great read actually and definitely on topic - thanks for posting :)

------
Spearchucker
Not as familiar with C# as I am VB.Net, but this (the before scenario) strikes
me as a little odd (incorrect, or not the whole story, maybe?):

 _Readonly properties require less syntax._

Before

 _private readonly int x;

public int X { get { return x; } }_

The only scenarios where I require _readonly_ properties are where I set or
otherwise calculate a private variable at runtime, and then enforce readonly
to the public getter.

In the example above, it looks like the private variable is readonly, and must
therefore be initialized with a value that cannot be changed. Am I reading
this correctly?

~~~
gnaritas
Yes; they can only be written to by a constructor.

------
louthy
I think Declaration expressions are a mistake and proper support for tuples
(and pattern matching) shold have been put in. It feels like an inbalanced
expression with the result on the left and the right:

    
    
        var success = int.TryParse(s, out var x);
    

I'm a bit 'meh' about Primary constructors, Auto-property initializers,
Getter-only auto-properties. It seems a bit messy and incomplete. Personaly I
don't use properties anymore and just use readonly fields with constructor
initialisation (which is enough to capture the property setting logic). What I
would like to have seen in this area is 'readonly' classes, with mechanisms
for cloning objects using named parameters for partial updates:

    
    
        readonly class ReadOnlyClass(public int X, public int Y, public int Z)
        {
        }
    

Usage:

    
    
        ReadOnlyClass obj = new ReadOnlyClass(1,2,3);
        ReadOnlyClass newObj = obj.X = 10;
    
    

Instead of the current system for creating immutable classes in C#, which
becomes quite unweildy and error prone as the number of fields grows.

    
    
        class ReadOnlyClass
        {
            public readonly X;
            public readonly Y;
            public readonly Z;
    
            public ReadOnlyClass(int x, int y, int z)
            {
                X = x;
                Y = y;
                Z = z;
            }
    
            public ReadOnlyClass SetX(int x)
            {
                return new ReadOnlyClass(x, Y, Z);
            }
    
            public ReadOnlyClass SetY(int y)
            {
                return new ReadOnlyClass(X, y, Z);
            }
    
            public ReadOnlyClass SetZ(int z)
            {
                return new ReadOnlyClass(X, Y, z);
            }
        } 
    

Usage:

    
    
        ReadOnlyClass obj = new ReadOnlyClass(1,2,3);
        ReadOnlyClass newObj = obj.SetX(10);
    

I think 'using' static members will be a huge win for creating functions which
appear to be part of the language. For example I use the following to do type
inference on lambda expressions:

    
    
        static class lamb
        {
            public static Func<T> da<T>(Func<T> fn)
            {
                return fn;
            }
        }
    
        var fn = lamb.da( () => 123 );
    

I'v tried to make it look like part of the language by making it all
lowercase, but it's still a little odd. Being able to 'using' a static class
in would be perfect for this kind of stuff. To be used sparingly obviously.

Expression bodied members, yes please! So pretty...

    
    
        public double Dist => Sqrt(X * X + Y * Y);
    

Typecase and Guarded Cases would be lovely too. Basically anything that
enables expression based coding in C#. It would be nice if the LINQ language
functions were extended too: count, take, skip, tolist. It's slightly less
pretty when having to wrap the expression in brackets to call .ToList();

~~~
Hakeashar
I would _love_ to see pattern matching and at least _some_ kind of tuple
support. I don't know if it's ever going to happen in C# though...

The `using` static is actually really good news. I have seen people who seem
to be really mad about it, but sometimes it would be nice to have, for
example:

    
    
        // Something like Scala's 'Predef'
        public static class Id<T>
        {
    	public static Func<T, T> Identity { get {  return x => x; } }
        }
    

and then do:

    
    
       using Id;
    
       var grouped = list.GroupBy(Identity);
    

Considering you can already open modules in F# (which are compiled down to
static classes), it seems that feature found its way to C#. So _maybe_ there
is still hope for pattern matching and tuple support :)

Equivalent of F#'s record types would be also awesome, which is what you put
as 'readonly class':

    
    
        type Person = { FirstName : string; LastName : string }
        let single = { FirstName = "Jane"; LastName = "Doe" }
        let married = { single with LastName = "Smith" }

~~~
louthy
Agreed on all counts . Not sure what the C# team's desire is for another
classification mechanism (record types), but it could be seen as an
opportunity to fix some of the problems of the past (mutable types, nullable
object references).

Perhaps C#'s record type could enforce immutability on not just the record but
anything it's assigned to (maybe by using 'let'). That would allow the old
mutable way to co-exist with language enforced immutability. It doesn't seem
like it would clutter up or modify any existing code either, so if you don't
like it, you never need to see it.

Not sure how that would work when assigning to a class's member
property/field. Perhaps you opt out of immutability (of the reference) with a
'mutable' keyword:

    
    
        class AClass
        {
            public mutable ARecordType Value;
        }
    

Functional languages also 'extend' the behaviour of a type by defining
functions that work with the type. But with an object-oriented language like
C# you'd still expect the functionality to come with the type I think. So I
suspect it would have to look something like this:

    
    
        type Vector
        {
            float X;
            float Y;
            float Z;
    
            int Length => Math.Sqrt(X*X+Y*Y+Z*Z);
    
            Vector Add( Vector value ) => new Vector { X+value.X,Y+value.Y,Z+value.Z };
        }
    

So it turns the entire class into one big constructor (with everything public
by default). All non-expression fields should be provided when you instantiate
the object:

    
    
        let obj = new Vector { X=1, Y=2, X=3 };
    

I'd be very happy with that. Maybe I'll fork the compiler and have a go... if
I can just find the time.... gah

------
AndrewDucker
Is there a list anywhere of all the new functionality?

~~~
_random_
Yes, of course:

[https://roslyn.codeplex.com/wikipage?title=Language%20Featur...](https://roslyn.codeplex.com/wikipage?title=Language%20Feature%20Status&referringTitle=Documentation)

~~~
MichaelAza
Some of these seem undocumented anywhere that I could find.

I posted an SO question about some of them, if anyone has any input on the
matter: [http://stackoverflow.com/questions/22881465/what-do-these-
ne...](http://stackoverflow.com/questions/22881465/what-do-these-new-c-
sharp-6-features-do)

~~~
fekberg
I've written a little bit more about them using the examples from CodePlex on
my blog ( [http://blog.filipekberg.se/2014/04/04/microsoft-open-
sources...](http://blog.filipekberg.se/2014/04/04/microsoft-open-sources-c-
compiler/) ).

There were also some interesting discussions on the C# sub-reddit:
[http://www.reddit.com/r/csharp/comments/225g4b/microsoft_ope...](http://www.reddit.com/r/csharp/comments/225g4b/microsoft_open_sources_c_compiler/)

Hope that helps and answers some of the questions you have!

------
greatdox
Well it is nice that C# 6 becomes cross platform, can someone please explain
to me the license behind it?

Microsoft usually does the license thing that takes away some of your rights.
Is it the Apache2 license or something else? What are the limitations on this
project?

Thanks in advance.

~~~
danabramov
The new compiler is Apache 2.

------
django-fanboy
What ever new feature C# includes, people will still hate it, whatsoever.

