Probable C# 6.0 features illustrated
- š
- š 883 words
- š 4 minutes
- š¦ .NET
- š·ļø C#
- š¬ 79 responses
C# 6.0 is now available and the final list of features is well explainedĀ by Sunny Ahuwanya so go there and try it with his interactive samplesĀ page.
Adam Ralph has a list of the probable C# 6.0Ā features Mads Torgersen from the C# design team coveredĀ at new Developers Conference() NDC 2013 inĀ London.
I thought it would be fun to show some before and after syntax for comparison and in doing so ended up with a few thoughts andĀ questions.
1. Primary Constructors
Shorter way to write a constructor that automatically assigns to private instanceĀ variables.
Before
public class Point {
private int x, y;
public Point(int x, int y)
this.x = x;
this.y = y;
}
}
After
public class Point(int x, int y) {
private int x, y;
}
Thoughts
- Do you need to independently define x andĀ y?
- Can you still write aĀ body?
- How would you make the defaultĀ private?
This solution feels too constrained, would have preferred somethingĀ like:
public Point(set int x, set int y)
That set the property and optionally created a private one if it didnāt. Would allow bodies, use on multiple constructorsĀ etc.
2. Readonly autoĀ properties
Readonly properties require lessĀ syntax.
Before
private readonly int x;
public int X { get { return x; } }
After
public int X { get; } = x;
Thoughts
- Love this.
- Very useful for immutableĀ classes.
3. Static type usingĀ statements;
Imports all the public static methods of a type into the currentĀ namespace.
Before
public double A { get { return Math.Sqrt(Math.Round(5.142)); } }
After
using System.Math;
public double A { get { return Sqrt(Round(5.142)); } }
Thoughts
- Not something Iāve run into often but no doubt very useful for Math-heavyĀ classes.
- Could be useful for Enumerable LINQ-heavy classes if it works with static extensionĀ methods.
4. Property Expressions
Allows you to define a property using a shorthandĀ syntax.
Before
public double Distance {
get { return Math.Sqrt((X * X) + (Y * Y)); }
}
After
public double Distance => Math.Sqrt((X * X) + (Y * Y));
Thoughts
- Small but useful syntaxĀ reduction.
- Has nothing to do with System.Linq.Expression despite theĀ name.
5. Method Expressions
Allows you to define a method using a shorthandĀ syntax.
Before
public Point Move(int dx, int dy) {
return new Point(X + dx1, Y + dy1);
}
After
public Point Move(int dx, int dy) => new Point(X + dx, Y + dy);
Thoughts
Same as PropertyĀ Expressions.
6. Params forĀ enumerables
No longer need to define your params methods as an array and force early evaluation of theĀ arguments.
Before
Do(someEnum.ToArray());
public void Do(params int[] values) { ... }
After
Do(someEnum);
public void Do(params IEnumerable<Point> points) { ... }
Thoughts
- Can have params methods for IEnumerable and array side-by-side? ProbablyĀ not.
- Is evaluation deferred until evaluated if you pass a single IEnumerable instead of aĀ params?
7. Monadic nullĀ checking
Removes the need to check for nulls before accessing properties or methods. Known asĀ the Safe Navigation Operator inĀ Groovy.
Before
if (points != null) {
var next = points.FirstOrDefault();
if (next != null && next.X != null) return next.X;
}
return -1;
After
var bestValue = points?.FirstOrDefault()?.X ?? -1;
Thoughts
Love it. Will reduce noise in code and hopefully reduce null reference errorsĀ everywhere!
8. Constructor type parameterĀ inference
Removes the need to create static factory methods to infer generic types. This is helpful with TuplesĀ etc.
Before
var x = MyClass.Create(1, "X");
public MyClass<T1, T2> Create<T1, T2>(T1 a, T2 b) {
return new MyClass<T1, T2>(a, b);
}
After
var x = new MyClass(1, "X");
Thoughts
- Another great addition.
- Does it understand list and collection initializers to automatically determine the generic typesĀ too?
9. Inline declarations for outĀ params
Lets you declare the out variables inline with theĀ call.
Before
int x;
int.TryParse("123", out x);
After
int.TryParse("123", out int x);
Thoughts
- Not a particularly large syntaxĀ reduction.
- Shorter code for Try methods andĀ DirectX.
Wrapping up
Hopefully there are a few more gems to come that would help reduce noise. Would especially like to see syntax that wired up an interface to an internal instance variable where not specifically overridden to aid in encapsulation,Ā e.g.
public MyClass : IList => myList {
private IList myList;
public Add(object item) {
// Do something first
myList.Add(item);
}
}
[)amien
79 responses to Probable C# 6.0 features illustrated
WriteLine(Ā«Welcome to my version of Roslyn!Ā»);Ā ā Nothing terrible everĀ seen! Give then add another denotation of theĀ brackets: WriteLine(<>); And maybe even add aliases for commandĀ localizations: alias ŠŠ°ŠæŠøŃŠ°ŃŃŠ”ŃŃŠ¾ŠŗŃ =Ā WriteLine; .. ŠŠ°ŠæŠøŃŠ°ŃŃŠ”ŃŃŠ¾ŠŗŃ(<>);
Until the anounce date of sixth version of the C# language shownĀ promise. Most who picked the language wishes to develop their program in āC++"-like programmingĀ language. Programmers who are wishing to use Scala or F# are very-veryĀ few! Instead of optimizing the compiling code and improve the quality of the language it was created another piece ofĀ trash.
And it increases the readability of theĀ programā¦
At a first glance it might be confused with theĀ delegate
Indexed member initializer:
and indexed memberĀ access
It generally looks like a failed attempt to realize the potential ofĀ DLR. The next step will probably be theĀ following:
But on the other hand, if field values will be stored in dictionaries within the class, then this programming language is generally not necessary. We can use JavaScript. His speed will then be theĀ same.
NameOf operator:
Although perhaps will finally something useful. If you do not think that there are betterĀ implementation..
Looks great. For #1, I like the way TypeScript has doneĀ this:
I love most of this, but the proposed syntax for readonly auto-properties is -- pardon my french -- butt ugly! Why not use the alreadyĀ existing
readonly
keyword?public readonly int X { get;Ā }
Values. Like
var
but cannot beĀ changed.Currently itās impossible to forceĀ this.
I hope none of this makes it to C#Ā 6.0.
I am OK withĀ 7
by quickly looking at 8 scrolling through code you might make the mistake to think you are making an instance of a non-genericĀ class. By using the āvarā keyword you also hide the fact that it isĀ actually
MyClass
and notMyClass
x and y are not compatible with eachĀ other.
I guess 8 is OK if the programmers use it likeĀ this:
To John Bergman:
I do hope the #2 doesnāt makeĀ it!
The point is ā¦ this syntax is confusing and would be better used for something different, for property with automatic backing fieldĀ initialization.
Now if you need such a property to be initialized to a different than the default value you have to do that somewhere many lines away in the constructor and if that property is static, it even has to be a static constructor with is something you are not supposed to have unless you have to according to Analyze Code inĀ VS.
Iād much ratherĀ have
in place of
than ā¦ waitasecond ā¦ what does that example actually mean?!? IsĀ the
really supposed to replace the two lines above? Whatās the āxāĀ then? If you really do care so much on the distinction between the property being āreadonlyā and āwith private setterā, then whyĀ not
I would definitely like to see #6, #7, #8, but I donāt care much for theĀ rest. It would be nice to make it easier to create immutable classes, but Iād prefer a syntaxĀ like
Most needed features are presented in Nemerle language and MS can adaptĀ them. For instance it has get-only properties as expected to beĀ used.
And this is how simple immutable class with constructors and properties looksĀ like:
One scoop of syntactic sugar that I think would be nice to have that is not on the list would be implicit var forĀ iterators. Instead of
or
just simply
...while still allowing the explicitĀ case
Inline out-parameters are nice but why not take it one step further to prevent the use of out-parameters completely; allow return tuples instead like inĀ python.
True anonymous types would be extremely helpful both in TDD and in production code. I would love to be able to quickly stub a dependency or parameter by saying var stub = new IMyInterface { value = āfooā, method => x*y }. This can work well for DTO objects, especially if they are only created and returned form only one or two linq statements, as well and encourage coding to interfaces. This is the only feature Java has that I wish C#Ā had.
Tom Tucker suggestion isĀ good. Today if you have an property that has some logic on int you must declare a private fieldĀ too. The problem is that inside the code of the class, the field can be accessed directly (without going through theĀ property). With Tuckerās suggestion we can write something likeĀ this:
Monadic null checking is very nice, but the others are just syntax pollution. I disliked āusing Mathā the most. Please do not introduce something like this! It has the same drawbacks as using namespace std. Methods are perfectly good wrapped intoĀ classes.
Inspired from functional programming? Most ideas sounds similar toĀ fsharp.
Why is that x introduced on read onlyĀ properties?
Why not simply
And the setter acts like a read-only attribute? The proposed syntax allows for thingsĀ like
and in the constructor you wouldĀ have
which would only bringĀ confusion
is cleaner, simpler, and avoidsĀ confusion.
#6 would be more logical if instead of IEnumerable, params could be used onĀ IReadOnlyList
And, method return typeĀ inference!
@Dave Van denĀ Eynde
Are you sure it doesnāt solveĀ it.
becomes
would more often become written using an extensionĀ method:
Or using the number 3 āStatic type using statementsā it might beĀ written
Lets wait and see how all thisĀ composes.
Suraj Deshpande is right. I felt that the syntaxes presented here are expressed as unreadable statements and they are hard toĀ maintain. Shorthands are supposed to be readable. It would be nice to write a bit more code in order to beĀ maintainable.
#7 is cool and all, but it wonāt make my homebrew Maybe extension method obsolete. Right now I can doĀ this:
Now that would be fine if it was obj?.Property instead, but I use it more often likeĀ this:
I donāt see how this new operator would āfixā that useĀ case.
I cannot stress enough how important what Keith Dahlby said is. I often had beautiful functional constructs that needed to use local variables just because of TryĀ methods.
In other news, I would like to see 4 & 5 combined asĀ well:
Have to agree with Patrick on thisĀ one.
I do like the groovy style null checkĀ syntax.
Algebraic data types, Higher kinded types, curried and partial function support like scala, scala style classes with primary constructors to reduce boilerplate code, type keyword for immuatable which is type checked, type aliases would be cool, enums as generic params as with integers likeĀ C++,
Itās good to see C# evolving. Most of the possible changes are welcome, but I canāt see any true radical changes on the horizon, which for the most part is a good thing. The last thing I would want is to have C# change into some horrible C++ like language, trying to squeeze every type of programming structure into theĀ language. Iāve been using C# since 2004 and feel that it has reached a maturity that wonāt be helped by simply adding features for very littleĀ gain.
People wanting progress to a more advanced and robust language on the .NET platform should simply go to F#. Iāve been using F# now for 3 years and I could never go back to C# as my primary problem solving language. Here is the list the goodness that F# providesĀ ā¦
The above features are what you need in a true 21st century programming language, and are unlikely to be incorporated into C# any timeĀ soon.
Given the massive attack vector it opens Iām okay withĀ that.
{Turns on the news} āThe human race has come together and weāve landed on Mars & C# still doesnāt have stringĀ interpolationā
My idea, a FormatStringAttribute to mark methods that take format strings and then to automate variable interpolation using names instead ofĀ positions.
Could become..
No more having to keep position and argument order inĀ line.
I would love to see more focus on performanceĀ issues. Most of these things are frankly uselessĀ typically.
The only relevant things to meĀ are:
I want toĀ see:
I would also like to see the templateĀ support. Useful for Vectors that need to be either float based or doubledĀ based.
Also things like CPU determined types like IntPtr but for ints andĀ floats. floatx = āfloat on ARM32 or double on x86_64ā³Ā etcā¦ intx = āint on ARM32 or int64 on x86_64ā³Ā etcā¦
Love the list. Will be pondering on this for some time. WhatĀ aboutā¦
Given:
Perhaps:
or
I like #7 most ofĀ all.
But #1 and #9 seems like itāll just cause maintainabilityĀ issues.
At first I saw no point in thisĀ syntax:
However, you need the x to exist so you can pass the property as an out or ref parameter, if that is the way you need to set it in the constructor, so I think itāsĀ great.
@Keith HillĀ ā Itās ākind of likeā but it isnāt, so I donāt think you can use unchecked here. You could use a new keyword, but new syntax might beĀ better.
I think I prefer this over ?., because I think it would be wrong to have code likeĀ this:
Note I started outĀ using
?.
and switched toĀ just.
in that expression. I can think of no valid reason to ever do that, but it seems like an easy thing to do by mistake.Ā The?()
syntax resolves thatĀ issue.My favourites are 4, 5 and 9. Iām wondering if theyāre gonna change the proposed syntax stronglyā¦ I really like this lambdaĀ style.
@LakshĀ ā I live the idea of monadic null checking but I donāt like the syntax. I wish we could do something likeĀ this:
This is kind of like the suppression of integer overflowĀ checking.
I love 7, and actually, itās the only Iād like to see out of the list, no offenceĀ intended.
3 has been supported by VB.NET forever if Iām notĀ wrong.
Would love to see extension properties, enum constraints for generics and a specification of the value type class for numbers, say, NumericValueType. Not to mention,Ā SIMD.
Some of the changes are good. However i think these changes will make the code less human readable. We are not writing code just for computer to understand but it should also readable by other humans. Especially 7. Monadic nullĀ checking
Iām surprised at the number of people who think the syntax makes things harder to read or parse. Sure they look a little odd now but seeing a single lineĀ like:
Will mean you immediately identify this is a readonly property in the future. Right now, you have to go to definition to go see what x is defined as and if it has a readonlyĀ property.
The same is true of the safe null operatorĀ ā you wonāt have to mentally parse several āif nullā checks just to understand it wants a property via some optionalĀ objects.
I agree with you on primary constructors. They seem oddly limited whereas something like what you proposeĀ ā public Point(set int x, set int y) could be used on anyĀ constructor.
I think I like 3 onwards; 1 and 2 areā¦ kind of weird: as though they do make sense, but donāt fit within the psychology of C# in some way. I think 1 is actively horribleā¦ I can see what theyāre doing, but it appears to me that itāll make the code very hard to parse: it might make sense to the compiler, but I donāt think itāll make a hell of a lot of sense to the user. And if you can do that in a constructor, can you do it in a method? Logic says you should be able to. What about if you do it in a loop in the constructorā¦? Itās a bit tooĀ ambiguous.
@mike: These came from somebody on the C# design team. They are not myĀ suggestions.
@Damien : you forgot to mention the 3rd option with params : you can totally ignore it and pass nothing atĀ all.
I like the the Before and After examples; they make the changes veryĀ clear.
Talking about code noise reductionĀ ā I would like to see a simple āis one ofā operator for comparisonĀ ā perhapsĀ =[
Interesting, but I donāt really see that much benefit to most of these. I agree with Scott Holodak, my biggest concern about these types of āenhancementsā is that they tend to obfuscate the code, and when you are dealing with enterprise applications and their maintenance by experts and novices, I view most of these as an impediment to the end goal; I do, however like #3 and #6 and see some benefit to #7 providing the syntax could be made more readable forĀ beginners.
What about having null checks built into ctors (mixed with auto private field creation)Ā ?
public class SomeClass(notnull set OtherClass instance) {Ā }
Wow #7 would be huge. I thought there wasnāt much they could do with C# to entice me to feel like I needed to upgrade. This list makes me want C# 6Ā now.
I also wish for property fields. Where the variable has class lifetime but can only be accessed inside theĀ property
this is going to be total mess if they implement all those syntaxes. especially in large teams where always one or two post graduates who have no clue what they are doing but āloveā writing cryptic mess.. And the devs who are responsible for pushing out the actual product will waste more time cleaning it.. Much more time than those ātricksā will save in writingā¦ #9 is only feature adding something to developmentĀ process.
The constructor change is a massive improvement over previous versions of C#. Forcing the split between assignment and declaration seemed like a poor design choice. I imagine that fixing it will get rid of many null referenceĀ exceptions.
It is a shame weāll have to wait so long for C# to catch up with other languages like F# & ScalaĀ though!
F# is available today and alreadyĀ has:
If anyone reading this would like to learn more about F# (from a C# perspective) I can recommend theseĀ resources:
After writing and maintaining code for the past 20 years, anything that hides the meaning of code, even if it saves a couple key strokes, is just a bad idea. These are mostly no more valuable than fads and they reduce maintainability. If you want it to be maintainable, code should read like a story. KISSā¦ the most basic and universal engineeringĀ principle.
Why not use the most intuitive syntax for readonly autoĀ properties:
wow! c# slowly moves to scalaā¦ by the way, your post is clear and interesting!Ā thanks!
Only number 7 has any chance of making it to C# 6.0. The design team is very, very conservative when it comes to adding features, and most of these are just not worth the effort, especially considering they are rewriting theĀ compiler.
To predict new C# features, you have to consider what compiler as a service enables. The new compiler will enable you to peek inside the AST, so I suspect more dynamics wrt compiling/inspecting code, not new languageĀ features.
For 6: Is evaluation deferred until evaluated if you pass a single IEnumerable instead of aĀ params?
params (certainly for arrays, Iād expect for enumerable also) affects the call site, not the method itselfĀ ā once youāre inside the code of the method, params doesnāt affect anythingĀ ā you just have an array or an enumerable. As such, if someone has called your method and passed an array/enumerable directly, you just receive whatever theyāve passed youĀ ā the params āmachineryā is not involved atĀ all.
As such, Iād strongly suspect that you get deferredĀ evaluation.
(3) could mean that instead ofĀ the
could be expressed more like I can do in DelphiĀ now:
aka
It would be the nice comeback of the one line/at a glanceĀ auxiliares.
I expected MS to start shifting more towards F#, but itās nice to see C# is still getting plenty ofĀ attention. Those are very nice features. I especially like method expressions and monadic null checking. Features 1ā4 I donāt like so much, because they seem to me like they will bring confusion into code. I think those are big updates, maybe too big for a mature language such as C#, considering that they donāt bring so much value to theĀ table.
Nice post! I also thought about writing an opinionated follow up whilst walking to work this morningĀ ;-)
Iāll put up my follow up post soon, I think my thoughts are largely similar to yoursĀ though.
Saat nambar ta Ekhani chai (#7 want right now)Ā !
āMonadic null checkingā
Some of these are nice, love 7,9 but would love to see some features that change whatās possible rather than cleaningĀ syntax. I would love to be able to use Lambda Expressions as constructor parameters forĀ Attributes
Yes please to #6, #7 and #9. Not really excited about any of the other ones. Iād be concerned that #1-#5 would impact readability/maintainability, particularly in teams where you have experts and beginners trying to peacefully coexist in the same codeĀ base.
@Damien: thank you for explanation. I donāt really know how āparamsā is implemented under the hood (I may guess how it works, but not sure), but letās take a start from the idea of āunrollingā of what the āparamsā is designed for: generally speaking itās designed just to simplify passing more same-typed arguments to variadic methods reducing the number of overloads. So basically all arguments must be evaluated before they are passed to a method in eager manner just like if they were āregularā arguments. I think that eager evaluation for method arguments is a must for CLR design, and if lazy evaluation for sequences is necessary, the IEnumerable must be used in the method explicitly, because array (and āparamsā) item dereferrencingĀ operator assumes that the whole sequence is known, and kept, for non-abstract instance, in memory -- IEnumerable does not have size per se byĀ design.
@james: While the scoping there would be great for the Try pattern it would render this function useless for DirectX programming where there are a lot of out parameters simply to avoid copying back and forth via theĀ stack.
@Lyubomyr: With (paramsĀ int someValues) you have two optionsĀ ā comma separated parameters and an array. Sometimes we have an array and so we have to pass that. Other times we have an IEnumerable and have to forceĀ evaluation.
With the new syntax Iād imagine people start switching to the IEnumerable syntax so that you can either comma separate the parameters or pass any enumerable (including array) to be evaluated as required. It should replace the older syntax as time goesĀ on.
(1) āprimary constructorsā syntax is scary. I donāt believe that it can be accepted.Ā Ever.
(3) is good borrowing the idea of static imports from Java. The code can be much and much cleaner, thatās true. However, Iād like to import particular classes, and other first class members. The āusingā keyword is uncontrollable when simply importing whole namespaces. Extension methods introducing is even more uncontrollable andĀ unpredictable.
(6) Couldnāt understand it. Isnāt passing IEnumerableĀ enough?
(9) Unnecessary and, according to James Hart, causesĀ issues.
(Wrapping Up) I do believe that introducing meta-programming can obtain more efficiency and enhancements at compile time. The given example is about a Decorator design pattern implementation, and a meta-programming template can easily cover this case without enhancing the language itself -- youād enhance the language yourself. Even a simple āforeachā statement could be expressed using a template. But itās a differentĀ story.
The improvement of inline out variable declaration might be more subtle than just eliminating the need for a prior declarationĀ ā it permits the scope of the variable to be reduced to where itĀ belongs:
Before:
After:
Liviu I have had something even more robust imo for a long timeā¦ at maybe.codeplex.com you can doĀ obj.Maybe(x=>x.Prop1.Prop2).
1, 4. 5 for extraĀ readability.
pattern matching would beĀ great
Looks interesting, but some syntaxs are confusing toĀ me.
Safe navigation is a killer, now i use following to simulateĀ it:
Safe is R Safe(FuncĀ propaccess)ā¦
What bothers me in these examples, is that the new features are just some cosmetic stuff, easy to implement by anĀ intern, when having a good parser likeĀ Roslynā¦
Why not syntactic macros, or again: string interpolation like many new and old languages have implemented forĀ ages? Why is C# soĀ conservative?
I canāt wait for #7. Iād actually be willing to kill for it rightĀ now.
This is NOT monadic null checking Monadic null checking would be using an Option or Maybe class and using LINQ extension method (specifically SelectMany) for stacking checks suchĀ as
Make sense?
Imitation being the sincerest form or flattery; F# should be very flattered! Still, looks a nice set ofĀ improvements.
For (1) Primary Constructors, I prefer a syntax which allows me to prefix the private instance variables with an underscore ( _x and _y ). This naming convention makes the code more readable, since one can easily distinguish between private instance variables ( _x and _y ) and method local variables ( say m and nĀ ).
I hope you will be also able toĀ write:
It is one of places there you have to declare type and cannotĀ use
var
.Yeah! Letās add more keywords doing nothing new in new ways and call that a new versionĀ !!
Seriously, I feel bad for CSharpers. It is really time they jump on the Fsharp wagon which is all thatās left to be cool on theĀ CLR.
I feel like Iāve been waiting for Monadic null checking (7) all my life. Primary Constructors (1) is a fantastic idea but I am not a fan of the given syntax. I like your rewrite. My first thought was to use the āthisā keyword, but āsetā allows it to be intuitive in static constructors as well. Iām not sure I like the idea of auto-creating private fields/properties if they donāt exist. That seems like it could easily cause confusion with anyone not familiar with the languageĀ feature.
I would love to see more hardcore features likeĀ : string interpolation dynamic enhancements and not least: Lambda Expressions to supportĀ statementsā¦
Whatās interesting about inline out declarations this is that a series of statements is now replaced by an expression, so you could do something likeĀ this:
Thanks Jesper that makes a lot more sense, I was sure I was wrong. I will update theĀ post.
4/5: āExpressionā in this context does not mean involving expression tree types at all, just expressions that are not standalone statements in brackets. Like how ā1 + 2ā³ in ā() => 1 +2;ā is not ā() => { return 1+ 2;Ā }".
So:
as a shorter way ofĀ writing
Itās going to be interesting how these play out. Iām not sure I like the syntax for #1 orĀ #2