The document summarizes several new features in C# 6, including the nameof() operator, auto-property initialization, indexed initializer lists, the using static directive, method and property expressions, string interpolation, enhanced exception filtering, and the null conditional operator (?.). Some key features allow getting a string representation of an identifier with nameof(), initializing auto-properties to non-default values more easily, using indexers for initialization lists, importing static members to simplify code, string interpolation for building strings with values inline, filtering exceptions based on logical conditions, and safely accessing members and indexers of objects that may be null with the null conditional operator. Overall, the new features add syntactic sugar to help reduce boilerplate code and improve readability
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
The Little Wonders of C# 6
1. The Little Wonders of C# 6
James Michael Hare
Microsoft Visual C# MVP
4/27/2015
http://www.blackrabbitcoder.net/
@BlkRabbitCoder
2. The CTP for VS2015 is available for download
Includes the CTP for C# 6
Several new language features
No earth-shaking changes
Still compatible with .NET 4.5
Syntactical sugar to help reduce boiler-plate code
Helps improve code readability and maintainability
Visual Studio 2015 is Upon Us!
3. The nameof() operator
Auto-property initialization
Indexed initializer lists
The using static directive
Method and property expressions
String interpolation
Enhanced exception filtering
The null conditional operator (?.)
New C# 6 Features
4. Sometimes we want the name of an identifier as a string
The nameof() Operator
5. We can hard-code, but if we rename the variable, we
have to remember to update the string:
The nameof() Operator (cont)
6. Now, you can get a string representation of an
identifier with nameof():
The nameof() Operator (cont)
7. Before, if you wanted to default an auto-property to a
non-default value, there wasn’t a simple way.
Either:
Create a backing field with initializer, then wrap in
property
Or create an auto-property and then assign a value in
the constructor
This should really be a simple, one-step process.
Auto-Property Initialization
8. Now instead of this:
Auto-Property Initialization (cont)
10. We can now do this!
Reduces several lines of boiler-plating.
Auto-Property Initialization (cont)
11. In addition, you can use it even if the property has no
setter (i.e. a truly read-only property):
Auto-Property Initialization (cont)
12. Initializer lists now allow you to use indexers if the
container supports them.
For example, you used to have to initialize a
dictionary like this:
Indexed Initialization Lists
13. But now you can use the indexer syntax instead:
The syntax is much cleaner and clearly identifies
which string is the key and which is the value.
Indexed Initialization Lists (cont)
14. Warning: just because a container supports indexing doesn’t
mean initializing with it will always be logically sound…
For example:
What’s wrong with this?
Indexed Initialization Lists (cont)
15. It is legal and compiles with no errors.
However, you are attempting to set elements that are
beyond the list size, which List<T> doesn’t allow.
This is the same as doing this:
Indexed Initialization Lists (cont)
16. So remember, it’s just syntactical sugar, it won’t stop
you from performing a run-time illegal action.
To make that example work, you’d have to do
something like:
Indexed Initialization Lists (cont)
17. There are many static methods where the enclosing
class mainly acts as an organization point (e.g. Math).
Sometimes, these class names give context to the
static member being called.
Other times, they become repetitive clutter.
The using static declaration allows you to import the
static members of a type into your namespace.
Also allows you to limit extension methods imported.
The using static Directive
18. Consider the following:
A lot of these class names we can assume from
context or are just organizational clutter.
The using static Directive (cont)
19. If our program is a console app, we can probably
assume the Console.
Similarly, the Math and Enumerable classes don’t add
much. We already know what Pow() and Range() do.
Now, we can import the static members of these
types with using static:
The using static Directive (cont)
20. This would simplify our code to be:
We’ve removed a lot of redundant code without
obscuring the clarity.
The using static Directive (cont)
21. It’s not just for classes, you can import the static
members of structs or enums.
For example, doing this:
Would allow us to do this:
The using static Directive (cont)
22. Warning: just because you can do this doesn’t mean
you always should.
Consider if you ran across this code:
There’s no context, so what the heck are we creating?
Here, the type would have given meaningful context:
The using static Directive (cont)
23. Sometimes, we have properties or methods that are
so simple, the body is mostly boilerplate
Method and Property Expressions
24. You can now simplify with lambda expression syntax:
Handy for simple get-only properties, reduces the
boilerplate around the get { } syntax.
Somewhat reduces syntax burden on methods.
Method and Property Expressions
(cont)
25. Consider building a string in a single statement with
multiple components.
Typically we either use concatenation:
Or string formatting:
String Interpolation
26. The problem with concatenation is that it breaks up
the flow of the string you are building and makes it
harder to envision the result.
Formatting helps solve this, but it removes the actual
values from the string and makes it harder to visualize
where the arguments will be placed.
In addition, if you specify the wrong indexes of
placeholders you will get a runtime error.
String Interpolation (cont)
27. String interpolation fixes this, it allows us to use the
actual values as the placeholders inside the string.
You simply use $ as a string prefix to signal the
compiler to use interpolation, then enclose the values
with curly brackets.
Behind the scenes, the compiler will generate the
appropriate string format expression for you.
Gives you all the power of string formatting, with
ability to visualize the values in the string itself.
String Interpolation (cont)
28. So now, our example becomes:
In addition, all string formatting options are available:
String Interpolation (cont)
29. .NET has long had exception filtering:
Enhanced Exception Filtering
30. Standard exception filtering is fine when you just care
about the type of the exception thrown.
If you needed to make a decision to catch or not
based on logic – instead of type -- it’s clunky.
For example, let’s assume we are dealing with a data
layer that throws a dependency exception with an
IsRetryable property.
You may want to catch and handle if the exception is
retryable, but let it bubble up if not.
Enhanced Exception Filtering (cont)
32. To catch only retryable exceptions, we used to do this:
Enhanced Exception Filtering (cont)
33. Now, with C# 6, you can specify a logical filter as well:
Enhanced Exception Filtering (cont)
34. Now, you can have multiple catches on same type:
Enhanced Exception Filtering (cont)
35. Filtering conditions do not have to involve the
exception, they can be any condition.
Filters are checked in order for the same type, this
means that an unfiltered catch for a type must be
after all filtered catches for that type.
Filter only evaluated if that exception type is thrown.
If exception does not meet the filter, it is not
rethrown behind the scenes, it is simply not caught.
Enhanced Exception Filtering (cont)
36. Have you ever consumed a web method (or other
API) with a deeply nested response?
To be safe you have to do several layers of null checks
before getting to what you really want to check:
Null Conditional Operator
37. C# 6 adds a new null conditional operator (?.) to
access a member if not null, or cascade if null.
This would make our logic:
In the above example, if response is null, or
response.Results is null, the whole result will be null.
Null Conditional Operator (cont)
38. Note that all of these are legal, but different:
The first throws if response null but cascades if
Results is null, the second cascades if response is null
but throws if Results is null, the third cascades both.
Null Conditional Operator (cont)
39. A null-cascade that results in a value type will result in
a nullable value type:
Though you can couple with the null-coallescing
operator (??) to provide a default if null.
Null Conditional Operator (cont)
40. The null conditional operator is not just for
properties, you can use it for method calls as well.
Null Conditional Operator (cont)
42. So what if you want to check for null before invoking
an indexer on an array, List<T>, etc?
C# 6 has a syntax for null cascade on indexers (?[…]):
Null Conditional Operator (cont)
43. C# 6 adds a lot of syntactical sugary goodness.
Some of the features are more powerful than others,
but all have power to help increase maintainability
and readability of your code.
Like any tools, know when to use them and when you
are overusing them.
Visual Studio 2015 is currently in CTP6, moving to RC.
Summary