Training - Beratung - Projektarbeiten

www.David-Tielke.de

Webcast C# 6.0 - Folge 7: nameof() Operator

Kleine Veränderungen können manchmal großes Bewirken. Auf kaum eine Erweiterung trifft diese Aussage mehr zu, als auf den neuen nameof Operator. Musste man in der Vergangenheit an bestimmten stellen den Namen eines Members einer Klasse oder Methode angeben, z.B. beim Logging oder dem Auslösen einer ArgumentException, so musste dieser Name als string angegeben werden. Wurde der Parameter später während eines Refactorings umbenannt, wurde dies oft beim übergebenen string nicht gemacht. Und so schlichen sich Fehler ein, die weder beim kompilieren noch noch während dem Betrieb aufgefallen sind, sondern an der Stelle, an der man sie am dringendsten Benötigte: Beim debuggen nach Fehlerzuständen. Dies ist nur ein Beispiel, bei dem der neue nameof Operator hilfreich sein kann. Für mich definitiv der heimliche Star von C# 6.0.

Dazu von der Project Roslyn Webseite

Occasionally you need to provide a string that names some program element: when throwing an ArgumentNullException you want to name the guilty argument; when raising a PropertyChanged event you want to name the property that changed, etc. Using string literals for this purpose is simple, but error prone. You may spell it wrong, or a refactoring may leave it stale. nameof expressions are essentially a fancy kind of string literal where the compiler checks that you have something of the given name, and Visual Studio knows what it refers to, so navigation and refactoring will work:
if (x == null) throw new ArgumentNullException(nameof(x));
You can put more elaborate dotted names in a nameof expression, but that’s just to tell the compiler where to look: only the final identifier will be used:
WriteLine(nameof(person.Address.ZipCode)); // prints "ZipCode"

Links:

Webcast C# 6.0 - Folge 6: String Interpolations

Das Arbeiten mit Strings gehört seit je her zu einem der meist durchgeführten Datenmanipulationen im Quellcode. Dabei gibt es in C# mehrere Möglichkeiten dazu, z.B. der + Operator, String.Format und natürlich der StringBuilder. Jede dieser Methoden hat Vor- und Nachteile was Performance und Lesbarkeit angeht, jedoch stechen zwei Vorteile immer wieder heraus: Die schnelle Handhabbarkeit des + Operators und die gute Formatfähigkeit von String.Format. Während ersteres sehr komplexen Code erzeugt, ist die Verwendung von String.Format zumeist etwas “too much”. In C# 6.0 wurde mit den String Interpolations eine neue Variante vorgestellt, welche die Vorteile von String.Format und dem + Operator verbindet und das erzeugen von formatierten Strings auf elegante und kurze Weise direkt in die Sprache integriert.

Dazu aus der Project Roslyn Webseite

String.Format and its cousins are very versatile and useful, but their use is a little clunky and error prone. Particularly unfortunate is the use of {0} etc. placeholders in the format string, which must line up with arguments supplied separately:
var s = String.Format("{0} is {1} year{{s}} old", p.Name, p.Age);
String interpolation lets you put the expressions right in their place, by having “holes” directly in the string literal:
var s = $"{p.Name} is {p.Age} year{{s}} old";
Just as with String.Format , optional alignment and format specifiers can be given:
var s = $"{p.Name,20} is {p.Age:D3} year{{s}} old";
The contents of the holes can be pretty much any expression, including even other strings:
var s = $"{p.Name} is {p.Age} year{(p.Age == 1 ? "" : "s")} old";
Notice that the conditional expression is parenthesized, so that the : "s" doesn’t get confused with a format specifier.
Links

Webcast C# 6.0 - Folge 5: Null Conditional Operator

Robusten Code zu schreiben ist nicht besonders schwer, aber mühsam. Neben vielen Fehlern die in einer Anwendung auftreten können, ist die NullReferenceException wahrscheinlich die am häufigst auftretende und wohl auch nervigste Ausnahme die es gibt. Will man diese vermeiden, muss theoretisch jede Referenz auf die Ungleichheit mit null überprüft werden, bevor darauf zugegriffen wird. Auch wenn dies recht einfach möglich ist, sorgen die vielen Überprüfungen und die damit einhergehenden Verzweigungen für sehr komplexen Code der schwierig zu überblicken ist. Mit C# 6.0 wurde mit dem “Null Conditional Operator” ein spezieller Operator eingeführt, die das schreiben von robusterem Code sehr einfach macht. Welche Möglichkeiten der Operator bietet, was damit angestellt werden kann und wann er den Code eher schlechter als besser lesbar macht, zeige ich im fünften Teil dieser Webcastserie.

Dazu aus der Project Roslyn Webseite:

Sometimes code tends to drown a bit in null-checking. The null-conditional operator lets you access members and elements only when the receiver is not-null, providing a null result otherwise:
int? length = customers?.Length; // null if customers is null
Customer first = customers?[0];  // null if customers is null
The null-conditional operator is conveniently used together with the null coalescing operator ?? :
int length = customers?.Length ?? 0; // 0 if customers is null
The null-conditional operator exhibits short-circuiting behavior, where an immediately following chain of member accesses, element accesses and invocations will only be executed if the original receiver was not null:
int? first = customers?[0].Orders.Count();
This example is essentially equivalent to:
int? first = (customers != null) ? customers[0].Orders.Count() : null;
Except that customers is only evaluated once. None of the member accesses, element accesses and invocations immediately following the ? are executed unless customers has a non-null value. Of course null-conditional operators can themselves be chained, in case there is a need to check for null more than once in a chain:
int? first = customers?[0].Orders?.Count();
Note that an invocation (a parenthesized argument list) cannot immediately follow the ? operator – that would lead to too many syntactic ambiguities. Thus, the straightforward way of calling a delegate only if it’s there does not work. However, you can do it via the Invoke method on the delegate:
if (predicate?.Invoke(e) ?? false) { … }
We expect that a very common use of this pattern will be for triggering events:
PropertyChanged?.Invoke(this, args);
This is an easy and thread-safe way to check for null before you trigger an event. The reason it’s thread-safe is that the feature evaluates the left-hand side only once, and keeps it in a temporary variable.
Links