From 506712a0fe6760049e05e3b5d5e6fecc93289947 Mon Sep 17 00:00:00 2001 From: Petr Onderka Date: Fri, 24 Mar 2017 22:10:35 +0100 Subject: [PATCH 1/2] Fixed VB code and syntax highlighting --- .../operators/null-conditional-operators.md | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/docs/csharp/language-reference/operators/null-conditional-operators.md b/docs/csharp/language-reference/operators/null-conditional-operators.md index 39a85ea2bd4d3..9267821c9181c 100644 --- a/docs/csharp/language-reference/operators/null-conditional-operators.md +++ b/docs/csharp/language-reference/operators/null-conditional-operators.md @@ -33,22 +33,24 @@ Used to test for null before performing a member access (`?.`) or index (`?[`) o int? length = customers?.Length; // null if customers is null Customer first = customers?[0]; // null if customers is null int? count = customers?[0]?.Orders?.Count(); // null if customers, the first customer, or Orders is null - ``` ```vb -Dim length = customers?.Length ‘’ null if customers is null -Dim first as Customer = customers?(0); ‘’ null if customers is null -Dim count as Integer? = customers?[0]?.Orders?.Count(); // null if customers, the first customer, or Orders is null - +Dim length = customers?.Length ' null if customers is null +Dim first as Customer = customers?(0) ' null if customers is null +Dim count as Integer? = customers?(0)?.Orders?.Count() ' null if customers, the first customer, or Orders is null ``` The last example demonstrates that the null-condition operators are short-circuiting. If one operation in a chain of conditional member access and index operation returns null, then the rest of the chain’s execution stops. Other operations with lower precedence in the expression continue. For example, `E` in the following always executes, and the `??` and `==` operations execute. -```vb-c# +```csharp A?.B?.C?[0] ?? E A?.B?.C?[0] == E - +``` + +```vb +A?.B?.C?(0) ?? E +A?.B?.C?(0) == E ``` Another use for the null-condition member access is invoking delegates in a thread-safe way with much less code. The old way requires code like the following: @@ -57,21 +59,18 @@ A?.B?.C?[0] == E var handler = this.PropertyChanged; if (handler != null) handler(…) - ``` ```vb Dim handler = AddressOf(Me.PropertyChanged) If handler IsNot Nothing Call handler(…) - ``` The new way is much simpler: -```vb-c# +```csharp PropertyChanged?.Invoke(e) - ``` The new way is thread-safe because the compiler generates code to evaluate `PropertyChanged` one time only, keeping the result in temporary variable. @@ -88,4 +87,4 @@ PropertyChanged?.Invoke(e) [C# Reference](../../../csharp/language-reference/index.md) [C# Programming Guide](../../../csharp/programming-guide/index.md) [Visual Basic Language Reference](../../../visual-basic/language-reference/index.md) - [Visual Basic Programming Guide](../../../visual-basic/programming-guide/index.md) \ No newline at end of file + [Visual Basic Programming Guide](../../../visual-basic/programming-guide/index.md) From 58847877d658a89186229b832f80d8d9b8667961 Mon Sep 17 00:00:00 2001 From: Petr Onderka Date: Fri, 24 Mar 2017 23:14:56 +0100 Subject: [PATCH 2/2] Addressed review comments --- .../operators/null-conditional-operators.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/csharp/language-reference/operators/null-conditional-operators.md b/docs/csharp/language-reference/operators/null-conditional-operators.md index 9267821c9181c..e3da2eb0711de 100644 --- a/docs/csharp/language-reference/operators/null-conditional-operators.md +++ b/docs/csharp/language-reference/operators/null-conditional-operators.md @@ -58,7 +58,7 @@ A?.B?.C?(0) == E ```csharp var handler = this.PropertyChanged; if (handler != null) - handler(…) + handler(…); ``` ```vb @@ -71,9 +71,13 @@ If handler IsNot Nothing ```csharp PropertyChanged?.Invoke(e) +``` + +```vb +PropertyChanged?.Invoke(e) ``` - The new way is thread-safe because the compiler generates code to evaluate `PropertyChanged` one time only, keeping the result in temporary variable. + The new way is thread-safe because the compiler generates code to evaluate `PropertyChanged` one time only, keeping the result in a temporary variable. You need to explicitly call the `Invoke` method because there is no null-conditional delegate invocation syntax `PropertyChanged?(e)`. There were too many ambiguous parsing situations to allow it.