100% found this document useful (4 votes)
739 views809 pages

C Sharp Notes For Professionals

c#

Uploaded by

Eder Negro
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (4 votes)
739 views809 pages

C Sharp Notes For Professionals

c#

Uploaded by

Eder Negro
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

C#

C#
Notes for Professionals

Notes for Professionals

700+ pages
of professional hints and tricks

Disclaimer
[Link] This is an unocial free book created for educational purposes and is
not aliated with ocial C# group(s) or company(s).
Free Programming Books All trademarks and registered trademarks are
the property of their respective owners
Contents
About ................................................................................................................................................................................... 1
Chapter 1: Getting started with C# Language ............................................................................................... 2
Section 1.1: Creating a new console application (Visual Studio) ............................................................................... 2
Section 1.2: Creating a new project in Visual Studio (console application) and Running it in Debug mode
.................................................................................................................................................................................. 4
Section 1.3: Creating a new program using .NET Core .............................................................................................. 7
Section 1.4: Creating a new program using Mono ..................................................................................................... 9
Section 1.5: Creating a new query using LinqPad ...................................................................................................... 9
Section 1.6: Creating a new project using Xamarin Studio ...................................................................................... 12
Chapter 2: Verbatim Strings ................................................................................................................................. 18
Section 2.1: Interpolated Verbatim Strings ............................................................................................................... 18
Section 2.2: Escaping Double Quotes ....................................................................................................................... 18
Section 2.3: Verbatim strings instruct the compiler to not use character escapes .............................................. 18
Section 2.4: Multiline Strings ....................................................................................................................................... 19
Chapter 3: Operators ................................................................................................................................................ 20
Section 3.1: Overloadable Operators ......................................................................................................................... 20
Section 3.2: Overloading equality operators ............................................................................................................ 21
Section 3.3: Relational Operators .............................................................................................................................. 22
Section 3.4: Implicit Cast and Explicit Cast Operators ............................................................................................. 24
Section 3.5: Short-circuiting Operators ..................................................................................................................... 25
Section 3.6: ? : Ternary Operator ............................................................................................................................... 26
Section 3.7: ?. (Null Conditional Operator) ................................................................................................................ 27
Section 3.8: "Exclusive or" Operator .......................................................................................................................... 27
Section 3.9: default Operator ..................................................................................................................................... 28
Section 3.10: Assignment operator '=' ........................................................................................................................ 28
Section 3.11: sizeof ........................................................................................................................................................ 28
Section 3.12: ?? Null-Coalescing Operator ................................................................................................................ 29
Section 3.13: Bit-Shifting Operators ........................................................................................................................... 29
Section 3.14: => Lambda operator ............................................................................................................................. 29
Section 3.15: Class Member Operators: Null Conditional Member Access ............................................................ 31
Section 3.16: Class Member Operators: Null Conditional Indexing ......................................................................... 31
Section 3.17: Postfix and Prefix increment and decrement ..................................................................................... 31
Section 3.18: typeof ..................................................................................................................................................... 32
Section 3.19: Binary operators with assignment ...................................................................................................... 32
Section 3.20: nameof Operator ................................................................................................................................. 32
Section 3.21: Class Member Operators: Member Access ........................................................................................ 33
Section 3.22: Class Member Operators: Function Invocation ................................................................................. 33
Section 3.23: Class Member Operators: Aggregate Object Indexing .................................................................... 33
Chapter 4: Extension Methods ............................................................................................................................. 34
Section 4.1: Extension methods - overview ............................................................................................................... 34
Section 4.2: Null checking ........................................................................................................................................... 36
Section 4.3: Explicitly using an extension method .................................................................................................... 37
Section 4.4: Generic Extension Methods ................................................................................................................... 37
Section 4.5: Extension methods can only see public (or internal) members of the extended class .................. 39
Section 4.6: Extension methods for chaining ............................................................................................................ 39
Section 4.7: Extension methods with Enumeration .................................................................................................. 40
Section 4.8: Extension methods dispatch based on static type ............................................................................. 41
Section 4.9: Extension methods on Interfaces ......................................................................................................... 42
Section 4.10: Extension methods in combination with interfaces ........................................................................... 43
Section 4.11: Extension methods aren't supported by dynamic code .................................................................... 43
Section 4.12: Extensions and interfaces together enable DRY code and mixin-like functionality ...................... 44
Section 4.13: IList<T> Extension Method Example: Comparing 2 Lists ................................................................... 45
Section 4.14: Extension methods as strongly typed wrappers ............................................................................... 46
Section 4.15: Using Extension methods to create beautiful mapper classes ........................................................ 46
Section 4.16: Using Extension methods to build new collection types (e.g. DictList) ............................................ 47
Section 4.17: Extension methods for handling special cases .................................................................................. 48
Section 4.18: Using Extension methods with Static methods and Callbacks ......................................................... 49
Chapter 5: Collection Initializers ......................................................................................................................... 51
Section 5.1: Collection initializers ................................................................................................................................ 51
Section 5.2: C# 6 Index Initializers .............................................................................................................................. 51
Section 5.3: Collection initializers in custom classes ................................................................................................ 52
Section 5.4: Using collection initializer inside object initializer ................................................................................ 53
Section 5.5: Collection Initializers with Parameter Arrays ....................................................................................... 54
Chapter 6: String Interpolation ........................................................................................................................... 55
Section 6.1: Format dates in strings ........................................................................................................................... 55
Section 6.2: Padding the output ................................................................................................................................. 55
Section 6.3: Expressions .............................................................................................................................................. 56
Section 6.4: Formatting numbers in strings .............................................................................................................. 56
Section 6.5: Simple Usage .......................................................................................................................................... 57
Chapter 7: An overview of C# collections ...................................................................................................... 58
Section 7.1: HashSet<T> .............................................................................................................................................. 58
Section 7.2: Dictionary<TKey, TValue> ..................................................................................................................... 58
Section 7.3: SortedSet<T> ........................................................................................................................................... 59
Section 7.4: T[ ] (Array of T) ...................................................................................................................................... 59
Section 7.5: List<T> ...................................................................................................................................................... 60
Section 7.6: Stack<T> .................................................................................................................................................. 60
Section 7.7: LinkedList<T> ........................................................................................................................................... 60
Section 7.8: Queue ....................................................................................................................................................... 61
Chapter 8: Constructors and Finalizers ........................................................................................................... 62
Section 8.1: Static constructor .................................................................................................................................... 62
Section 8.2: Singleton constructor pattern ............................................................................................................... 63
Section 8.3: Default Constructor ................................................................................................................................ 63
Section 8.4: Forcing a static constructor to be called ............................................................................................. 64
Section 8.5: Calling a constructor from another constructor ................................................................................. 65
Section 8.6: Calling the base class constructor ........................................................................................................ 65
Section 8.7: Finalizers on derived classes ................................................................................................................. 66
Section 8.8: Exceptions in static constructors .......................................................................................................... 66
Section 8.9: Constructor and Property Initialization ................................................................................................ 67
Section 8.10: Generic Static Constructors ................................................................................................................. 69
Section 8.11: Calling virtual methods in constructor ................................................................................................. 69
Chapter 9: Static Classes ........................................................................................................................................ 71
Section 9.1: Static Classes ........................................................................................................................................... 71
Section 9.2: Static class lifetime ................................................................................................................................. 71
Section 9.3: Static keyword ........................................................................................................................................ 72
Chapter 10: Keywords ............................................................................................................................................... 73
Section 10.1: as ............................................................................................................................................................. 73
Section 10.2: goto ........................................................................................................................................................ 74
Section 10.3: volatile .................................................................................................................................................... 75
Section 10.4: checked, unchecked .............................................................................................................................. 76
Section 10.5: virtual, override, new ............................................................................................................................. 77
Section 10.6: stackalloc ............................................................................................................................................... 80
Section 10.7: break ....................................................................................................................................................... 81
Section 10.8: const ....................................................................................................................................................... 83
Section 10.9: async, await ........................................................................................................................................... 84
Section 10.10: for .......................................................................................................................................................... 85
Section 10.11: abstract .................................................................................................................................................. 86
Section 10.12: fixed ....................................................................................................................................................... 87
Section 10.13: default ................................................................................................................................................... 88
Section 10.14: sealed .................................................................................................................................................... 89
Section 10.15: is ............................................................................................................................................................. 89
Section 10.16: this ......................................................................................................................................................... 90
Section 10.17: readonly ................................................................................................................................................ 91
Section 10.18: typeof .................................................................................................................................................... 92
Section 10.19: foreach .................................................................................................................................................. 92
Section 10.20: dynamic ............................................................................................................................................... 93
Section 10.21: try, catch, finally, throw ....................................................................................................................... 94
Section 10.22: void ....................................................................................................................................................... 95
Section 10.23: namespace .......................................................................................................................................... 95
Section 10.24: ref, out .................................................................................................................................................. 96
Section 10.25: base ...................................................................................................................................................... 97
Section 10.26: float, double, decimal ......................................................................................................................... 99
Section 10.27: operator ............................................................................................................................................. 100
Section 10.28: char .................................................................................................................................................... 101
Section 10.29: params ............................................................................................................................................... 101
Section 10.30: while .................................................................................................................................................... 102
Section 10.31: null ....................................................................................................................................................... 104
Section 10.32: continue .............................................................................................................................................. 105
Section 10.33: string ................................................................................................................................................... 105
Section 10.34: return .................................................................................................................................................. 106
Section 10.35: unsafe ................................................................................................................................................. 106
Section 10.36: switch .................................................................................................................................................. 108
Section 10.37: var ....................................................................................................................................................... 109
Section 10.38: when ................................................................................................................................................... 110
Section 10.39: lock ..................................................................................................................................................... 111
Section 10.40: uint ...................................................................................................................................................... 112
Section 10.41: if, if...else, if... else if ............................................................................................................................. 112
Section 10.42: static ................................................................................................................................................... 113
Section 10.43: internal ............................................................................................................................................... 115
Section 10.44: using ................................................................................................................................................... 116
Section 10.45: where .................................................................................................................................................. 116
Section 10.46: int ........................................................................................................................................................ 118
Section 10.47: ulong ................................................................................................................................................... 119
Section 10.48: true, false ........................................................................................................................................... 119
Section 10.49: struct .................................................................................................................................................. 119
Section 10.50: extern ................................................................................................................................................. 120
Section 10.51: bool ...................................................................................................................................................... 121
Section 10.52: interface ............................................................................................................................................. 121
Section 10.53: delegate ............................................................................................................................................. 122
Section 10.54: unchecked ......................................................................................................................................... 122
Section 10.55: ushort ................................................................................................................................................. 123
Section 10.56: sizeof .................................................................................................................................................. 123
Section 10.57: in ......................................................................................................................................................... 123
Section 10.58: implicit ................................................................................................................................................ 124
Section 10.59: do ........................................................................................................................................................ 124
Section 10.60: long ..................................................................................................................................................... 125
Section 10.61: enum ................................................................................................................................................... 125
Section 10.62: partial ................................................................................................................................................. 126
Section 10.63: event ................................................................................................................................................... 127
Section 10.64: sbyte ................................................................................................................................................... 128
Chapter 11: Object Oriented Programming In C# ..................................................................................... 129
Section 11.1: Classes: .................................................................................................................................................. 129
Chapter 12: Inheritance .......................................................................................................................................... 130
Section 12.1: Inheritance. Constructors' calls sequence ......................................................................................... 130
Section 12.2: Inheriting from a base class .............................................................................................................. 132
Section 12.3: Inheriting from a class and implementing an interface .................................................................. 133
Section 12.4: Inheriting from a class and implementing multiple interfaces ...................................................... 133
Section 12.5: Constructors In A Subclass ................................................................................................................. 134
Section 12.6: Inheritance Anti-patterns ................................................................................................................... 134
Section 12.7: Extending an abstract base class ...................................................................................................... 135
Section 12.8: Testing and navigating inheritance .................................................................................................. 136
Section 12.9: Inheriting methods .............................................................................................................................. 136
Section 12.10: Base class with recursive type specification ................................................................................... 137
Chapter 13: Generics ................................................................................................................................................ 140
Section 13.1: Implicit type inference (methods) ...................................................................................................... 140
Section 13.2: Type inference (classes) .................................................................................................................... 141
Section 13.3: Using generic method with an interface as a constraint type ....................................................... 141
Section 13.4: Type constraints (new-keyword) ...................................................................................................... 142
Section 13.5: Type constraints (classes and interfaces) ........................................................................................ 143
Section 13.6: Checking equality of generic values ................................................................................................. 144
Section 13.7: Reflecting on type parameters .......................................................................................................... 145
Section 13.8: Covariance ........................................................................................................................................... 145
Section 13.9: Contravariance .................................................................................................................................... 146
Section 13.10: Invariance ........................................................................................................................................... 147
Section 13.11: Variant interfaces ............................................................................................................................... 147
Section 13.12: Variant delegates ............................................................................................................................... 148
Section 13.13: Variant types as parameters and return values ............................................................................ 149
Section 13.14: Type Parameters (Interfaces) .......................................................................................................... 149
Section 13.15: Type constraints (class and struct) ................................................................................................. 150
Section 13.16: Explicit type parameters ................................................................................................................... 150
Section 13.17: Type Parameters (Classes) ............................................................................................................... 150
Section 13.18: Type Parameters (Methods) ............................................................................................................. 151
Section 13.19: Generic type casting .......................................................................................................................... 151
Section 13.20: Configuration reader with generic type casting ............................................................................ 152
Chapter 14: Using Statement ............................................................................................................................. 154
Section 14.1: Using Statement Basics ....................................................................................................................... 154
Section 14.2: Gotcha: returning the resource which you are disposing ............................................................... 155
Section 14.3: Multiple using statements with one block ......................................................................................... 156
Section 14.4: Gotcha: Exception in Dispose method masking other errors in Using blocks .............................. 157
Section 14.5: Using statements are null-safe .......................................................................................................... 157
Section 14.6: Using Dispose Syntax to define custom scope ................................................................................ 157
Section 14.7: Using Statements and Database Connections ................................................................................ 158
Section 14.8: Executing code in constraint context ................................................................................................ 160
Chapter 15: Using Directive ................................................................................................................................. 161
Section 15.1: Associate an Alias to Resolve Conflicts ............................................................................................. 161
Section 15.2: Using alias directives .......................................................................................................................... 161
Section 15.3: Access Static Members of a Class ..................................................................................................... 161
Section 15.4: Basic Usage ......................................................................................................................................... 162
Section 15.5: Reference a Namespace .................................................................................................................... 162
Section 15.6: Associate an Alias with a Namespace .............................................................................................. 162
Chapter 16: Reflection ............................................................................................................................................ 164
Section 16.1: Get the members of a type ................................................................................................................. 164
Section 16.2: Get a method and invoke it ................................................................................................................ 164
Section 16.3: Creating an instance of a Type ......................................................................................................... 165
Section 16.4: Get a Strongly-Typed Delegate to a Method or Property via Reflection ..................................... 168
Section 16.5: Get a generic method and invoke it .................................................................................................. 169
Section 16.6: Get a [Link] .............................................................................................................................. 170
Section 16.7: Getting and setting properties ........................................................................................................... 170
Section 16.8: Create an instance of a Generic Type and invoke it's method ...................................................... 170
Section 16.9: Custom Attributes ............................................................................................................................... 171
Section 16.10: Instantiating classes that implement an interface (e.g. plugin activation) .................................. 172
Section 16.11: Get a Type by name with namespace ............................................................................................. 172
Section 16.12: Determining generic arguments of instances of generic types ................................................... 173
Section 16.13: Looping through all the properties of a class ................................................................................. 174
Chapter 17: Null-Coalescing Operator ........................................................................................................... 175
Section 17.1: Basic usage ........................................................................................................................................... 175
Section 17.2: Null fall-through and chaining ........................................................................................................... 175
Section 17.3: Null coalescing operator with method calls ..................................................................................... 176
Section 17.4: Use existing or create new ................................................................................................................. 177
Section 17.5: Lazy properties initialization with null coalescing operator ............................................................ 177
Chapter 18: Getting Started: Json with C# .................................................................................................. 178
Section 18.1: Simple Json Example .......................................................................................................................... 178
Section 18.2: First things First: Library to work with Json ..................................................................................... 178
Section 18.3: C# Implementation ............................................................................................................................. 178
Section 18.4: Serialization .......................................................................................................................................... 179
Section 18.5: Deserialization ..................................................................................................................................... 179
Section 18.6: Serialization & De-Serialization Common Utilities function ............................................................ 179
Chapter 19: LINQ Queries ...................................................................................................................................... 181
Section 19.1: Chaining methods ................................................................................................................................ 181
Section 19.2: First, FirstOrDefault, Last, LastOrDefault, Single, and SingleOrDefault ......................................... 182
Section 19.3: Except ................................................................................................................................................... 185
Section 19.4: SelectMany .......................................................................................................................................... 187
Section 19.5: Any ........................................................................................................................................................ 188
Section 19.6: JOINS .................................................................................................................................................... 188
Section 19.7: Skip and Take ...................................................................................................................................... 191
Section 19.8: Defining a variable inside a Linq query (let keyword) .................................................................... 191
Section 19.9: Zip ......................................................................................................................................................... 192
Section 19.10: Range and Repeat ............................................................................................................................ 192
Section 19.11: Basics ................................................................................................................................................... 193
Section 19.12: All ......................................................................................................................................................... 193
Section 19.13: Aggregate ........................................................................................................................................... 194
Section 19.14: Distinct ................................................................................................................................................. 195
Section 19.15: SelectMany: Flattening a sequence of sequences ......................................................................... 195
Section 19.16: GroupBy .............................................................................................................................................. 197
Section 19.17: Query collection by type / cast elements to type .......................................................................... 198
Section 19.18: Enumerating the Enumerable .......................................................................................................... 199
Section 19.19: Using Range with various Linq methods ......................................................................................... 200
Section 19.20: Where ................................................................................................................................................. 201
Section 19.21: Using SelectMany instead of nested loops ..................................................................................... 201
Section 19.22: Contains ............................................................................................................................................. 201
Section 19.23: Joining multiple sequences .............................................................................................................. 203
Section 19.24: Joining on multiple keys .................................................................................................................. 205
Section 19.25: ToLookup ........................................................................................................................................... 205
Section 19.26: SkipWhile ............................................................................................................................................ 205
Section 19.27: Query Ordering - OrderBy() ThenBy() OrderByDescending() ThenByDescending() ............... 206
Section 19.28: Sum ..................................................................................................................................................... 207
Section 19.29: GroupBy one or multiple fields ........................................................................................................ 207
Section 19.30: OrderBy .............................................................................................................................................. 208
Section 19.31: Any and First(OrDefault) - best practice ......................................................................................... 209
Section 19.32: GroupBy Sum and Count ................................................................................................................. 209
Section 19.33: SequenceEqual .................................................................................................................................. 210
Section 19.34: ElementAt and ElementAtOrDefault ............................................................................................... 210
Section 19.35: DefaultIfEmpty .................................................................................................................................. 211
Section 19.36: ToDictionary ...................................................................................................................................... 212
Section 19.37: Concat ................................................................................................................................................ 213
Section 19.38: Build your own Linq operators for IEnumerable<T> ..................................................................... 213
Section 19.39: Select - Transforming elements ...................................................................................................... 214
Section 19.40: OrderByDescending ......................................................................................................................... 215
Section 19.41: Union ................................................................................................................................................... 215
Section 19.42: GroupJoin with outer range variable .............................................................................................. 216
Section 19.43: Linq Quantifiers ................................................................................................................................. 216
Section 19.44: TakeWhile .......................................................................................................................................... 216
Section 19.45: Reverse .............................................................................................................................................. 217
Section 19.46: Count and LongCount ...................................................................................................................... 218
Section 19.47: Incrementally building a query ........................................................................................................ 218
Section 19.48: Select with Func<TSource, int, TResult> selector - Use to get ranking of elements .................. 220
Chapter 20: C# 7.0 Features ............................................................................................................................... 222
Section 20.1: Language support for Tuples ............................................................................................................ 222
Section 20.2: Local functions ................................................................................................................................... 226
Section 20.3: out var declaration ............................................................................................................................. 227
Section 20.4: Pattern Matching ................................................................................................................................ 228
Section 20.5: Digit separators .................................................................................................................................. 230
Section 20.6: Binary literals ...................................................................................................................................... 230
Section 20.7: throw expressions .............................................................................................................................. 231
Section 20.8: Extended expression bodied members list ...................................................................................... 232
Section 20.9: ref return and ref local ...................................................................................................................... 233
Section 20.10: ValueTask<T> .................................................................................................................................... 234
Chapter 21: C# 6.0 Features ................................................................................................................................ 236
Section 21.1: Exception filters .................................................................................................................................... 236
Section 21.2: String interpolation ............................................................................................................................. 240
Section 21.3: Auto-property initializers .................................................................................................................... 246
Section 21.4: Null propagation ................................................................................................................................. 249
Section 21.5: Expression-bodied function members .............................................................................................. 252
Section 21.6: Operator nameof ................................................................................................................................ 254
Section 21.7: Using static type .................................................................................................................................. 256
Section 21.8: Index initializers ................................................................................................................................... 256
Section 21.9: Improved overload resolution ........................................................................................................... 258
Section 21.10: Await in catch and finally .................................................................................................................. 259
Section 21.11: Minor changes and bugfixes ............................................................................................................. 260
Section 21.12: Using an extension method for collection initialization ................................................................. 260
Section 21.13: Disable Warnings Enhancements .................................................................................................... 261
Chapter 22: C# 5.0 Features ............................................................................................................................... 263
Section 22.1: Async & Await ...................................................................................................................................... 263
Section 22.2: Caller Information Attributes ............................................................................................................ 264
Chapter 23: C# 4.0 Features ............................................................................................................................... 265
Section 23.1: Optional parameters and named arguments .................................................................................. 265
Section 23.2: Variance .............................................................................................................................................. 266
Section 23.3: Dynamic member lookup .................................................................................................................. 266
Section 23.4: Optional ref keyword when using COM ........................................................................................... 267
Chapter 24: C# 3.0 Features ............................................................................................................................... 268
Section 24.1: Implicitly typed variables (var) .......................................................................................................... 268
Section 24.2: Language Integrated Queries (LINQ) .............................................................................................. 268
Section 24.3: Lambda expresions ............................................................................................................................ 269
Section 24.4: Anonymous types .............................................................................................................................. 269
Chapter 25: String Escape Sequences ........................................................................................................... 271
Section 25.1: Escaping special symbols in string literals ....................................................................................... 271
Section 25.2: Unicode character escape sequences ............................................................................................. 271
Section 25.3: Escaping special symbols in character literals ............................................................................... 271
Section 25.4: Using escape sequences in identifiers ............................................................................................. 271
Section 25.5: Unrecognized escape sequences produce compile-time errors .................................................. 272
Chapter 26: Exception Handling ........................................................................................................................ 273
Section 26.1: Creating Custom Exceptions .............................................................................................................. 273
Section 26.2: Finally block ........................................................................................................................................ 275
Section 26.3: Best Practices ..................................................................................................................................... 276
Section 26.4: Exception Anti-patterns ..................................................................................................................... 278
Section 26.5: Basic Exception Handling .................................................................................................................. 280
Section 26.6: Handling specific exception types .................................................................................................... 280
Section 26.7: Aggregate exceptions / multiple exceptions from one method ................................................... 281
Section 26.8: Throwing an exception ...................................................................................................................... 282
Section 26.9: Unhandled and Thread Exception .................................................................................................... 282
Section 26.10: Implementing IErrorHandler for WCF Services ............................................................................. 283
Section 26.11: Using the exception object ................................................................................................................ 285
Section 26.12: Nesting of Exceptions & try catch blocks ....................................................................................... 287
Chapter 27: Null-conditional Operators ....................................................................................................... 288
Section 27.1: Null-Conditional Operator .................................................................................................................. 288
Section 27.2: The Null-Conditional Index ................................................................................................................ 288
Section 27.3: Avoiding NullReferenceExceptions ................................................................................................... 289
Section 27.4: Null-conditional Operator can be used with Extension Method .................................................... 289
Chapter 28: Built-in Types .................................................................................................................................... 291
Section 28.1: Conversion of boxed value types ...................................................................................................... 291
Section 28.2: Comparisons with boxed value types .............................................................................................. 291
Section 28.3: Immutable reference type - string ................................................................................................... 291
Section 28.4: Value type - char ................................................................................................................................ 292
Section 28.5: Value type - short, int, long (signed 16 bit, 32 bit, 64 bit integers) ................................................. 292
Section 28.6: Value type - ushort, uint, ulong (unsigned 16 bit, 32 bit, 64 bit integers) ...................................... 292
Section 28.7: Value type - bool ................................................................................................................................ 293
Chapter 29: Lambda expressions ..................................................................................................................... 294
Section 29.1: Lambda Expressions as Shorthand for Delegate Initialization ...................................................... 294
Section 29.2: Lambda Expression as an Event Handler ........................................................................................ 294
Section 29.3: Lambda Expressions with Multiple Parameters or No Parameters .............................................. 295
Section 29.4: Lambdas can be emitted both as `Func` and `Expression` ............................................................ 295
Section 29.5: Put Multiple Statements in a Statement Lambda ........................................................................... 295
Section 29.6: Lambdas for both `Func` and `Action` .............................................................................................. 296
Section 29.7: Passing a Lambda Expression as a Parameter to a Method ........................................................ 296
Chapter 30: Async-Await ....................................................................................................................................... 297
Section 30.1: Await operator and async keyword .................................................................................................. 297
Section 30.2: Concurrent calls .................................................................................................................................. 298
Section 30.3: Try/Catch/Finally ............................................................................................................................... 299
Section 30.4: Returning a Task without await ........................................................................................................ 300
Section 30.5: Async/await will only improve performance if it allows the machine to do additional work
............................................................................................................................................................................. 300
Section 30.6: [Link]fig setup to target 4.5 for correct async behaviour ........................................................ 301
Section 30.7: Simple consecutive calls .................................................................................................................... 301
Section 30.8: Blocking on async code can cause deadlocks ............................................................................... 302
Chapter 31: Properties ............................................................................................................................................ 304
Section 31.1: Auto-implemented properties ............................................................................................................ 304
Section 31.2: Default Values for Properties ............................................................................................................. 304
Section 31.3: Public Get ............................................................................................................................................. 305
Section 31.4: Public Set .............................................................................................................................................. 305
Section 31.5: Accessing Properties ........................................................................................................................... 305
Section 31.6: Read-only properties .......................................................................................................................... 307
Section 31.7: Various Properties in Context ............................................................................................................. 307
Chapter 32: Threading ........................................................................................................................................... 309
Section 32.1: Avoiding Reading and Writing Data Simultaneously ...................................................................... 309
Section 32.2: Creating and Starting a Second Thread .......................................................................................... 310
Section 32.3: [Link] Loop ........................................................................................................................ 310
Section 32.4: Deadlocks (hold resource and wait) ................................................................................................ 311
Section 32.5: Simple Complete Threading Demo .................................................................................................. 313
Section 32.6: Creating One Thread Per Processor ................................................................................................ 314
Section 32.7: Simple Complete Threading Demo using Tasks ............................................................................. 314
Section 32.8: Deadlocks (two threads waiting on each other) ............................................................................. 315
Section 32.9: Explicit Task Parallism ........................................................................................................................ 316
Section 32.10: Implicit Task Parallelism ................................................................................................................... 316
Section 32.11: Starting a thread with parameters .................................................................................................. 317
Chapter 33: Methods ............................................................................................................................................... 318
Section 33.1: Calling a Method .................................................................................................................................. 318
Section 33.2: Anonymous method ........................................................................................................................... 318
Section 33.3: Declaring a Method ............................................................................................................................ 319
Section 33.4: Parameters and Arguments .............................................................................................................. 319
Section 33.5: Return Types ....................................................................................................................................... 319
Section 33.6: Default Parameters ............................................................................................................................ 320
Section 33.7: Method overloading ........................................................................................................................... 321
Section 33.8: Access rights ....................................................................................................................................... 322
Chapter 34: Yield Keyword .................................................................................................................................. 323
Section 34.1: Simple Usage ....................................................................................................................................... 323
Section 34.2: Correctly checking arguments ......................................................................................................... 323
Section 34.3: Early Termination ............................................................................................................................... 324
Section 34.4: More Pertinent Usage ........................................................................................................................ 325
Section 34.5: Lazy Evaluation .................................................................................................................................. 326
Section 34.6: Try...finally ............................................................................................................................................ 327
Section 34.7: Eager evaluation ................................................................................................................................. 328
Section 34.8: Using yield to create an IEnumerator<T> when implementing IEnumerable<T> ........................ 328
Section 34.9: Lazy Evaluation Example: Fibonacci Numbers ............................................................................... 329
Section 34.10: The dierence between break and yield break ............................................................................ 330
Section 34.11: Return another Enumerable within a method returning Enumerable .......................................... 331
Chapter 35: Events ................................................................................................................................................... 332
Section 35.1: Declaring and Raising Events ............................................................................................................ 332
Section 35.2: Event Properties ................................................................................................................................. 333
Section 35.3: Creating cancelable event ................................................................................................................. 334
Section 35.4: Standard Event Declaration .............................................................................................................. 335
Section 35.5: Anonymous Event Handler Declaration ........................................................................................... 336
Section 35.6: Non-Standard Event Declaration ..................................................................................................... 336
Section 35.7: Creating custom EventArgs containing additional data ................................................................ 337
Chapter 36: Common String Operations ...................................................................................................... 339
Section 36.1: Formatting a string ............................................................................................................................. 339
Section 36.2: Correctly reversing a string ............................................................................................................... 339
Section 36.3: Padding a string to a fixed length .................................................................................................... 340
Section 36.4: Getting x characters from the right side of a string ....................................................................... 341
Section 36.5: Checking for empty String using [Link]() and [Link]()
............................................................................................................................................................................. 342
Section 36.6: Trimming Unwanted Characters O the Start and/or End of Strings ......................................... 343
Section 36.7: Convert Decimal Number to Binary,Octal and Hexadecimal Format .......................................... 343
Section 36.8: Construct a string from Array ........................................................................................................... 343
Section 36.9: Formatting using ToString ................................................................................................................. 344
Section 36.10: Splitting a String by another string ................................................................................................. 345
Section 36.11: Splitting a String by specific character ............................................................................................ 345
Section 36.12: Getting Substrings of a given string ................................................................................................ 345
Section 36.13: Determine whether a string begins with a given sequence .......................................................... 345
Section 36.14: Getting a char at specific index and enumerating the string ....................................................... 345
Section 36.15: Joining an array of strings into a new one .................................................................................... 346
Section 36.16: Replacing a string within a string .................................................................................................... 346
Section 36.17: Changing the case of characters within a String ........................................................................... 346
Section 36.18: Concatenate an array of strings into a single string .................................................................... 347
Section 36.19: String Concatenation ........................................................................................................................ 347
Chapter 37: Expression Trees ............................................................................................................................. 348
Section 37.1: Create Expression Trees with a lambda expression ........................................................................ 348
Section 37.2: Creating Expression Trees by Using the API ................................................................................... 348
Section 37.3: Compiling Expression Trees .............................................................................................................. 348
Section 37.4: Parsing Expression Trees ................................................................................................................... 349
Section 37.5: Expression Tree Basic ........................................................................................................................ 349
Section 37.6: Examining the Structure of an Expression using Visitor ................................................................. 350
Section 37.7: Understanding the expressions API .................................................................................................. 350
Chapter 38: Overload Resolution ..................................................................................................................... 352
Section 38.1: Basic Overloading Example ............................................................................................................... 352
Section 38.2: "params" is not expanded, unless necessary .................................................................................. 352
Section 38.3: Passing null as one of the arguments .............................................................................................. 353
Chapter 39: [Link] ................................................................................................................................... 354
Section 39.1: Since C# 6.0 .......................................................................................................................................... 354
Section 39.2: Places where [Link] is 'embedded' in the framework ....................................................... 354
Section 39.3: Create a custom format provider ..................................................................................................... 354
Section 39.4: Date Formatting ................................................................................................................................. 355
Section 39.5: Currency Formatting .......................................................................................................................... 356
Section 39.6: Using custom number format ........................................................................................................... 357
Section 39.7: Align left/ right, pad with spaces ...................................................................................................... 357
Section 39.8: Numeric formats ................................................................................................................................ 358
Section 39.9: ToString() ............................................................................................................................................ 358
Section 39.10: Escaping curly brackets inside a [Link]() expression ...................................................... 359
Section 39.11: Relationship with ToString() .............................................................................................................. 359
Chapter 40: nameof Operator .......................................................................................................................... 360
Section 40.1: Basic usage: Printing a variable name ............................................................................................. 360
Section 40.2: Raising PropertyChanged event ...................................................................................................... 360
Section 40.3: Argument Checking and Guard Clauses .......................................................................................... 361
Section 40.4: Strongly typed MVC action links ...................................................................................................... 361
Section 40.5: Handling PropertyChanged events .................................................................................................. 362
Section 40.6: Applied to a generic type parameter .............................................................................................. 362
Section 40.7: Printing a parameter name ............................................................................................................... 363
Section 40.8: Applied to qualified identifiers .......................................................................................................... 363
Chapter 41: Unsafe Code in .NET ...................................................................................................................... 364
Section 41.1: Using unsafe with arrays .................................................................................................................... 364
Section 41.2: Using unsafe with strings ................................................................................................................... 364
Section 41.3: Unsafe Array Index ............................................................................................................................. 365
Chapter 42: Initializing Properties ................................................................................................................... 366
Section 42.1: C# 6.0: Initialize an Auto-Implemented Property ............................................................................. 366
Section 42.2: Initializing Property with a Backing Field ......................................................................................... 366
Section 42.3: Property Initialization during object instantiation ........................................................................... 366
Section 42.4: Initializing Property in Constructor ................................................................................................... 366
Chapter 43: BindingList<T> ................................................................................................................................. 367
Section 43.1: Add item to list ..................................................................................................................................... 367
Section 43.2: Avoiding N*2 iteration ........................................................................................................................ 367
Chapter 44: ILGenerator ...................................................................................................................................... 368
Section 44.1: Creates a DynamicAssembly that contains a UnixTimestamp helper method ........................... 368
Section 44.2: Create method override .................................................................................................................... 369
Chapter 45: Object initializers ........................................................................................................................... 371
Section 45.1: Simple usage ....................................................................................................................................... 371
Section 45.2: Usage with non-default constructors .............................................................................................. 371
Section 45.3: Usage with anonymous types .......................................................................................................... 371
Chapter 46: XML Documentation Comments ............................................................................................ 373
Section 46.1: Simple method annotation ................................................................................................................. 373
Section 46.2: Generating XML from documentation comments .......................................................................... 373
Section 46.3: Method documentation comment with param and returns elements ......................................... 375
Section 46.4: Interface and class documentation comments .............................................................................. 375
Section 46.5: Referencing another class in documentation ................................................................................. 376
Chapter 47: Preprocessor directives ............................................................................................................. 377
Section 47.1: Conditional Expressions ...................................................................................................................... 377
Section 47.2: Other Compiler Instructions .............................................................................................................. 377
Section 47.3: Defining and Undefining Symbols .................................................................................................... 378
Section 47.4: Region Blocks ..................................................................................................................................... 379
Section 47.5: Disabling and Restoring Compiler Warnings .................................................................................. 379
Section 47.6: Generating Compiler Warnings and Errors ..................................................................................... 379
Section 47.7: Custom Preprocessors at project level ............................................................................................ 380
Section 47.8: Using the Conditional attribute ......................................................................................................... 380
Chapter 48: Dynamic type .................................................................................................................................. 382
Section 48.1: Creating a dynamic object with properties ...................................................................................... 382
Section 48.2: Creating a dynamic variable ............................................................................................................ 382
Section 48.3: Returning dynamic ............................................................................................................................. 382
Section 48.4: Handling Specific Types Unknown at Compile Time ...................................................................... 382
Chapter 49: Anonymous types .......................................................................................................................... 384
Section 49.1: Anonymous vs dynamic ..................................................................................................................... 384
Section 49.2: Creating an anonymous type ........................................................................................................... 384
Section 49.3: Anonymous type equality ................................................................................................................. 384
Section 49.4: Generic methods with anonymous types ........................................................................................ 385
Section 49.5: Instantiating generic types with anonymous types ........................................................................ 385
Section 49.6: Implicitly typed arrays ....................................................................................................................... 385
Chapter 50: Structs ................................................................................................................................................. 387
Section 50.1: Declaring a struct ................................................................................................................................ 387
Section 50.2: Struct usage ........................................................................................................................................ 388
Section 50.3: Structs are copied on assignment .................................................................................................... 389
Section 50.4: Struct implementing interface .......................................................................................................... 389
Chapter 51: Tuples .................................................................................................................................................... 390
Section 51.1: Accessing tuple elements .................................................................................................................... 390
Section 51.2: Creating tuples .................................................................................................................................... 390
Section 51.3: Comparing and sorting Tuples .......................................................................................................... 390
Section 51.4: Return multiple values from a method ............................................................................................. 391
Chapter 52: Enum ..................................................................................................................................................... 392
Section 52.1: Enum basics ......................................................................................................................................... 392
Section 52.2: Enum as flags ..................................................................................................................................... 393
Section 52.3: Using << notation for flags ................................................................................................................ 395
Section 52.4: Test flags-style enum values with bitwise logic .............................................................................. 395
Section 52.5: Add and remove values from flagged enum .................................................................................. 396
Section 52.6: Enum to string and back ................................................................................................................... 396
Section 52.7: Enums can have unexpected values ................................................................................................ 397
Section 52.8: Default value for enum == ZERO ...................................................................................................... 397
Section 52.9: Adding additional description information to an enum value ....................................................... 398
Section 52.10: Get all the members values of an enum ........................................................................................ 399
Section 52.11: Bitwise Manipulation using enums ................................................................................................... 399
Chapter 53: Access Modifiers ............................................................................................................................. 400
Section 53.1: Access Modifiers Diagrams ................................................................................................................ 400
Section 53.2: public ................................................................................................................................................... 401
Section 53.3: private .................................................................................................................................................. 401
Section 53.4: protected internal ............................................................................................................................... 402
Section 53.5: internal ................................................................................................................................................. 403
Section 53.6: protected ............................................................................................................................................. 404
Chapter 54: Task Parallel Library ................................................................................................................... 405
Section 54.1: [Link] ................................................................................................................................... 405
Section 54.2: [Link] .......................................................................................................................................... 405
Section 54.3: [Link] ..................................................................................................................................... 406
Chapter 55: Attributes ........................................................................................................................................... 407
Section 55.1: Creating a custom attribute ............................................................................................................... 407
Section 55.2: Reading an attribute .......................................................................................................................... 407
Section 55.3: Using an attribute ............................................................................................................................... 408
Section 55.4: DebuggerDisplay Attribute ............................................................................................................... 408
Section 55.5: Caller info attributes ........................................................................................................................... 409
Section 55.6: Obsolete Attribute .............................................................................................................................. 410
Section 55.7: Reading an attribute from interface ................................................................................................ 410
Chapter 56: Guid ....................................................................................................................................................... 412
Section 56.1: Getting the string representation of a Guid ...................................................................................... 412
Section 56.2: Creating a Guid ................................................................................................................................... 412
Section 56.3: Declaring a nullable GUID ................................................................................................................. 412
Chapter 57: Singleton Implementation ......................................................................................................... 414
Section 57.1: Statically Initialized Singleton ............................................................................................................. 414
Section 57.2: Lazy, thread-safe Singleton (using Lazy<T>) .................................................................................. 414
Section 57.3: Lazy, thread-safe Singleton (using Double Checked Locking) ...................................................... 414
Section 57.4: Lazy, thread safe singleton (for .NET 3.5 or older, alternate implementation) ........................... 415
Chapter 58: Delegates ........................................................................................................................................... 417
Section 58.1: Declaring a delegate type ................................................................................................................. 417
Section 58.2: The Func<T, TResult>, Action<T> and Predicate<T> delegate types ............................................ 418
Section 58.3: Combine Delegates (Multicast Delegates) ...................................................................................... 419
Section 58.4: Safe invoke multicast delegate ........................................................................................................ 420
Section 58.5: Delegate Equality ............................................................................................................................... 421
Section 58.6: Underlying references of named method delegates ..................................................................... 421
Section 58.7: Assigning a named method to a delegate ...................................................................................... 422
Section 58.8: Assigning to a delegate by lambda ................................................................................................. 423
Section 58.9: Encapsulating transformations in funcs .......................................................................................... 423
Section 58.10: Passing delegates as parameters .................................................................................................. 423
Section 58.11: Closure inside a delegate .................................................................................................................. 424
Chapter 59: Nullable types .................................................................................................................................. 425
Section 59.1: Initialising a nullable ............................................................................................................................ 425
Section 59.2: Check if a Nullable has a value ......................................................................................................... 425
Section 59.3: Get the value of a nullable type ........................................................................................................ 425
Section 59.4: Getting a default value from a nullable ........................................................................................... 426
Section 59.5: Default value of nullable types is null .............................................................................................. 426
Section 59.6: Eective usage of underlying Nullable<T> argument .................................................................... 427
Section 59.7: Check if a generic type parameter is a nullable type .................................................................... 428
Chapter 60: Garbage Collector in .Net .......................................................................................................... 429
Section 60.1: Weak References ................................................................................................................................ 429
Section 60.2: Large Object Heap compaction ....................................................................................................... 430
Chapter 61: Networking ......................................................................................................................................... 431
Section 61.1: Basic TCP Communication Client ....................................................................................................... 431
Section 61.2: Download a file from a web server ................................................................................................... 431
Section 61.3: Async TCP Client .................................................................................................................................. 432
Section 61.4: Basic UDP Client .................................................................................................................................. 433
Chapter 62: Arrays ................................................................................................................................................... 434
Section 62.1: Declaring an array .............................................................................................................................. 434
Section 62.2: Initializing an array filled with a repeated non-default value ....................................................... 434
Section 62.3: Copying arrays ................................................................................................................................... 435
Section 62.4: Comparing arrays for equality ......................................................................................................... 435
Section 62.5: Multi-dimensional arrays ................................................................................................................... 436
Section 62.6: Getting and setting array values ...................................................................................................... 436
Section 62.7: Iterate over an array .......................................................................................................................... 436
Section 62.8: Creating an array of sequential numbers ....................................................................................... 437
Section 62.9: Jagged arrays .................................................................................................................................... 437
Section 62.10: Array covariance .............................................................................................................................. 439
Section 62.11: Arrays as IEnumerable<> instances ................................................................................................. 439
Section 62.12: Checking if one array contains another array .............................................................................. 439
Chapter 63: Equality Operator .......................................................................................................................... 441
Section 63.1: Equality kinds in c# and equality operator ...................................................................................... 441
Chapter 64: Lock Statement .............................................................................................................................. 442
Section 64.1: Throwing exception in a lock statement ........................................................................................... 442
Section 64.2: Simple usage ...................................................................................................................................... 442
Section 64.3: Return in a lock statement ................................................................................................................ 443
Section 64.4: Anti-Patterns and gotchas ................................................................................................................ 443
Section 64.5: Using instances of Object for lock .................................................................................................... 447
Chapter 65: Action Filters ..................................................................................................................................... 448
Section 65.1: Custom Action Filters .......................................................................................................................... 448
Chapter 66: XmlDocument and the [Link] namespace ............................................................ 449
Section 66.1: XmlDocument vs XDocument (Example and comparison) ............................................................ 449
Section 66.2: Reading from XML document ........................................................................................................... 451
Section 66.3: Basic XML document interaction ...................................................................................................... 452
Chapter 67: DateTime Methods ........................................................................................................................ 453
Section 67.1: DateTime Formatting ......................................................................................................................... 453
Section 67.2: [Link](Double) ............................................................................................................. 454
Section 67.3: [Link](Double) ............................................................................................................ 454
Section 67.4: [Link](String) ..................................................................................................................... 454
Section 67.5: [Link](String, DateTime) ............................................................................................. 454
Section 67.6: [Link](Double) .................................................................................................. 455
Section 67.7: [Link](DateTime t1, DateTime t2 ) ............................................................................. 455
Section 67.8: [Link](Int32, Int32) ............................................................................................... 455
Section 67.9: [Link](Int32) ................................................................................................................ 456
Section 67.10: Pure functions warning when dealing with DateTime ................................................................... 456
Section 67.11: [Link](String, String, IFormatProvider, DateTimeStyles, DateTime)
............................................................................................................................................................................. 456
Section 67.12: [Link](TimeSpan) ................................................................................................................ 458
Section 67.13: Parse and TryParse with culture info .............................................................................................. 458
Section 67.14: DateTime as initializer in for-loop ................................................................................................... 459
Section 67.15: [Link](String, String, IFormatProvider) ............................................................... 459
Section 67.16: DateTime ToString, ToShortDateString, ToLongDateString and ToString formatted ............... 460
Section 67.17: Current Date ...................................................................................................................................... 460
Chapter 68: BackgroundWorker ....................................................................................................................... 461
Section 68.1: Using a BackgroundWorker to complete a task ............................................................................. 461
Section 68.2: Assigning Event Handlers to a BackgroundWorker ....................................................................... 462
Section 68.3: Creating a new BackgroundWorker instance ................................................................................. 463
Section 68.4: Assigning Properties to a BackgroundWorker ............................................................................... 463
Chapter 69: Polymorphism .................................................................................................................................. 464
Section 69.1: Types of Polymorphism ..................................................................................................................... 464
Section 69.2: Another Polymorphism Example ...................................................................................................... 465
Chapter 70: Indexer ................................................................................................................................................. 468
Section 70.1: A simple indexer .................................................................................................................................. 468
Section 70.2: Overloading the indexer to create a SparseArray ......................................................................... 468
Section 70.3: Indexer with 2 arguments and interface .......................................................................................... 469
Chapter 71: IDisposable interface .................................................................................................................... 470
Section 71.1: In a class that contains only managed resources ............................................................................ 470
Section 71.2: In a class with managed and unmanaged resources ..................................................................... 470
Section 71.3: IDisposable, Dispose ........................................................................................................................... 471
Section 71.4: using keyword ..................................................................................................................................... 471
Section 71.5: In an inherited class with managed resources ................................................................................. 472
Chapter 72: Aliases of built-in types ............................................................................................................... 473
Section 72.1: Built-In Types Table ............................................................................................................................ 473
Chapter 73: Immutability ...................................................................................................................................... 474
Section 73.1: [Link] class .............................................................................................................................. 474
Section 73.2: Strings and immutability .................................................................................................................... 474
Chapter 74: XDocument and the [Link] namespace ...................................................... 475
Section 74.1: Generate an XML document .............................................................................................................. 475
Section 74.2: Generate an XML document using fluent syntax ............................................................................ 475
Section 74.3: Modify XML File ................................................................................................................................... 476
Chapter 75: Performing HTTP requests ....................................................................................................... 478
Section 75.1: Creating and sending an HTTP POST request ................................................................................. 478
Section 75.2: Creating and sending an HTTP GET request .................................................................................. 478
Section 75.3: Error handling of specific HTTP response codes (such as 404 Not Found) ................................ 479
Section 75.4: Retrieve HTML for Web Page (Simple) ............................................................................................ 479
Section 75.5: Sending asynchronous HTTP POST request with JSON body ...................................................... 479
Chapter 76: Generating Random Numbers in C# .................................................................................... 481
Section 76.1: Generate a random int ....................................................................................................................... 481
Section 76.2: Generate a random int in a given range ......................................................................................... 481
Section 76.3: Generating the same sequence of random numbers over and over again ................................ 481
Section 76.4: Create multiple random class with dierent seeds simultaneously ............................................. 482
Section 76.5: Generate a Random double .............................................................................................................. 482
Section 76.6: Generate a random character .......................................................................................................... 482
Section 76.7: Generate a number that is a percentage of a max value ............................................................. 482
Chapter 77: Looping ................................................................................................................................................ 484
Section 77.1: For Loop ............................................................................................................................................... 484
Section 77.2: Do - While Loop .................................................................................................................................. 485
Section 77.3: Foreach Loop ...................................................................................................................................... 485
Section 77.4: Looping styles ..................................................................................................................................... 486
Section 77.5: Nested loops ....................................................................................................................................... 487
Section 77.6: continue ............................................................................................................................................... 487
Section 77.7: While loop ............................................................................................................................................ 488
Section 77.8: break .................................................................................................................................................... 488
Chapter 78: Named Arguments ........................................................................................................................ 490
Section 78.1: Argument order is not necessary ...................................................................................................... 490
Section 78.2: Named arguments and optional parameters ................................................................................. 490
Section 78.3: Named Arguments can make your code more clear .................................................................... 490
Chapter 79: Diagnostics ........................................................................................................................................ 492
Section 79.1: Redirecting log output with TraceListeners ...................................................................................... 492
Section 79.2: [Link] ................................................................................................................................. 492
Chapter 80: Interfaces ........................................................................................................................................... 493
Section 80.1: Implementing an interface ................................................................................................................. 493
Section 80.2: Explicit interface implementation ..................................................................................................... 493
Section 80.3: Interface Basics .................................................................................................................................. 495
Section 80.4: IComparable<T> as an Example of Implementing an Interface ................................................... 497
Section 80.5: Implementing multiple interfaces ..................................................................................................... 498
Section 80.6: Why we use interfaces ...................................................................................................................... 498
Section 80.7: "Hiding" members with Explicit Implementation ............................................................................. 499
Chapter 81: IEnumerable ....................................................................................................................................... 501
Section 81.1: IEnumerable with custom Enumerator .............................................................................................. 501
Section 81.2: IEnumerable<int> ................................................................................................................................ 502
Chapter 82: Naming Conventions .................................................................................................................... 503
Section 82.1: Capitalization conventions ................................................................................................................. 503
Section 82.2: Enums .................................................................................................................................................. 504
Section 82.3: Interfaces ............................................................................................................................................ 504
Section 82.4: Exceptions ........................................................................................................................................... 504
Section 82.5: Private fields ....................................................................................................................................... 505
Section 82.6: Namespaces ....................................................................................................................................... 505
Chapter 83: Checked and Unchecked ............................................................................................................ 506
Section 83.1: Checked and Unchecked .................................................................................................................... 506
Section 83.2: Checked and Unchecked as a scope ............................................................................................... 506
Chapter 84: Recursion ........................................................................................................................................... 507
Section 84.1: Recursion in plain English ................................................................................................................... 507
Section 84.2: Fibonacci Sequence ........................................................................................................................... 507
Section 84.3: PowerOf calculation ........................................................................................................................... 508
Section 84.4: Recursively describe an object structure ........................................................................................ 508
Section 84.5: Using Recursion to Get Directory Tree ............................................................................................ 509
Section 84.6: Factorial calculation ........................................................................................................................... 512
Chapter 85: Functional Programming ........................................................................................................... 513
Section 85.1: Func and Action .................................................................................................................................. 513
Section 85.2: Higher-Order Functions ..................................................................................................................... 513
Section 85.3: Avoid Null References ........................................................................................................................ 513
Section 85.4: Immutability ........................................................................................................................................ 515
Section 85.5: Immutable collections ........................................................................................................................ 516
Chapter 86: Literals ................................................................................................................................................. 517
Section 86.1: uint literals ............................................................................................................................................ 517
Section 86.2: int literals ............................................................................................................................................. 517
Section 86.3: sbyte literals ........................................................................................................................................ 517
Section 86.4: decimal literals .................................................................................................................................... 517
Section 86.5: double literals ..................................................................................................................................... 517
Section 86.6: float literals ......................................................................................................................................... 517
Section 86.7: long literals .......................................................................................................................................... 517
Section 86.8: ulong literal ......................................................................................................................................... 517
Section 86.9: string literals ....................................................................................................................................... 518
Section 86.10: char literals ........................................................................................................................................ 518
Section 86.11: byte literals ......................................................................................................................................... 518
Section 86.12: short literal ......................................................................................................................................... 518
Section 86.13: ushort literal ....................................................................................................................................... 518
Section 86.14: bool literals ........................................................................................................................................ 518
Chapter 87: Casting ................................................................................................................................................. 519
Section 87.1: Checking compatibility without casting ............................................................................................ 519
Section 87.2: Cast an object to a base type ........................................................................................................... 519
Section 87.3: Conversion Operators ........................................................................................................................ 519
Section 87.4: LINQ Casting operations ................................................................................................................... 521
Section 87.5: Explicit Casting .................................................................................................................................... 521
Section 87.6: Safe Explicit Casting (`as` operator) ................................................................................................. 521
Section 87.7: Implicit Casting ................................................................................................................................... 522
Section 87.8: Explicit Numeric Conversions ............................................................................................................ 522
Chapter 88: NullReferenceException ............................................................................................................. 523
Section 88.1: NullReferenceException explained .................................................................................................... 523
Chapter 89: Func delegates ................................................................................................................................ 524
Section 89.1: Without parameters ............................................................................................................................ 524
Section 89.2: With multiple variables ...................................................................................................................... 524
Section 89.3: Lambda & anonymous methods ...................................................................................................... 525
Section 89.4: Covariant & Contravariant Type Parameters ................................................................................. 525
Chapter 90: LINQ to XML ...................................................................................................................................... 527
Section 90.1: Read XML using LINQ to XML ............................................................................................................ 527
Chapter 91: Hash Functions ................................................................................................................................. 529
Section 91.1: PBKDF2 for Password Hashing .......................................................................................................... 529
Section 91.2: Complete Password Hashing Solution using Pbkdf2 ...................................................................... 529
Section 91.3: MD5 ....................................................................................................................................................... 533
Section 91.4: SHA1 ...................................................................................................................................................... 533
Section 91.5: SHA256 ................................................................................................................................................. 534
Section 91.6: SHA384 ................................................................................................................................................. 534
Section 91.7: SHA512 .................................................................................................................................................. 535
Chapter 92: Handling FormatException when converting string to other types .................... 536
Section 92.1: Converting string to integer ............................................................................................................... 536
Chapter 93: Cryptography ([Link]) ............................................................ 538
Section 93.1: Modern Examples of Symmetric Authenticated Encryption of a string ........................................ 538
Section 93.2: Introduction to Symmetric and Asymmetric Encryption ................................................................ 549
Section 93.3: Simple Symmetric File Encryption .................................................................................................... 550
Section 93.4: Cryptographically Secure Random Data ........................................................................................ 551
Section 93.5: Password Hashing .............................................................................................................................. 552
Section 93.6: Fast Asymmetric File Encryption ...................................................................................................... 552
Chapter 94: INotifyPropertyChanged interface ...................................................................................... 557
Section 94.1: Implementing INotifyPropertyChanged in C# 6 .............................................................................. 557
Section 94.2: INotifyPropertyChanged With Generic Set Method ........................................................................ 558
Chapter 95: Value type vs Reference type ................................................................................................. 560
Section 95.1: Passing by reference using ref keyword .......................................................................................... 560
Section 95.2: Changing values elsewhere .............................................................................................................. 561
Section 95.3: ref vs out parameters ........................................................................................................................ 562
Section 95.4: Assignment ......................................................................................................................................... 563
Section 95.5: Dierence with method parameters ref and out ............................................................................ 563
Section 95.6: Passing by reference ......................................................................................................................... 564
Chapter 96: IQueryable interface .................................................................................................................... 565
Section 96.1: Translating a LINQ query to a SQL query ........................................................................................ 565
Chapter 97: Task Parallel Library (TPL) Dataflow Constructs .......................................................... 566
Section 97.1: ActionBlock<T> .................................................................................................................................... 566
Section 97.2: BroadcastBlock<T> ............................................................................................................................ 566
Section 97.3: BuerBlock<T> ................................................................................................................................... 567
Section 97.4: JoinBlock<T1, T2,…> ............................................................................................................................ 568
Section 97.5: WriteOnceBlock<T> ............................................................................................................................ 569
Section 97.6: BatchedJoinBlock<T1, T2,…> .............................................................................................................. 570
Section 97.7: TransformBlock<TInput, TOutput> ................................................................................................... 571
Section 97.8: TransformManyBlock<TInput, TOutput> ......................................................................................... 571
Section 97.9: BatchBlock<T> .................................................................................................................................... 572
Chapter 98: Stream ................................................................................................................................................. 574
Section 98.1: Using Streams ..................................................................................................................................... 574
Chapter 99: Runtime Compile ............................................................................................................................ 576
Section 99.1: RoslynScript ......................................................................................................................................... 576
Section 99.2: CSharpCodeProvider ......................................................................................................................... 576
Chapter 100: Conditional Statements ............................................................................................................ 577
Section 100.1: If-Else Statement ............................................................................................................................... 577
Section 100.2: If statement conditions are standard boolean expressions and values ..................................... 577
Section 100.3: If-Else If-Else Statement ................................................................................................................... 578
Chapter 101: Interoperability .............................................................................................................................. 579
Section 101.1: Import function from unmanaged C++ DLL .................................................................................... 579
Section 101.2: Calling conventions ........................................................................................................................... 579
Section 101.3: C++ name mangling .......................................................................................................................... 580
Section 101.4: Dynamic loading and unloading of unmanaged DLLs ................................................................. 580
Section 101.5: Reading structures with Marshal ..................................................................................................... 581
Section 101.6: Dealing with Win32 Errors ................................................................................................................. 582
Section 101.7: Pinned Object ..................................................................................................................................... 583
Section 101.8: Simple code to expose class for com .............................................................................................. 584
Chapter 102: Overflow ............................................................................................................................................ 586
Section 102.1: Integer overflow ................................................................................................................................. 586
Section 102.2: Overflow during operation .............................................................................................................. 586
Section 102.3: Ordering matters .............................................................................................................................. 586
Chapter 103: Equals and GetHashCode ......................................................................................................... 587
Section 103.1: Writing a good GetHashCode override ........................................................................................... 587
Section 103.2: Default Equals behavior ................................................................................................................... 587
Section 103.3: Override Equals and GetHashCode on custom types ................................................................... 588
Section 103.4: Equals and GetHashCode in IEqualityComparator ....................................................................... 589
Chapter 104: Type Conversion .......................................................................................................................... 591
Section 104.1: Explicit Type Conversion ................................................................................................................... 591
Section 104.2: MSDN implicit operator example .................................................................................................... 591
Chapter 105: Parallel LINQ (PLINQ) ................................................................................................................. 593
Section 105.1: Simple example .................................................................................................................................. 593
Section 105.2: WithDegreeOfParallelism ................................................................................................................. 593
Section 105.3: AsOrdered .......................................................................................................................................... 593
Section 105.4: AsUnordered ..................................................................................................................................... 593
Chapter 106: String Manipulation ..................................................................................................................... 594
Section 106.1: Replacing a string within a string ..................................................................................................... 594
Section 106.2: Finding a string within a string ........................................................................................................ 594
Section 106.3: Removing (Trimming) white-space from a string ......................................................................... 594
Section 106.4: Splitting a string using a delimiter ................................................................................................... 595
Section 106.5: Concatenate an array of strings into a single string .................................................................... 595
Section 106.6: String Concatenation ........................................................................................................................ 595
Section 106.7: Changing the case of characters within a String ........................................................................... 595
Chapter 107: String Concatenate ..................................................................................................................... 597
Section 107.1: + Operator .......................................................................................................................................... 597
Section 107.2: Concatenate strings using [Link] .................................................................. 597
Section 107.3: Concat string array elements using [Link] ............................................................................. 597
Section 107.4: Concatenation of two strings using $ ............................................................................................. 598
Chapter 108: Partial class and methods ....................................................................................................... 599
Section 108.1: Partial classes .................................................................................................................................... 599
Section 108.2: Partial classes inheriting from a base class ................................................................................... 599
Section 108.3: Partial methods ................................................................................................................................. 600
Chapter 109: Stopwatches ................................................................................................................................... 601
Section 109.1: IsHighResolution ................................................................................................................................ 601
Section 109.2: Creating an Instance of a Stopwatch ............................................................................................. 601
Chapter 110: Regex Parsing ................................................................................................................................. 603
Section 110.1: Single match ....................................................................................................................................... 603
Section 110.2: Multiple matches ................................................................................................................................ 603
Chapter 111: C# Script ............................................................................................................................................. 604
Section 111.1: Simple code evaluation ....................................................................................................................... 604
Chapter 112: Async/await, Backgroundworker, Task and Thread Examples ............................ 605
Section 112.1: [Link] Configure Await ................................................................................................................... 605
Section 112.2: Task "run and forget" extension ...................................................................................................... 607
Section 112.3: Async/await ....................................................................................................................................... 607
Section 112.4: BackgroundWorker ........................................................................................................................... 608
Section 112.5: Task ..................................................................................................................................................... 609
Section 112.6: Thread ................................................................................................................................................. 610
Chapter 113: Timers .................................................................................................................................................. 611
Section 113.1: Multithreaded Timers ......................................................................................................................... 611
Section 113.2: Creating an Instance of a Timer ...................................................................................................... 612
Section 113.3: Assigning the "Tick" event handler to a Timer ................................................................................ 613
Section 113.4: Example: Using a Timer to perform a simple countdown ............................................................. 613
Chapter 114: Function with multiple return values .................................................................................. 615
Section 114.1: "anonymous object" + "dynamic keyword" solution ...................................................................... 615
Section 114.2: Tuple solution ..................................................................................................................................... 615
Section 114.3: Ref and Out Parameters ................................................................................................................... 615
Chapter 115: Binary Serialization ...................................................................................................................... 617
Section 115.1: Controlling serialization behavior with attributes ............................................................................ 617
Section 115.2: Serialization Binder ............................................................................................................................ 617
Section 115.3: Some gotchas in backward compatibility ....................................................................................... 619
Section 115.4: Making an object serializable ........................................................................................................... 621
Section 115.5: Serialization surrogates (Implementing ISerializationSurrogate) ................................................. 622
Section 115.6: Adding more control by implementing ISerializable ...................................................................... 624
Chapter 116: Making a variable thread safe ............................................................................................... 626
Section 116.1: Controlling access to a variable in a [Link] loop ................................................................... 626
Chapter 117: IComparable .................................................................................................................................... 627
Section 117.1: Sort versions ........................................................................................................................................ 627
Chapter 118: Code Contracts ............................................................................................................................... 629
Section 118.1: Postconditions ..................................................................................................................................... 629
Section 118.2: Invariants ............................................................................................................................................ 629
Section 118.3: Defining Contracts on Interface ....................................................................................................... 630
Section 118.4: Preconditions ...................................................................................................................................... 631
Chapter 119: Iterators ............................................................................................................................................. 633
Section 119.1: Creating Iterators Using Yield ............................................................................................................ 633
Section 119.2: Simple Numeric Iterator Example .................................................................................................... 634
Chapter 120: [Link] Examples ....................................................................................................... 635
Section 120.1: Global and local AssemblyInfo ......................................................................................................... 635
Section 120.2: [AssemblyVersion] ........................................................................................................................... 635
Section 120.3: Automated versioning ...................................................................................................................... 636
Section 120.4: Common fields .................................................................................................................................. 636
Section 120.5: [AssemblyTitle] ................................................................................................................................. 636
Section 120.6: [AssemblyProduct] ........................................................................................................................... 636
Section 120.7: [InternalsVisibleTo] ........................................................................................................................... 636
Section 120.8: [AssemblyConfiguration] ................................................................................................................. 637
Section 120.9: [AssemblyKeyFile] ............................................................................................................................ 637
Section 120.10: Reading Assembly Attributes ......................................................................................................... 637
Chapter 121: File and Stream I/O ...................................................................................................................... 639
Section 121.1: Reading from a file using the [Link] class ......................................................................... 639
Section 121.2: Lazily reading a file line-by-line via an IEnumerable ..................................................................... 639
Section 121.3: Async write text to a file using StreamWriter ................................................................................. 639
Section 121.4: Copy File ............................................................................................................................................. 639
Section 121.5: Writing lines to a file using the [Link] class ..................................................... 640
Section 121.6: Writing to a file using the [Link] class ................................................................................ 640
Section 121.7: Create File ........................................................................................................................................... 641
Section 121.8: Move File ............................................................................................................................................. 641
Section 121.9: Delete File ........................................................................................................................................... 642
Section 121.10: Files and Directories ......................................................................................................................... 642
Chapter 122: Code Contracts and Assertions ............................................................................................. 643
Section 122.1: Assertions to check logic should always be true ............................................................................ 643
Chapter 123: Caching ............................................................................................................................................... 644
Section 123.1: MemoryCache .................................................................................................................................... 644
Chapter 124: Implementing Flyweight Design Pattern ......................................................................... 645
Section 124.1: Implementing map in RPG game ..................................................................................................... 645
Chapter 125: StringBuilder ................................................................................................................................... 648
Section 125.1: What a StringBuilder is and when to use one ................................................................................. 648
Section 125.2: Use StringBuilder to create string from a large number of records ........................................... 649
Chapter 126: Implementing Decorator Design Pattern ......................................................................... 650
Section 126.1: Simulating cafeteria ........................................................................................................................... 650
Chapter 127: Accessing Databases .................................................................................................................. 652
Section 127.1: Connection Strings ............................................................................................................................. 652
Section 127.2: Entity Framework Connections ....................................................................................................... 652
Section 127.3: [Link] Connections ...................................................................................................................... 653
Chapter 128: T4 Code Generation .................................................................................................................... 656
Section 128.1: Runtime Code Generation ................................................................................................................ 656
Chapter 129: [Link] ......................................................................................... 657
Section 129.1: Retrieve Specified User's Out of Oce Settings ............................................................................. 657
Section 129.2: Update Specific User's Out of Oce Settings ................................................................................ 657
Chapter 130: .NET Compiler Platform (Roslyn) ......................................................................................... 659
Section 130.1: Semantic model ................................................................................................................................. 659
Section 130.2: Syntax tree ......................................................................................................................................... 659
Section 130.3: Create workspace from MSBuild project ........................................................................................ 660
Chapter 131: Data Annotation ............................................................................................................................. 661
Section 131.1: Data Annotation Basics ...................................................................................................................... 661
Section 131.2: Creating a custom validation attribute ............................................................................................ 661
Section 131.3: Manually Execute Validation Attributes ........................................................................................... 662
Section 131.4: Validation Attributes .......................................................................................................................... 662
Section 131.5: EditableAttribute (data modeling attribute) ................................................................................... 664
Chapter 132: Using SQLite in C# ........................................................................................................................ 666
Section 132.1: Creating simple CRUD using SQLite in C# ...................................................................................... 666
Section 132.2: Executing Query ................................................................................................................................ 669
Chapter 133: [Link] ....................................................................................... 671
Section 133.1: Invoke simple synchronous pipeline ................................................................................................ 671
Chapter 134: FileSystemWatcher ..................................................................................................................... 672
Section 134.1: IsFileReady ......................................................................................................................................... 672
Section 134.2: Basic FileWatcher .............................................................................................................................. 672
Chapter 135: [Link] .............................................. 674
Section 135.1: Authenticated SSL LDAP connection, SSL cert does not match reverse DNS ............................. 674
Section 135.2: Super Simple anonymous LDAP ...................................................................................................... 675
Chapter 136: Named and Optional Arguments ......................................................................................... 676
Section 136.1: Optional Arguments ........................................................................................................................... 676
Section 136.2: Named Arguments ............................................................................................................................ 677
Chapter 137: Comments and regions ............................................................................................................. 680
Section 137.1: Comments ........................................................................................................................................... 680
Section 137.2: Regions ............................................................................................................................................... 680
Section 137.3: Documentation comments ............................................................................................................... 681
Chapter 138: C# Authentication handler ....................................................................................................... 683
Section 138.1: Authentication handler ...................................................................................................................... 683
Chapter 139: Pointers & Unsafe Code ............................................................................................................. 685
Section 139.1: Introduction to unsafe code .............................................................................................................. 685
Section 139.2: Accessing Array Elements Using a Pointer .................................................................................... 686
Section 139.3: Compiling Unsafe Code .................................................................................................................... 686
Section 139.4: Retrieving the Data Value Using a Pointer ..................................................................................... 687
Section 139.5: Passing Pointers as Parameters to Methods ................................................................................. 688
Chapter 140: Pointers ............................................................................................................................................. 689
Section 140.1: Pointers for array access .................................................................................................................. 689
Section 140.2: Pointer arithmetic ............................................................................................................................. 689
Section 140.3: The asterisk is part of the type ........................................................................................................ 690
Section 140.4: void* .................................................................................................................................................... 690
Section 140.5: Member access using -> .................................................................................................................. 690
Section 140.6: Generic pointers ................................................................................................................................ 691
Chapter 141: How to use C# Structs to create a Union type (Similar to C Unions) ................ 692
Section 141.1: C-Style Unions in C# ........................................................................................................................... 692
Section 141.2: Union Types in C# can also contain Struct fields ........................................................................... 693
Chapter 142: BigInteger ........................................................................................................................................ 695
Section 142.1: Calculate the First 1,000-Digit Fibonacci Number .......................................................................... 695
Chapter 143: Dependency Injection ................................................................................................................ 696
Section 143.1: Dependency Injection C# and [Link] with Unity ........................................................................ 696
Section 143.2: Dependency injection using MEF ..................................................................................................... 698
Chapter 144: Reactive Extensions (Rx) ......................................................................................................... 701
Section 144.1: Observing TextChanged event on a TextBox ................................................................................. 701
Section 144.2: Streaming Data from Database with Observable ......................................................................... 701
Chapter 145: Creational Design Patterns .................................................................................................... 702
Section 145.1: Singleton Pattern ............................................................................................................................... 702
Section 145.2: Factory Method pattern ................................................................................................................... 703
Section 145.3: Abstract Factory Pattern .................................................................................................................. 706
Section 145.4: Builder Pattern ................................................................................................................................... 708
Section 145.5: Prototype Pattern ............................................................................................................................. 712
Chapter 146: Creating a Console Application using a Plain-Text Editor and the C#
Compiler ([Link]) .................................................................................................................................................... 715
Section 146.1: Creating a Console application using a Plain-Text Editor and the C# Compiler ........................ 715
Chapter 147: Reading and writing .zip files ................................................................................................ 717
Section 147.1: Writing to a zip file ............................................................................................................................. 717
Section 147.2: Writing Zip Files in-memory ............................................................................................................. 717
Section 147.3: Get files from a Zip file ..................................................................................................................... 717
Section 147.4: The following example shows how to open a zip archive and extract all .txt files to a folder
............................................................................................................................................................................. 718
Chapter 148: Lambda Expressions .................................................................................................................. 719
Section 148.1: Using lambda syntax to create a closure ....................................................................................... 719
Section 148.2: Basic lambda expressions ............................................................................................................... 719
Section 148.3: Basic lambda expressions with LINQ .............................................................................................. 720
Section 148.4: Lambda syntax with statement block body .................................................................................. 720
Section 148.5: Lambda expressions with [Link] ...................................................................... 720
Chapter 149: Generic Lambda Query Builder ............................................................................................ 721
Section 149.1: QueryFilter class ................................................................................................................................ 721
Section 149.2: GetExpression Method ...................................................................................................................... 721
Section 149.3: GetExpression Private overload ....................................................................................................... 722
Section 149.4: ConstantExpression Method ............................................................................................................ 723
Section 149.5: Usage ................................................................................................................................................. 724
Chapter 150: Import Google Contacts ........................................................................................................... 725
Section 150.1: Requirements ..................................................................................................................................... 725
Section 150.2: Source code in the controller ........................................................................................................... 725
Section 150.3: Source code in the view .................................................................................................................... 728
Chapter 151: CLSCompliantAttribute ............................................................................................................... 729
Section 151.1: Access Modifier to which CLS rules apply ........................................................................................ 729
Section 151.2: Violation of CLS rule: Unsigned types / sbyte ................................................................................ 729
Section 151.3: Violation of CLS rule: Same naming ................................................................................................. 730
Section 151.4: Violation of CLS rule: Identifier _ ...................................................................................................... 731
Section 151.5: Violation of CLS rule: Inherit from non CLSComplaint class .......................................................... 731
Chapter 152: ObservableCollection<T> .......................................................................................................... 732
Section 152.1: Initialize ObservableCollection<T> ................................................................................................... 732
Chapter 153: Synchronization Context in Async-Await .......................................................................... 733
Section 153.1: Pseudocode for async/await keywords .......................................................................................... 733
Section 153.2: Disabling synchronization context .................................................................................................. 733
Section 153.3: Why SynchronizationContext is so important? .............................................................................. 734
Chapter 154: ICloneable ........................................................................................................................................ 735
Section 154.1: Implementing ICloneable in a class ................................................................................................. 735
Section 154.2: Implementing ICloneable in a struct ............................................................................................... 735
Chapter 155: Read & Understand Stacktraces ......................................................................................... 737
Section 155.1: Stack trace for a simple NullReferenceException in Windows Forms ......................................... 737
Chapter 156: Linq to Objects ............................................................................................................................... 739
Section 156.1: Using LINQ to Objects in C# ............................................................................................................. 739
Chapter 157: [Link] Identity ........................................................................................................................... 743
Section 157.1: How to implement password reset token in [Link] identity using user manager .................... 743
Chapter 158: Access network shared folder with username and password .............................. 746
Section 158.1: Code to access network shared file ................................................................................................. 746
Chapter 159: Asynchronous Socket ................................................................................................................. 748
Section 159.1: Asynchronous Socket (Client / Server) example ........................................................................... 748
Chapter 160: Structural Design Patterns ...................................................................................................... 755
Section 160.1: Adapter Design Pattern .................................................................................................................... 755
Chapter 161: O(n) Algorithm for circular rotation of an array .......................................................... 759
Section 161.1: Example of a generic method that rotates an array by a given shift .......................................... 759
Chapter 162: Creating Own MessageBox in Windows Form Application ...................................... 761
Section 162.1: How to use own created MessageBox control in another Windows Form application ............. 761
Section 162.2: Creating Own MessageBox Control ................................................................................................ 761
Chapter 163: Including Font Resources ......................................................................................................... 764
Section 163.1: Instantiate 'Fontfamily' from Resources .......................................................................................... 764
Section 163.2: Integration method ........................................................................................................................... 764
Section 163.3: Usage with a 'Button' ........................................................................................................................ 764
Chapter 164: Using [Link] ................................................................................................................................. 766
Section 164.1: Using JsonConverter on simple values ........................................................................................... 766
Section 164.2: Collect all fields of JSON object ...................................................................................................... 768
Chapter 165: Windows Communication Foundation ............................................................................... 770
Section 165.1: Getting started sample ...................................................................................................................... 770
Credits ............................................................................................................................................................................ 772
You may also like ...................................................................................................................................................... 786
About

Please feel free to share this PDF with anyone for free,
latest version of this book can be downloaded from:
[Link]

This C# Notes for Professionals book is compiled from Stack Overflow


Documentation, the content is written by the beautiful people at Stack Overflow.
Text content is released under Creative Commons BY-SA, see credits at the end
of this book whom contributed to the various chapters. Images may be copyright
of their respective owners unless otherwise specified

This is an unofficial free book created for educational purposes and is not
affiliated with official C# group(s) or company(s) nor Stack Overflow. All
trademarks and registered trademarks are the property of their respective
company owners

The information presented in this book is not guaranteed to be correct nor


accurate, use at your own risk

Please send feedback and corrections to web@[Link]

[Link] – C# Notes for Professionals 1


Chapter 1: Getting started with C#
Language
Version Release Date
1.0 2002-01-01
1.2 2003-04-01
2.0 2005-09-01
3.0 2007-08-01
4.0 2010-04-01
5.0 2013-06-01
6.0 2015-07-01
7.0 2017-03-07

Section 1.1: Creating a new console application (Visual Studio)


1. Open Visual Studio
2. In the toolbar, go to File → New Project
3. Select the Console Application project type
4. Open the file [Link] in the Solution Explorer
5. Add the following code to Main():

public class Program


{
public static void Main()
{
// Prints a message to the console.
[Link]("Hello, World!");

/* Wait for the user to press a key. This is a common


way to prevent the console window from terminating
and disappearing before the programmer can see the contents
of the window, when the application is run via Start from within VS. */
[Link]();
}
}

6. In the toolbar, click Debug -> Start Debugging or hit F5 or ctrl + F5 (running without debugger) to run the
program.

Live Demo on ideone

Explanation

class Program is a class declaration. The class Program contains the data and method definitions that your
program uses. Classes generally contain multiple methods. Methods define the behavior of the class.
However, the Program class has only one method: Main.

static void Main() defines the Main method, which is the entry point for all C# programs. The Main method
states what the class does when executed. Only one Main method is allowed per class.

[Link]("Hello, world!"); method prints a given data (in this example, Hello,
world!) as an output in the console window.

[Link] – C# Notes for Professionals 2


[Link](), ensures that the program won't close immediately after displaying the message.
It does this by waiting for the user to press a key on the keyboard. Any key press from the user will terminate
the program. The program terminates when it has finished the last line of code in the main() method.

Using the command line

To compile via command line use either MSBuild or [Link] (the C# compiler), both part of the Microsoft Build Tools
package.

To compile this example, run the following command in the same directory where [Link] is located:

%WINDIR%\\[Link]\\Framework64\\v4.0.30319\\[Link] [Link]

It can also be possible that you have two main methods inside one application. In this case, you have to tell the
compiler which main method to execute by typing the following command in the console.(suppose Class ClassA
also has a main method in the same [Link] file in HelloWorld namespace)

%WINDIR%\\[Link]\\Framework64\\v4.0.30319\\[Link] [Link] /main:[Link]

where HelloWorld is namespace

Note: This is the path where .NET framework v4.0 is located in general. Change the path according to your .NET version.
In addition, the directory might be framework instead of framework64 if you're using the 32-bit .NET Framework. From
the Windows Command Prompt, you can list all the [Link] Framework paths by running the following commands (the first
for 32-bit Frameworks):

dir %WINDIR%\\[Link]\\Framework\\[Link] /s/b


dir %WINDIR%\\[Link]\\Framework64\\[Link] /s/b

There should now be an executable file named [Link] in the same directory. To execute the program
from the command prompt, simply type the executable's name and hit Enter as follows:

[Link]

This will produce:

Hello, world!

[Link] – C# Notes for Professionals 3


You may also double click the executable and launch a new console window with the message "Hello, world!"

Section 1.2: Creating a new project in Visual Studio (console


application) and Running it in Debug mode
1. Download and install Visual Studio. Visual Studio can be downloaded from [Link]. The
Community edition is suggested, first because it is free, and second because it involves all the general
features and can be extended further.

2. Open Visual Studio.

3. Welcome. Go to File → New → Project.

4. Click Templates → Visual C# → Console Application

[Link] – C# Notes for Professionals 4


5. After selecting Console Application, Enter a name for your project, and a location to save and press OK .
Don't worry about the Solution name.

6. Project created. The newly created project will look similar to:

(Always use descriptive names for projects so that they can easily be distinguished from other projects. It is
recommended not to use spaces in project or class name.)

[Link] – C# Notes for Professionals 5


7. Write code. You can now update your [Link] to present "Hello world!" to the user.

using System;

namespace ConsoleApplication1
{
public class Program
{
public static void Main(string[] args)
{
}
}
}

Add the following two lines to the public static void Main(string[] args) object in [Link]: (make
sure it's inside the braces)

[Link]("Hello world!");
[Link]();

Why [Link]()? The first line prints out the text "Hello world!" to the console, and the second line
waits for a single character to be entered; in effect, this causes the program to pause execution so that you're
able to see the output while debugging. Without [Link]();, when you start debugging the application
it will just print "Hello world!" to the console and then immediately close. Your code window should now look
like the following:

using System;

namespace ConsoleApplication1
{
public class Program
{
public static void Main(string[] args)
{
[Link]("Hello world!");
[Link]();
}
}
}

8. Debug your program. Press the Start Button on the toolbar near the top of the window or press
F5 on your keyboard to run your application. If the button is not present, you can run the program from
the top menu: Debug → Start Debugging. The program will compile and then open a console window. It
should look similar to the following screenshot:

[Link] – C# Notes for Professionals 6


9. Stop the program. To close the program, just press any key on your keyboard. The [Link]() we
added was for this same purpose. Another way to close the program is by going to the menu where the
Start button was, and clicking on the Stop button.

Section 1.3: Creating a new program using .NET Core


First install the .NET Core SDK by going through the installation instructions for the platform of your choice:

Windows
OSX
Linux
Docker

After the installation has completed, open a command prompt, or terminal window.

1. Create a new directory with mkdir hello_world and change into the newly created directory with cd
hello_world.

2. Create a new console application with dotnet new console.


This will produce two files:

hello_world.csproj

<Project Sdk="[Link]">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp1.1</TargetFramework>
</PropertyGroup>

</Project>

[Link]

using System;

[Link] – C# Notes for Professionals 7


namespace hello_world
{
class Program
{
static void Main(string[] args)
{
[Link]("Hello World!");
}
}
}

3. Restore the needed packages with dotnet restore.

4. Optional Build the application with dotnet build for Debug or dotnet build -c Release for Release. dotnet
run will also run the compiler and throw build errors, if any are found.

5. Run the application with dotnet run for Debug or dotnet run
.\bin\Release\netcoreapp1.1\hello_world.dll for Release.

Command Prompt output

[Link] – C# Notes for Professionals 8


Section 1.4: Creating a new program using Mono
First install Mono by going through the install instructions for the platform of your choice as described in their
installation section.

Mono is available for Mac OS X, Windows and Linux.

After installation is done, create a text file, name it [Link] and copy the following content into it:

public class Program


{
public static void Main()
{
[Link]("Hello, world!");
[Link]("Press any key to exit..");
[Link]();
}
}

If you are using Windows, run the Mono Command Prompt which is included in the Mono installation and ensures
that the necessary environment variables are set. If on Mac or Linux, open a new terminal.

To compile the newly created file, run the following command in the directory containing [Link]:

mcs -out:[Link] [Link]

The resulting [Link] can then be executed with:

mono [Link]

which will produce the output:

Hello, world!
Press any key to exit..

Section 1.5: Creating a new query using LinqPad


LinqPad is a great tool that allows you to learn and test features of .Net languages (C#, F# and [Link].)

1. Install LinqPad

2. Create a new Query ( Ctrl + N )

[Link] – C# Notes for Professionals 9


3. Under language, select "C# statements"

4. Type the following code and hit run ( F5 )

string hw = "Hello World";

[Link](); //or [Link](hw);

[Link] – C# Notes for Professionals 10


5. You should see "Hello World" printed out in the results screen.

6. Now that you have created your first .Net program, go and check out the samples included in LinqPad via the
"Samples" browser. There are many great examples that will show you many different features of the .Net
languages.

Notes:

1. If you click on "IL", you can inspect the IL code that your .net code generates. This is a great learning tool.

[Link] – C# Notes for Professionals 11


2. When using LINQ to SQL or Linq to Entities you can inspect the SQL that's being generated which is
another great way to learn about LINQ.

Section 1.6: Creating a new project using Xamarin Studio


1. Download and install Xamarin Studio Community.
2. Open Xamarin Studio.
3. Click File → New → Solution.

[Link] – C# Notes for Professionals 12


4. Click .NET → Console Project and choose C#.
5. Click Next to proceed.

[Link] – C# Notes for Professionals 13


6. Enter the Project Name and Browse... for a Location to Save and then click Create .

[Link] – C# Notes for Professionals 14


7. The newly created project will look similar to:

8. This is the code in the Text Editor:

[Link] – C# Notes for Professionals 15


using System;

namespace FirstCsharp
{
public class MainClass
{
public static void Main(string[] args)
{
[Link]("Hello World!");
[Link]();
}
}
}

9. To run the code, press F5 or click the Play Button as shown below:

10. Following is the Output:

[Link] – C# Notes for Professionals 16


[Link] – C# Notes for Professionals 17
Chapter 2: Verbatim Strings
Section 2.1: Interpolated Verbatim Strings
Verbatim strings can be combined with the new String interpolation features found in C#6.

[Link]($@"Testing \n 1 2 {5 - 2}
New line");

Output:

Testing \n 1 2 3
New line

Live Demo on .NET Fiddle

As expected from a verbatim string, the backslashes are ignored as escape characters. And as expected from an
interpolated string, any expression inside curly braces is evaluated before being inserted into the string at that
position.

Section 2.2: Escaping Double Quotes


Double Quotes inside verbatim strings can be escaped by using 2 sequential double quotes "" to represent one
double quote " in the resulting string.

var str = @"""I don't think so,"" he said.";


[Link](str);

Output:

"I don't think so," he said.

Live Demo on .NET Fiddle

Section 2.3: Verbatim strings instruct the compiler to not use


character escapes
In a normal string, the backslash character is the escape character, which instructs the compiler to look at the next
character(s) to determine the actual character in the string. (Full list of character escapes)

In verbatim strings, there are no character escapes (except for "" which is turned into a "). To use a verbatim string,
just prepend a @ before the starting quotes.

This verbatim string

var filename = @"c:\temp\[Link]"

Output:

[Link] – C# Notes for Professionals 18


c:\temp\newfi[Link]

As opposed to using an ordinary (non-verbatim) string:

var filename = "c:\temp\[Link]"

that will output:

c: emp
[Link]

using character escaping. (The \t is replaced with a tab character and the \n is replace with a newline.)

Live Demo on .NET Fiddle

Section 2.4: Multiline Strings


var multiLine = @"This is a

multiline paragraph";

Output:

This is a

multiline paragraph

Live Demo on .NET Fiddle

Multi-line strings that contain double-quotes can also be escaped just as they were on a single line, because they
are verbatim strings.

var multilineWithDoubleQuotes = @"I went to a city named

""San Diego""

during summer vacation.";

Live Demo on .NET Fiddle

It should be noted that the spaces/tabulations at the start of lines 2 and 3 here are actually present in the value of the
variable; check this question for possible solutions.

[Link] – C# Notes for Professionals 19


Chapter 3: Operators
Parameter Details
operatorSymbol The operator being overloaded, e.g. +, -, /, *
OperandType The type that will be returned by the overloaded operator.
operand1 The first operand to be used in performing the operation.
operand2 The second operand to be used in performing the operation, when doing binary operations.
statements Optional code needed to perform the operation before returning the result.

In C#, an operator is a program element that is applied to one or more operands in an expression or statement.
Operators that take one operand, such as the increment operator (++) or new, are referred to as unary operators.
Operators that take two operands, such as arithmetic operators (+,-,*,/), are referred to as binary operators. One
operator, the conditional operator (?:), takes three operands and is the sole ternary operator in C#.

Section 3.1: Overloadable Operators


C# allows user-defined types to overload operators by defining static member functions using the operator
keyword.
The following example illustrates an implementation of the + operator.

If we have a Complex class which represents a complex number:

public struct Complex


{
public double Real { get; set; }
public double Imaginary { get; set; }
}

And we want to add the option to use the + operator for this class. i.e.:

Complex a = new Complex() { Real = 1, Imaginary = 2 };


Complex b = new Complex() { Real = 4, Imaginary = 8 };
Complex c = a + b;

We will need to overload the + operator for the class. This is done using a static function and the operator keyword:

public static Complex operator +(Complex c1, Complex c2)


{
return new Complex
{
Real = [Link] + [Link],
Imaginary = [Link] + [Link]
};
}

Operators such as +, -, *, / can all be overloaded. This also includes Operators that don't return the same type (for
example, == and != can be overloaded, despite returning booleans) The rule below relating to pairs is also enforced
here.

Comparison operators have to be overloaded in pairs (e.g. if < is overloaded, > also needs to be overloaded).

A full list of overloadable operators (as well as non-overloadable operators and the restrictions placed on some
overloadable operators) can be seen at MSDN - Overloadable Operators (C# Programming Guide).

[Link] – C# Notes for Professionals 20


Version ≥ 7.0

overloading of operator is was introduced with the pattern matching mechanism of C# 7.0. For details see Pattern
Matching

Given a type Cartesian defined as follows

public class Cartesian


{
public int X { get; }
public int Y { get; }
}

An overloadable operator is could e.g. be defined for Polar coordinates

public static class Polar


{
public static bool operator is(Cartesian c, out double R, out double Theta)
{
R = [Link](c.X*c.X + c.Y*c.Y);
Theta = Math.Atan2(c.Y, c.X);
return c.X != 0 || c.Y != 0;
}
}

which can be used like this

var c = Cartesian(3, 4);


if (c is Polar(var R, *))
{
[Link](R);
}

(The example is taken from the Roslyn Pattern Matching Documentation)

Section 3.2: Overloading equality operators


Overloading just equality operators is not enough. Under different circumstances, all of the following can be called:

1. [Link] and [Link]


2. IEquatable<T>.Equals (optional, allows avoiding boxing)
3. operator == and operator != (optional, allows using operators)

When overriding Equals, GetHashCode must also be overridden. When implementing Equals, there are many
special cases: comparing to objects of a different type, comparing to self etc.

When NOT overridden Equals method and == operator behave differently for classes and structs. For classes just
references are compared, and for structs values of properties are compared via reflection what can negatively
affect performance. == can not be used for comparing structs unless it is overridden.

Generally equality operation must obey the following rules:

Must not throw exceptions.


Reflexivity: A always equals A (may not be true for NULL values in some systems).
Transitvity: if A equals B, and B equals C, then A equals C.
If A equals B, then A and B have equal hash codes.

[Link] – C# Notes for Professionals 21


Inheritance tree independence: if B and C are instances of Class2 inherited from Class1:
[Link](A,B) must always return the same value as the call to [Link](A,B).

class Student : IEquatable<Student>


{
public string Name { get; set; } = "";

public bool Equals(Student other)


{
if (ReferenceEquals(other, null)) return false;
if (ReferenceEquals(other, this)) return true;
return [Link](Name, [Link]);
}

public override bool Equals(object obj)


{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;

return Equals(obj as Student);


}

public override int GetHashCode()


{
return Name?.GetHashCode() ?? 0;
}

public static bool operator ==(Student left, Student right)


{
return Equals(left, right);
}

public static bool operator !=(Student left, Student right)


{
return !Equals(left, right);
}
}

Section 3.3: Relational Operators


Equals

Checks whether the supplied operands (arguments) are equal

"a" == "b" // Returns false.


"a" == "a" // Returns true.
1 == 0 // Returns false.
1 == 1 // Returns true.
false == true // Returns false.
false == false // Returns true.

Unlike Java, the equality comparison operator works natively with strings.

The equality comparison operator will work with operands of differing types if an implicit cast exists from one to
the other. If no suitable implicit cast exists, you may call an explicit cast or use a method to convert to a compatible
type.

1 == 1.0 // Returns true because there is an implicit cast from int to double.
new Object() == 1.0 // Will not compile.

[Link] – C# Notes for Professionals 22


[Link]() == 1 // Calls AsInt() on MyStruct and compares the resulting int with 1.

Unlike Visual [Link], the equality comparison operator is not the same as the equality assignment operator.

var x = new Object();


var y = new Object();
x == y // Returns false, the operands (objects in this case) have different references.
x == x // Returns true, both operands have the same reference.

Not to be confused with the assignment operator (=).

For value types, the operator returns true if both operands are equal in value.
For reference types, the operator returns true if both operands are equal in reference (not value). An exception is
that string objects will be compared with value equality.

Not Equals

Checks whether the supplied operands are not equal.

"a" != "b" // Returns true.


"a" != "a" // Returns false.
1 != 0 // Returns true.
1 != 1 // Returns false.
false != true // Returns true.
false != false // Returns false.

var x = new Object();


var y = new Object();
x != y // Returns true, the operands have different references.
x != x // Returns false, both operands have the same reference.

This operator effectively returns the opposite result to that of the equals (==) operator

Greater Than

Checks whether the first operand is greater than the second operand.

3 > 5 //Returns false.


1 > 0 //Returns true.
2 > 2 //Return false.

var x = 10;
var y = 15;
x > y //Returns false.
y > x //Returns true.

Less Than

Checks whether the first operand is less than the second operand.

2 < 4 //Returns true.


1 < -3 //Returns false.
2 < 2 //Return false.

var x = 12;
var y = 22;
x < y //Returns true.
y < x //Returns false.

[Link] – C# Notes for Professionals 23


Greater Than Equal To

Checks whether the first operand is greater than equal to the second operand.

7 >= 8 //Returns false.


0 >= 0 //Returns true.

Less Than Equal To

Checks whether the first operand is less than equal to the second operand.

2 <= 4 //Returns true.


1 <= -3 //Returns false.
1 <= 1 //Returns true.

Section 3.4: Implicit Cast and Explicit Cast Operators


C# allows user-defined types to control assignment and casting through the use of the explicit and implicit
keywords. The signature of the method takes the form:

public static <implicit/explicit> operator <ResultingType>(<SourceType> myType)

The method cannot take any more arguments, nor can it be an instance method. It can, however, access any private
members of type it is defined within.

An example of both an implicit and explicit cast:

public class BinaryImage


{
private bool[] _pixels;

public static implicit operator ColorImage(BinaryImage im)


{
return new ColorImage(im);
}

public static explicit operator bool[](BinaryImage im)


{
return im._pixels;
}
}

Allowing the following cast syntax:

var binaryImage = new BinaryImage();


ColorImage colorImage = binaryImage; // implicit cast, note the lack of type
bool[] pixels = (bool[])binaryImage; // explicit cast, defining the type

The cast operators can work both ways, going from your type and going to your type:

public class BinaryImage


{
public static explicit operator ColorImage(BinaryImage im)
{
return new ColorImage(im);
}

[Link] – C# Notes for Professionals 24


public static explicit operator BinaryImage(ColorImage cm)
{
return new BinaryImage(cm);
}
}

Finally, the as keyword, which can be involved in casting within a type hierarchy, is not valid in this situation. Even
after defining either an explicit or implicit cast, you cannot do:

ColorImage cm = myBinaryImage as ColorImage;

It will generate a compilation error.

Section 3.5: Short-circuiting Operators


By definition, the short-circuiting boolean operators will only evaluate the second operand if the first operand can not
determine the overall result of the expression.

It means that, if you are using && operator as firstCondition && secondCondition it will evaluate secondCondition only
when firstCondition is true and ofcource the overall result will be true only if both of firstOperand and secondOperand
are evaluated to true. This is useful in many scenarios, for example imagine that you want to check whereas your
list has more than three elements but you also have to check if list has been initialized to not run into
NullReferenceException. You can achieve this as below:

bool hasMoreThanThreeElements = myList != null && [Link] > 3;

[Link] > 3 will not be checked untill myList != null is met.

Logical AND

&& is the short-circuiting counterpart of the standard boolean AND (&) operator.

var x = true;
var y = false;

x && x // Returns true.


x && y // Returns false (y is evaluated).
y && x // Returns false (x is not evaluated).
y && y // Returns false (right y is not evaluated).

Logical OR

|| is the short-circuiting counterpart of the standard boolean OR (|) operator.

var x = true;
var y = false;

x || x // Returns true (right x is not evaluated).


x || y // Returns true (y is not evaluated).
y || x // Returns true (x and y are evaluated).
y || y // Returns false (y and y are evaluated).

Example usage

if(object != null && [Link])


// [Link] is never accessed if object is null, because of the short circuit.

[Link] – C# Notes for Professionals 25


Action1();
else
Action2();

Section 3.6: ? : Ternary Operator


Returns one of two values depending on the value of a Boolean expression.

Syntax:

condition ? expression_if_true : expression_if_false;

Example:

string name = "Frank";


[Link](name == "Frank" ? "The name is Frank" : "The name is not Frank");

The ternary operator is right-associative which allows for compound ternary expressions to be used. This is done by
adding additional ternary equations in either the true or false position of a parent ternary equation. Care should be
taken to ensure readability, but this can be useful shorthand in some circumstances.

In this example, a compound ternary operation evaluates a clamp function and returns the current value if it's
within the range, the min value if it's below the range, or the max value if it's above the range.

[Link] = Clamp([Link], minLight, maxLight);

public static float Clamp(float val, float min, float max)


{
return (val < min) ? min : (val > max) ? max : val;
}

Ternary operators can also be nested, such as:

a ? b ? "a is true, b is true" : "a is true, b is false" : "a is false"

// This is evaluated from left to right and can be more easily seen with parenthesis:

a ? (b ? x : y) : z

// Where the result is x if a && b, y if a && !b, and z if !a

When writing compound ternary statements, it's common to use parenthesis or indentation to improve readability.

The types of expression_if_true and expression_if_false must be identical or there must be an implicit conversion from
one to the other.

condition ? 3 : "Not three"; // Doesn't compile because `int` and `string` lack an implicit
conversion.

condition ? [Link]() : "Not three"; // OK because both possible outputs are strings.

condition ? 3 : 3.5; // OK because there is an implicit conversion from `int` to `double`. The
ternary operator will return a `double`.

condition ? 3.5 : 3; // OK because there is an implicit conversion from `int` to `double`. The
ternary operator will return a `double`.

[Link] – C# Notes for Professionals 26


The type and conversion requirements apply to your own classes too.

public class Car


{}

public class SportsCar : Car


{}

public class SUV : Car


{}

condition ? new SportsCar() : new Car(); // OK because there is an implicit conversion from
`SportsCar` to `Car`. The ternary operator will return a reference of type `Car`.

condition ? new Car() : new SportsCar(); // OK because there is an implicit conversion from
`SportsCar` to `Car`. The ternary operator will return a reference of type `Car`.

condition ? new SportsCar() : new SUV(); // Doesn't compile because there is no implicit conversion
from `SportsCar` to SUV or `SUV` to `SportsCar`. The compiler is not smart enough to realize that
both of them have an implicit conversion to `Car`.

condition ? new SportsCar() as Car : new SUV() as Car; // OK because both expressions evaluate to a
reference of type `Car`. The ternary operator will return a reference of type `Car`.

Section 3.7: ?. (Null Conditional Operator)


Version ≥ 6.0

Introduced in C# 6.0, the Null Conditional Operator ?. will immediately return null if the expression on its left-
hand side evaluates to null, instead of throwing a NullReferenceException. If its left-hand side evaluates to a non-
null value, it is treated just like a normal . operator. Note that because it might return null, its return type is
always a nullable type. That means that for a struct or primitive type, it is wrapped into a Nullable<T>.

var bar = [Link]()?.Value; // will return null if GetBar() returns null


var baz = [Link]()?.IntegerValue; // baz will be of type Nullable<int>, i.e. int?

This comes handy when firing events. Normally you would have to wrap the event call in an if statement checking
for null and raise the event afterwards, which introduces the possibility of a race condition. Using the Null
conditional operator this can be fixed in the following way:

event EventHandler<string> RaiseMe;


RaiseMe?.Invoke("Event raised");

Section 3.8: "Exclusive or" Operator


The operator for an "exclusive or" (for short XOR) is: ^

This operator returns true when one, but only one, of the supplied bools are true.

true ^ false // Returns true


false ^ true // Returns true
false ^ false // Returns false
true ^ true // Returns false

[Link] – C# Notes for Professionals 27


Section 3.9: default Operator
Value Type (where T : struct)

The built-in primitive data types, such as char, int, and float, as well as user-defined types declared with struct,
or enum. Their default value is new T() :

default(int) // 0
default(DateTime) // 0001-01-01 [Link] AM
default(char) // '\0' This is the "null character", not a zero or a line break.
default(Guid) // 00000000-0000-0000-0000-000000000000
default(MyStruct) // new MyStruct()

// Note: default of an enum is 0, and not the first *key* in that enum
// so it could potentially fail the [Link] test
default(MyEnum) // (MyEnum)0

Reference Type (where T : class)

Any class, interface, array or delegate type. Their default value is null :

default(object) // null
default(string) // null
default(MyClass) // null
default(IDisposable) // null
default(dynamic) // null

Section 3.10: Assignment operator '='


The assignment operator = sets thr left hand operand's value to the value of right hand operand, and return that
value:

int a = 3; // assigns value 3 to variable a


int b = a = 5; // first assigns value 5 to variable a, then does the same for variable b
[Link](a = 3 + 4); // prints 7

Section 3.11: sizeof


Returns an int holding the size of a type* in bytes.

sizeof(bool) // Returns 1.
sizeof(byte) // Returns 1.
sizeof(sbyte) // Returns 1.
sizeof(char) // Returns 2.
sizeof(short) // Returns 2.
sizeof(ushort) // Returns 2.
sizeof(int) // Returns 4.
sizeof(uint) // Returns 4.
sizeof(float) // Returns 4.
sizeof(long) // Returns 8.
sizeof(ulong) // Returns 8.
sizeof(double) // Returns 8.
sizeof(decimal) // Returns 16.

*Only supports certain primitive types in safe context.

[Link] – C# Notes for Professionals 28


In an unsafe context, sizeof can be used to return the size of other primitive types and structs.

public struct CustomType


{
public int value;
}

static void Main()


{
unsafe
{
[Link](sizeof(CustomType)); // outputs: 4
}
}

Section 3.12: ?? Null-Coalescing Operator


The Null-Coalescing operator ?? will return the left-hand side when not null. If it is null, it will return the right-hand
side.

object foo = null;


object bar = new object();

var c = foo ?? bar;


//c will be bar since foo was null

The ?? operator can be chained which allows the removal of if checks.

//config will be the first non-null returned.


var config = RetrieveConfigOnMachine() ??
RetrieveConfigFromService() ??
new DefaultConfiguration();

Section 3.13: Bit-Shifting Operators


The shift operators allow programmers to adjust an integer by shifting all of its bits to the left or the right. The
following diagram shows the affect of shifting a value to the left by one digit.

Left-Shift

uint value = 15; // 00001111

uint doubled = value << 1; // Result = 00011110 = 30


uint shiftFour = value << 4; // Result = 11110000 = 240

Right-Shift

uint value = 240; // 11110000

uint halved = value >> 1; // Result = 01111000 = 120


uint shiftFour = value >> 4; // Result = 00001111 = 15

Section 3.14: => Lambda operator


Version ≥ 3.0

[Link] – C# Notes for Professionals 29


The => operator has the same precedence as the assignment operator = and is right-associative.

It is used to declare lambda expressions and also it is widely used with LINQ Queries:

string[] words = { "cherry", "apple", "blueberry" };

int shortestWordLength = [Link]((string w) => [Link]); //5

When used in LINQ extensions or queries the type of the objects can usually be skipped as it is inferred by the
compiler:

int shortestWordLength = [Link](w => [Link]); //also compiles with the same result

The general form of lambda operator is the following:

(input parameters) => expression

The parameters of the lambda expression are specified before => operator, and the actual
expression/statement/block to be executed is to the right of the operator:

// expression
(int x, string s) => [Link] > x

// expression
(int x, int y) => x + y

// statement
(string x) => [Link](x)

// block
(string x) => {
x += " says Hello!";
[Link](x);
}

This operator can be used to easily define delegates, without writing an explicit method:

delegate void TestDelegate(string s);

TestDelegate myDelegate = s => [Link](s + " World");

myDelegate("Hello");

instead of

void MyMethod(string s)
{
[Link](s + " World");
}

delegate void TestDelegate(string s);

TestDelegate myDelegate = MyMethod;

myDelegate("Hello");

[Link] – C# Notes for Professionals 30


Section 3.15: Class Member Operators: Null Conditional
Member Access
var zipcode = myEmployee?.Address?.ZipCode;
//returns null if the left operand is null.
//the above is the equivalent of:
var zipcode = (string)null;
if (myEmployee != null && [Link] != null)
zipcode = [Link];

Section 3.16: Class Member Operators: Null Conditional


Indexing
var letters = null;
char? letter = letters?[1];
[Link]("Second Letter is {0}",letter);
//in the above example rather than throwing an error because letters is null
//letter is assigned the value null

Section 3.17: Postfix and Prefix increment and decrement


Postfix increment X++ will add 1 to x

var x = 42;
x++;
[Link](x); // 43

Postfix decrement

X--

will subtract one


var x = 42
x--;
[Link](x); // 41

++x is called prefix increment it increments the value of x and then returns x while x++ returns the value of x and
then increments

var x = 42;
[Link](++x); // 43
[Link](x); // 43

while

var x = 42;
[Link](x++); // 42
[Link](x); // 43

both are commonly used in for loop

for(int i = 0; i < 10; i++)


{
}

[Link] – C# Notes for Professionals 31


Section 3.18: typeof
Gets [Link] object for a type.

[Link] type = typeof(Point) //[Link]


[Link] type = typeof(IDisposable) //[Link]
[Link] type = typeof(Colors) //[Link]
[Link] type = typeof(List<>) //[Link]`1[T]

To get the run-time type, use GetType method to obtain the [Link] of the current instance.

Operator typeof takes a type name as parameter, which is specified at compile time.

public class Animal {}


public class Dog : Animal {}

var animal = new Dog();

[Link]([Link]() == typeof(Animal)); // fail, animal is typeof(Dog)


[Link]([Link]() == typeof(Dog)); // pass, animal is typeof(Dog)
[Link](animal is Animal); // pass, animal implements Animal

Section 3.19: Binary operators with assignment


C# has several operators that can be combined with an = sign to evaluate the result of the operator and then assign
the result to the original variable.

Example:

x += y

is the same as

x = x + y

Assignment operators:

+=
-=
*=
/=
%=
&=
|=
^=
<<=
>>=

Section 3.20: nameof Operator


Returns a string that represents the unqualified name of a variable, type, or member.

int counter = 10;


nameof(counter); // Returns "counter"
Client client = new Client();

[Link] – C# Notes for Professionals 32


nameof([Link])); // Returns "PostalCode"

The nameof operator was introduced in C# 6.0. It is evaluated at compile-time and the returned string value is
inserted inline by the compiler, so it can be used in most cases where the constant string can be used (e.g., the case
labels in a switch statement, attributes, etc...). It can be useful in cases like raising & logging exceptions, attributes,
MVC Action links, etc...

Section 3.21: Class Member Operators: Member Access


var now = [Link];
//accesses member of a class. In this case the UtcNow property.

Section 3.22: Class Member Operators: Function Invocation


var age = GetAge(dateOfBirth);
//the above calls the function GetAge passing parameter dateOfBirth.

Section 3.23: Class Member Operators: Aggregate Object


Indexing
var letters = "letters".ToCharArray();
char letter = letters[1];
[Link]("Second Letter is {0}",letter);
//in the above example we take the second character from the array
//by calling letters[1]
//NB: Array Indexing starts at 0; i.e. the first letter would be given by letters[0].

[Link] – C# Notes for Professionals 33


Chapter 4: Extension Methods
Parameter Details
The first parameter of an extension method should always be preceded by the this keyword, followed
this
by the identifier with which to refer to the "current" instance of the object you are extending

Section 4.1: Extension methods - overview


Extension methods were introduced in C# 3.0. Extension methods extend and add behavior to existing types
without creating a new derived type, recompiling, or otherwise modifying the original type. They are especially
helpful when you cannot modify the source of a type you are looking to enhance. Extension methods may be created for
system types, types defined by third parties, and types that you have defined yourself. The extension method can
be invoked as though it were a member method of the original type. This allows for Method Chaining used to
implement a Fluent Interface.

An extension method is created by adding a static method to a static class which is distinct from the original type
being extended. The static class holding the extension method is often created for the sole purpose of holding
extension methods.

Extension methods take a special first parameter that designates the original type being extended. This first
parameter is decorated with the keyword this (which constitutes a special and distinct use of this in C#—it should
be understood as different from the use of this which allows referring to members of the current object instance).

In the following example, the original type being extended is the class string. String has been extended by a
method Shorten(), which provides the additional functionality of shortening. The static class StringExtensions
has been created to hold the extension method. The extension method Shorten() shows that it is an extension of
string via the specially marked first parameter. To show that the Shorten() method extends string, the first
parameter is marked with this. Therefore, the full signature of the first parameter is this string text, where
string is the original type being extended and text is the chosen parameter name.

static class StringExtensions


{
public static string Shorten(this string text, int length)
{
return [Link](0, length);
}
}

class Program
{
static void Main()
{
// This calls method [Link]()
var myString = "Hello World!".ToUpper();

// This calls the extension method [Link]()


var newString = [Link](5);

// It is worth noting that the above call is purely syntactic sugar


// and the assignment below is functionally equivalent
var newString2 = [Link](myString, 5);
}
}

Live Demo on .NET Fiddle

[Link] – C# Notes for Professionals 34


The object passed as the first argument of an extension method (which is accompanied by the this keyword) is the
instance the extension method is called upon.

For example, when this code is executed:

"some string".Shorten(5);

The values of the arguments are as below:

text: "some string"


length: 5

Note that extension methods are only usable if they are in the same namespace as their definition, if the namespace is
imported explicitly by the code using the extension method, or if the extension class is namespace-less. The .NET
framework guidelines recommend putting extension classes in their own namespace. However, this may lead to
discovery issues.

This results in no conflicts between the extension methods and the libraries being used, unless namespaces which
might conflict are explicitly pulled in. For example LINQ Extensions:

using [Link]; // Allows use of extension methods from the [Link] namespace

class Program
{
static void Main()
{
var ints = new int[] {1, 2, 3, 4};

// Call Where() extension method from the [Link] namespace


var even = [Link](x => x % 2 == 0);
}
}

Live Demo on .NET Fiddle

Since C# 6.0, it is also possible to put a using static directive to the class containing the extension methods. For
example, using static [Link];. This makes extension methods from that particular class
available without bringing other types from the same namespace into scope.

When a class method with the same signature is available, the compiler prioritizes it over the extension method
call. For example:

class Test
{
public void Hello()
{
[Link]("From Test");
}
}

static class TestExtensions


{
public static void Hello(this Test test)
{
[Link]("From extension method");
}
}

[Link] – C# Notes for Professionals 35


class Program
{
static void Main()
{
Test t = new Test();
[Link](); // Prints "From Test"
}
}

Live demo on .NET Fiddle

Note that if there are two extension functions with the same signature, and one of them is in the same namespace,
then that one will be prioritized. On the other hand, if both of them are accessed by using, then a compile time
error will ensue with the message:

The call is ambiguous between the following methods or properties

Note that the syntactic convenience of calling an extension method via [Link]()
is an optional convenience. The method can also be called in the traditional manner, so that the special first
parameter is used as a parameter to the method.

I.e., both of the following work:

//Calling as though method belongs to string--it seamlessly extends string


String s = "Hello World";
[Link](5);

//Calling as a traditional static method with two parameters


[Link](s, 5);

Section 4.2: Null checking


Extension methods are static methods which behave like instance methods. However, unlike what happens when
calling an instance method on a null reference, when an extension method is called with a null reference, it does
not throw a NullReferenceException. This can be quite useful in some scenarios.

For example, consider the following static class:

public static class StringExtensions


{
public static string EmptyIfNull(this string text)
{
return text ?? [Link];
}

public static string NullIfEmpty(this string text)


{
return [Link] == text ? null : text;
}
}

string nullString = null;


string emptyString = [Link]();// will return ""
string anotherNullString = [Link](); // will return null

Live Demo on .NET Fiddle

[Link] – C# Notes for Professionals 36


Section 4.3: Explicitly using an extension method
Extension methods can also be used like ordinary static class methods. This way of calling an extension method is
more verbose, but is necessary in some cases.

static class StringExtensions


{
public static string Shorten(this string text, int length)
{
return [Link](0, length);
}
}

Usage:

var newString = [Link]("Hello World", 5);

When to call extension methods as static methods

There are still scenarios where you would need to use an extension method as a static method:

Resolving conflict with a member method. This can happen if a new version of a library introduces a new
member method with the same signature. In this case, the member method will be preferred by the
compiler.
Resolving conflicts with another extension method with the same signature. This can happen if two libraries
include similar extension methods and namespaces of both classes with extension methods are used in the
same file.
Passing extension method as a method group into delegate parameter.
Doing your own binding through Reflection.
Using the extension method in the Immediate window in Visual Studio.

Using static

If a using static directive is used to bring static members of a static class into global scope, extension methods
are skipped. Example:

using static [Link]; // refers to class in previous example

// OK: extension method syntax still works.


"Hello World".Shorten(5);
// OK: static method syntax still works.
[Link]("Hello World", 5);
// Compile time error: extension methods can't be called as static without specifying class.
Shorten("Hello World", 5);

If you remove the this modifier from the first argument of the Shorten method, the last line will compile.

Section 4.4: Generic Extension Methods


Just like other methods, extension methods can use generics. For example:

static class Extensions


{
public static bool HasMoreThanThreeElements<T>(this IEnumerable<T> enumerable)
{
return [Link](4).Count() > 3;
}

[Link] – C# Notes for Professionals 37


}

and calling it would be like:

IEnumerable<int> numbers = new List<int> {1,2,3,4,5,6};


var hasMoreThanThreeElements = [Link]();

View Demo

Likewise for multiple Type Arguments:

public static TU GenericExt<T, TU>(this T obj)


{
TU ret = default(TU);
// do some stuff with obj
return ret;
}

Calling it would be like:

IEnumerable<int> numbers = new List<int> {1,2,3,4,5,6};


var result = [Link]<IEnumerable<int>,String>();

View Demo

You can also create extension methods for partially bound types in multi generic types:

class MyType<T1, T2>


{
}

static class Extensions


{
public static void Example<T>(this MyType<int, T> test)
{
}
}

Calling it would be like:

MyType<int, string> t = new MyType<int, string>();


[Link]();

View Demo

You can also specify type constraints with where :

public static bool IsDefault<T>(this T obj) where T : struct, IEquatable<T>


{
return EqualityComparer<T>.[Link](obj, default(T));
}

Calling code:

int number = 5;
var IsDefault = [Link]();

[Link] – C# Notes for Professionals 38


View Demo

Section 4.5: Extension methods can only see public (or


internal) members of the extended class
public class SomeClass
{
public void DoStuff()
{

protected void DoMagic()


{

}
}

public static class SomeClassExtensions


{
public static void DoStuffWrapper(this SomeClass someInstance)
{
[Link](); // ok
}

public static void DoMagicWrapper(this SomeClass someInstance)


{
[Link](); // compilation error
}
}

Extension methods are just a syntactic sugar, and are not actually members of the class they extend. This means
that they cannot break encapsulation—they only have access to public (or when implemented in the same
assembly, internal) fields, properties and methods.

Section 4.6: Extension methods for chaining


When an extension method returns a value that has the same type as its this argument, it can be used to "chain"
one or more method calls with a compatible signature. This can be useful for sealed and/or primitive types, and
allows the creation of so-called "fluent" APIs if the method names read like natural human language.

void Main()
{
int result = [Link]().Decrement().Increment();
// result is now 6
}

public static class IntExtensions


{
public static int Increment(this int number) {
return ++number;
}

public static int Decrement(this int number) {


return --number;
}
}

[Link] – C# Notes for Professionals 39


Or like this

void Main()
{
int[] ints = new[] { 1, 2, 3, 4, 5, 6};
int[] a = [Link]();
//a is { 2, 4, 6 };
int[] b = [Link]().WhereGreaterThan(2);
//b is { 4, 6 };
}

public static class IntArrayExtensions


{
public static int[] WhereEven(this int[] array)
{
//Enumerable.* extension methods use a fluent approach
return [Link](i => (i%2) == 0).ToArray();
}

public static int[] WhereGreaterThan(this int[] array, int value)


{
return [Link](i => i > value).ToArray();
}
}

Section 4.7: Extension methods with Enumeration


Extension methods are useful for adding functionality to enumerations.

One common use is to implement a conversion method.

public enum YesNo


{
Yes,
No,
}

public static class EnumExtentions


{
public static bool ToBool(this YesNo yn)
{
return yn == [Link];
}
public static YesNo ToYesNo(this bool yn)
{
return yn ? [Link] : [Link];
}
}

Now you can quickly convert your enum value to a different type. In this case a bool.

bool yesNoBool = [Link](); // yesNoBool == true


YesNo yesNoEnum = [Link](); // yesNoEnum == [Link]

Alternatively extension methods can be used to add property like methods.

public enum Element


{
Hydrogen,

[Link] – C# Notes for Professionals 40


Helium,
Lithium,
Beryllium,
Boron,
Carbon,
Nitrogen,
Oxygen
//Etc
}

public static class ElementExtensions


{
public static double AtomicMass(this Element element)
{
switch(element)
{
case [Link]: return 1.00794;
case [Link]: return 4.002602;
case [Link]: return 6.941;
case [Link]: return 9.012182;
case [Link]: return 10.811;
case [Link]: return 12.0107;
case [Link]: return 14.0067;
case [Link]: return 15.9994;
//Etc
}
return [Link];
}
}

var massWater = 2*[Link]() + [Link]();

Section 4.8: Extension methods dispatch based on static type


The static (compile-time) type is used rather than the dynamic (run-time type) to match parameters.

public class Base


{
public virtual string GetName()
{
return "Base";
}
}

public class Derived : Base


{
public override string GetName()
{
return "Derived";
}
}

public static class Extensions


{
public static string GetNameByExtension(this Base item)
{
return "Base";
}

public static string GetNameByExtension(this Derived item)


{

[Link] – C# Notes for Professionals 41


return "Derived";
}
}

public static class Program


{
public static void Main()
{
Derived derived = new Derived();
Base @base = derived;

// Use the instance method "GetName"


[Link]([Link]()); // Prints "Derived"
[Link](@[Link]()); // Prints "Derived"

// Use the static extension method "GetNameByExtension"


[Link]([Link]()); // Prints "Derived"
[Link](@[Link]()); // Prints "Base"
}
}

Live Demo on .NET Fiddle

Also the dispatch based on static type does not allow an extension method to be called on a dynamic object:

public class Person


{
public string Name { get; set; }
}

public static class ExtenionPerson


{
public static string GetPersonName(this Person person)
{
return [Link];
}
}

dynamic person = new Person { Name = "Jon" };


var name = [Link](); // RuntimeBinderException is thrown

Section 4.9: Extension methods on Interfaces


One useful feature of extension methods is that you can create common methods for an interface. Normally an
interface cannot have shared implementations, but with extension methods they can.

public interface IVehicle


{
int MilesDriven { get; set; }
}

public static class Extensions


{
public static int FeetDriven(this IVehicle vehicle)
{
return [Link] * 5028;
}
}

[Link] – C# Notes for Professionals 42


In this example, the method FeetDriven can be used on any IVehicle. This logic in this method would apply to all
IVehicles, so it can be done this way so that there doesn't have to be a FeetDriven in the IVehicle definition
which would be implemented the same way for all children.

Section 4.10: Extension methods in combination with


interfaces
It is very convenient to use extension methods with interfaces as implementation can be stored outside of class and
all it takes to add some functionality to class is to decorate class with interface.

public interface IInterface


{
string Do()
}

public static class ExtensionMethods{


public static string DoWith(this IInterface obj){
//does something with IInterface instance
}
}

public class Classy : IInterface


{
// this is a wrapper method; you could also call DoWith() on a Classy instance directly,
// provided you import the namespace containing the extension method
public Do(){
return [Link]();
}
}

use like:

var classy = new Classy();


[Link](); // will call the extension
[Link](); // Classy implements IInterface so it can also be called this way

Section 4.11: Extension methods aren't supported by dynamic


code
static class Program
{
static void Main()
{
dynamic dynamicObject = new ExpandoObject();

string awesomeString = "Awesome";

// Prints True
[Link]([Link]());

[Link] = awesomeString;

// Prints True
[Link]([Link]([Link]));

// No compile time error or warning, but on runtime throws RuntimeBinderException


[Link]([Link]());
}

[Link] – C# Notes for Professionals 43


}

static class StringExtensions


{
public static bool IsThisAwesome(this string value)
{
return [Link]("Awesome");
}
}

The reason [calling extension methods from dynamic code] doesn't work is because in regular, non-
dynamic code extension methods work by doing a full search of all the classes known to the compiler for
a static class that has an extension method that matches. The search goes in order based on the
namespace nesting and available using directives in each namespace.

That means that in order to get a dynamic extension method invocation resolved correctly, somehow the
DLR has to know at runtime what all the namespace nestings and using directives were in your source
code. We do not have a mechanism handy for encoding all that information into the call site. We
considered inventing such a mechanism, but decided that it was too high cost and produced too much
schedule risk to be worth it.

Source

Section 4.12: Extensions and interfaces together enable DRY


code and mixin-like functionality
Extension methods enable you to simplify your interface definitions by only including core required functionality in
the interface itself and allowing you to define convenience methods and overloads as extension methods.
Interfaces with fewer methods are easier to implement in new classes. Keeping overloads as extensions rather than
including them in the interface directly saves you from copying boilerplate code into every implementation, helping
you keep your code DRY. This in fact is similar to the mixin pattern which C# does not support.

[Link]’s extensions to IEnumerable<T> is a great example of this. IEnumerable<T> only requires


the implementing class to implement two methods: generic and non-generic GetEnumerator(). But
[Link] provides countless useful utilities as extensions enabling concise and clear consumption
of IEnumerable<T>.

The following is a very simple interface with convenience overloads provided as extensions.

public interface ITimeFormatter


{
string Format(TimeSpan span);
}

public static class TimeFormatter


{
// Provide an overload to *all* implementers of ITimeFormatter.
public static string Format(
this ITimeFormatter formatter,
int millisecondsSpan)
=> [Link]([Link](millisecondsSpan));
}

// Implementations only need to provide one method. Very easy to


// write additional implementations.

[Link] – C# Notes for Professionals 44


public class SecondsTimeFormatter : ITimeFormatter
{
public string Format(TimeSpan span)
{
return $"{(int)[Link]}s";
}
}

class Program
{
static void Main(string[] args)
{
var formatter = new SecondsTimeFormatter();
// Callers get two method overloads!
[Link]($"4500ms is rougly {[Link](4500)}");
var span = [Link](5);
[Link]($"{span} is formatted as {[Link](span)}");
}
}

Section 4.13: IList<T> Extension Method Example: Comparing 2


Lists
You can use the following extension method for comparing the contents of two IList< T > instances of the same
type.

By default the items are compared based on their order within the list and the items themselves, passing false to
the isOrdered parameter will compare only the items themselves regardless of their order.

For this method to work, the generic type (T) must override both Equals and GetHashCode methods.

Usage:

List<string> list1 = new List<string> {"a1", "a2", null, "a3"};


List<string> list2 = new List<string> {"a1", "a2", "a3", null};

[Link](list2);//this gives false


[Link](list2, false);//this gives true. they are equal when the order is disregarded

Method:

public static bool Compare<T>(this IList<T> list1, IList<T> list2, bool isOrdered = true)
{
if (list1 == null && list2 == null)
return true;
if (list1 == null || list2 == null || [Link] != [Link])
return false;

if (isOrdered)
{
for (int i = 0; i < [Link]; i++)
{
var l1 = list1[i];
var l2 = list2[i];
if (
(l1 == null && l2 != null) ||
(l1 != null && l2 == null) ||
(![Link](l2)))
{

[Link] – C# Notes for Professionals 45


return false;
}
}
return true;
}
else
{
List<T> list2Copy = new List<T>(list2);
//Can be done with Dictionary without O(n^2)
for (int i = 0; i < [Link]; i++)
{
if (![Link](list1[i]))
return false;
}
return true;
}
}

Section 4.14: Extension methods as strongly typed wrappers


Extension methods can be used for writing strongly typed wrappers for dictionary-like objects. For example a cache,
[Link] at cetera...

public static class CacheExtensions


{
public static void SetUserInfo(this Cache cache, UserInfo data) =>
cache["UserInfo"] = data;

public static UserInfo GetUserInfo(this Cache cache) =>


cache["UserInfo"] as UserInfo;
}

This approach removes the need of using string literals as keys all over the codebase as well as the need of casting
to the required type during the read operation. Overall it creates a more secure, strongly typed way of interacting
with such loosely typed objects as Dictionaries.

Section 4.15: Using Extension methods to create beautiful


mapper classes
We can create a better mapper classes with extension methods, Suppose if i have some DTO classes like

public class UserDTO


{
public AddressDTO Address { get; set; }
}

public class AddressDTO


{
public string Name { get; set; }
}

and i need to map to corresponding view model classes

public class UserViewModel


{
public AddressViewModel Address { get; set; }
}

[Link] – C# Notes for Professionals 46


public class AddressViewModel
{
public string Name { get; set; }
}

then I can create my mapper class like below

public static class ViewModelMapper


{
public static UserViewModel ToViewModel(this UserDTO user)
{
return user == null ?
null :
new UserViewModel()
{
Address = [Link]()
// Job = [Link](),
// Contact = [Link]() .. and so on
};
}

public static AddressViewModel ToViewModel(this AddressDTO userAddr)


{
return userAddr == null ?
null :
new AddressViewModel()
{
Name = [Link]
};
}
}

Then finally i can invoke my mapper like below

UserDTO userDTOObj = new UserDTO() {


Address = new AddressDTO() {
Name = "Address of the user"
}
};

UserViewModel user = [Link](); // My DTO mapped to Viewmodel

The beauty here is all the mapping method have a common name (ToViewModel) and we can reuse it several ways

Section 4.16: Using Extension methods to build new collection


types (e.g. DictList)
You can create extension methods to improve usability for nested collections like a Dictionary with a List<T>
value.

Consider the following extension methods:

public static class DictListExtensions


{
public static void Add<TKey, TValue, TCollection>(this Dictionary<TKey, TCollection> dict, TKey
key, TValue value)
where TCollection : ICollection<TValue>, new()
{
TCollection list;

[Link] – C# Notes for Professionals 47


if (![Link](key, out list))
{
list = new TCollection();
[Link](key, list);
}

[Link](value);
}

public static bool Remove<TKey, TValue, TCollection>(this Dictionary<TKey, TCollection> dict,


TKey key, TValue value)
where TCollection : ICollection<TValue>
{
TCollection list;
if (![Link](key, out list))
{
return false;
}

var ret = [Link](value);


if ([Link] == 0)
{
[Link](key);
}
return ret;
}
}

you can use the extension methods as follows:

var dictList = new Dictionary<string, List<int>>();

[Link]("example", 5);
[Link]("example", 10);
[Link]("example", 15);

[Link]([Link](", ", dictList["example"])); // 5, 10, 15

[Link]("example", 5);
[Link]("example", 10);

[Link]([Link](", ", dictList["example"])); // 15

[Link]("example", 15);

[Link]([Link]("example")); // False

View Demo

Section 4.17: Extension methods for handling special cases


Extension methods can be used to "hide" processing of inelegant business rules that would otherwise require
cluttering up a calling function with if/then statements. This is similar to and analogous to handling nulls with
extension methods. For example,

public static class CakeExtensions


{
public static Cake EnsureTrueCake(this Cake cake)
{
//If the cake is a lie, substitute a cake from grandma, whose cakes aren't as tasty but are

[Link] – C# Notes for Professionals 48


known never to be lies. If the cake isn't a lie, don't do anything and return it.
return [Link](cake) ? GrandmasKitchen.Get1950sCake() : cake;
}
}

Cake myCake = [Link]().EnsureTrueCake();


[Link](myCake);//Eat the cake, confident that it is not a lie.

Section 4.18: Using Extension methods with Static methods


and Callbacks
Consider using Extension Methods as Functions which wrap other code, here's a great example that uses both a
static method and and extension method to wrap the Try Catch construct. Make your code Bullet Proof...

using System;
using [Link];

namespace Samples
{
/// <summary>
/// Wraps a try catch statement as a static helper which uses
/// Extension methods for the exception
/// </summary>
public static class Bullet
{
/// <summary>
/// Wrapper for Try Catch Statement
/// </summary>
/// <param name="code">Call back for code</param>
/// <param name="error">Already handled and logged exception</param>
public static void Proof(Action code, Action<Exception> error)
{
try
{
code();
}
catch (Exception iox)
{
//extension method used here
[Link]("BP2200-ERR-Unexpected Error");
//callback, exception already handled and logged
error(iox);
}
}
/// <summary>
/// Example of a logging method helper, this is the extension method
/// </summary>
/// <param name="error">The Exception to log</param>
/// <param name="messageID">A unique error ID header</param>
public static void Log(this Exception error, string messageID)
{
[Link](messageID);
[Link]([Link]);
[Link]([Link]);
[Link]("");
}
}
/// <summary>
/// Shows how to use both the wrapper and extension methods.
/// </summary>
public class UseBulletProofing

[Link] – C# Notes for Professionals 49


{
public UseBulletProofing()
{
var ok = false;
var result = DoSomething();
if (![Link]("ERR"))
{
ok = true;
DoSomethingElse();
}
}

/// <summary>
/// How to use Bullet Proofing in your code.
/// </summary>
/// <returns>A string</returns>
public string DoSomething()
{
string result = [Link];
//Note that the [Link] method forces this construct.
[Link](() =>
{
//this is the code callback
result = "DST5900-INF-No Exceptions in this code";
}, error =>
{
//error is the already logged and handled exception
//determine the base result
result = "DTS6200-ERR-An exception happened look at console log";
if ([Link]("SomeMarker"))
{
//filter the result for Something within the exception message
result = "DST6500-ERR-Some marker was found in the exception";
}
});
return result;
}

/// <summary>
/// Next step in workflow
/// </summary>
public void DoSomethingElse()
{
//Only called if no exception was thrown before
}
}
}

[Link] – C# Notes for Professionals 50


Chapter 5: Collection Initializers
Section 5.1: Collection initializers
Initialize a collection type with values:

var stringList = new List<string>


{
"foo",
"bar",
};

Collection initializers are syntactic sugar for Add() calls. Above code is equivalent to:

var temp = new List<string>();


[Link]("foo");
[Link]("bar");
var stringList = temp;

Note that the intialization is done atomically using a temporary variable, to avoid race conditions.

For types that offer multiple parameters in their Add() method, enclose the comma-separated arguments in curly
braces:

var numberDictionary = new Dictionary<int, string>


{
{ 1, "One" },
{ 2, "Two" },
};

This is equivalent to:

var temp = new Dictionary<int, string>();


[Link](1, "One");
[Link](2, "Two");
var numberDictionarynumberDictionary = temp;

Section 5.2: C# 6 Index Initializers


Starting with C# 6, collections with indexers can be initialized by specifying the index to assign in square brackets,
followed by an equals sign, followed by the value to assign.

Dictionary Initialization

An example of this syntax using a Dictionary:

var dict = new Dictionary<string, int>


{
["key1"] = 1,
["key2"] = 50
};

This is equivalent to:

var dict = new Dictionary<string, int>();

[Link] – C# Notes for Professionals 51


dict["key1"] = 1;
dict["key2"] = 50

The collection initializer syntax to do this before C# 6 was:

var dict = new Dictionary<string, int>


{
{ "key1", 1 },
{ "key2", 50 }
};

Which would correspond to:

var dict = new Dictionary<string, int>();


[Link]("key1", 1);
[Link]("key2", 50);

So there is a significant difference in functionality, as the new syntax uses the indexer of the initialized object to
assign values instead of using its Add() method. This means the new syntax only requires a publicly available
indexer, and works for any object that has one.

public class IndexableClass


{
public int this[int index]
{
set
{
[Link]("{0} was assigned to index {1}", value, index);
}
}
}

var foo = new IndexableClass


{
[0] = 10,
[1] = 20
}

This would output:

10 was assigned to index 0


20 was assigned to index 1

Section 5.3: Collection initializers in custom classes


To make a class support collection initializers, it must implement IEnumerable interface and have at least one Add
method. Since C# 6, any collection implementing IEnumerable can be extended with custom Add methods using
extension methods.

class Program
{
static void Main()
{
var col = new MyCollection {
"foo",
{ "bar", 3 },

[Link] – C# Notes for Professionals 52


"baz",
123.45d,
};
}
}

class MyCollection : IEnumerable


{
private IList list = new ArrayList();

public void Add(string item)


{
[Link](item)
}

public void Add(string item, int count)


{
for(int i=0;i< count;i++) {
[Link](item);
}
}

public IEnumerator GetEnumerator()


{
return [Link]();
}
}

static class MyCollectionExtensions


{
public static void Add(this MyCollection @this, double value) =>
@[Link]([Link]());
}

Section 5.4: Using collection initializer inside object initializer


public class Tag
{
public IList<string> Synonyms { get; set; }
}

Synonyms is a collection-type property. When the Tag object is created using object initializer syntax, Synonyms can
also be initialized with collection initializer syntax:

Tag t = new Tag


{
Synonyms = new List<string> {"c#", "c-sharp"}
};

The collection property can be readonly and still support collection initializer syntax. Consider this modified
example (Synonyms property now has a private setter):

public class Tag


{
public Tag()
{
Synonyms = new List<string>();
}

[Link] – C# Notes for Professionals 53


public IList<string> Synonyms { get; private set; }
}

A new Tag object can be created like this:

Tag t = new Tag


{
Synonyms = {"c#", "c-sharp"}
};

This works because collection initializers are just syntatic sugar over calls to Add(). There's no new list being created
here, the compiler is just generating calls to Add() on the exiting object.

Section 5.5: Collection Initializers with Parameter Arrays


You can mix normal parameters and parameter arrays:

public class LotteryTicket : IEnumerable{


public int[] LuckyNumbers;
public string UserName;

public void Add(string userName, params int[] luckyNumbers){


UserName = userName;
Lottery = luckyNumbers;
}
}

This syntax is now possible:

var Tickets = new List<LotteryTicket>{


{"Mr Cool" , 35663, 35732, 12312, 75685},
{"Bruce" , 26874, 66677, 24546, 36483, 46768, 24632, 24527},
{"John Cena", 25446, 83356, 65536, 23783, 24567, 89337}
}

[Link] – C# Notes for Professionals 54


Chapter 6: String Interpolation
Section 6.1: Format dates in strings
var date = new DateTime(2015, 11, 11);
var str = $"It's {date:MMMM d, yyyy}, make a wish!";
[Link](str);

You can also use the [Link] method to format the DateTime object. This will produce the same output
as the code above.

var date = new DateTime(2015, 11, 11);


var str = [Link]("MMMM d, yyyy");
str = "It's " + str + ", make a wish!";
[Link](str);

Output:

It's November 11, 2015, make a wish!

Live Demo on .NET Fiddle

Live Demo using [Link]

Note: MM stands for months and mm for minutes. Be very careful when using these as mistakes can
introduce bugs that may be difficult to discover.

Section 6.2: Padding the output


String can be formatted to accept a padding parameter that will specify how many character positions the inserted
string will use :

${value, padding}

NOTE: Positive padding values indicate left padding and negative padding values indicate right padding.

Left Padding

A left padding of 5 (adds 3 spaces before the value of number, so it takes up a total of 5 character positions in the
resulting string.)

var number = 42;


var str = $"The answer to life, the universe and everything is {number, 5}.";
//str is "The answer to life, the universe and everything is 42.";
// ^^^^^
[Link](str);

Output:

[Link] – C# Notes for Professionals 55


The answer to life, the universe and everything is 42.

Live Demo on .NET Fiddle

Right Padding

Right padding, which uses a negative padding value, will add spaces to the end of the current value.

var number = 42;


var str = $"The answer to life, the universe and everything is ${number, -5}.";
//str is "The answer to life, the universe and everything is 42 .";
// ^^^^^
[Link](str);

Output:

The answer to life, the universe and everything is 42 .

Live Demo on .NET Fiddle

Padding with Format Specifiers

You can also use existing formatting specifiers in conjunction with padding.

var number = 42;


var str = $"The answer to life, the universe and everything is ${number, 5:f1}";
//str is "The answer to life, the universe and everything is 42.1 ";
// ^^^^^

Live Demo on .NET Fiddle

Section 6.3: Expressions


Full expressions can also be used in interpolated strings.

var StrWithMathExpression = $"1 + 2 = {1 + 2}"; // -> "1 + 2 = 3"

string world = "world";


var StrWithFunctionCall = $"Hello, {[Link]()}!"; // -> "Hello, WORLD!"

Live Demo on .NET Fiddle

Section 6.4: Formatting numbers in strings


You can use a colon and the standard numeric format syntax to control how numbers are formatted.

var decimalValue = 120.5;

var asCurrency = $"It costs {decimalValue:C}";


// String value is "It costs $120.50" (depending on your local currency settings)

var withThreeDecimalPlaces = $"Exactly {decimalValue:F3}";


// String value is "Exactly 120.500"

var integerValue = 57;

[Link] – C# Notes for Professionals 56


var prefixedIfNecessary = $"{integerValue:D5}";
// String value is "00057"

Live Demo on .NET Fiddle

Section 6.5: Simple Usage


var name = "World";
var str = $"Hello, {name}!";
//str now contains: "Hello, World!";

Behind the scenes

Internally this

$"Hello, {name}!"

Will be compiled to something like this:

[Link]("Hello, {0}!", name);

[Link] – C# Notes for Professionals 57


Chapter 7: An overview of C# collections
Section 7.1: HashSet<T>
This is a collection of unique items, with O(1) lookup.

HashSet<int> validStoryPointValues = new HashSet<int>() { 1, 2, 3, 5, 8, 13, 21 };


bool containsEight = [Link](8); // O(1)

By way of comparison, doing a Contains on a List yields poorer performance:

List<int> validStoryPointValues = new List<int>() { 1, 2, 3, 5, 8, 13, 21 };


bool containsEight = [Link](8); // O(n)

[Link] uses a hash table, so that lookups are extremely fast, regardless of the number of items in the
collection.

Section 7.2: Dictionary<TKey, TValue>


Dictionary<TKey, TValue> is a map. For a given key there can be one value in the dictionary.

using [Link];

var people = new Dictionary<string, int>


{
{ "John", 30 }, {"Mary", 35}, {"Jack", 40}
};

// Reading data
[Link](people["John"]); // 30
[Link](people["George"]); // throws KeyNotFoundException

int age;
if ([Link]("Mary", out age))
{
[Link](age); // 35
}

// Adding and changing data


people["John"] = 40; // Overwriting values this way is ok
[Link]("John", 40); // Throws ArgumentException since "John" already exists

// Iterating through contents


foreach(KeyValuePair<string, int> person in people)
{
[Link]("Name={0}, Age={1}", [Link], [Link]);
}

foreach(string name in [Link])


{
[Link]("Name={0}", name);
}

foreach(int age in [Link])


{
[Link]("Age={0}", age);
}

[Link] – C# Notes for Professionals 58


Duplicate key when using collection initialization
var people = new Dictionary<string, int>
{
{ "John", 30 }, {"Mary", 35}, {"Jack", 40}, {"Jack", 40}
}; // throws ArgumentException since "Jack" already exists

Section 7.3: SortedSet<T>


// create an empty set
var mySet = new SortedSet<int>();

// add something
// note that we add 2 before we add 1
[Link](2);
[Link](1);

// enumerate through the set


foreach(var item in mySet)
{
[Link](item);
}

// output:
// 1
// 2

Section 7.4: T[ ] (Array of T)


// create an array with 2 elements
var myArray = new [] { "one", "two" };

// enumerate through the array


foreach(var item in myArray)
{
[Link](item);
}

// output:
// one
// two

// exchange the element on the first position


// note that all collections start with the index 0
myArray[0] = "something else";

// enumerate through the array again


foreach(var item in myArray)
{
[Link](item);
}

// output:
// something else
// two

[Link] – C# Notes for Professionals 59


Section 7.5: List<T>
List<T> is a list of a given type. Items can be added, inserted, removed and addressed by index.

using [Link];

var list = new List<int>() { 1, 2, 3, 4, 5 };


[Link](6);
[Link]([Link]); // 6
[Link](3);
[Link]([Link]); // 5
[Link](list[3]); // 5

List<T> can be thought of as an array that you can resize. Enumerating over the collection in order is quick, as is
access to individual elements via their index. To access elements based on some aspect of their value, or some
other key, a Dictionary<T> will provide faster lookup.

Section 7.6: Stack<T>


// Initialize a stack object of integers
var stack = new Stack<int>();

// add some data


[Link](3);
[Link](5);
[Link](8);

// elements are stored with "first in, last out" order.


// stack from top to bottom is: 8, 5, 3

// We can use peek to see the top element of the stack.


[Link]([Link]()); // prints 8

// Pop removes the top element of the stack and returns it.
[Link]([Link]()); // prints 8
[Link]([Link]()); // prints 5
[Link]([Link]()); // prints 3

Section 7.7: LinkedList<T>


// initialize a LinkedList of integers
LinkedList list = new LinkedList<int>();

// add some numbers to our list.


[Link](3);
[Link](5);
[Link](8);

// the list currently is 3, 5, 8

[Link](2);
// the list now is 2, 3, 5, 8

[Link]();
// the list is now 3, 5, 8

[Link]();
// the list is now 3, 5

[Link] – C# Notes for Professionals 60


Note that LinkedList<T> represents the doubly linked list. So, it's simply collection of nodes and each node
contains an element of type T. Each node is linked to the preceding node and the following node.

Section 7.8: Queue


// Initalize a new queue of integers
var queue = new Queue<int>();

// Add some data


[Link](6);
[Link](4);
[Link](9);

// Elements in a queue are stored in "first in, first out" order.


// The queue from first to last is: 6, 4, 9

// View the next element in the queue, without removing it.


[Link]([Link]()); // prints 6

// Removes the first element in the queue, and returns it.


[Link]([Link]()); // prints 6
[Link]([Link]()); // prints 4
[Link]([Link]()); // prints 9

Thread safe heads up! Use ConcurrentQueue in multi-thread environments.

[Link] – C# Notes for Professionals 61


Chapter 8: Constructors and Finalizers
Constructors are methods in a class that are invoked when an instance of that class is created. Their main
responsibility is to leave the new object in a useful and consistent state.

Destructors/Finalizers are methods in a class that are invoked when an instance of that is destroyed. In C# they are
rarely explicitely written/used.

Section 8.1: Static constructor


A static constructor is called the first time any member of a type is initialized, a static class member is called or a
static method. The static constructor is thread safe. A static constructor is commonly used to:

Initialize static state, that is state which is shared across different instances of the same class.
Create a singleton

Example:

class Animal
{
// * A static constructor is executed only once,
// when a class is first accessed.
// * A static constructor cannot have any access modifiers
// * A static constructor cannot have any parameters
static Animal()
{
[Link]("Animal initialized");
}

// Instance constructor, this is executed every time the class is created


public Animal()
{
[Link]("Animal created");
}

public static void Yawn()


{
[Link]("Yawn!");
}
}

var turtle = new Animal();


var giraffe = new Animal();

Output:

Animal initialized
Animal created
Animal created

View Demo

If the first call is to a static method, the static constructor is invoked without the instance constructor. This is OK,
because the static method can't access instance state anyways.

[Link] – C# Notes for Professionals 62


[Link]();

This will output:

Animal initialized
Yawn!

See also Exceptions in static constructors and Generic Static Constructors .

Singleton example:

public class SessionManager


{
public static SessionManager Instance;

static SessionManager()
{
Instance = new SessionManager();
}
}

Section 8.2: Singleton constructor pattern


public class SingletonClass
{
public static SingletonClass Instance { get; } = new SingletonClass();

private SingletonClass()
{
// Put custom constructor code here
}
}

Because the constructor is private, no new instances of SingletonClass can be made by consuming code. The only
way to access the single instance of SingletonClass is by using the static property [Link].

The Instance property is assigned by a static constructor that the C# compiler generates. The .NET runtime
guarantees that the static constructor is run at most once and is run before Instance is first read. Therefore, all
synchronization and initialization concerns are carried out by the runtime.

Note, that if the static constructor fails the Singleton class becomes permanently unusable for the life of the
AppDomain.

Also, the static constructor is not guaranteed to run at the time of the first access of Instance. Rather, it will run at
some point before that. This makes the time at which initialization happens non-deterministic. In practical cases the
JIT often calls the static constructor during compilation (not execution) of a method referencing Instance. This is a
performance optimization.

See the Singleton Implementations page for other ways to implement the singleton pattern.

Section 8.3: Default Constructor


When a type is defined without a constructor:

[Link] – C# Notes for Professionals 63


public class Animal
{
}

then the compiler generates a default constructor equivalent to the following:

public class Animal


{
public Animal() {}
}

The definition of any constructor for the type will suppress the default constructor generation. If the type were
defined as follows:

public class Animal


{
public Animal(string name) {}
}

then an Animal could only be created by calling the declared constructor.

// This is valid
var myAnimal = new Animal("Fluffy");
// This fails to compile
var unnamedAnimal = new Animal();

For the second example, the compiler will display an error message:

'Animal' does not contain a constructor that takes 0 arguments

If you want a class to have both a parameterless constructor and a constructor that takes a parameter, you can do
it by explicitly implementing both constructors.

public class Animal


{

public Animal() {} //Equivalent to a default constructor.


public Animal(string name) {}
}

The compiler will not be able to generate a default constructor if the class extends another class which doesn't have
a parameterless constructor. For example, if we had a class Creature:

public class Creature


{
public Creature(Genus genus) {}
}

then Animal defined as class Animal : Creature {} would not compile.

Section 8.4: Forcing a static constructor to be called


While static constructors are always called before the first usage of a type it's sometimes useful to be able to force
them to be called and the RuntimeHelpers class provide an helper for it:

[Link] – C# Notes for Professionals 64


using [Link];
// ...
[Link](typeof(Foo).TypeHandle);

Remark: All static initialization (fields initializers for example) will run, not only the constructor itself.

Potential usages: Forcing initialization during the splash screen in an UI application or ensuring that a static
constructor doesn't fail in an unit test.

Section 8.5: Calling a constructor from another constructor


public class Animal
{
public string Name { get; set; }

public Animal() : this("Dog")


{
}

public Animal(string name)


{
Name = name;
}
}

var dog = new Animal(); // [Link] will be set to "Dog" by default.


var cat = new Animal("Cat"); // [Link] is "Cat", the empty constructor is not called.

Section 8.6: Calling the base class constructor


A constructor of a base class is called before a constructor of a derived class is executed. For example, if Mammal
extends Animal, then the code contained in the constructor of Animal is called first when creating an instance of a
Mammal.

If a derived class doesn't explicitly specify which constructor of the base class should be called, the compiler
assumes the parameterless constructor.

public class Animal


{
public Animal() { [Link]("An unknown animal gets born."); }
public Animal(string name) { [Link](name + " gets born"); }
}

public class Mammal : Animal


{
public Mammal(string name)
{
[Link](name + " is a mammal.");
}
}

In this case, instantiating a Mammal by calling new Mammal("George the Cat") will print

An unknown animal gets born.


George the Cat is a mammal.

[Link] – C# Notes for Professionals 65


View Demo

Calling a different constructor of the base class is done by placing : base(args) between the constructor's
signature and its body:

public class Mammal : Animal


{
public Mammal(string name) : base(name)
{
[Link](name + " is a mammal.");
}
}

Calling new Mammal("George the Cat") will now print:

George the Cat gets born.


George the Cat is a mammal.

View Demo

Section 8.7: Finalizers on derived classes


When an object graph is finalized, the order is the reverse of the construction. E.g. the super-type is finalized before
the base-type as the following code demonstrates:

class TheBaseClass
{
~TheBaseClass()
{
[Link]("Base class finalized!");
}
}

class TheDerivedClass : TheBaseClass


{
~TheDerivedClass()
{
[Link]("Derived class finalized!");
}
}

//Don't assign to a variable


//to make the object unreachable
new TheDerivedClass();

//Just to make the example work;


//this is otherwise NOT recommended!
[Link]();

//Derived class finalized!


//Base class finalized!

Section 8.8: Exceptions in static constructors


If a static constructor throws an exception, it is never retried. The type is unusable for the lifetime of the
AppDomain. Any further usages of the type will raise a TypeInitializationException wrapped around the original

[Link] – C# Notes for Professionals 66


exception.

public class Animal


{
static Animal()
{
[Link]("Static ctor");
throw new Exception();
}

public static void Yawn() {}


}

try
{
[Link]();
}
catch (Exception e)
{
[Link]([Link]());
}

try
{
[Link]();
}
catch (Exception e)
{
[Link]([Link]());
}

This will output:

Static ctor

[Link]: The type initializer for 'Animal' threw an exception. --->


[Link]: Exception of type '[Link]' was thrown.

[...]

[Link]: The type initializer for 'Animal' threw an exception. --->


[Link]: Exception of type '[Link]' was thrown.

where you can see that the actual constructor is only executed once, and the exception is re-used.

Section 8.9: Constructor and Property Initialization


Shall the property value's assignment be executed before or after the class' constructor?

public class TestClass


{
public int TestProperty { get; set; } = 2;

public TestClass()
{
if (TestProperty == 1)

[Link] – C# Notes for Professionals 67


{
[Link]("Shall this be executed?");
}

if (TestProperty == 2)
{
[Link]("Or shall this be executed");
}
}
}

var testInstance = new TestClass() { TestProperty = 1 };

In the example above, shall the TestProperty value be 1 in the class' constructor or after the class constructor?

Assigning property values in the instance creation like this:

var testInstance = new TestClass() {TestProperty = 1};

Will be executed after the constructor is run. However, initializing the property value in the class' property in C# 6.0
like this:

public class TestClass


{
public int TestProperty { get; set; } = 2;

public TestClass()
{
}
}

will be done before the constructor is run.

Combining the two concepts above in a single example:

public class TestClass


{
public int TestProperty { get; set; } = 2;

public TestClass()
{
if (TestProperty == 1)
{
[Link]("Shall this be executed?");
}

if (TestProperty == 2)
{
[Link]("Or shall this be executed");
}
}
}

static void Main(string[] args)


{
var testInstance = new TestClass() { TestProperty = 1 };
[Link]([Link]); //resulting in 1
}

[Link] – C# Notes for Professionals 68


Final result:

"Or shall this be executed"


"1"

Explanation:

The TestProperty value will first be assigned as 2, then the TestClass constructor will be run, resulting in printing
of

"Or shall this be executed"

And then the TestProperty will be assigned as 1 due to new TestClass() { TestProperty = 1 }, making the final
value for the TestProperty printed by [Link]([Link]) to be

"1"

Section 8.10: Generic Static Constructors


If the type on which the static constructor is declared is generic, the static constructor will be called once for each
unique combination of generic arguments.

class Animal<T>
{
static Animal()
{
[Link](typeof(T).FullName);
}

public static void Yawn() { }


}

Animal<Object>.Yawn();
Animal<String>.Yawn();

This will output:

[Link]
[Link]

See also How do static constructors for generic types work ?

Section 8.11: Calling virtual methods in constructor


Unlike C++ in C# you can call a virtual method from class constructor (OK, you can also in C++ but behavior at first is
surprising). For example:

abstract class Base


{
protected Base()
{
_obj = CreateAnother();
}

[Link] – C# Notes for Professionals 69


protected virtual AnotherBase CreateAnother()
{
return new AnotherBase();
}

private readonly AnotherBase _obj;


}

sealed class Derived : Base


{
public Derived() { }

protected override AnotherBase CreateAnother()


{
return new AnotherDerived();
}
}

var test = new Derived();


// test._obj is AnotherDerived

If you come from a C++ background this is surprising, base class constructor already sees derived class virtual
method table!

Be careful: derived class may not been fully initialized yet (its constructor will be executed after base class
constructor) and this technique is dangerous (there is also a StyleCop warning for this). Usually this is regarded as
bad practice.

[Link] – C# Notes for Professionals 70


Chapter 9: Static Classes
Section 9.1: Static Classes
The "static" keyword when referring to a class has three effects:

1. You cannot create an instance of a static class (this even removes the default constructor)
2. All properties and methods in the class must be static as well.
3. A static class is a sealed class, meaning it cannot be inherited.

public static class Foo


{
//Notice there is no constructor as this cannot be an instance
public static int Counter { get; set; }
public static int GetCount()
{
return Counter;
}
}

public class Program


{
static void Main(string[] args)
{
[Link]++;
[Link]([Link]()); //this will print 1

//var foo1 = new Foo();


//this line would break the code as the Foo class does not have a constructor
}
}

Section 9.2: Static class lifetime


A static class is lazily initialized on member access and lives for the duration of the application domain.

void Main()
{
[Link]("Static classes are lazily initialized");
[Link]("The static constructor is only invoked when the class is first accessed");
[Link]();

[Link]("Reflecting on a type won't trigger its static .ctor");


var barType = typeof(Bar);

[Link]("However, you can manually trigger it with


[Link]");
[Link]([Link]);
}

// Define other methods and classes here


public static class Foo
{
static Foo()
{
[Link]("static [Link]");
}
public static void SayHi()

[Link] – C# Notes for Professionals 71


{
[Link]("Foo: Hi");
}
}
public static class Bar
{
static Bar()
{
[Link]("static [Link]");
}
}

Section 9.3: Static keyword


The static keyword means 2 things:

1. This value does not change from object to object but rather changes on a class as a whole
2. Static properties and methods don't require an instance.

public class Foo


{
public Foo{
Counter++;
NonStaticCounter++;
}

public static int Counter { get; set; }


public int NonStaticCounter { get; set; }
}

public class Program


{
static void Main(string[] args)
{
//Create an instance
var foo1 = new Foo();
[Link]([Link]); //this will print "1"

//Notice this next call doesn't access the instance but calls by the class name.
[Link]([Link]); //this will also print "1"

//Create a second instance


var foo2 = new Foo();

[Link]([Link]); //this will print "1"

[Link]([Link]); //this will now print "2"


//The static property incremented on both instances and can persist for the whole class

}
}

[Link] – C# Notes for Professionals 72


Chapter 10: Keywords
Keywords are predefined, reserved identifiers with special meaning to the compiler. They cannot be used as
identifiers in your program without the @ prefix. For example @if is a legal identifier but not the keyword if.

Section 10.1: as
The as keyword is an operator similar to a cast. If a cast is not possible, using as produces null rather than
resulting in an InvalidCastException.

expression as type is equivalent to expression is type ? (type)expression : (type)null with the caveat that
as is only valid on reference conversions, nullable conversions, and boxing conversions. User-defined conversions
are not supported; a regular cast must be used instead.

For the expansion above, the compiler generates code such that expression will only be evaluated once and use
single dynamic type check (unlike the two in the sample above).

as can be useful when expecting an argument to facilitate several types. Specifically it grants the user multiple
options - rather than checking every possibility with is before casting, or just casting and catching exceptions. It is
best practice to use 'as' when casting/checking an object which will cause only one unboxing penalty. Using is to
check, then casting will cause two unboxing penalties.

If an argument is expected to be an instance of a specific type, a regular cast is preferred as its purpose is more
clear to the reader.

Because a call to as may produce null, always check the result to avoid a NullReferenceException.

Example usage

object something = "Hello";


[Link](something as string); //Hello
[Link](something as Nullable<int>); //null
[Link](something as int?); //null

//This does NOT compile:


//destination type must be a reference type (or a nullable value type)
[Link](something as int);

Live Demo on .NET Fiddle

Equivalent example without using as:

[Link](something is string ? (string)something : (string)null);

This is useful when overriding the Equals function in custom classes.

class MyCustomClass
{

public override bool Equals(object obj)


{
MyCustomClass customObject = obj as MyCustomClass;

// if it is null it may be really null


// or it may be of a different type

[Link] – C# Notes for Professionals 73


if ([Link](null, customObject))
{
// If it is null then it is not equal to this instance.
return false;
}

// Other equality controls specific to class


}

Section 10.2: goto


goto can be used to jump to a specific line inside the code, specified by a label.

goto as a:
Label:
void InfiniteHello()
{
sayHello:
[Link]("Hello!");
goto sayHello;
}

Live Demo on .NET Fiddle

Case statement:
enum Permissions { Read, Write };

switch (GetRequestedPermission())
{
case [Link]:
GrantReadAccess();
break;

case [Link]:
GrantWriteAccess();
goto case [Link]; //People with write access also get read
}

Live Demo on .NET Fiddle

This is particularly useful in executing multiple behaviors in a switch statement, as C# does not support fall-through
case blocks.

Exception Retry
var exCount = 0;
retry:
try
{
//Do work
}
catch (IOException)
{
exCount++;
if (exCount < 3)
{
[Link](100);

[Link] – C# Notes for Professionals 74


goto retry;
}
throw;
}

Live Demo on .NET Fiddle

Similar to many languages, use of goto keyword is discouraged except the cases below.

Valid usages of goto which apply to C#:

Fall-through case in switch statement.

Multi-level break. LINQ can often be used instead, but it usually has worse performance.

Resource deallocation when working with unwrapped low-level objects. In C#, low-level objects should
usually be wrapped in separate classes.

Finite state machines, for example, parsers; used internally by compiler generated async/await state
machines.

Section 10.3: volatile


Adding the volatile keyword to a field indicates to the compiler that the field's value may be changed by multiple
separate threads. The primary purpose of the volatile keyword is to prevent compiler optimizations that assume
only single-threaded access. Using volatile ensures that the value of the field is the most recent value that is
available, and the value is not subject to the caching that non-volatile values are.

It is good practice to mark every variable that may be used by multiple threads as volatile to prevent unexpected
behavior due to behind-the-scenes optimizations. Consider the following code block:

public class Example


{
public int x;

public void DoStuff()


{
x = 5;

// the compiler will optimize this to y = 15


var y = x + 10;

/* the value of x will always be the current value, but y will always be "15" */
[Link]("x = " + x + ", y = " + y);
}
}

In the above code-block, the compiler reads the statements x = 5 and y = x + 10 and determines that the value of
y will always end up as 15. Thus, it will optimize the last statement as y = 15. However, the variable x is in fact a
public field and the value of x may be modified at runtime through a different thread acting on this field
separately. Now consider this modified code-block. Do note that the field x is now declared as volatile.

public class Example


{
public volatile int x;

public void DoStuff()

[Link] – C# Notes for Professionals 75


{
x = 5;

// the compiler no longer optimizes this statement


var y = x + 10;

/* the value of x and y will always be the correct values */


[Link]("x = " + x + ", y = " + y);
}
}

Now, the compiler looks for read usages of the field x and ensures that the current value of the field is always
retrieved. This ensures that even if multiple threads are reading and writing to this field, the current value of x is
always retrieved.

volatile can only be used on fields within classes or structs. The following is not valid:

public void MyMethod() { volatile int x; }

volatile can only be applied to fields of following types:

reference types or generic type parameters known to be reference types


primitive types such as sbyte, byte, short, ushort, int, uint, char, float, and bool
enums types based on byte, sbyte, short, ushort, int or uint
IntPtr and UIntPtr

Remarks:

The volatile modifier is usually used for a field that is accessed by multiple threads without using the lock
statement to serialize access.
The volatile keyword can be applied to fields of reference types
The volatile keyword will not make operating on 64-bit primitives on a 32-bit platform atomic. Interlocked
operations such as [Link] and [Link] must still be used for safe multi-threaded
access on these platforms.

Section 10.4: checked, unchecked


The checked and unchecked keywords define how operations handle mathematical overflow. "Overflow" in the
context of the checked and unchecked keywords is when an integer arithmetic operation results in a value which is
greater in magnitude than the target data type can represent.

When overflow occurs within a checked block (or when the compiler is set to globally use checked arithmetic), an
exception is thrown to warn of undesired behavior. Meanwhile, in an unchecked block, overflow is silent: no
exceptions are thrown, and the value will simply wrap around to the opposite boundary. This can lead to subtle,
hard to find bugs.

Since most arithmetic operations are done on values that are not large or small enough to overflow, most of the
time, there is no need to explicitly define a block as checked. Care needs to be taken when doing arithmetic on
unbounded input that may cause overflow, for example when doing arithmetic in recursive functions or while
taking user input.

Neither checked nor unchecked affect floating point arithmetic operations.

When a block or expression is declared as unchecked, any arithmetic operations inside it are allowed to overflow
without causing an error. An example where this behavior is desired would be the calculation of a checksum, where

[Link] – C# Notes for Professionals 76


the value is allowed to "wrap around" during calculation:

byte Checksum(byte[] data) {


byte result = 0;
for (int i = 0; i < [Link]; i++) {
result = unchecked(result + data[i]); // unchecked expression
}
return result;
}

One of the most common uses for unchecked is implementing a custom override for [Link](), a type
of checksum. You can see the keyword's use in the answers to this question: What is the best algorithm for an
overridden [Link]?.

When a block or expression is declared as checked, any arithmetic operation that causes an overflow results in an
OverflowException being thrown.

int SafeSum(int x, int y) {


checked { // checked block
return x + y;
}
}

Both checked and unchecked may be in block and expression form.

Checked and unchecked blocks do not affect called methods, only operators called directly in the current method.
For example, [Link](), Convert.ToInt32(), and user-defined operators are not affected by custom
checked/unchecked contexts.

Note: The default overflow default behavior (checked vs. unchecked) may be changed in the Project Properties or
through the /checked[+|-] command line switch. It is common to default to checked operations for debug builds and
unchecked for release builds. The checked and unchecked keywords would then be used only where a default approach
does not apply and you need an explicit behavior to ensure correctness.

Section 10.5: virtual, override, new


virtual and override

The virtual keyword allows a method, property, indexer or event to be overridden by derived classes and present
polymorphic behavior. (Members are non-virtual by default in C#)

public class BaseClass


{
public virtual void Foo()
{
[Link]("Foo from BaseClass");
}
}

In order to override a member, the override keyword is used in the derived classes. (Note the signature of the
members must be identical)

public class DerivedClass: BaseClass


{
public override void Foo()
{

[Link] – C# Notes for Professionals 77


[Link]("Foo from DerivedClass");
}
}

The polymorphic behavior of virtual members means that when invoked, the actual member being executed is
determined at runtime instead of at compile time. The overriding member in the most derived class the particular
object is an instance of will be the one executed.

In short, object can be declared of type BaseClass at compile time but if at runtime it is an instance of
DerivedClass then the overridden member will be executed:

BaseClass obj1 = new BaseClass();


[Link](); //Outputs "Foo from BaseClass"

obj1 = new DerivedClass();


[Link](); //Outputs "Foo from DerivedClass"

Overriding a method is optional:

public class SecondDerivedClass: DerivedClass {}

var obj1 = new SecondDerivedClass();


[Link](); //Outputs "Foo from DerivedClass"

new

Since only members defined as virtual are overridable and polymorphic, a derived class redefining a non virtual
member might lead to unexpected results.

public class BaseClass


{
public void Foo()
{
[Link]("Foo from BaseClass");
}
}

public class DerivedClass: BaseClass


{
public void Foo()
{
[Link]("Foo from DerivedClass");
}
}

BaseClass obj1 = new BaseClass();


[Link](); //Outputs "Foo from BaseClass"

obj1 = new DerivedClass();


[Link](); //Outputs "Foo from BaseClass" too!

When this happens, the member executed is always determined at compile time based on the type of the object.

If the object is declared of type BaseClass (even if at runtime is of a derived class) then the method of
BaseClass is executed
If the object is declared of type DerivedClass then the method of DerivedClass is executed.

This is usually an accident (When a member is added to the base type after an identical one was added to the

[Link] – C# Notes for Professionals 78


derived type) and a compiler warning CS0108 is generated in those scenarios.

If it was intentional, then the new keyword is used to suppress the compiler warning (And inform other developers
of your intentions!). the behavior remains the same, the new keyword just suppresses the compiler warning.

public class BaseClass


{
public void Foo()
{
[Link]("Foo from BaseClass");
}
}

public class DerivedClass: BaseClass


{
public new void Foo()
{
[Link]("Foo from DerivedClass");
}
}

BaseClass obj1 = new BaseClass();


[Link](); //Outputs "Foo from BaseClass"

obj1 = new DerivedClass();


[Link](); //Outputs "Foo from BaseClass" too!

The usage of override is not optional

Unlike in C++, the usage of the override keyword is not optional:

public class A
{
public virtual void Foo()
{
}
}

public class B : A
{
public void Foo() // Generates CS0108
{
}
}

The above example also causes warning CS0108, because [Link]() is not automatically overriding [Link](). Add
override when the intention is to override the base class and cause polymorphic behavior, add new when you want
non-polymorphic behavior and resolve the call using the static type. The latter should be used with caution, as it
may cause severe confusion.

The following code even results in an error:

public class A
{
public void Foo()
{
}
}

public class B : A

[Link] – C# Notes for Professionals 79


{
public override void Foo() // Error: Nothing to override
{
}
}

Derived classes can introduce polymorphism

The following code is perfectly valid (although rare):

public class A
{
public void Foo()
{
[Link]("A");
}
}

public class B : A
{
public new virtual void Foo()
{
[Link]("B");
}
}

Now all objects with a static reference of B (and its derivatives) use polymorphism to resolve Foo(), while
references of A use [Link]().

A a = new A();
[Link](); // Prints "A";
a = new B();
[Link](); // Prints "A";
B b = new B();
[Link](); // Prints "B";

Virtual methods cannot be private

The C# compiler is strict in preventing senseless constructs. Methods marked as virtual cannot be private.
Because a private method cannot be seen from a derived type, it couldn't be overwritten either. This fails to
compile:

public class A
{
private virtual void Foo() // Error: virtual methods cannot be private
{
}
}

Section 10.6: stackalloc


The stackalloc keyword creates a region of memory on the stack and returns a pointer to the start of that
memory. Stack allocated memory is automatically removed when the scope it was created in is exited.

//Allocate 1024 bytes. This returns a pointer to the first byte.


byte* ptr = stackalloc byte[1024];

//Assign some values...


ptr[0] = 109;
ptr[1] = 13;

[Link] – C# Notes for Professionals 80


ptr[2] = 232;
...

Used in an unsafe context.

As with all pointers in C# there is no bounds checking on reads and assignments. Reading beyond the bounds of
the allocated memory will have unpredictable results - it may access some arbitrary location within memory or it
may cause an access violation exception.

//Allocate 1 byte
byte* ptr = stackalloc byte[1];

//Unpredictable results...
ptr[10] = 1;
ptr[-1] = 2;

Stack allocated memory is automatically removed when the scope it was created in is exited. This means that you
should never return the memory created with stackalloc or store it beyond the lifetime of the scope.

unsafe IntPtr Leak() {


//Allocate some memory on the stack
var ptr = stackalloc byte[1024];

//Return a pointer to that memory (this exits the scope of "Leak")


return new IntPtr(ptr);
}

unsafe void Bad() {


//ptr is now an invalid pointer, using it in any way will have
//unpredictable results. This is exactly the same as accessing beyond
//the bounds of the pointer.
var ptr = Leak();
}

stackalloc can only be used when declaring and initialising variables. The following is not valid:

byte* ptr;
...
ptr = stackalloc byte[1024];

Remarks:

stackalloc should only be used for performance optimizations (either for computation or interop). This is due to
the fact that:

The garbage collector is not required as the memory is allocated on the stack rather than the heap - the
memory is released as soon as the variable goes out of scope
It is faster to allocate memory on the stack rather than the heap
Increase the chance of cache hits on the CPU due to the locality of data

Section 10.7: break


In a loop (for, foreach, do, while) the break statement aborts the execution of the innermost loop and returns to the
code after it. Also it can be used with yield in which it specifies that an iterator has come to an end.

for (var i = 0; i < 10; i++)


{

[Link] – C# Notes for Professionals 81


if (i == 5)
{
break;
}
[Link]("This will appear only 5 times, as the break will stop the loop.");
}

Live Demo on .NET Fiddle

foreach (var stuff in stuffCollection)


{
if ([Link] == null)
break;
// If [Link] for any "stuff" is null, the loop is aborted.
[Link]([Link]);
}

The break-statement is also used in switch-case constructs to break out of a case or default segment.

switch(a)
{
case 5:
[Link]("a was 5!");
break;

default:
[Link]("a was something else!");
break;
}

In switch statements, the 'break' keyword is required at the end of each case statement. This is contrary to some
languages that allow for 'falling through' to the next case statement in the series. Workarounds for this would
include 'goto' statements or stacking the 'case' statements sequentially.

Following code will give numbers 0, 1, 2, ..., 9 and the last line will not be executed. yield break signifies the
end of the function (not just a loop).

public static IEnumerable<int> GetNumbers()


{
int i = 0;
while (true) {
if (i < 10) {
yield return i++;
} else {
yield break;
}
}
[Link]("This line will not be executed");
}

Live Demo on .NET Fiddle

Note that unlike some other languages, there is no way to label a particular break in C#. This means that in the case
of nested loops, only the innermost loop will be stopped:

foreach (var outerItem in outerList)


{
foreach (var innerItem in innerList)

[Link] – C# Notes for Professionals 82


{
if ([Link])
// This will only break out of the inner loop, the outer will continue:
break;
}
}

If you want to break out of the outer loop here, you can use one of several different strategies, such as:

A goto statement to jump out of the whole looping structure.


A specific flag variable (shouldBreak in the following example) that can be checked at the end of each
iteration of the outer loop.
Refactoring the code to use a return statement in the innermost loop body, or avoid the whole nested loop
structure altogether.

bool shouldBreak = false;


while(comeCondition)
{
while(otherCondition)
{
if (conditionToBreak)
{
// Either tranfer control flow to the label below...
goto endAllLooping;

// OR use a flag, which can be checked in the outer loop:


shouldBreak = true;
}
}

if(shouldBreakNow)
{
break; // Break out of outer loop if flag was set to true
}
}

endAllLooping: // label from where control flow will continue

Section 10.8: const


const is used to represent values that will never change throughout the lifetime of the program. Its value is
constant from compile-time, as opposed to the readonly keyword, whose value is constant from run-time.

For example, since the speed of light will never change, we can store it in a constant.

const double c = 299792458; // Speed of light

double CalculateEnergy(double mass)


{
return mass * c * c;
}

This is essentially the same as having return mass * 299792458 * 299792458, as the compiler will directly
substitute c with its constant value.

As a result, c cannot be changed once declared. The following will produce a compile-time error:

const double c = 299792458; // Speed of light

[Link] – C# Notes for Professionals 83


c = 500; //compile-time error

A constant can be prefixed with the same access modifiers as methods:

private const double c = 299792458;


public const double c = 299792458;
internal const double c = 299792458;

const members are static by nature. However using static explicitly is not permitted.

You can also define method-local constants:

double CalculateEnergy(double mass)


{
const c = 299792458;
return mass * c * c;
}

These can not be prefixed with a private or public keyword, since they are implicitly local to the method they are
defined in.

Not all types can be used in a const declaration. The value types that are allowed, are the pre-defined types sbyte,
byte, short, ushort, int, uint, long, ulong, char, float, double, decimal, bool, and all enum types. Trying to declare
const members with other value types (such as TimeSpan or Guid) will fail at compile-time.

For the special pre-defined reference type string, constants can be declared with any value. For all other reference
types, constants can be declared but must always have the value null.

Because const values are known at compile-time, they are allowed as case labels in a switch statement, as
standard arguments for optional parameters, as arguments to attribute specifications, and so on.

If const values are used across different assemblies, care must be taken with versioning. For example, if assembly A
defines a public const int MaxRetries = 3;, and assembly B uses that constant, then if the value of MaxRetries
is later changed to 5 in assembly A (which is then re-compiled), that change will not be effective in assembly B unless
assembly B is also re-compiled (with a reference to the new version of A).

For that reason, if a value might change in future revisions of the program, and if the value needs to be publicly
visible, do not declare that value const unless you know that all dependent assemblies will be re-compiled
whenever something is changed. The alternative is using static readonly instead of const, which is resolved at
runtime.

Section 10.9: async, await


The await keyword was added as part of C# 5.0 release which is supported from Visual Studio 2012 onwards. It
leverages Task Parallel Library (TPL) which made the multi-threading relatively easier. The async and await
keywords are used in pair in the same function as shown below. The await keyword is used to pause the current
asynchronous method's execution until the awaited asynchronous task is completed and/or its results returned. In
order to use the await keyword, the method that uses it must be marked with the async keyword.

Using async with void is strongly discouraged. For more info you can look here.

Example:

public async Task DoSomethingAsync()


{

[Link] – C# Notes for Professionals 84


[Link]("Starting a useless process...");
Stopwatch stopwatch = [Link]();
int delay = await UselessProcessAsync(1000);
[Link]();
[Link]("A useless process took {0} milliseconds to execute.",
[Link]);
}

public async Task<int> UselessProcessAsync(int x)


{
await [Link](x);
return x;
}

Output:

"Starting a useless process..."

**... 1 second delay... **

"A useless process took 1000 milliseconds to execute."

The keyword pairs async and await can be omitted if a Task or Task<T> returning method only returns a single
asynchronous operation.

Rather than this:

public async Task PrintAndDelayAsync(string message, int delay)


{
[Link](message);
await [Link](x);
}

It is preferred to do this:

public Task PrintAndDelayAsync(string message, int delay)


{
[Link](message);
return [Link](x);
}
Version = 5.0

In C# 5.0 await cannot be used in catch and finally.

Version ≥ 6.0

With C# 6.0 await can be used in catch and finally.

Section 10.10: for


Syntax: for (initializer; condition; iterator)

The for loop is commonly used when the number of iterations is known.
The statements in the initializer section run only once, before you enter the loop.
The condition section contains a boolean expression that's evaluated at the end of every loop iteration to

[Link] – C# Notes for Professionals 85


determine whether the loop should exit or should run again.
The iterator section defines what happens after each iteration of the body of the loop.

This example shows how for can be used to iterate over the characters of a string:

string str = "Hello";


for (int i = 0; i < [Link]; i++)
{
[Link](str[i]);
}

Output:

H
e
l
l
o

Live Demo on .NET Fiddle

All of the expressions that define a for statement are optional; for example, the following statement is used to
create an infinite loop:

for( ; ; )
{
// Your code here
}

The initializer section can contain multiple variables, so long as they are of the same type. The condition
section can consist of any expression which can be evaluated to a bool. And the iterator section can perform
multiple actions separated by comma:

string hello = "hello";


for (int i = 0, j = 1, k = 9; i < 3 && k > 0; i++, hello += i) {
[Link](hello);
}

Output:

hello
hello1
hello12

Live Demo on .NET Fiddle

Section 10.11: abstract


A class marked with the keyword abstract cannot be instantiated.

A class must be marked as abstract if it contains abstract members or if it inherits abstract members that it doesn't
implement. A class may be marked as abstract even if no abstract members are involved.

[Link] – C# Notes for Professionals 86


Abstract classes are usually used as base classes when some part of the implementation needs to be specified by
another component.

abstract class Animal


{
string Name { get; set; }
public abstract void MakeSound();
}

public class Cat : Animal


{
public override void MakeSound()
{
[Link]("Meov meov");
}
}

public class Dog : Animal


{
public override void MakeSound()
{
[Link]("Bark bark");
}
}

Animal cat = new Cat(); // Allowed due to Cat deriving from Animal
[Link](); // will print out "Meov meov"

Animal dog = new Dog(); // Allowed due to Dog deriving from Animal
[Link](); // will print out "Bark bark"

Animal animal = new Animal(); // Not allowed due to being an abstract class

A method, property, or event marked with the keyword abstract indicates that the implementation for that
member is expected to be provided in a subclass. As mentioned above, abstract members can only appear in
abstract classes.

abstract class Animal


{
public abstract string Name { get; set; }
}

public class Cat : Animal


{
public override string Name { get; set; }
}

public class Dog : Animal


{
public override string Name { get; set; }
}

Section 10.12: fixed


The fixed statement fixes memory in one location. Objects in memory are usually moving arround, this makes
garbage collection possible. But when we use unsafe pointers to memory addresses, that memory must not be
moved.

We use the fixed statement to ensure that the garbage collector does not relocate the string data.

[Link] – C# Notes for Professionals 87


Fixed Variables

var myStr = "Hello world!";

fixed (char* ptr = myStr)


{
// myStr is now fixed (won't be [re]moved by the Garbage Collector).
// We can now do something with ptr.
}

Used in an unsafe context.

Fixed Array Size

unsafe struct Example


{
public fixed byte SomeField[8];
public fixed char AnotherField[64];
}

fixed can only be used on fields in a struct (must also be used in an unsafe context).

Section 10.13: default


For classes, interfaces, delegate, array, nullable (such as int?) and pointer types, default(TheType) returns null:

class MyClass {}
[Link](default(MyClass) == null);
[Link](default(string) == null);

For structs and enums, default(TheType) returns the same as new TheType():

struct Coordinates
{
public int X { get; set; }
public int Y { get; set; }
}

struct MyStruct
{
public string Name { get; set; }
public Coordinates Location { get; set; }
public Coordinates? SecondLocation { get; set; }
public TimeSpan Duration { get; set; }
}

var defaultStruct = default(MyStruct);


[Link]([Link](new MyStruct()));
[Link]([Link](new Coordinates()));
[Link]([Link].X == 0);
[Link]([Link].Y == 0);
[Link]([Link] == null);
[Link]([Link] == null);
[Link]([Link] == [Link]);

default(T) can be particularly useful when T is a generic parameter for which no constraint is present to decide
whether T is a reference type or a value type, for example:

[Link] – C# Notes for Professionals 88


public T GetResourceOrDefault<T>(string resourceName)
{
if (ResourceExists(resourceName))
{
return (T)GetResource(resourceName);
}
else
{
return default(T);
}
}

Section 10.14: sealed


When applied to a class, the sealed modifier prevents other classes from inheriting from it.

class A { }
sealed class B : A { }
class C : B { } //error : Cannot derive from the sealed class

When applied to a virtual method (or virtual property), the sealed modifier prevents this method (property) from
being overridden in derived classes.

public class A
{
public sealed override string ToString() // Virtual method inherited from class Object
{
return "Do not override me!";
}
}

public class B: A
{
public override string ToString() // Compile time error
{
return "An attempt to override";
}
}

Section 10.15: is
Checks if an object is compatible with a given type, i.e. if an object is an instance of the BaseInterface type, or a
type that derives from BaseInterface:

interface BaseInterface {}
class BaseClass : BaseInterface {}
class DerivedClass : BaseClass {}

var d = new DerivedClass();


[Link](d is DerivedClass); // True
[Link](d is BaseClass); // True
[Link](d is BaseInterface); // True
[Link](d is object); // True
[Link](d is string); // False

var b = new BaseClass();


[Link](b is DerivedClass); // False
[Link](b is BaseClass); // True

[Link] – C# Notes for Professionals 89


[Link](b is BaseInterface); // True
[Link](b is object); // True
[Link](b is string); // False

If the intent of the cast is to use the object, it is best practice to use the as keyword'

interface BaseInterface {}
class BaseClass : BaseInterface {}
class DerivedClass : BaseClass {}

var d = new DerivedClass();


[Link](d is DerivedClass); // True - valid use of 'is'
[Link](d is BaseClass); // True - valid use of 'is'

if(d is BaseClass){
var castedD = (BaseClass)d;
[Link](); // valid, but not best practice
}

var asD = d as BaseClass;

if(asD!=null){
[Link](); //preferred method since you incur only one unboxing penalty
}

But, from C# 7 pattern matching feature extends the is operator to check for a type and declare a new variable at
the same time. Same code part with C# 7 :

Version ≥ 7.0
if(d is BaseClass asD ){
[Link]();
}

Section 10.16: this


The this keyword refers to the current instance of class(object). That way two variables with the same name, one at
the class-level (a field) and one being a parameter (or local variable) of a method, can be distinguished.

public MyClass {
int a;

void set_a(int a)
{
//this.a refers to the variable defined outside of the method,
//while a refers to the passed parameter.
this.a = a;
}
}

Other usages of the keyword are chaining non-static constructor overloads:

public MyClass(int arg) : this(arg, null)


{
}

and writing indexers:

public string this[int idx1, string idx2]

[Link] – C# Notes for Professionals 90


{
get { /* ... */ }
set { /* ... */ }
}

and declaring extension methods:

public static int Count<TItem>(this IEnumerable<TItem> source)


{
// ...
}

If there is no conflict with a local variable or parameter, it is a matter of style whether to use this or not, so
[Link] and MemberOfType would be equivalent in that case. Also see base keyword.

Note that if an extension method is to be called on the current instance, this is required. For example if your are
inside a non-static method of a class which implements IEnumerable<> and you want to call the extension Count
from before, you must use:

[Link]() // works like [Link](this)

and this cannot be omitted there.

Section 10.17: readonly


The readonly keyword is a field modifier. When a field declaration includes a readonly modifier, assignments to
that field can only occur as part of the declaration or in a constructor in the same class.

The readonly keyword is different from the const keyword. A const field can only be initialized at the declaration of
the field. A readonly field can be initialized either at the declaration or in a constructor. Therefore, readonly fields
can have different values depending on the constructor used.

The readonly keyword is often used when injecting dependencies.

class Person
{
readonly string _name;
readonly string _surname = "Surname";

Person(string name)
{
_name = name;
}
void ChangeName()
{
_name = "another name"; // Compile error
_surname = "another surname"; // Compile error
}
}

Note: Declaring a field readonly does not imply immutability. If the field is a reference type then the
content of the object can be changed. Readonly is typically used to prevent having the object being
overwritten and assigned only during instantiation of that object.

[Link] – C# Notes for Professionals 91


Note: Inside the constructor a readonly field can be reassigned

public class Car


{
public double Speed {get; set;}
}

//In code

private readonly Car car = new Car();

private void SomeMethod()


{
[Link] = 100;
}

Section 10.18: typeof


Returns the Type of an object, without the need to instantiate it.

Type type = typeof(string);


[Link]([Link]); //[Link]
[Link]("Hello".GetType() == type); //True
[Link]("Hello".GetType() == typeof(string)); //True

Section 10.19: foreach


foreach is used to iterate over the elements of an array or the items within a collection which implements
IEnumerable✝.

var lines = new string[] {


"Hello world!",
"How are you doing today?",
"Goodbye"
};

foreach (string line in lines)


{
[Link](line);
}

This will output

"Hello world!"
"How are you doing today?"
"Goodbye"

Live Demo on .NET Fiddle

You can exit the foreach loop at any point by using the break keyword or move on to the next iteration using the
continue keyword.

var numbers = new int[] {1, 2, 3, 4, 5, 6};

foreach (var number in numbers)

[Link] – C# Notes for Professionals 92


{
// Skip if 2
if (number == 2)
continue;

// Stop iteration if 5
if (number == 5)
break;

[Link](number + ", ");


}

// Prints: 1, 3, 4,

Live Demo on .NET Fiddle

Notice that the order of iteration is guaranteed only for certain collections such as arrays and List, but not
guaranteed for many other collections.

✝ While IEnumerable is typically used to indicate enumerable collections, foreach only requires that the collection
expose publicly the object GetEnumerator() method, which should return an object that exposes the bool
MoveNext() method and the object Current { get; } property.

Section 10.20: dynamic


The dynamic keyword is used with dynamically typed objects. Objects declared as dynamic forego compile-time
static checks, and are instead evaluated at runtime.

using System;
using [Link];

dynamic info = new ExpandoObject();


[Link] = 123;
[Link] = 456;

[Link]([Link]);
// 456

[Link]([Link]);
// Throws RuntimeBinderException

The following example uses dynamic with Newtonsoft's library [Link], in order to easily read data from a
deserialized JSON file.

try
{
string json = @"{ x : 10, y : ""ho""}";
dynamic deserializedJson = [Link](json);
int x = deserializedJson.x;
string y = deserializedJson.y;
// int z = deserializedJson.z; // throws RuntimeBinderException
}
catch (RuntimeBinderException e)
{
// This exception is thrown when a property
// that wasn't assigned to a dynamic variable is used
}

[Link] – C# Notes for Professionals 93


There are some limitations associated with the dynamic keyword. One of them is the use of extension methods.
The following example adds an extension method for string: SayHello.

static class StringExtensions


{
public static string SayHello(this string s) => $"Hello {s}!";
}

The first approach will be to call it as usual (as for a string):

var person = "Person";


[Link]([Link]());

dynamic manager = "Manager";


[Link]([Link]()); // RuntimeBinderException

No compilation error, but at runtime you get a RuntimeBinderException. The workaround for this will be to call the
extension method via the static class:

var helloManager = [Link](manager);


[Link](helloManager);

Section 10.21: try, catch, finally, throw


try, catch, finally, and throw allow you to handle exceptions in your code.

var processor = new InputProcessor();

// The code within the try block will be executed. If an exception occurs during execution of
// this code, execution will pass to the catch block corresponding to the exception type.
try
{
[Link](input);
}
// If a FormatException is thrown during the try block, then this catch block
// will be executed.
catch (FormatException ex)
{
// Throw is a keyword that will manually throw an exception, triggering any catch block that is
// waiting for that exception type.
throw new InvalidOperationException("Invalid input", ex);
}
// catch can be used to catch all or any specific exceptions. This catch block,
// with no type specified, catches any exception that hasn't already been caught
// in a prior catch block.
catch
{
LogUnexpectedException();
throw; // Re-throws the original exception.
}
// The finally block is executed after all try-catch blocks have been; either after the try has
// succeeded in running all commands or after all exceptions have been caught.
finally
{
[Link]();
}

Note: The return keyword can be used in try block, and the finally block will still be executed (just before

[Link] – C# Notes for Professionals 94


returning). For example:

try
{
[Link]();
return [Link](query);
}
finally
{
[Link]();
}

The statement [Link]() will execute before the result of [Link](query) is returned.

Section 10.22: void


The reserved word "void" is an alias of [Link] type, and has two uses:

1. Declare a method that doesn't have a return value:

public void DoSomething()


{
// Do some work, don't return any value to the caller.
}

A method with a return type of void can still have the return keyword in its body. This is useful when you want to
exit the method's execution and return the flow to the caller:

public void DoSomething()


{
// Do some work...

if (condition)
return;

// Do some more work if the condition evaluated to false.


}

2. Declare a pointer to an unknown type in an unsafe context.

In an unsafe context, a type may be a pointer type, a value type, or a reference type. A pointer type declaration is
usually type* identifier, where the type is a known type - i.e int* myInt, but can also be void* identifier,
where the type is unknown.

Note that declaring a void pointer type is discouraged by Microsoft.

Section 10.23: namespace


The namespace keyword is an organization construct that helps us understand how a codebase is arranged.
Namespaces in C# are virtual spaces rather than being in a physical folder.

namespace StackOverflow
{
namespace Documentation
{
namespace [Link]
{

[Link] – C# Notes for Professionals 95


public class Program
{
public static void Main()
{
[Link](typeof(Program).Namespace);
//[Link]
}
}
}
}
}

Namespaces in C# can also be written in chained syntax. The following is equivalent to above:

namespace [Link]
{
public class Program
{
public static void Main()
{
[Link](typeof(Program).Namespace);
//[Link]
}
}
}

Section 10.24: ref, out


The ref and out keywords cause an argument to be passed by reference, not by value. For value types, this means
that the value of the variable can be changed by the callee.

int x = 5;
ChangeX(ref x);
// The value of x could be different now

For reference types, the instance in the variable can not only be modified (as is the case without ref), but it can also
be replaced altogether:

Address a = new Address();


ChangeFieldInAddress(a);
// a will be the same instance as before, even if it is modified
CreateANewInstance(ref a);
// a could be an entirely new instance now

The main difference between the out and ref keyword is that ref requires the variable to be initialized by the
caller, while out passes that responsibility to the callee.

To use an out parameter, both the method definition and the calling method must explicitly use the out keyword.

int number = 1;
[Link]("Before AddByRef: " + number); // number = 1
AddOneByRef(ref number);
[Link]("After AddByRef: " + number); // number = 2
SetByOut(out number);
[Link]("After SetByOut: " + number); // number = 34

void AddOneByRef(ref int value)


{

[Link] – C# Notes for Professionals 96


value++;
}

void SetByOut(out int value)


{
value = 34;
}

Live Demo on .NET Fiddle

The following does not compile, because out parameters must have a value assigned before the method returns (it
would compile using ref instead):

void PrintByOut(out int value)


{
[Link]("Hello!");
}

using out keyword as Generic Modifier

out keyword can also be used in generic type parameters when defining generic interfaces and delegates. In this
case, the out keyword specifies that the type parameter is covariant.

Covariance enables you to use a more derived type than that specified by the generic parameter. This
allows for implicit conversion of classes that implement variant interfaces and implicit conversion of
delegate types. Covariance and contravariance are supported for reference types, but they are not
supported for value types. - MSDN

//if we have an interface like this


interface ICovariant<out R> { }

//and two variables like


ICovariant<Object> iobj = new Sample<Object>();
ICovariant<String> istr = new Sample<String>();

// then the following statement is valid


// without the out keyword this would have thrown error
iobj = istr; // implicit conversion occurs here

Section 10.25: base


The base keyword is used to access members from a base class. It is commonly used to call base implementations
of virtual methods, or to specify which base constructor should be called.

Choosing a constructor

public class Child : SomeBaseClass {


public Child() : base("some string for the base class")
{
}
}

public class SomeBaseClass {


public SomeBaseClass()
{
// new Child() will not call this constructor, as it does not have a parameter

[Link] – C# Notes for Professionals 97


}
public SomeBaseClass(string message)
{
// new Child() will use this base constructor because of the specified parameter in Child's
constructor
[Link](message);
}
}

Calling base implementation of virtual method

public override void SomeVirtualMethod() {


// Do something, then call base implementation
[Link]();
}

It is possible to use the base keyword to call a base implementation from any method. This ties the method call
directly to the base implementation, which means that even if new child classes override a virtual method, the base
implementation will still be called so this needs to be used with caution.

public class Parent


{
public virtual int VirtualMethod()
{
return 1;
}
}

public class Child : Parent


{
public override int VirtualMethod() {
return 11;
}

public int NormalMethod()


{
return [Link]();
}

public void CallMethods()


{
[Link](11, VirtualMethod());

[Link](1, NormalMethod());
[Link](1, [Link]());
}
}

public class GrandChild : Child


{
public override int VirtualMethod()
{
return 21;
}

public void CallAgain()


{
[Link](21, VirtualMethod());
[Link](11, [Link]());

[Link] – C# Notes for Professionals 98


// Notice that the call to NormalMethod below still returns the value
// from the extreme base class even though the method has been overridden
// in the child class.
[Link](1, NormalMethod());
}
}

Section 10.26: float, double, decimal


float

float is an alias to the .NET datatype [Link]. It allows IEEE 754 single-precision floating point numbers to
be stored. This data type is present in [Link] which is implicitly referenced by every C# project when you
create them.

Approximate range: -3.4 × 1038 to 3.4 × 1038

Decimal precision: 6-9 significant digits

Notation:

float f = 0.1259;
var f1 = 0.7895f; // f is literal suffix to represent float values

It should be noted that the float type often results in significant rounding errors. In applications where
precision is important, other data types should be considered.

double

double is an alias to the .NET datatype [Link]. It represents a double-precision 64-bit floating-point
number. This datatype is present in [Link] which is implicitly referenced in any C# project.

Range: ±5.0 × 10−324 to ±1.7 × 10308

Decimal precision: 15-16 significant digits

Notation:

double distance = 200.34; // a double value


double salary = 245; // an integer implicitly type-casted to double value
var marks = 123.764D; // D is literal suffix to represent double values

decimal

decimal is an alias to the .NET datatype [Link]. It represents a keyword indicates a 128-bit data type.
Compared to floating-point types, the decimal type has more precision and a smaller range, which makes it
appropriate for financial and monetary calculations. This datatype is present in [Link] which is implicitly
referenced in any C# project.

Range: -7.9 × 1028 to 7.9 × 1028

Decimal precision: 28-29 significant digits

[Link] – C# Notes for Professionals 99


Notation:

decimal payable = 152.25m; // a decimal value


var marks = 754.24m; // m is literal suffix to represent decimal values

Section 10.27: operator


Most of the built-in operators (including conversion operators) can be overloaded by using the operator keyword
along with the public and static modifiers.

The operators comes in three forms: unary operators, binary operators and conversion operators.

Unary and binary operators requires at least one parameter of same type as the containing type, and some
requires a complementary matching operator.

Conversion operators must convert to or from the enclosing type.

public struct Vector32


{

public Vector32(int x, int y)


{
X = x;
Y = y;
}

public int X { get; }


public int Y { get; }

public static bool operator ==(Vector32 left, Vector32 right)


=> left.X == right.X && left.Y == right.Y;

public static bool operator !=(Vector32 left, Vector32 right)


=> !(left == right);

public static Vector32 operator +(Vector32 left, Vector32 right)


=> new Vector32(left.X + right.X, left.Y + right.Y);

public static Vector32 operator +(Vector32 left, int right)


=> new Vector32(left.X + right, left.Y + right);

public static Vector32 operator +(int left, Vector32 right)


=> right + left;

public static Vector32 operator -(Vector32 left, Vector32 right)


=> new Vector32(left.X - right.X, left.Y - right.Y);

public static Vector32 operator -(Vector32 left, int right)


=> new Vector32(left.X - right, left.Y - right);

public static Vector32 operator -(int left, Vector32 right)


=> right - left;

public static implicit operator Vector64(Vector32 vector)


=> new Vector64(vector.X, vector.Y);

public override string ToString() => $"{{{X}, {Y}}}";

[Link] – C# Notes for Professionals 100


public struct Vector64
{

public Vector64(long x, long y)


{
X = x;
Y = y;
}

public long X { get; }


public long Y { get; }

public override string ToString() => $"{{{X}, {Y}}}";

Example

var vector1 = new Vector32(15, 39);


var vector2 = new Vector32(87, 64);

[Link](vector1 == vector2); // false


[Link](vector1 != vector2); // true
[Link](vector1 + vector2); // {102, 103}
[Link](vector1 - vector2); // {-72, -25}

Section 10.28: char


A char is single letter stored inside a variable. It is built-in value type which takes two bytes of memory space. It
represents [Link] data type found in [Link] which is implicitly referenced by every C# project when
you create them.

There are multiple ways to do this.

1. char c = 'c';
2. char c = '\u0063'; //Unicode
3. char c = '\x0063'; //Hex
4. char c = (char)99;//Integral

A char can be implicitly converted to ushort, int, uint, long, ulong, float, double, or decimal and it will
return the integer value of that char.

ushort u = c;

returns 99 etc.

However, there are no implicit conversions from other types to char. Instead you must cast them.

ushort u = 99;
char c = (char)u;

Section 10.29: params


params allows a method parameter to receive a variable number of arguments, i.e. zero, one or multiple arguments
are allowed for that parameter.

[Link] – C# Notes for Professionals 101


static int AddAll(params int[] numbers)
{
int total = 0;
foreach (int number in numbers)
{
total += number;
}

return total;
}

This method can now be called with a typical list of int arguments, or an array of ints.

AddAll(5, 10, 15, 20); // 50


AddAll(new int[] { 5, 10, 15, 20 }); // 50

params must appear at most once and if used, it must be last in the argument list, even if the succeeding type is
different to that of the array.

Be careful when overloading functions when using the params keyword. C# prefers matching more specific
overloads before resorting to trying to use overloads with params. For example if you have two methods:

static double Add(params double[] numbers)


{
[Link]("Add with array of doubles");
double total = 0.0;
foreach (double number in numbers)
{
total += number;
}

return total;
}

static int Add(int a, int b)


{
[Link]("Add with 2 ints");
return a + b;
}

Then the specific 2 argument overload will take precedence before trying the params overload.

Add(2, 3); //prints "Add with 2 ints"


Add(2, 3.0); //prints "Add with array of doubles" (doubles are not ints)
Add(2, 3, 4); //prints "Add with array of doubles" (no 3 argument overload)

Section 10.30: while


The while operator iterates over a block of code until the conditional query equals false or the code is interrupted
with a goto, return, break or throw statement.

Syntax for while keyword:

while( condition ) { code block; }

Example:

[Link] – C# Notes for Professionals 102


int i = 0;
while (i++ < 5)
{
[Link]("While is on loop number {0}.", i);
}

Output:

"While is on loop number 1."


"While is on loop number 2."
"While is on loop number 3."
"While is on loop number 4."
"While is on loop number 5."

Live Demo on .NET Fiddle

A while loop is Entry Controlled, as the condition is checked before the execution of the enclosed code block. This
means that the while loop wouldn't execute its statements if the condition is false.

bool a = false;

while (a == true)
{
[Link]("This will never be printed.");
}

Giving a while condition without provisioning it to become false at some point will result in an infinite or endless
loop. As far as possible, this should be avoided, however, there may be some exceptional circumstances when you
need this.

You can create such a loop as follows:

while (true)
{
//...
}

Note that the C# compiler will transform loops such as

while (true)
{
// ...
}

or

for(;;)
{
// ...
}

into

{
:label

[Link] – C# Notes for Professionals 103


// ...
goto label;
}

Note that a while loop may have any condition, no matter how complex, as long as it evaluates to (or returns) a
boolean value (bool). It may also contain a function that returns a boolean value (as such a function evaluates to the
same type as an expression such as `a==x'). For example,

while ([Link]([Link]()))
{
[Link]();
}

Section 10.31: null


A variable of a reference type can hold either a valid reference to an instance or a null reference. The null reference
is the default value of reference type variables, as well as nullable value types.

null is the keyword that represents a null reference.

As an expression, it can be used to assign the null reference to variables of the aforementioned types:

object a = null;
string b = null;
int? c = null;
List<int> d = null;

Non-nullable value types cannot be assigned a null reference. All the following assignments are invalid:

int a = null;
float b = null;
decimal c = null;

The null reference should not be confused with valid instances of various types such as:

an empty list (new List<int>())


an empty string ("")
the number zero (0, 0f, 0m)
the null character ( '\0' )

Sometimes, it is meaningful to check if something is either null or an empty/default object. The


[Link](String) method may be used to check this, or you may implement your own equivalent
method.

private void GreetUser(string userName)


{
if ([Link](userName))
{
//The method that called us either sent in an empty string, or they sent us a null reference.
Either way, we need to report the problem.
throw new InvalidOperationException("userName may not be null or empty.");
}
else
{
//userName is acceptable.
[Link]("Hello, " + userName + "!");
}

[Link] – C# Notes for Professionals 104


}

Section 10.32: continue


Immediately pass control to the next iteration of the enclosing loop construct (for, foreach, do, while):

for (var i = 0; i < 10; i++)


{
if (i < 5)
{
continue;
}
[Link](i);
}

Output:

5
6
7
8
9

Live Demo on .NET Fiddle

var stuff = new [] {"a", "b", null, "c", "d"};

foreach (var s in stuff)


{
if (s == null)
{
continue;
}
[Link](s);
}

Output:

a
b
c
d

Live Demo on .NET Fiddle

Section 10.33: string


string is an alias to the .NET datatype [Link], which allows text (sequences of characters) to be stored.

Notation:

string a = "Hello";
var b = "world";

[Link] – C# Notes for Professionals 105


var f = new string(new []{ 'h', 'i', '!' }); // hi!

Each character in the string is encoded in UTF-16, which means that each character will require a minimum 2 bytes
of storage space.

Section 10.34: return

MSDN: The return statement terminates execution of the method in which it appears and returns control
to the calling method. It can also return an optional value. If the method is a void type, the return
statement can be omitted.

public int Sum(int valueA, int valueB)


{
return valueA + valueB;
}

public void Terminate(bool terminateEarly)


{
if (terminateEarly) return; // method returns to caller if true was passed in
else [Link]("Not early"); // prints only if terminateEarly was false
}

Section 10.35: unsafe


The unsafe keyword can be used in type or method declarations or to declare an inline block.

The purpose of this keyword is to enable the use of the unsafe subset of C# for the block in question. The unsafe
subset includes features like pointers, stack allocation, C-like arrays, and so on.

Unsafe code is not verifiable and that's why its usage is discouraged. Compilation of unsafe code requires passing a
switch to the C# compiler. Additionally, the CLR requires that the running assembly has full trust.

Despite these limitations, unsafe code has valid usages in making some operations more performant (e.g. array
indexing) or easier (e.g. interop with some unmanaged libraries).

As a very simple example

// compile with /unsafe


class UnsafeTest
{
unsafe static void SquarePtrParam(int* p)
{
*p *= *p; // the '*' dereferences the pointer.
//Since we passed in "the address of i", this becomes "i *= i"
}

unsafe static void Main()


{
int i = 5;
// Unsafe method: uses address-of operator (&):
SquarePtrParam(&i); // "&i" means "the address of i". The behavior is similar to "ref i"
[Link](i); // Output: 25
}
}

[Link] – C# Notes for Professionals 106


While working with pointers, we can change the values of memory locations directly, rather than having to address
them by name. Note that this often requires the use of the fixed keyword to prevent possible memory corruption
as the garbage collector moves things around (otherwise, you may get error CS0212). Since a variable that has been
"fixed" cannot be written to, we also often have to have a second pointer that starts out pointing to the same
location as the first.

void Main()
{
int[] intArray = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

UnsafeSquareArray(intArray);
foreach(int i in intArray)
[Link](i);
}

unsafe static void UnsafeSquareArray(int[] pArr)


{
int len = [Link];

//in C or C++, we could say


// int* a = &(pArr[0])
// however, C# requires you to "fix" the variable first
fixed(int* fixedPointer = &(pArr[0]))
{
//Declare a new int pointer because "fixedPointer" cannot be written to.
// "p" points to the same address space, but we can modify it
int* p = fixedPointer;

for (int i = 0; i < len; i++)


{
*p *= *p; //square the value, just like we did in SquarePtrParam, above
p++; //move the pointer to the next memory space.
// NOTE that the pointer will move 4 bytes since "p" is an
// int pointer and an int takes 4 bytes

//the above 2 lines could be written as one, like this:


// "*p *= *p++;"
}
}
}

Output:

1
4
9
16
25
36
49
64
81
100

unsafe also allows the use of stackalloc which will allocate memory on the stack like _alloca in the C run-time
library. We can modify the above example to use stackalloc as follows:

unsafe void Main()


{

[Link] – C# Notes for Professionals 107


const int len=10;
int* seedArray = stackalloc int[len];

//We can no longer use the initializer "{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}" as before.


// We have at least 2 options to populate the array. The end result of either
// option will be the same (doing both will also be the same here).

//FIRST OPTION:
int* p = seedArray; // we don't want to lose where the array starts, so we
// create a shadow copy of the pointer
for(int i=1; i<=len; i++)
*p++ = i;
//end of first option

//SECOND OPTION:
for(int i=0; i<len; i++)
seedArray[i] = i+1;
//end of second option

UnsafeSquareArray(seedArray, len);
for(int i=0; i< len; i++)
[Link](seedArray[i]);
}

//Now that we are dealing directly in pointers, we don't need to mess around with
// "fixed", which dramatically simplifies the code
unsafe static void UnsafeSquareArray(int* p, int len)
{
for (int i = 0; i < len; i++)
*p *= *p++;
}

(Output is the same as above)

Section 10.36: switch


The switch statement is a control statement that selects a switch section to execute from a list of candidates. A
switch statement includes one or more switch sections. Each switch section contains one or more case labels
followed by one or more statements. If no case label contains a matching value, control is transferred to the
default section, if there is one. Case fall-through is not supported in C#, strictly speaking. However, if 1 or more
case labels are empty, execution will follow the code of the next case block which contains code. This allows
grouping of multiple case labels with the same implementation. In the following example, if month equals 12, the
code in case 2 will be executed since the case labels 12 1 and 2 are grouped. If a case block is not empty, a break
must be present before the next case label, otherwise the compiler will flag an error.

int month = [Link]; // this is expected to be 1-12 for Jan-Dec

switch (month)
{
case 12:
case 1:
case 2:
[Link]("Winter");
break;
case 3:
case 4:
case 5:
[Link]("Spring");
break;

[Link] – C# Notes for Professionals 108


case 6:
case 7:
case 8:
[Link]("Summer");
break;
case 9:
case 10:
case 11:
[Link]("Autumn");
break;
default:
[Link]("Incorrect month index");
break;
}

A case can only be labeled by a value known at compile time (e.g. 1, "str", Enum.A), so a variable isn't a valid case
label, but a const or an Enum value is (as well as any literal value).

Section 10.37: var


An implicitly-typed local variable that is strongly typed just as if the user had declared the type. Unlike other
variable declarations, the compiler determines the type of variable that this represents based on the value that is
assigned to it.

var i = 10; // implicitly typed, the compiler must determine what type of variable this is
int i = 10; // explicitly typed, the type of variable is explicitly stated to the compiler

// Note that these both represent the same type of variable (int) with the same value (10).

Unlike other types of variables, variable definitions with this keyword need to be initialized when declared. This is
due to the var keyword representing an implicitly-typed variable.

var i;
i = 10;

// This code will not run as it is not initialized upon declaration.

The var keyword can also be used to create new datatypes on the fly. These new datatypes are known as
anonymous types. They are quite useful, as they allow a user to define a set of properties without having to explicitly
declare any kind of object type first.

Plain anonymous type

var a = new { number = 1, text = "hi" };

LINQ query that returns an anonymous type

public class Dog


{
public string Name { get; set; }
public int Age { get; set; }
}

public class DogWithBreed


{
public Dog Dog { get; set; }
public string BreedName { get; set; }

[Link] – C# Notes for Professionals 109


}

public void GetDogsWithBreedNames()


{
var db = new DogDataContext(ConnectString);
var result = from d in [Link]
join b in [Link] on [Link] equals [Link]
select new
{
DogName = [Link],
BreedName = [Link]
};

DoStuff(result);
}

You can use var keyword in foreach statement

public bool hasItemInList(List<String> list, string stringToSearch)


{
foreach(var item in list)
{
if( ( (string)item ).equals(stringToSearch) )
return true;
}

return false;
}

Section 10.38: when


The when is a keyword added in C# 6, and it is used for exception filtering.

Before the introduction of the when keyword, you could have had one catch clause for each type of exception; with
the addition of the keyword, a more fine-grained control is now possible.

A when expression is attached to a catch branch, and only if the when condition is true, the catch clause will be
executed. It is possible to have several catch clauses with the same exception class types, and different when
conditions.

private void CatchException(Action action)


{
try
{
[Link]();
}

// exception filter
catch (Exception ex) when ([Link]("when"))
{
[Link]("Caught an exception with when");
}

catch (Exception ex)


{
[Link]("Caught an exception without when");
}
}

[Link] – C# Notes for Professionals 110


private void Method1() { throw new Exception("message for exception with when"); }
private void Method2() { throw new Exception("message for general exception"); }

CatchException(Method1);
CatchException(Method2);

Section 10.39: lock


lock provides thread-safety for a block of code, so that it can be accessed by only one thread within the same
process. Example:

private static object _lockObj = new object();


static void Main(string[] args)
{
[Link](() => TaskWork());
[Link](() => TaskWork());
[Link](() => TaskWork());

[Link]();
}

private static void TaskWork()


{
lock(_lockObj)
{
[Link]("Entered");

[Link](3000);
[Link]("Done Delaying");

// Access shared resources safely

[Link]("Leaving");
}
}

Output:

Entered
Done Delaying
Leaving
Entered
Done Delaying
Leaving
Entered
Done Delaying
Leaving

Use cases:

Whenever you have a block of code that might produce side-effects if executed by multiple threads at the same
time. The lock keyword along with a shared synchronization object (_objLock in the example) can be used to
prevent that.

Note that _objLock can't be null and multiple threads executing the code must use the same object instance
(either by making it a static field, or by using the same class instance for both threads)

From the compiler side, the lock keyword is a syntactic sugar that is replaced by [Link](_lockObj); and

[Link] – C# Notes for Professionals 111


[Link](_lockObj);. So if you replace the lock by surrounding the block of code with these two methods,
you would get the same results. You can see actual code in Syntactic sugar in C# - lock example

Section 10.40: uint


An unsigned integer, or uint, is a numeric datatype that only can hold positive integers. Like it's name suggests, it
represents an unsigned 32-bit integer. The uint keyword itself is an alias for the Common Type System type
System.UInt32. This datatype is present in [Link], which is implicitly referenced by every C# project when
you create them. It occupies four bytes of memory space.

Unsigned integers can hold any value from 0 to 4,294,967,295.

Examples on how and now not to declare unsigned integers

uint i = 425697; // Valid expression, explicitly stated to compiler


var i1 = 789247U; // Valid expression, suffix allows compiler to determine datatype
uint x = 3.0; // Error, there is no implicit conversion

Please note: According to Microsoft, it is recommended to use the int datatype wherever possible as the uint
datatype is not CLS-compliant.

Section 10.41: if, if...else, if... else if


The if statement is used to control the flow of the program. An if statement identifies which statement to run
based on the value of a Boolean expression.

For a single statement, the braces{} are optional but recommended.

int a = 4;
if(a % 2 == 0)
{
[Link]("a contains an even number");
}
// output: "a contains an even number"

The if can also have an else clause, that will be executed in case the condition evaluates to false:

int a = 5;
if(a % 2 == 0)
{
[Link]("a contains an even number");
}
else
{
[Link]("a contains an odd number");
}
// output: "a contains an odd number"

The if...else if construct lets you specify multiple conditions:

int a = 9;
if(a % 2 == 0)
{
[Link]("a contains an even number");
}
else if(a % 3 == 0)

[Link] – C# Notes for Professionals 112


{
[Link]("a contains an odd number that is a multiple of 3");
}
else
{
[Link]("a contains an odd number");
}
// output: "a contains an odd number that is a multiple of 3"

Important to note that if a condition is met in the above example , the control skips other tests and jumps to
the end of that particular if else [Link], the order of tests is important if you are using if .. else if
construct

C# Boolean expressions use short-circuit evaluation. This is important in cases where evaluating conditions may
have side effects:

if (someBooleanMethodWithSideEffects() && someOtherBooleanMethodWithSideEffects()) {


//...
}

There's no guarantee that someOtherBooleanMethodWithSideEffects will actually run.

It's also important in cases where earlier conditions ensure that it's "safe" to evaluate later ones. For example:

if (someCollection != null && [Link] > 0) {


// ..
}

The order is very important in this case because, if we reverse the order:

if ([Link] > 0 && someCollection != null) {

it will throw a NullReferenceException if someCollection is null.

Section 10.42: static


The static modifier is used to declare a static member, which does not need to be instantiated in order to be
accessed, but instead is accessed simply through its name, i.e. [Link].

static can be used with classes, fields, methods, properties, operators, events, and constructors.

While an instance of a class contains a separate copy of all instance fields of the class, there is only one copy of
each static field.

class A
{
static public int count = 0;

public A()
{
count++;
}
}

class Program
{
static void Main(string[] args)

[Link] – C# Notes for Professionals 113


{
A a = new A();
A b = new A();
A c = new A();

[Link]([Link]); // 3
}
}

count equals to the total number of instances of A class.

The static modifier can also be used to declare a static constructor for a class, to initialize static data or run code
that only needs to be called once. Static constructors are called before the class is referenced for the first time.

class A
{
static public DateTime InitializationTime;

// Static constructor
static A()
{
InitializationTime = [Link];
// Guaranteed to only run once
[Link]([Link]());
}
}

A static class is marked with the static keyword, and can be used as a beneficial container for a set of methods
that work on parameters, but don't necessarily require being tied to an instance. Because of the static nature of
the class, it cannot be instantiated, but it can contain a static constructor. Some features of a static class
include:

Can't be inherited
Can't inherit from anything other than Object
Can contain a static constructor but not an instance constructor
Can only contain static members
Is sealed

The compiler is also friendly and will let the developer know if any instance members exist within the class. An
example would be a static class that converts between US and Canadian metrics:

static class ConversionHelper {


private static double oneGallonPerLitreRate = 0.264172;

public static double litreToGallonConversion(int litres) {


return litres * oneGallonPerLitreRate;
}
}

When classes are declared static:

public static class Functions


{
public static int Double(int value)
{
return value + value;
}

[Link] – C# Notes for Professionals 114


}

all function, properties or members within the class also need to be declared static. No instance of the class can be
created. In essence a static class allows you to create bundles of functions that are grouped together logically.

Since C#6 static can also be used alongside using to import static members and methods. They can be used then
without class name.

Old way, without using static:

using System;

public class ConsoleApplication


{
public static void Main()
{
[Link]("Hello World!"); //Writeline is method belonging to static class Console
}

Example with using static

using static [Link];

public class ConsoleApplication


{
public static void Main()
{
WriteLine("Hello World!"); //Writeline is method belonging to static class Console
}

Drawbacks

While static classes can be incredibly useful, they do come with their own caveats:

Once the static class has been called, the class is loaded into memory and cannot be run through the
garbage collector until the AppDomain housing the static class is unloaded.

A static class cannot implement an interface.

Section 10.43: internal


The internal keyword is an access modifier for types and type members. Internal types or members are
accessible only within files in the same assembly

usage:

public class BaseClass


{
// Only accessible within the same assembly
internal static int x = 0;
}

The difference between different access modifiers is clarified here

[Link] – C# Notes for Professionals 115


Access modifiers

public

The type or member can be accessed by any other code in the same assembly or another assembly that
references it.

private

The type or member can only be accessed by code in the same class or struct.

protected

The type or member can only be accessed by code in the same class or struct, or in a derived class.

internal

The type or member can be accessed by any code in the same assembly, but not from another assembly.

protected internal

The type or member can be accessed by any code in the same assembly, or by any derived class in
another assembly.

When no access modifier is set, a default access modifier is used. So there is always some form of access modifier
even if it's not set.

Section 10.44: using


There are two types of using keyword usage, using statement and using directive:

1. using statement:

The using keyword ensures that objects that implement the IDisposable interface are properly disposed
after usage. There is a separate topic for the using statement

2. using directive

The using directive has three usages, see the msdn page for the using directive. There is a separate topic for
the using directive.

Section 10.45: where


where can serve two purposes in C#: type constraining in a generic argument, and filtering LINQ queries.

[Link] – C# Notes for Professionals 116


In a generic class, let's consider

public class Cup<T>


{
// ...
}

T is called a type parameter. The class definition can impose constraints on the actual types that can be supplied for
T.

The following kinds of constraints can be applied:

value type
reference type
default constructor
inheritance and implementation

value type

In this case only structs (this includes 'primitive' data types such as int, boolean etc) can be supplied

public class Cup<T> where T : struct


{
// ...
}

reference type

In this case only class types can be supplied

public class Cup<T> where T : class


{
// ...
}

hybrid value/reference type

Occasionally it is desired to restrict type arguments to those available in a database, and these will usually map to
value types and strings. As all type restrictions must be met, it is not possible to specify where T : struct or
string (this is not valid syntax). A workaround is to restrict type arguments to IConvertible which has built in
types of "... Boolean, SByte, Byte, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single, Double, Decimal, DateTime,
Char, and String." It is possible other objects will implement IConvertible, though this is rare in practice.

public class Cup<T> where T : IConvertible


{
// ...
}

default constructor

Only types that contain a default constructor will be allowed. This includes value types and classes that contain a
default (parameterless) constructor

public class Cup<T> where T : new


{
// ...

[Link] – C# Notes for Professionals 117


}

inheritance and implementation

Only types that inherit from a certain base class or implement a certain interface can be supplied.

public class Cup<T> where T : Beverage


{
// ...
}

public class Cup<T> where T : IBeer


{
// ...
}

The constraint can even reference another type parameter:

public class Cup<T, U> where U : T


{
// ...
}

Multiple constraints can be specified for a type argument:

public class Cup<T> where T : class, new()


{
// ...
}

The previous examples show generic constraints on a class definition, but constraints can be used
anywhere a type argument is supplied: classes, structs, interfaces, methods, etc.

where can also be a LINQ clause. In this case it is analogous to WHERE in SQL:

int[] nums = { 5, 2, 1, 3, 9, 8, 6, 7, 2, 0 };

var query =
from num in nums
where num < 5
select num;

foreach (var n in query)


{
[Link](n + " ");
}
// prints 2 1 3 2 0

Section 10.46: int


int is an alias for System.Int32, which is a data type for signed 32-bit integers. This data type can be found in
[Link] which is implicitly referenced by every C# project when you create them.

Range: -2,147,483,648 to 2,147,483,647

int int1 = -10007;

[Link] – C# Notes for Professionals 118


var int2 = 2132012521;

Section 10.47: ulong


Keyword used for unsigned 64-bit integers. It represents System.UInt64 data type found in [Link] which is
implicitly referenced by every C# project when you create them.

Range: 0 to 18,446,744,073,709,551,615

ulong veryLargeInt = 18446744073609451315;


var anotherVeryLargeInt = 15446744063609451315UL;

Section 10.48: true, false


The true and false keywords have two uses:

1. As literal Boolean values

var myTrueBool = true;


var myFalseBool = false;

2. As operators that can be overloaded

public static bool operator true(MyClass x)


{
return [Link] >= 0;
}

public static bool operator false(MyClass x)


{
return [Link] < 0;
}

Overloading the false operator was useful prior to C# 2.0, before the introduction of Nullable types.
A type that overloads the true operator, must also overload the false operator.

Section 10.49: struct


A struct type is a value type that is typically used to encapsulate small groups of related variables, such as the
coordinates of a rectangle or the characteristics of an item in an inventory.

Classes are reference types, structs are value types.

using static [Link];

namespace ConsoleApplication1
{
struct Point
{
public int X;
public int Y;

public override string ToString()


{
return $"X = {X}, Y = {Y}";

[Link] – C# Notes for Professionals 119


}

public void Display(string name)


{
WriteLine(name + ": " + ToString());
}
}

class Program
{
static void Main()
{
var point1 = new Point {X = 10, Y = 20};
// it's not a reference but value type
var point2 = point1;
point2.X = 777;
point2.Y = 888;
[Link](nameof(point1)); // point1: X = 10, Y = 20
[Link](nameof(point2)); // point2: X = 777, Y = 888

ReadKey();
}
}
}

Structs can also contain constructors, constants, fields, methods, properties, indexers, operators, events, and
nested types, although if several such members are required, you should consider making your type a class instead.

Some suggestions from MS on when to use struct and when to use class:

CONSIDER

defining a struct instead of a class if instances of the type are small and commonly short-lived or are commonly
embedded in other objects.

AVOID

defining a struct unless the type has all of the following characteristics:

It logically represents a single value, similar to primitive types (int, double, etc.)
It has an instance size under 16 bytes.
It is immutable.
It will not have to be boxed frequently.

Section 10.50: extern


The extern keyword is used to declare methods that are implemented externally. This can be used in conjunction
with the DllImport attribute to call into unmanaged code using Interop services. which in this case it will come with
static modifier

For Example:

using [Link];
public class MyClass
{
[DllImport("[Link]")]
private static extern int SetForegroundWindow(IntPtr point);

[Link] – C# Notes for Professionals 120


public void ActivateProcessWindow(Process p)
{
SetForegroundWindow([Link]);
}
}

This uses the SetForegroundWindow method imported from the [Link] library

This can also be used to define an external assembly alias. which let us to reference different versions of same
components from single assembly.

To reference two assemblies with the same fully-qualified type names, an alias must be specified at a command
prompt, as follows:

/r:GridV1=[Link]
/r:GridV2=[Link]

This creates the external aliases GridV1 and GridV2. To use these aliases from within a program, reference them by
using the extern keyword. For example:

extern alias GridV1;


extern alias GridV2;

Section 10.51: bool


Keyword for storing the Boolean values true and false. bool is an alias of [Link].

The default value of a bool is false.

bool b; // default value is false


b = true; // true
b = ((5 + 2) == 6); // false

For a bool to allow null values it must be initialized as a bool?.

The default value of a bool? is null.

bool? a // default value is null

Section 10.52: interface


An interface contains the signatures of methods, properties and events. The derived classes defines the members
as the interface contains only the declaration of the members.

An interface is declared using the interface keyword.

interface IProduct
{
decimal Price { get; }
}

class Product : IProduct


{
const decimal vat = 0.2M;

public Product(decimal price)

[Link] – C# Notes for Professionals 121


{
_price = price;
}

private decimal _price;


public decimal Price { get { return _price * (1 + vat); } }
}

Section 10.53: delegate


Delegates are types that represent a reference to a method. They are used for passing methods as arguments to
other methods.

Delegates can hold static methods, instance methods, anonymous methods, or lambda expressions.

class DelegateExample
{
public void Run()
{
//using class method
InvokeDelegate( WriteToConsole );

//using anonymous method


DelegateInvoker di = delegate ( string input )
{
[Link]( [Link]( "di: {0} ", input ) );
return true;
};
InvokeDelegate( di );

//using lambda expression


InvokeDelegate( input => false );
}

public delegate bool DelegateInvoker( string input );

public void InvokeDelegate(DelegateInvoker func)


{
var ret = func( "hello world" );
[Link]( [Link]( " > delegate returned {0}", ret ) );
}

public bool WriteToConsole( string input )


{
[Link]( [Link]( "WriteToConsole: '{0}'", input ) );
return true;
}
}

When assigning a method to a delegate it is important to note that the method must have the same return type as
well as parameters. This differs from 'normal' method overloading, where only the parameters define the signature
of the method.

Events are built on top of delegates.

Section 10.54: unchecked


The unchecked keyword prevents the compiler from checking for overflows/underflows.

[Link] – C# Notes for Professionals 122


For example:

const int ConstantMax = [Link];


unchecked
{
int1 = 2147483647 + 10;
}
int1 = unchecked(ConstantMax + 10);

Without the unchecked keyword, neither of the two addition operations will compile.

When is this useful?

This is useful as it may help speed up calculations that definitely will not overflow since checking for overflow takes
time, or when an overflow/underflow is desired behavior (for instance, when generating a hash code).

Section 10.55: ushort


A numeric type used to store 16-bit positive integers. ushort is an alias for System.UInt16, and takes up 2 bytes of
memory.

Valid range is 0 to 65535.

ushort a = 50; // 50
ushort b = 65536; // Error, cannot be converted
ushort c = unchecked((ushort)65536); // Overflows (wraps around to 0)

Section 10.56: sizeof


Used to obtain the size in bytes for an unmanaged type

int byteSize = sizeof(byte) // 1


int sbyteSize = sizeof(sbyte) // 1
int shortSize = sizeof(short) // 2
int ushortSize = sizeof(ushort) // 2
int intSize = sizeof(int) // 4
int uintSize = sizeof(uint) // 4
int longSize = sizeof(long) // 8
int ulongSize = sizeof(ulong) // 8
int charSize = sizeof(char) // 2(Unicode)
int floatSize = sizeof(float) // 4
int doubleSize = sizeof(double) // 8
int decimalSize = sizeof(decimal) // 16
int boolSize = sizeof(bool) // 1

Section 10.57: in
The in keyword has three uses:

a) As part of the syntax in a foreach statement or as part of the syntax in a LINQ query

foreach (var member in sequence)


{
// ...
}

[Link] – C# Notes for Professionals 123


b) In the context of generic interfaces and generic delegate types signifies contravariance for the type parameter in
question:

public interface IComparer<in T>


{
// ...
}

c) In the context of LINQ query refers to the collection that is being queried

var query = from x in source select new { [Link], [Link], };

Section 10.58: implicit


The implicit keyword is used to overload a conversion operator. For example, you may declare a Fraction class
that should automatically be converted to a double when needed, and that can be automatically converted from
int:

class Fraction(int numerator, int denominator)


{
public int Numerator { get; } = numerator;
public int Denominator { get; } = denominator;
// ...
public static implicit operator double(Fraction f)
{
return [Link] / (double) [Link];
}
public static implicit operator Fraction(int i)
{
return new Fraction(i, 1);
}
}

Section 10.59: do
The do operator iterates over a block of code until a conditional query equals false. The do-while loop can also be
interrupted by a goto, return, break or throw statement.

The syntax for the do keyword is:

do { code block; } while( condition );

Example:

int i = 0;

do
{
[Link]("Do is on loop number {0}.", i);
} while (i++ < 5);

Output:

"Do is on loop number 1."

[Link] – C# Notes for Professionals 124


"Do is on loop number 2."
"Do is on loop number 3."
"Do is on loop number 4."
"Do is on loop number 5."

Unlike the while loop, the do-while loop is Exit Controlled. This means that the do-while loop would execute its
statements at least once, even if the condition fails the first time.

bool a = false;

do
{
[Link]("This will be printed once, even if a is false.");
} while (a == true);

Section 10.60: long


The long keyword is used to represent signed 64-bit integers. It is an alias for the System.Int64 datatype present in
[Link], which is implicitly referenced by every C# project when you create them.

Any long variable can be declared both explicitly and implicitly:

long long1 = 9223372036854775806; // explicit declaration, long keyword used


var long2 = -9223372036854775806L; // implicit declaration, 'L' suffix used

A long variable can hold any value from –9,223,372,036,854,775,808 to 9,223,372,036,854,775,807, and can be
useful in situations which a variable must hold a value that exceeds the bounds of what other variables (such as the
int variable) can hold.

Section 10.61: enum


The enum keyword tells the compiler that this class inherits from the abstract class Enum, without the programmer
having to explicitly inherit it. Enum is a descendant of ValueType, which is intended for use with distinct set of named
constants.

public enum DaysOfWeek


{
Monday,
Tuesday,
}

You can optionally specify a specific value for each one (or some of them):

public enum NotableYear


{
EndOfWwI = 1918;
EnfOfWwII = 1945,
}

In this example I omitted a value for 0, this is usually a bad practice. An enum will always have a default value
produced by explicit conversion (YourEnumType) 0, where YourEnumType is your declared enume type. Without a
value of 0 defined, an enum will not have a defined value at initiation.

The default underlying type of enum is int, you can change the underlying type to any integral type including byte,

[Link] – C# Notes for Professionals 125


sbyte, short, ushort, int, uint, long and ulong. Below is an enum with underlying type byte:

enum Days : byte


{
Sunday = 0,
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday
};

Also note that you can convert to/from underlying type simply with a cast:

int value = (int)[Link];

For these reasons you'd better always check if an enum is valid when you're exposing library functions:

void PrintNotes(NotableYear year)


{
if (![Link](typeof(NotableYear), year))
throw InvalidEnumArgumentException("year", (int)year, typeof(NotableYear));

// ...
}

Section 10.62: partial


The keyword partial can be used during type definition of class, struct, or interface to allow the type definition to
be split into several files. This is useful to incorporate new features in auto generated code.

[Link]

namespace A
{
public partial class Test
{
public string Var1 {get;set;}
}
}

[Link]

namespace A
{
public partial class Test
{
public string Var2 {get;set;}
}
}

Note: A class can be split into any number of files. However, all declaration must be under same namespace and
the same assembly.

Methods can also be declared partial using the partial keyword. In this case one file will contain only the method
definition and another file will contain the implementation.

[Link] – C# Notes for Professionals 126


A partial method has its signature defined in one part of a partial type, and its implementation defined in
another part of the type. Partial methods enable class designers to provide method hooks, similar to
event handlers, that developers may decide to implement or not. If the developer does not supply an
implementation, the compiler removes the signature at compile time. The following conditions apply to
partial methods:

Signatures in both parts of the partial type must match.


The method must return void.
No access modifiers are allowed. Partial methods are implicitly private.

-- MSDN

[Link]

namespace A
{
public partial class Test
{
public string Var1 {get;set;}
public partial Method1(string str);
}
}

[Link]

namespace A
{
public partial class Test
{
public string Var2 {get;set;}
public partial Method1(string str)
{
[Link](str);
}
}
}

Note: The type containing the partial method must also be declared partial.

Section 10.63: event


An event allows the developer to implement a notification pattern.

Simple example

public class Server


{
// defines the event
public event EventHandler DataChangeEvent;

void RaiseEvent()
{
var ev = DataChangeEvent;
if(ev != null)
{
ev(this, [Link]);
}

[Link] – C# Notes for Professionals 127


}
}

public class Client


{
public void Client(Server server)
{
// client subscribes to the server's DataChangeEvent
[Link] += server_DataChanged;
}

private void server_DataChanged(object sender, EventArgs args)


{
// notified when the server raises the DataChangeEvent
}
}

MSDN reference

Section 10.64: sbyte


A numeric type used to store 8-bit signed integers. sbyte is an alias for [Link], and takes up 1 byte of
memory. For the unsigned equivalent, use byte.

Valid range is -127 to 127 (the leftover is used to store the sign).

sbyte a = 127; // 127


sbyte b = -127; // -127
sbyte c = 200; // Error, cannot be converted
sbyte d = unchecked((sbyte)129); // -127 (overflows)

[Link] – C# Notes for Professionals 128


Chapter 11: Object Oriented Programming
In C#
This topic try to tell us how we can write programs based on OOP [Link] we don't try to teach Object
Oriented Programming paradigm. We'll be covering following topics:
Classes,Properties,Inheritance,Polymorphism,Interfaces and so on.

Section 11.1: Classes:


Skeleton of declaring class is:

<>:Required

[]:Optional

[private/public/protected/internal] class <Desired Class Name> [:[Inherited class][,][[Interface


Name 1],[Interface Name 2],...]
{
//Your code
}

Don't worry if you can't understand whole syntax,We'll be get familiar with all part of [Link] first example consider
following class:

class MyClass
{
int i = 100;
public void getMyValue()
{
[Link](this.i);//Will print number 100 in output
}
}

in this class we create variable i with int type and with default private Access Modifiers and getMyValue() method
with public access modifiers.

[Link] – C# Notes for Professionals 129


Chapter 12: Inheritance
Section 12.1: Inheritance. Constructors' calls sequence
Consider we have a class Animal which has a child class Dog

class Animal
{
public Animal()
{
[Link]("In Animal's constructor");
}
}

class Dog : Animal


{
public Dog()
{
[Link]("In Dog's constructor");
}
}

By default every class implicitly inherits the Object class.

This is same as the above code.

class Animal : Object


{
public Animal()
{
[Link]("In Animal's constructor");
}
}

When creating an instance of Dog class, the base classes's default constructor (without parameters) will be
called if there is no explicit call to another constructor in the parent class. In our case, first will be called
Object's constructor, then Animal's and at the end Dog's constructor.

public class Program


{
public static void Main()
{
Dog dog = new Dog();
}
}

Output will be

In Animal's constructor
In Dog's constructor

View Demo

Call parent's constructor explicitly.

[Link] – C# Notes for Professionals 130


In the above examples, our Dog class constructor calls the default constructor of the Animal class. If you want, you
can specify which constructor should be called: it is possible to call any constructor which is defined in the parent
class.

Consider we have these two classes.

class Animal
{
protected string name;

public Animal()
{
[Link]("Animal's default constructor");
}

public Animal(string name)


{
[Link] = name;
[Link]("Animal's constructor with 1 parameter");
[Link]([Link]);
}
}

class Dog : Animal


{
public Dog() : base()
{
[Link]("Dog's default constructor");
}

public Dog(string name) : base(name)


{
[Link]("Dog's constructor with 1 parameter");
[Link]([Link]);
}
}

What is going here?

We have 2 constructors in each class.

What does base mean?

base is a reference to the parent class. In our case, when we create an instance of Dog class like this

Dog dog = new Dog();

The runtime first calls the Dog(), which is the parameterless constructor. But its body doesn't work immediately.
After the parentheses of the constructor we have a such call: base(), which means that when we call the default
Dog constructor, it will in turn call the parent's default constructor. After the parent's constructor runs, it will return
and then, finally, run the Dog() constructor body.

So output will be like this:

Animal's default constructor


Dog's default constructor

[Link] – C# Notes for Professionals 131


View Demo

Now what if we call the Dog's constructor with a parameter?

Dog dog = new Dog("Rex");

You know that members in the parent class which are not private are inherited by the child class, meaning that Dog
will also have the name field.
In this case we passed an argument to our constructor. It in his turn passes the argument to the parent class'
constructor with a parameter, which initializes the name field.

Output will be

Animal's constructor with 1 parameter


Rex
Dog's constructor with 1 parameter
Rex

Summary:

Every object creation starts from the base class. In the inheritance, the classes which are in the hierarchy are
chained. As all classes derive from Object, the first constructor to be called when any object is created is the Object
class constructor; Then the next constructor in the chain is called and only after all of them are called the object is
created

base keyword

1. The base keyword is used to access members of the base class from within a derived class:
2. Call a method on the base class that has been overridden by another method. Specify which base-class
constructor should be called when creating instances of the derived class.

Section 12.2: Inheriting from a base class


To avoid duplicating code, define common methods and attributes in a general class as a base:

public class Animal


{
public string Name { get; set; }
// Methods and attributes common to all animals
public void Eat(Object dinner)
{
// ...
}
public void Stare()
{
// ...
}
public void Roll()
{
// ...
}
}

Now that you have a class that represents Animal in general, you can define a class that describes the peculiarities
of specific animals:

[Link] – C# Notes for Professionals 132


public class Cat : Animal
{
public Cat()
{
Name = "Cat";
}
// Methods for scratching furniture and ignoring owner
public void Scratch(Object furniture)
{
// ...
}
}

The Cat class gets access to not only the methods described in its definition explicitly, but also all the methods
defined in the general Animal base class. Any Animal (whether or not it was a Cat) could Eat, Stare, or Roll. An
Animal would not be able to Scratch, however, unless it was also a Cat. You could then define other classes
describing other animals. (Such as Gopher with a method for destroying flower gardens and Sloth with no extra
methods at all.)

Section 12.3: Inheriting from a class and implementing an


interface
public class Animal
{
public string Name { get; set; }
}

public interface INoiseMaker


{
string MakeNoise();
}

//Note that in C#, the base class name must come before the interface names
public class Cat : Animal, INoiseMaker
{
public Cat()
{
Name = "Cat";
}

public string MakeNoise()


{
return "Nyan";
}
}

Section 12.4: Inheriting from a class and implementing


multiple interfaces
public class LivingBeing
{
string Name { get; set; }
}

public interface IAnimal


{
bool HasHair { get; set; }
}

[Link] – C# Notes for Professionals 133


public interface INoiseMaker
{
string MakeNoise();
}

//Note that in C#, the base class name must come before the interface names
public class Cat : LivingBeing, IAnimal, INoiseMaker
{
public Cat()
{
Name = "Cat";
HasHair = true;
}

public bool HasHair { get; set; }

public string Name { get; set; }

public string MakeNoise()


{
return "Nyan";
}
}

Section 12.5: Constructors In A Subclass


When you make a subclass of a base class, you can construct the base class by using : base after the subclass
constructor's parameters.

class Instrument
{
string type;
bool clean;

public Instrument (string type, bool clean)


{
[Link] = type;
[Link] = clean;
}
}

class Trumpet : Instrument


{
bool oiled;

public Trumpet(string type, bool clean, bool oiled) : base(type, clean)


{
[Link] = oiled;
}
}

Section 12.6: Inheritance Anti-patterns


Improper Inheritance

Lets say there are 2 classes class Foo and Bar. Foo has two features Do1 and Do2. Bar needs to use Do1 from Foo, but
it doesn't need Do2 or needs feature that is equivalent to Do2 but does something completely different.

Bad way: make Do2() on Foo virtual then override it in Bar or just throw Exception in Bar for Do2()

[Link] – C# Notes for Professionals 134


public class Bar : Foo
{
public override void Do2()
{
//Does something completely different that you would expect Foo to do
//or simply throws new Exception
}
}

Good way

Take out Do1() from Foo and put it into new class Baz then inherit both Foo and Bar from Baz and implement Do2()
separately

public class Baz


{
public void Do1()
{
// magic
}
}

public class Foo : Baz


{
public void Do2()
{
// foo way
}
}

public class Bar : Baz


{
public void Do2()
{
// bar way or not have Do2 at all
}
}

Now why first example is bad and second is good: When developer nr2 has to do a change in Foo, chances are he
will break implementation of Bar because Bar is now inseparable from Foo. When doing it by latter example Foo
and Bar commonalty has been moved to Baz and they do not affect each other (like the shouldn't).

Section 12.7: Extending an abstract base class


Unlike interfaces, which can be described as contracts for implementation, abstract classes act as contracts for
extension.

An abstract class cannot be instantiated, it must be extended and the resulting class (or derived class) can then be
instantiated.

Abstract classes are used to provide generic implementations

public abstract class Car


{
public void HonkHorn() {
// Implementation of horn being honked
}
}

[Link] – C# Notes for Professionals 135


public class Mustang : Car
{
// Simply by extending the abstract class Car, the Mustang can HonkHorn()
// If Car were an interface, the HonkHorn method would need to be included
// in every class that implemented it.
}

The above example shows how any class extending Car will automatically receive the HonkHorn method with the
implementation. This means that any developer creating a new Car will not need to worry about how it will honk it's
horn.

Section 12.8: Testing and navigating inheritance


interface BaseInterface {}
class BaseClass : BaseInterface {}

interface DerivedInterface {}
class DerivedClass : BaseClass, DerivedInterface {}

var baseInterfaceType = typeof(BaseInterface);


var derivedInterfaceType = typeof(DerivedInterface);
var baseType = typeof(BaseClass);
var derivedType = typeof(DerivedClass);

var baseInstance = new BaseClass();


var derivedInstance = new DerivedClass();

[Link](derivedInstance is DerivedClass); //True


[Link](derivedInstance is DerivedInterface); //True
[Link](derivedInstance is BaseClass); //True
[Link](derivedInstance is BaseInterface); //True
[Link](derivedInstance is object); //True

[Link]([Link]); //BaseClass
[Link]([Link]); //Object
[Link](typeof(object).BaseType); //null

[Link]([Link](derivedInstance)); //True
[Link]([Link](baseInstance)); //False

[Link](
[Link](",",
[Link]().Select(t => [Link]).ToArray()));
//BaseInterface,DerivedInterface

[Link]([Link](derivedType)); //True
[Link]([Link](derivedType)); //True
[Link]([Link](baseType)); //False

Section 12.9: Inheriting methods


There are several ways methods can be inherited

public abstract class Car


{
public void HonkHorn() {
// Implementation of horn being honked
}

[Link] – C# Notes for Professionals 136


// virtual methods CAN be overridden in derived classes
public virtual void ChangeGear() {
// Implementation of gears being changed
}

// abstract methods MUST be overridden in derived classes


public abstract void Accelerate();
}

public class Mustang : Car


{
// Before any code is added to the Mustang class, it already contains
// implementations of HonkHorn and ChangeGear.

// In order to compile, it must be given an implementation of Accelerate,


// this is done using the override keyword
public override void Accelerate() {
// Implementation of Mustang accelerating
}

// If the Mustang changes gears differently to the implementation in Car


// this can be overridden using the same override keyword as above
public override void ChangeGear() {
// Implementation of Mustang changing gears
}
}

Section 12.10: Base class with recursive type specification


One time definition of a generic base class with recursive type specifier. Each node has one parent and multiple
children.

/// <summary>
/// Generic base class for a tree structure
/// </summary>
/// <typeparam name="T">The node type of the tree</typeparam>
public abstract class Tree<T> where T : Tree<T>
{
/// <summary>
/// Constructor sets the parent node and adds this node to the parent's child nodes
/// </summary>
/// <param name="parent">The parent node or null if a root</param>
protected Tree(T parent)
{
[Link]=parent;
[Link]=new List<T>();
if(parent!=null)
{
[Link](this as T);
}
}
public T Parent { get; private set; }
public List<T> Children { get; private set; }
public bool IsRoot { get { return Parent==null; } }
public bool IsLeaf { get { return [Link]==0; } }
/// <summary>
/// Returns the number of hops to the root object
/// </summary>
public int Level { get { return IsRoot ? 0 : [Link]+1; } }
}

[Link] – C# Notes for Professionals 137


The above can be re-used every time a tree hierarchy of objects needs to be defined. The node object in the tree
has to inherit from the base class with

public class MyNode : Tree<MyNode>


{
// stuff
}

each node class knows where it is in the hierarchy, what the parent object is as well as what the children objects
are. Several built in types use a tree structure, like Control or XmlElement and the above Tree<T> can be used as a
base class of any type in your code.

For example, to create a hierarchy of parts where the total weight is calculated from the weight of all the children,
do the following:

public class Part : Tree<Part>


{
public static readonly Part Empty = new Part(null) { Weight=0 };
public Part(Part parent) : base(parent) { }
public Part Add(float weight)
{
return new Part(this) { Weight=weight };
}
public float Weight { get; set; }

public float TotalWeight { get { return Weight+[Link]((part) => [Link]); } }


}

to be used as

// [Q:2.5] -- [P:4.2] -- [R:0.4]


// \
// - [Z:0.8]
var Q = [Link](2.5f);
var P = [Link](4.2f);
var R = [Link](0.4f);
var Z = [Link](0.9f);

// 2.5+(4.2+0.4)+0.9 = 8.0
float weight = [Link];

Another example would in the definition of relative coordinate frames. In this case the true position of the
coordinate frame depends on the positions of all the parent coordinate frames.

public class RelativeCoordinate : Tree<RelativeCoordinate>


{
public static readonly RelativeCoordinate Start = new RelativeCoordinate(null, [Link]) {
};
public RelativeCoordinate(RelativeCoordinate parent, PointF local_position)
: base(parent)
{
[Link]=local_position;
}
public PointF LocalPosition { get; set; }
public PointF GlobalPosition
{
get
{
if(IsRoot) return LocalPosition;

[Link] – C# Notes for Professionals 138


var parent_pos = [Link];
return new PointF(parent_pos.X+LocalPosition.X, parent_pos.Y+LocalPosition.Y);
}
}
public float TotalDistance
{
get
{
float dist =
(float)[Link](LocalPosition.X*LocalPosition.X+LocalPosition.Y*LocalPosition.Y);
return IsRoot ? dist : [Link]+dist;
}
}
public RelativeCoordinate Add(PointF local_position)
{
return new RelativeCoordinate(this, local_position);
}
public RelativeCoordinate Add(float x, float y)
{
return Add(new PointF(x, y));
}
}

to be used as

// Define the following coordinate system hierarchy


//
// o--> [A1] --+--> [B1] -----> [C1]
// |
// +--> [B2] --+--> [C2]
// |
// +--> [C3]

var A1 = [Link];
var B1 = [Link](100, 20);
var B2 = [Link](160, 10);

var C1 = [Link](120, -40);


var C2 = [Link](80, -20);
var C3 = [Link](60, -30);

double dist1 = [Link];

[Link] – C# Notes for Professionals 139


Chapter 13: Generics
Parameter(s) Description
T, V Type placeholders for generic declarations

Section 13.1: Implicit type inference (methods)


When passing formal arguments to a generic method, relevant generic type arguments can usually be inferred
implicitly. If all generic type can be inferred, then specifying them in the syntax is optional.

Consider the following generic method. It has one formal parameter and one generic type parameter. There is a
very obvious relationship between them -- the type passed as an argument to the generic type parameter must be
the same as the compile-time type of the argument passed to the formal parameter.

void M<T>(T obj)


{
}

These two calls are equivalent:

M<object>(new object());
M(new object());

These two calls are also equivalent:

M<string>("");
M("");

And so are these three calls:

M<object>("");
M((object) "");
M("" as object);

Notice that if at least one type argument cannot be inferred, then all of them have to be specified.

Consider the following generic method. The first generic type argument is the same as the type of the formal
argument. But there is no such relationship for the second generic type argument. Therefore, the compiler has no
way of inferring the second generic type argument in any call to this method.

void X<T1, T2>(T1 obj)


{
}

This doesn't work anymore:

X("");

This doesn't work either, because the compiler isn't sure if we are specifying the first or the second generic
parameter (both would be valid as object):

X<object>("");

[Link] – C# Notes for Professionals 140


We are required to type out both of them, like this:

X<string, object>("");

Section 13.2: Type inference (classes)


Developers can be caught out by the fact that type inference doesn't work for constructors:

class Tuple<T1,T2>
{
public Tuple(T1 value1, T2 value2)
{
}
}

var x = new Tuple(2, "two"); // This WON'T work...


var y = new Tuple<int, string>(2, "two"); // even though the explicit form will.

The first way of creating instance without explicitly specifying type parameters will cause compile time error which
would say:

Using the generic type 'Tuple<T1, T2>' requires 2 type arguments

A common workaround is to add a helper method in a static class:

static class Tuple


{
public static Tuple<T1, T2> Create<T1, T2>(T1 value1, T2 value2)
{
return new Tuple<T1, T2>(value1, value2);
}
}

var x = [Link](2, "two"); // This WILL work...

Section 13.3: Using generic method with an interface as a


constraint type
This is an example of how to use the generic type TFood inside Eat method on the class Animal

public interface IFood


{
void EatenBy(Animal animal);
}

public class Grass: IFood


{
public void EatenBy(Animal animal)
{
[Link]("Grass was eaten by: {0}", [Link]);
}
}

public class Animal


{
public string Name { get; set; }

[Link] – C# Notes for Professionals 141


public void Eat<TFood>(TFood food)
where TFood : IFood
{
[Link](this);
}
}

public class Carnivore : Animal


{
public Carnivore()
{
Name = "Carnivore";
}
}

public class Herbivore : Animal, IFood


{
public Herbivore()
{
Name = "Herbivore";
}

public void EatenBy(Animal animal)


{
[Link]("Herbivore was eaten by: {0}", [Link]);
}
}

You can call the Eat method like this:

var grass = new Grass();


var sheep = new Herbivore();
var lion = new Carnivore();

[Link](grass);
//Output: Grass was eaten by: Herbivore

[Link](sheep);
//Output: Herbivore was eaten by: Carnivore

In this case if you try to call:

[Link](lion);

It won't be possible because the object lion does not implement the interface IFood. Attempting to make the above
call will generate a compiler error: "The type 'Carnivore' cannot be used as type parameter 'TFood' in the generic
type or method '[Link](TFood)'. There is no implicit reference conversion from 'Carnivore' to 'IFood'."

Section 13.4: Type constraints (new-keyword)


By using the new() constraint, it is possible to enforce type parameters to define an empty (default) constructor.

class Foo
{
public Foo () { }
}

class Bar
{

[Link] – C# Notes for Professionals 142


public Bar (string s) { ... }
}

class Factory<T>
where T : new()
{
public T Create()
{
return new T();
}
}

Foo f = new Factory<Foo>().Create(); // Valid.


Bar b = new Factory<Bar>().Create(); // Invalid, Bar does not define a default/empty constructor.

The second call to to Create() will give compile time error with following message:

'Bar' must be a non-abstract type with a public parameterless constructor in order to use it as parameter
'T' in the generic type or method 'Factory'

There is no constraint for a constructor with parameters, only parameterless constructors are supported.

Section 13.5: Type constraints (classes and interfaces)


Type constraints are able to force a type parameter to implement a certain interface or class.

interface IType;
interface IAnotherType;

// T must be a subtype of IType


interface IGeneric<T>
where T : IType
{
}

// T must be a subtype of IType


class Generic<T>
where T : IType
{
}

class NonGeneric
{
// T must be a subtype of IType
public void DoSomething<T>(T arg)
where T : IType
{
}
}

// Valid definitions and expressions:


class Type : IType { }
class Sub : IGeneric<Type> { }
class Sub : Generic<Type> { }
new NonGeneric().DoSomething(new Type());

// Invalid definitions and expressions:


class AnotherType : IAnotherType { }

[Link] – C# Notes for Professionals 143


class Sub : IGeneric<AnotherType> { }
class Sub : Generic<AnotherType> { }
new NonGeneric().DoSomething(new AnotherType());

Syntax for multiple constraints:

class Generic<T, T1>


where T : IType
where T1 : Base, new()
{
}

Type constraints works in the same way as inheritance, in that it is possible to specify multiple interfaces as
constraints on the generic type, but only one class:

class A { /* ... */ }
class B { /* ... */ }

interface I1 { }
interface I2 { }

class Generic<T>
where T : A, I1, I2
{
}

class Generic2<T>
where T : A, B //Compilation error
{
}

Another rule is that the class must be added as the first constraint and then the interfaces:

class Generic<T>
where T : A, I1
{
}

class Generic2<T>
where T : I1, A //Compilation error
{
}

All declared constraints must be satisfied simultaneously for a particular generic instantiation to work. There is no
way to specify two or more alternative sets of constraints.

Section 13.6: Checking equality of generic values


If logic of generic class or method requires checking equality of values having generic type, use
EqualityComparer<TType>.Default property:

public void Foo<TBar>(TBar arg1, TBar arg2)


{
var comparer = EqualityComparer<TBar>.Default;
if ([Link](arg1,arg2)
{
...
}

[Link] – C# Notes for Professionals 144


}

This approach is better than simply calling [Link]() method, because default comparer implementation
checks, whether TBar type implements IEquatale<TBar> interface and if yes, calls IEquatable<TBar>.Equals(TBar
other) method. This allows to avoid boxing/unboxing of value types.

Section 13.7: Reflecting on type parameters


The typeof operator works on type parameters.

class NameGetter<T>
{
public string GetTypeName()
{
return typeof(T).Name;
}
}

Section 13.8: Covariance


When is an IEnumerable<T> a subtype of a different IEnumerable<T1>? When T is a subtype of T1. IEnumerable is
covariant in its T parameter, which means that IEnumerable's subtype relationship goes in the same direction as T's.

class Animal { /* ... */ }


class Dog : Animal { /* ... */ }

IEnumerable<Dog> dogs = [Link]<Dog>();


IEnumerable<Animal> animals = dogs; // IEnumerable<Dog> is a subtype of IEnumerable<Animal>
// dogs = animals; // Compilation error - IEnumerable<Animal> is not a subtype of IEnumerable<Dog>

An instance of a covariant generic type with a given type parameter is implicitly convertible to the same generic
type with a less derived type parameter.

This relationship holds because IEnumerable produces Ts but doesn't consume them. An object that produces Dogs
can be used as if it produces Animals.

Covariant type parameters are declared using the out keyword, because the parameter must be used only as an
output.

interface IEnumerable<out T> { /* ... */ }

A type parameter declared as covariant may not appear as an input.

interface Bad<out T>


{
void SetT(T t); // type error
}

Here's a complete example:

using [Link];

namespace ToyStore
{
enum Taste { Bitter, Sweet };

[Link] – C# Notes for Professionals 145


interface IWidget
{
int Weight { get; }
}

interface IFactory<out TWidget>


where TWidget : IWidget
{
TWidget Create();
}

class Toy : IWidget


{
public int Weight { get; set; }
public Taste Taste { get; set; }
}

class ToyFactory : IFactory<Toy>


{
public const int StandardWeight = 100;
public const Taste StandardTaste = [Link];

public Toy Create() { return new Toy { Weight = StandardWeight, Taste = StandardTaste }; }
}

[TestFixture]
public class GivenAToyFactory
{
[Test]
public static void WhenUsingToyFactoryToMakeWidgets()
{
var toyFactory = new ToyFactory();

//// Without out keyword, note the verbose explicit cast:


// IFactory<IWidget> rustBeltFactory = (IFactory<IWidget>)toyFactory;

// covariance: concrete being assigned to abstract (shiny and new)


IFactory<IWidget> widgetFactory = toyFactory;
IWidget anotherToy = [Link]();
[Link]([Link], [Link]([Link])); // abstract
contract
[Link](((Toy)anotherToy).Taste, [Link]([Link])); // concrete
contract
}
}
}

Section 13.9: Contravariance


When is an IComparer<T> a subtype of a different IComparer<T1>? When T1 is a subtype of T. IComparer is
contravariant in its T parameter, which means that IComparer's subtype relationship goes in the opposite direction as
T's.

class Animal { /* ... */ }


class Dog : Animal { /* ... */ }

IComparer<Animal> animalComparer = /* ... */;


IComparer<Dog> dogComparer = animalComparer; // IComparer<Animal> is a subtype of IComparer<Dog>
// animalComparer = dogComparer; // Compilation error - IComparer<Dog> is not a subtype of
IComparer<Animal>

[Link] – C# Notes for Professionals 146


An instance of a contravariant generic type with a given type parameter is implicitly convertible to the same generic
type with a more derived type parameter.

This relationship holds because IComparer consumes Ts but doesn't produce them. An object which can compare
any two Animals can be used to compare two Dogs.

Contravariant type parameters are declared using the in keyword, because the parameter must be used only as an
input.

interface IComparer<in T> { /* ... */ }

A type parameter declared as contravariant may not appear as an output.

interface Bad<in T>


{
T GetT(); // type error
}

Section 13.10: Invariance


IList<T> is never a subtype of a different IList<T1>. IList is invariant in its type parameter.

class Animal { /* ... */ }


class Dog : Animal { /* ... */ }

IList<Dog> dogs = new List<Dog>();


IList<Animal> animals = dogs; // type error

There is no subtype relationship for lists because you can put values into a list and take values out of a list.

If IList was covariant, you'd be able to add items of the wrong subtype to a given list.

IList<Animal> animals = new List<Dog>(); // supposing this were allowed...


[Link](new Giraffe()); // ... then this would also be allowed, which is bad!

If IList was contravariant, you'd be able to extract values of the wrong subtype from a given list.

IList<Dog> dogs = new List<Animal> { new Dog(), new Giraffe() }; // if this were allowed...
Dog dog = dogs[1]; // ... then this would be allowed, which is bad!

Invariant type parameters are declared by omitting both the in and out keywords.

interface IList<T> { /* ... */ }

Section 13.11: Variant interfaces


Interfaces may have variant type parameters.

interface IEnumerable<out T>


{
// ...
}
interface IComparer<in T>
{
// ...

[Link] – C# Notes for Professionals 147


}

but classes and structures may not

class BadClass<in T1, out T2> // not allowed


{
}

struct BadStruct<in T1, out T2> // not allowed


{
}

nor do generic method declarations

class MyClass
{
public T Bad<out T, in T1>(T1 t1) // not allowed
{
// ...
}
}

The example below shows multiple variance declarations on the same interface

interface IFoo<in T1, out T2, T3>


// T1 : Contravariant type
// T2 : Covariant type
// T3 : Invariant type
{
// ...
}

IFoo<Animal, Dog, int> foo1 = /* ... */;


IFoo<Dog, Animal, int> foo2 = foo1;
// IFoo<Animal, Dog, int> is a subtype of IFoo<Dog, Animal, int>

Section 13.12: Variant delegates


Delegates may have variant type parameters.

delegate void Action<in T>(T t); // T is an input


delegate T Func<out T>(); // T is an output
delegate T2 Func<in T1, out T2>(); // T1 is an input, T2 is an output

This follows from the Liskov Substitution Principle, which states (among other things) that a method D can be
considered more derived than a method B if:

D has an equal or more derived return type than B


D has equal or more general corresponding parameter types than B

Therefore the following assignments are all type safe:

Func<object, string> original = SomeMethod;


Func<object, object> d1 = original;
Func<string, string> d2 = original;
Func<string, object> d3 = original;

[Link] – C# Notes for Professionals 148


Section 13.13: Variant types as parameters and return values
If a covariant type appears as an output, the containing type is covariant. Producing a producer of Ts is like
producing Ts.

interface IReturnCovariant<out T>


{
IEnumerable<T> GetTs();
}

If a contravariant type appears as an output, the containing type is contravariant. Producing a consumer of Ts is like
consuming Ts.

interface IReturnContravariant<in T>


{
IComparer<T> GetTComparer();
}

If a covariant type appears as an input, the containing type is contravariant. Consuming a producer of Ts is like
consuming Ts.

interface IAcceptCovariant<in T>


{
void ProcessTs(IEnumerable<T> ts);
}

If a contravariant type appears as an input, the containing type is covariant. Consuming a consumer of Ts is like
producing Ts.

interface IAcceptContravariant<out T>


{
void CompareTs(IComparer<T> tComparer);
}

Section 13.14: Type Parameters (Interfaces)


Declaration:

interface IMyGenericInterface<T1, T2, T3, ...> { ... }

Usage (in inheritance):

class ClassA<T1, T2, T3> : IMyGenericInterface<T1, T2, T3> { ... }

class ClassB<T1, T2> : IMyGenericInterface<T1, T2, int> { ... }

class ClassC<T1> : IMyGenericInterface<T1, char, int> { ... }

class ClassD : IMyGenericInterface<bool, char, int> { ... }

Usage (as the type of a parameter):

void SomeMethod(IMyGenericInterface<int, char, bool> arg) { ... }

[Link] – C# Notes for Professionals 149


Section 13.15: Type constraints (class and struct)
It is possible to specify whether or not the type argument should be a reference type or a value type by using the
respective constraints class or struct. If these constraints are used, they must be defined before all other
constraints (for example a parent type or new()) can be listed.

// TRef must be a reference type, the use of Int32, Single, etc. is invalid.
// Interfaces are valid, as they are reference types
class AcceptsRefType<TRef>
where TRef : class
{
// TStruct must be a value type.
public void AcceptStruct<TStruct>()
where TStruct : struct
{
}

// If multiple constraints are used along with class/struct


// then the class or struct constraint MUST be specified first
public void Foo<TComparableClass>()
where TComparableClass : class, IComparable
{
}
}

Section 13.16: Explicit type parameters


There are different cases where you must Explicitly specify the type parameters for a generic method. In both of the
below cases, the compiler is not able to infer all of the type parameters from the specified method parameters.

One case is when there are no parameters:

public void SomeMethod<T, V>()


{
// No code for simplicity
}

SomeMethod(); // doesn't compile


SomeMethod<int, bool>(); // compiles

Second case is when one (or more) of the type parameters is not part of the method parameters:

public K SomeMethod<K, V>(V input)


{
return default(K);
}

int num1 = SomeMethod(3); // doesn't compile


int num2 = SomeMethod<int>("3"); // doesn't compile
int num3 = SomeMethod<int, string>("3"); // compiles.

Section 13.17: Type Parameters (Classes)


Declaration:

class MyGenericClass<T1, T2, T3, ...>


{

[Link] – C# Notes for Professionals 150


// Do something with the type parameters.
}

Initialisation:

var x = new MyGenericClass<int, char, bool>();

Usage (as the type of a parameter):

void AnotherMethod(MyGenericClass<float, byte, char> arg) { ... }

Section 13.18: Type Parameters (Methods)


Declaration:

void MyGenericMethod<T1, T2, T3>(T1 a, T2 b, T3 c)


{
// Do something with the type parameters.
}

Invocation:

There is no need to supply type arguements to a genric method, because the compiler can implicitly infer the type.

int x =10;
int y =20;
string z = "test";
MyGenericMethod(x,y,z);

However, if there is an ambiguity, generic methods need to be called with type arguemnts as

MyGenericMethod<int, int, string>(x,y,z);

Section 13.19: Generic type casting


/// <summary>
/// Converts a data type to another data type.
/// </summary>
public static class Cast
{
/// <summary>
/// Converts input to Type of default value or given as typeparam T
/// </summary>
/// <typeparam name="T">typeparam is the type in which value will be returned, it could be
any type eg. int, string, bool, decimal etc.</typeparam>
/// <param name="input">Input that need to be converted to specified type</param>
/// <param name="defaultValue">defaultValue will be returned in case of value is null or any
exception occures</param>
/// <returns>Input is converted in Type of default value or given as typeparam T and
returned</returns>
public static T To<T>(object input, T defaultValue)
{
var result = defaultValue;
try
{
if (input == null || input == [Link]) return result;
if (typeof (T).IsEnum)

[Link] – C# Notes for Professionals 151


{
result = (T) [Link](typeof (T), To(input,
Convert.ToInt32(defaultValue)));
}
else
{
result = (T) [Link](input, typeof (T));
}
}
catch (Exception ex)
{
[Link](ex);
}

return result;
}

/// <summary>
/// Converts input to Type of typeparam T
/// </summary>
/// <typeparam name="T">typeparam is the type in which value will be returned, it could be
any type eg. int, string, bool, decimal etc.</typeparam>
/// <param name="input">Input that need to be converted to specified type</param>
/// <returns>Input is converted in Type of default value or given as typeparam T and
returned</returns>
public static T To<T>(object input)
{
return To(input, default(T));
}

Usages:

[Link] = [Link]<string>(drConnection["Name"]);
[Link] = [Link]<int>(drConnection["Age"]);
[Link] = [Link]<bool>(drConnection["IsPassed"]);

// Casting type using default value


//Following both ways are correct
// Way 1 (In following style input is converted into type of default value)
[Link] = [Link](drConnection["Name"], "");
[Link] = [Link](drConnection["Marks"], 0);
// Way 2
[Link] = [Link]<string>(drConnection["Name"], "");
[Link] = [Link]<int>(drConnection["Marks"], 0);

Section 13.20: Configuration reader with generic type casting


/// <summary>
/// Read configuration values from [Link] and convert to specified types
/// </summary>
public static class ConfigurationReader
{
/// <summary>
/// Get value from AppSettings by key, convert to Type of default value or typeparam T and
return

[Link] – C# Notes for Professionals 152


/// </summary>
/// <typeparam name="T">typeparam is the type in which value will be returned, it could be
any type eg. int, string, bool, decimal etc.</typeparam>
/// <param name="strKey">key to find value from AppSettings</param>
/// <param name="defaultValue">defaultValue will be returned in case of value is null or any
exception occures</param>
/// <returns>AppSettings value against key is returned in Type of default value or given as
typeparam T</returns>
public static T GetConfigKeyValue<T>(string strKey, T defaultValue)
{
var result = defaultValue;
try
{
if ([Link][strKey] != null)
result = (T)[Link]([Link][strKey],
typeof(T));
}
catch (Exception ex)
{
[Link](ex);
}

return result;
}
/// <summary>
/// Get value from AppSettings by key, convert to Type of default value or typeparam T and
return
/// </summary>
/// <typeparam name="T">typeparam is the type in which value will be returned, it could be
any type eg. int, string, bool, decimal etc.</typeparam>
/// <param name="strKey">key to find value from AppSettings</param>
/// <returns>AppSettings value against key is returned in Type given as typeparam T</returns>
public static T GetConfigKeyValue<T>(string strKey)
{
return GetConfigKeyValue(strKey, default(T));
}

Usages:

var timeOut = [Link]("RequestTimeout", 2000);


var url = [Link]("URL", "[Link]");
var enabled = [Link]("IsEnabled", false);

[Link] – C# Notes for Professionals 153


Chapter 14: Using Statement
Provides a convenient syntax that ensures the correct use of IDisposable objects.

Section 14.1: Using Statement Basics


using is syntactic sugar that allows you to guarantee that a resource is cleaned up without needing an explicit try-
finally block. This means your code will be much cleaner, and you won't leak non-managed resources.

Standard Dispose cleanup pattern, for objects that implement the IDisposable interface (which the FileStream's
base class Stream does in .NET):

int Foo()
{
var fileName = "[Link]";

{
FileStream disposable = null;

try
{
disposable = [Link](fileName, [Link]);

return [Link]();
}
finally
{
// finally blocks are always run
if (disposable != null) [Link]();
}
}
}

using simplifies your syntax by hiding the explicit try-finally:

int Foo()
{
var fileName = "[Link]";

using (var disposable = [Link](fileName, [Link]))


{
return [Link]();
}
// [Link] is called even if we return earlier
}

Just like finally blocks always execute regardless of errors or returns, using always calls Dispose(), even in the
event of an error:

int Foo()
{
var fileName = "[Link]";

using (var disposable = [Link](fileName, [Link]))


{
throw new InvalidOperationException();
}
// [Link] is called even if we throw an exception earlier

[Link] – C# Notes for Professionals 154


}

Note: Since Dispose is guaranteed to be called irrespective of the code flow, it's a good idea to make sure that
Dispose never throws an exception when you implement IDisposable. Otherwise an actual exception would get
overridden by the new exception resulting in a debugging nightmare.

Returning from using block


using ( var disposable = new DisposableItem() )
{
return [Link];
}

Because of the semantics of try..finally to which the using block translates, the return statement works as
expected - the return value is evaluated before finally block is executed and the value disposed. The order of
evaluation is as follows:

1. Evaluate the try body


2. Evaluate and cache the returned value
3. Execute finally block
4. Return the cached return value

However, you may not return the variable disposable itself, as it would contain invalid, disposed reference - see
related example.

Section 14.2: Gotcha: returning the resource which you are


disposing
The following is a bad idea because it would dispose the db variable before returning it.

public IDBContext GetDBContext()


{
using (var db = new DBContext())
{
return db;
}
}

This can also create more subtle mistakes:

public IEnumerable<Person> GetPeople(int age)


{
using (var db = new DBContext())
{
return [Link](p => [Link] == age);
}
}

This looks ok, but the catch is that the LINQ expression evaluation is lazy, and will possibly only be executed later
when the underlying DBContext has already been disposed.

So in short the expression isn't evaluated before leaving the using. One possible solution to this problem, which
still makes use of using, is to cause the expression to evaluate immediately by calling a method that will enumerate
the result. For example ToList(), ToArray(), etc. If you are using the newest version of Entity Framework you could
use the async counterparts like ToListAsync() or ToArrayAsync().

[Link] – C# Notes for Professionals 155


Below you find the example in action:

public IEnumerable<Person> GetPeople(int age)


{
using (var db = new DBContext())
{
return [Link](p => [Link] == age).ToList();
}
}

It is important to note, though, that by calling ToList() or ToArray(), the expression will be eagerly evaluated,
meaning that all the persons with the specified age will be loaded to memory even if you do not iterate on them.

Section 14.3: Multiple using statements with one block


It is possible to use multiple nested using statements without added multiple levels of nested braces. For example:

using (var input = [Link]("[Link]"))


{
using (var output = [Link]("[Link]"))
{
[Link](output);
} // output is disposed here
} // input is disposed here

An alternative is to write:

using (var input = [Link]("[Link]"))


using (var output = [Link]("[Link]"))
{
[Link](output);
} // output and then input are disposed here

Which is exactly equivalent to the first example.

Note: Nested using statements might trigger Microsoft Code Analysis rule CS2002 (see this answer for clarification)
and generate a warning. As explained in the linked answer, it is generally safe to nest using statements.

When the types within the using statement are of the same type you can comma-delimit them and specify the type
only once (though this is uncommon):

using (FileStream file = [Link]("[Link]"), file2 = [Link]("[Link]"))


{
}

This can also be used when the types have a shared hierarchy:

using (Stream file = [Link]("[Link]"), data = new MemoryStream())


{
}

The var keyword cannot be used in the above example. A compilation error would occur. Even the comma
separated declaration won't work when the declared variables have types from different hierarchies.

[Link] – C# Notes for Professionals 156


Section 14.4: Gotcha: Exception in Dispose method masking
other errors in Using blocks
Consider the following block of code.

try
{
using (var disposable = new MyDisposable())
{
throw new Exception("Couldn't perform operation.");
}
}
catch (Exception ex)
{
[Link]([Link]);
}

class MyDisposable : IDisposable


{
public void Dispose()
{
throw new Exception("Couldn't dispose successfully.");
}
}

You may expect to see "Couldn't perform operation" printed to the Console but you would actually see "Couldn't
dispose successfully." as the Dispose method is still called even after the first exception is thrown.

It is worth being aware of this subtlety as it may be masking the real error that prevented the object from being
disposed and make it harder to debug.

Section 14.5: Using statements are null-safe


You don't have to check the IDisposable object for null. using will not throw an exception and Dispose() will not
be called:

DisposableObject TryOpenFile()
{
return null;
}

// disposable is null here, but this does not throw an exception


using (var disposable = TryOpenFile())
{
// this will throw a NullReferenceException because disposable is null
[Link]();

if(disposable != null)
{
// here we are safe because disposable has been checked for null
[Link]();
}
}

Section 14.6: Using Dispose Syntax to define custom scope


For some use cases, you can use the using syntax to help define a custom scope. For example, you can define the
following class to execute code in a specific culture.

[Link] – C# Notes for Professionals 157


public class CultureContext : IDisposable
{
private readonly CultureInfo originalCulture;

public CultureContext(string culture)


{
originalCulture = [Link];
[Link] = new CultureInfo(culture);
}

public void Dispose()


{
[Link] = originalCulture;
}
}

You can then use use this class to define blocks of code that execute in a specific culture.

[Link] = new CultureInfo("en-US");

using (new CultureContext("nl-NL"))


{
// Code in this block uses the "nl-NL" culture
[Link](new DateTime(2016, 12, 25)); // Output: 25-12-2016 [Link]
}

using (new CultureContext("es-ES"))


{
// Code in this block uses the "es-ES" culture
[Link](new DateTime(2016, 12, 25)); // Output: 25/12/2016 [Link]
}

// Reverted back to the original culture


[Link](new DateTime(2016, 12, 25)); // Output: 12/25/2016 [Link] AM

Note: as we don't use the CultureContext instance we create, we don't assign a variable for it.

This technique is used by the BeginForm helper in [Link] MVC.

Section 14.7: Using Statements and Database Connections


The using keyword ensures that the resource defined within the statement only exists within the scope of the
statement itself. Any resources defined within the statement must implement the IDisposable interface.

These are incredibly important when dealing with any connections that implement the IDisposable interface as it
can ensure the connections are not only properly closed but that their resources are freed after the using
statement is out of scope.

Common IDisposable Data Classes

Many of the following are data-related classes that implement the IDisposable interface and are perfect
candidates for a using statement :

SqlConnection,SqlCommand,SqlDataReader, etc.
OleDbConnection,OleDbCommand,OleDbDataReader, etc.
MySqlConnection, MySqlCommand, MySqlDbDataReader, etc.
DbContext

[Link] – C# Notes for Professionals 158


All of these are commonly used to access data through C# and will be commonly encountered throughout building
data-centric applications. Many other classes that are not mentioned that implement the same
FooConnection,FooCommand,FooDataReader classes can be expected to behave the same way.

Common Access Pattern for [Link] Connections

A common pattern that can be used when accessing your data through an [Link] connection might look as
follows :

// This scopes the connection (your specific class may vary)


using(var connection = new SqlConnection("{your-connection-string}")
{
// Build your query
var query = "SELECT * FROM YourTable WHERE Property = @property");
// Scope your command to execute
using(var command = new SqlCommand(query, connection))
{
// Open your connection
[Link]();

// Add your parameters here if necessary

// Execute your query as a reader (again scoped with a using statement)


using(var reader = [Link]())
{
// Iterate through your results here
}
}
}

Or if you were just performing a simple update and didn't require a reader, the same basic concept would apply :

using(var connection = new SqlConnection("{your-connection-string}"))


{
var query = "UPDATE YourTable SET Property = Value WHERE Foo = @foo";
using(var command = new SqlCommand(query,connection))
{
[Link]();

// Add parameters here

// Perform your update


[Link]();
}
}

Using Statements with DataContexts

Many ORMs such as Entity Framework expose abstraction classes that are used to interact with underlying
databases in the form of classes like DbContext. These contexts generally implement the IDisposable interface as
well and should take advantage of this through using statements when possible :

using(var context = new YourDbContext())


{
// Access your context and perform your query
var data = [Link]();
}

[Link] – C# Notes for Professionals 159


Section 14.8: Executing code in constraint context
If you have code (a routine) you want to execute under a specific (constraint) context, you can use dependency
injection.

The following example shows the constraint of executing under an open SSL connection. This first part would be in
your library or framework, which you won't expose to the client code.

public static class SSLContext


{
// define the delegate to inject
public delegate void TunnelRoutine(BinaryReader sslReader, BinaryWriter sslWriter);

// this allows the routine to be executed under SSL


public static void ClientTunnel(TcpClient tcpClient, TunnelRoutine routine)
{
using (SslStream sslStream = new SslStream([Link](), true, _validate))
{
[Link](HOSTNAME, null, [Link], false);

if (![Link])
{
throw new SecurityException("SSL tunnel not authenticated");
}

if (![Link])
{
throw new SecurityException("SSL tunnel not encrypted");
}

using (BinaryReader sslReader = new BinaryReader(sslStream))


using (BinaryWriter sslWriter = new BinaryWriter(sslStream))
{
routine(sslReader, sslWriter);
}
}
}
}

Now the client code which wants to do something under SSL but does not want to handle all the SSL details. You
can now do whatever you want inside the SSL tunnel, for example exchange a symmetric key:

public void ExchangeSymmetricKey(BinaryReader sslReader, BinaryWriter sslWriter)


{
byte[] bytes = new byte[8];
(new RNGCryptoServiceProvider()).GetNonZeroBytes(bytes);
[Link](BitConverter.ToUInt64(bytes, 0));
}

You execute this routine as follows:

[Link](tcpClient, [Link]);

To do this, you need the using() clause because it is the only way (apart from a try..finally block) you can
guarantee the client code (ExchangeSymmetricKey) never exits without properly disposing of the disposable
resources. Without using() clause, you would never know if a routine could break the context's constraint to
dispose of those resources.

[Link] – C# Notes for Professionals 160


Chapter 15: Using Directive
Section 15.1: Associate an Alias to Resolve Conflicts
If you are using multiple namespaces that may have same-name classes(such as [Link] and
[Link]), you can use an alias to specify that Random comes from one or the other without having to
use the entire namespace in the call.

For instance:

using UnityEngine;
using System;

Random rnd = new Random();

This will cause the compiler to be unsure which Random to evaluate the new variable as. Instead, you can do:

using UnityEngine;
using System;
using Random = [Link];

Random rnd = new Random();

This doesn't preclude you from calling the other by it's fully qualified namespace, like this:

using UnityEngine;
using System;
using Random = [Link];

Random rnd = new Random();


int unityRandom = [Link](0,100);

rnd will be a [Link] variable and unityRandom will be a [Link] variable.

Section 15.2: Using alias directives


You can use using in order to set an alias for a namespace or type. More detail can be found in here.

Syntax:

using <identifier> = <namespace-or-type-name>;

Example:

using NewType = Dictionary<string, Dictionary<string,int>>;


NewType multiDictionary = new NewType();
//Use instances as you are using the original one
[Link]("test", new Dictionary<string,int>());

Section 15.3: Access Static Members of a Class


Version ≥ 6.0

Allows you to import a specific type and use the type's static members without qualifying them with the type name.
This shows an example using static methods:

[Link] – C# Notes for Professionals 161


using static [Link];

// ...

string GetName()
{
WriteLine("Enter your name.");
return ReadLine();
}

And this shows an example using static properties and methods:

using static [Link];

namespace Geometry
{
public class Circle
{
public double Radius { get; set; };

public double Area => PI * Pow(Radius, 2);


}
}

Section 15.4: Basic Usage


using System;
using BasicStuff = System;
using Sayer = [Link];
using static [Link]; //From C# 6

class Program
{
public static void Main()
{
[Link]("Ignoring usings and specifying full type name");
[Link]("Thanks to the 'using System' directive");
[Link]("Namespace aliasing");
[Link]("Type aliasing");
WriteLine("Thanks to the 'using static' directive (from C# 6)");
}
}

Section 15.5: Reference a Namespace


using [Link];
//allows you to access classes within this namespace such as StringBuilder
//without prefixing them with the namespace. i.e:

//...
var sb = new StringBuilder();
//instead of
var sb = new [Link]();

Section 15.6: Associate an Alias with a Namespace


using st = [Link];
//allows you to access classes within this namespace such as StringBuilder

[Link] – C# Notes for Professionals 162


//prefixing them with only the defined alias and not the full namespace. i.e:

//...
var sb = new [Link]();
//instead of
var sb = new [Link]();

[Link] – C# Notes for Professionals 163


Chapter 16: Reflection
Reflection is a C# language mechanism for accessing dynamic object properties on runtime. Typically, reflection is
used to fetch the information about dynamic object type and object attribute values. In REST application, for
example, reflection could be used to iterate through serialized response object.

Remark: According to MS guidelines performance critical code should avoid reflection. See
[Link]

Section 16.1: Get the members of a type


using System;
using [Link];
using [Link];

public class Program


{
public static void Main()
{
var members = typeof(object)
.GetMembers([Link] |
[Link] |
[Link]);

foreach (var member in members)


{
bool inherited = [Link]( typeof(object).Name );
[Link]($"{[Link]} is a {[Link]}, " +
$"it has {(inherited ? "":"not")} been inherited.");
}
}
}

Output (see note about output order further down):

GetType is a Method, it has not been inherited. GetHashCode is a Method, it has not been inherited. ToString is a
Method, it has not been inherited. Equals is a Method, it has not been inherited. Equals is a Method, it has not been
inherited. ReferenceEquals is a Method, it has not been inherited. .ctor is a Constructor, it has not been inherited.

We can also use the GetMembers() without passing any BindingFlags. This will return all public members of that
specific type.

One thing to note that GetMembers does not return the members in any particular order, so never rely on the order
that GetMembers returns you.

View Demo

Section 16.2: Get a method and invoke it


Get Instance method and invoke it

using System;

public class Program


{
public static void Main()

[Link] – C# Notes for Professionals 164


{
var theString = "hello";
var method = theString
.GetType()
.GetMethod("Substring",
new[] {typeof(int), typeof(int)}); //The types of the method
arguments
var result = [Link](theString, new object[] {0, 4});
[Link](result);
}
}

Output:

hell

View Demo

Get Static method and invoke it

On the other hand, if the method is static, you do not need an instance to call it.

var method = typeof(Math).GetMethod("Exp");


var result = [Link](null, new object[] {2});//Pass null as the first argument (no need for an
instance)
[Link](result); //You'll get e^2

Output:

7.38905609893065

View Demo

Section 16.3: Creating an instance of a Type


The simplest way is to use the Activator class.

However, even though Activator performance have been improved since .NET 3.5, using
[Link]() is bad option sometimes, due to (relatively) low performance: Test 1, Test 2, Test 3...

With Activator class


Type type = typeof(BigInteger);
object result = [Link](type); //Requires parameterless constructor.
[Link](result); //Output: 0
result = [Link](type, 123); //Requires a constructor which can receive an 'int'
compatible argument.
[Link](result); //Output: 123

You can pass an object array to [Link] if you have more than one parameter.

// With a constructor such as MyClass(int, int, string)


[Link](typeof(MyClass), new object[] { 1, 2, "Hello World" });

[Link] – C# Notes for Professionals 165


Type type = typeof(someObject);
var instance = [Link](type);

For a generic type

The MakeGenericType method turns an open generic type (like List<>) into a concrete type (like List<string>) by
applying type arguments to it.

// generic List with no parameters


Type openType = typeof(List<>);

// To create a List<string>
Type[] tArgs = { typeof(string) };
Type target = [Link](tArgs);

// Create an instance - [Link] will call the default constructor.


// This is equivalent to calling new List<string>().
List<string> result = (List<string>)[Link](target);

The List<> syntax is not permitted outside of a typeof expression.

Without Activator class

Using new keyword (will do for parameterless constructors)

T GetInstance<T>() where T : new()


{
T instance = new T();
return instance;
}

Using Invoke method

// Get the instance of the desired constructor (here it takes a string as a parameter).
ConstructorInfo c = typeof(T).GetConstructor(new[] { typeof(string) });
// Don't forget to check if such constructor exists
if (c == null)
throw new InvalidOperationException([Link]("A constructor for type '{0}' was not
found.", typeof(T)));
T instance = (T)[Link](new object[] { "test" });

Using Expression trees

Expression trees represent code in a tree-like data structure, where each node is an expression. As MSDN explains:

Expression is a sequence of one or more operands and zero or more operators that can be evaluated to a
single value, object, method, or namespace. Expressions can consist of a literal value, a method
invocation, an operator and its operands, or a simple name. Simple names can be the name of a variable,
type member, method parameter, namespace or type.

public class GenericFactory<TKey, TType>


{
private readonly Dictionary<TKey, Func<object[], TType>> _registeredTypes; // dictionary,
that holds constructor functions.
private object _locker = new object(); // object for locking dictionary, to guarantee thread

[Link] – C# Notes for Professionals 166


safety

public GenericFactory()
{
_registeredTypes = new Dictionary<TKey, Func<object[], TType>>();
}

/// <summary>
/// Find and register suitable constructor for type
/// </summary>
/// <typeparam name="TType"></typeparam>
/// <param name="key">Key for this constructor</param>
/// <param name="parameters">Parameters</param>
public void Register(TKey key, params Type[] parameters)
{
ConstructorInfo ci = typeof(TType).GetConstructor([Link] |
[Link], null, [Link], parameters, new ParameterModifier[] { });
// Get the instance of ctor.
if (ci == null)
throw new InvalidOperationException([Link]("Constructor for type '{0}' was
not found.", typeof(TType)));

Func<object[], TType> ctor;

lock (_locker)
{
if (!_registeredTypes.TryGetValue(key, out ctor)) // check if such ctor already
been registered
{
var pExp = [Link](typeof(object[]), "arguments"); // create
parameter Expression
var ctorParams = [Link](); // get parameter info from constructor

var argExpressions = new Expression[[Link]]; // array that will


contains parameter expessions
for (var i = 0; i < [Link]; i++)
{

var indexedAcccess = [Link](pExp, [Link](i));

if (!parameters[i].IsClass && !parameters[i].IsInterface) // check if


parameter is a value type
{
var localVariable = [Link](parameters[i],
"localVariable"); // if so - we should create local variable that will store paraameter value

var block = [Link](new[] { localVariable },


[Link]([Link](indexedAcccess,
[Link](null)),
[Link](localVariable,
[Link](parameters[i])),
[Link](localVariable,
[Link](indexedAcccess, parameters[i]))
),
localVariable
);

argExpressions[i] = block;

}
else
argExpressions[i] = [Link](indexedAcccess, parameters[i]);

[Link] – C# Notes for Professionals 167


}
var newExpr = [Link](ci, argExpressions); // create expression that
represents call to specified ctor with the specified arguments.

_registeredTypes.Add(key, [Link](newExpr, new[] { pExp }).Compile()


as Func<object[], TType>); // compile expression to create delegate, and add function to dictionary
}
}
}

/// <summary>
/// Returns instance of registered type by key.
/// </summary>
/// <typeparam name="TType"></typeparam>
/// <param name="key"></param>
/// <param name="args"></param>
/// <returns></returns>
public TType Create(TKey key, params object[] args)
{
Func<object[], TType> foo;
if (_registeredTypes.TryGetValue(key, out foo))
{
return (TType)foo(args);
}

throw new ArgumentException("No type registered for this key.");


}
}

Could be used like this:

public class TestClass


{
public TestClass(string parameter)
{
[Link](parameter);
}
}

public void TestMethod()


{
var factory = new GenericFactory<string, TestClass>();
[Link]("key", typeof(string));
TestClass newInstance = [Link]("key", "testParameter");
}

Using [Link]

T instance = (T)[Link](typeof(T));

In case of using [Link] constructors and field initializers will not be called. It
is meant to be used in serializers and remoting engines

Section 16.4: Get a Strongly-Typed Delegate to a Method or


Property via Reflection
When performance is a concern, invoking a method via reflection (i.e. via the [Link] method) is not
ideal. However, it is relatively straightforward to obtain a more performant strongly-typed delegate using the

[Link] – C# Notes for Professionals 168


[Link] function. The performance penalty for using reflection is incurred only during the
delegate-creation process. Once the delegate is created, there is little-to-no performance penalty for invoking it:

// Get a MethodInfo for the [Link](int, int) method...


var maxMethod = typeof(Math).GetMethod("Max", new Type[] { typeof(int), typeof(int) });
// Now get a strongly-typed delegate for [Link](int, int)...
var stronglyTypedDelegate = (Func<int, int, int>)[Link](typeof(Func<int, int,
int>), null, maxMethod);
// Invoke the [Link](int, int) method using the strongly-typed delegate...
[Link]("Max of 3 and 5 is: {0}", stronglyTypedDelegate(3, 5));

This technique can be extended to properties as well. If we have a class named MyClass with an int property
named MyIntProperty, the code to get a strongly-typed getter would be (the following example assumes 'target' is
a valid instance of MyClass):

// Get a MethodInfo for the [Link] getter...


var theProperty = typeof(MyClass).GetProperty("MyIntProperty");
var theGetter = [Link]();
// Now get a strongly-typed delegate for MyIntProperty that can be executed against any MyClass
instance...
var stronglyTypedGetter = (Func<MyClass, int>)[Link](typeof(Func<MyClass, int>),
theGetter);
// Invoke the MyIntProperty getter against MyClass instance 'target'...
[Link]("[Link] is: {0}", stronglyTypedGetter(target));

...and the same can be done for the setter:

// Get a MethodInfo for the [Link] setter...


var theProperty = typeof(MyClass).GetProperty("MyIntProperty");
var theSetter = [Link]();
// Now get a strongly-typed delegate for MyIntProperty that can be executed against any MyClass
instance...
var stronglyTypedSetter = (Action<MyClass, int>)[Link](typeof(Action<MyClass,
int>), theSetter);
// Set MyIntProperty to 5...
stronglyTypedSetter(target, 5);

Section 16.5: Get a generic method and invoke it


Let's say you have class with generic methods. And you need to call its functions with reflection.

public class Sample


{
public void GenericMethod<T>()
{
// ...
}

public static void StaticMethod<T>()


{
//...
}
}

Let's say we want to call the GenericMethod with type string.

Sample sample = new Sample();//or you can get an instance via reflection

[Link] – C# Notes for Professionals 169


MethodInfo method = typeof(Sample).GetMethod("GenericMethod");
MethodInfo generic = [Link](typeof(string));
[Link](sample, null);//Since there are no arguments, we are passing null

For the static method you do not need an instance. Therefore the first argument will also be null.

MethodInfo method = typeof(Sample).GetMethod("StaticMethod");


MethodInfo generic = [Link](typeof(string));
[Link](null, null);

Section 16.6: Get a [Link]


For an instance of a type:

var theString = "hello";


var theType = [Link]();

From the type itself:

var theType = typeof(string);

Section 16.7: Getting and setting properties


Basic usage:

PropertyInfo prop = [Link]().GetProperty("myProperty");


// get the value [Link]
object value = [Link](myInstance);

int newValue = 1;
// set the value [Link] to newValue
[Link](myInstance, newValue);

Setting read-only automatically-implemented properties can be done through it's backing field (in .NET Framework
name of backing field is "k__BackingField"):

// get backing field info


FieldInfo fieldInfo = [Link]()
.GetField("<myProperty>k__BackingField", [Link] | [Link]);

int newValue = 1;
// set the value of [Link] backing field to newValue
[Link](myInstance, newValue);

Section 16.8: Create an instance of a Generic Type and invoke


it's method
var baseType = typeof(List<>);
var genericType = [Link](typeof(String));
var instance = [Link](genericType);
var method = [Link]("GetHashCode");
var result = [Link](instance, new object[] { });

[Link] – C# Notes for Professionals 170


Section 16.9: Custom Attributes
Find properties with a custom attribute - MyAttribute

var props = [Link]([Link] | [Link] |


[Link]).Where(
prop => [Link](prop, typeof(MyAttribute)));

Find all custom attributes on a given property

var attributes = typeof(t).GetProperty("Name").GetCustomAttributes(false);

Enumerate all classes with custom attribute - MyAttribute

static IEnumerable<Type> GetTypesWithAttribute(Assembly assembly) {


foreach(Type type in [Link]()) {
if ([Link](typeof(MyAttribute), true).Length > 0) {
yield return type;
}
}
}

Read value of a custom attribute at runtime

public static class AttributeExtensions


{

/// <summary>
/// Returns the value of a member attribute for any member in a class.
/// (a member is a Field, Property, Method, etc...)
/// <remarks>
/// If there is more than one member of the same name in the class, it will return the first
one (this applies to overloaded methods)
/// </remarks>
/// <example>
/// Read [Link] Description Attribute from method 'MyMethodName' in class
'MyClass':
/// var Attribute = typeof(MyClass).GetAttribute("MyMethodName", (DescriptionAttribute d)
=> [Link]);
/// </example>
/// <param name="type">The class that contains the member as a type</param>
/// <param name="MemberName">Name of the member in the class</param>
/// <param name="valueSelector">Attribute type and property to get (will return first
instance if there are multiple attributes of the same type)</param>
/// <param name="inherit">true to search this member's inheritance chain to find the
attributes; otherwise, false. This parameter is ignored for properties and events</param>
/// </summary>
public static TValue GetAttribute<TAttribute, TValue>(this Type type, string MemberName,
Func<TAttribute, TValue> valueSelector, bool inherit = false) where TAttribute : Attribute
{
var att =
[Link](MemberName).FirstOrDefault().GetCustomAttributes(typeof(TAttribute),
inherit).FirstOrDefault() as TAttribute;
if (att != null)
{
return valueSelector(att);
}
return default(TValue);
}

[Link] – C# Notes for Professionals 171


}

Usage

//Read [Link] Description Attribute from method 'MyMethodName' in class 'MyClass'


var Attribute = typeof(MyClass).GetAttribute("MyMethodName", (DescriptionAttribute d) =>
[Link]);

Section 16.10: Instantiating classes that implement an


interface (e.g. plugin activation)
If you want your application to support a plug-in system, for example to load plug-ins from assemblies located in
plugins folder:

interface IPlugin
{
string PluginDescription { get; }
void DoWork();
}

This class would be located in a separate dll

class HelloPlugin : IPlugin


{
public string PluginDescription => "A plugin that says Hello";
public void DoWork()
{
[Link]("Hello");
}
}

Your application's plugin loader would find the dll files, get all types in those assemblies that implement IPlugin,
and create instances of those.

public IEnumerable<IPlugin> InstantiatePlugins(string directory)


{
var pluginAssemblyNames = [Link](directory, "*.[Link]").Select(name => new
FileInfo(name).FullName).ToArray();
//load the assemblies into the current AppDomain, so we can instantiate the types later
foreach (var fileName in pluginAssemblyNames)
[Link]([Link](fileName));
var assemblies = [Link]([Link]);
var typesInAssembly = [Link](asm => [Link]());
var pluginTypes = [Link](type => typeof (IPlugin).IsAssignableFrom(type));
return [Link]([Link]).Cast<IPlugin>();
}

Section 16.11: Get a Type by name with namespace


To do this you need a reference to the assembly which contains the type. If you have another type available which
you know is in the same assembly as the one you want you can do this:

typeof(KnownType).[Link](typeName);

where typeName is the name of the type you are looking for (including the namespace) , and KnownType is the
type you know is in the same assembly.

[Link] – C# Notes for Professionals 172


Less efficient but more general is as follows:

Type t = null;
foreach (Assembly ass in [Link]())
{
if ([Link]("System."))
continue;
t = [Link](typeName);
if (t != null)
break;
}

Notice the check to exclude scanning System namespace assemblies to speed up the search. If your type may
actually be a CLR type, you will have to delete these two lines.

If you happen to have the fully assembly-qualified type name including the assembly you can simply get it with

[Link](fullyQualifiedName);

Section 16.12: Determining generic arguments of instances of


generic types
If you have an instance of a generic type but for some reason don't know the specific type, you might want to
determine the generic arguments that were used to create this instance.

Let's say someone created an instance of List<T> like that and passes it to a method:

var myList = new List<int>();


ShowGenericArguments(myList);

where ShowGenericArguments has this signature:

public void ShowGenericArguments(object o)

so at compile time you don't have any idea what generic arguments have been used to create o. Reflection provides
a lot of methods to inspect generic types. At first, we can determine if the type of o is a generic type at all:

public void ShowGenericArguments(object o)


{
if (o == null) return;

Type t = [Link]();
if (![Link]) return;
...

[Link] returns true if the type is a generic type and false if not.

But this is not all we want to know. List<> itself is a generic type, too. But we only want to examine instances of
specific constructed generic types. A constructed generic type is for example a List<int> that has a specific type
argument for all its generic parameters.

The Type class provides two more properties, IsConstructedGenericType and IsGenericTypeDefinition, to
distinguish these constructed generic types from generic type definitions:

typeof(List<>).IsGenericType // true
typeof(List<>).IsGenericTypeDefinition // true

[Link] – C# Notes for Professionals 173


typeof(List<>).IsConstructedGenericType// false

typeof(List<int>).IsGenericType // true
typeof(List<int>).IsGenericTypeDefinition // false
typeof(List<int>).IsConstructedGenericType// true

To enumerate the generic arguments of an instance, we can use the GetGenericArguments() method that returns
an Type array containing the generic type arguments:

public void ShowGenericArguments(object o)


{
if (o == null) return;
Type t = [Link]();
if (![Link]) return;

foreach(Type genericTypeArgument in [Link]())


[Link]([Link]);
}

So the call from above (ShowGenericArguments(myList)) results in this output:

Int32

Section 16.13: Looping through all the properties of a class


Type type = [Link]();
//To restrict return properties. If all properties are required don't provide flag.
BindingFlags flags = [Link] | [Link];
PropertyInfo[] properties = [Link](flags);

foreach (PropertyInfo property in properties)


{
[Link]("Name: " + [Link] + ", Value: " + [Link](obj, null));
}

[Link] – C# Notes for Professionals 174


Chapter 17: Null-Coalescing Operator
Parameter Details
possibleNullObject The value to test for null value. If non null, this value is returned. Must be a nullable type.
The value returned if possibleNullObject is null. Must be the same type as
defaultValue
possibleNullObject.

Section 17.1: Basic usage


Using the null-coalescing operator (??) allows you to specify a default value for a nullable type if the left-hand
operand is null.

string testString = null;


[Link]("The specified string is - " + (testString ?? "not provided"));

Live Demo on .NET Fiddle

This is logically equivalent to:

string testString = null;


if (testString == null)
{
[Link]("The specified string is - not provided");
}
else
{
[Link]("The specified string is - " + testString);
}

or using the ternary operator (?:) operator:

string testString = null;


[Link]("The specified string is - " + (testString == null ? "not provided" :
testString));

Section 17.2: Null fall-through and chaining


The left-hand operand must be nullable, while the right-hand operand may or may not be. The result will be typed
accordingly.

Non-nullable

int? a = null;
int b = 3;
var output = a ?? b;
var type = [Link]();

[Link]($"Output Type :{type}");


[Link]($"Output value :{output}");

Output:

Type :System.Int32

[Link] – C# Notes for Professionals 175


value :3

View Demo

Nullable

int? a = null;
int? b = null;
var output = a ?? b;

output will be of type int? and equal to b, or null.

Multiple Coalescing

Coalescing can also be done in chains:

int? a = null;
int? b = null;
int c = 3;
var output = a ?? b ?? c;

var type = [Link]();


[Link]($"Type :{type}");
[Link]($"value :{output}");

Output:

Type :System.Int32
value :3

View Demo

Null Conditional Chaining

The null coalescing operator can be used in tandem with the null propagation operator to provide safer access to
properties of objects.

object o = null;
var output = o?.ToString() ?? "Default Value";

Output:

Type :[Link]
value :Default Value

View Demo

Section 17.3: Null coalescing operator with method calls


The null coalescing operator makes it easy to ensure that a method that may return null will fall back to a default
value.

[Link] – C# Notes for Professionals 176


Without the null coalescing operator:

string name = GetName();

if (name == null)
name = "Unknown!";

With the null coalescing operator:

string name = GetName() ?? "Unknown!";

Section 17.4: Use existing or create new


A common usage scenario that this feature really helps with is when you are looking for an object in a collection
and need to create a new one if it does not already exist.

IEnumerable<MyClass> myList = GetMyList();


var item = [Link](x => [Link] == 2) ?? new MyClass { Id = 2 };

Section 17.5: Lazy properties initialization with null coalescing


operator
private List<FooBar> _fooBars;

public List<FooBar> FooBars


{
get { return _fooBars ?? (_fooBars = new List<FooBar>()); }
}

The first time the property .FooBars is accessed the _fooBars variable will evaluate as null, thus falling through to
the assignment statement assigns and evaluates to the resulting value.

Thread safety

This is not thread-safe way of implementing lazy properties. For thread-safe laziness, use the Lazy<T> class built
into the .NET Framework.

C# 6 Syntactic Sugar using expression bodies

Note that since C# 6, this syntax can be simplified using expression body for the property:

private List<FooBar> _fooBars;

public List<FooBar> FooBars => _fooBars ?? ( _fooBars = new List<FooBar>() );

Subsequent accesses to the property will yield the value stored in the _fooBars variable.

Example in the MVVM pattern

This is often used when implementing commands in the MVVM pattern. Instead of initializing the commands
eagerly with the construction of a viewmodel, commands are lazily initialized using this pattern as follows:

private ICommand _actionCommand = null;


public ICommand ActionCommand =>
_actionCommand ?? ( _actionCommand = new DelegateCommand( DoAction ) );

[Link] – C# Notes for Professionals 177


Chapter 18: Getting Started: Json with C#
The following topic will introduce a way to work with Json using C# language and concepts of Serialization and
Deserialization.

Section 18.1: Simple Json Example


{
"id": 89,
"name": "Aldous Huxley",
"type": "Author",
"books":[{
"name": "Brave New World",
"date": 1932
},
{
"name": "Eyeless in Gaza",
"date": 1936
},
{
"name": "The Genius and the Goddess",
"date": 1955
}]
}

If you are new into Json, here is an exemplified tutorial.

Section 18.2: First things First: Library to work with Json


To work with Json using C#, it is need to use Newtonsoft (.net library). This library provides methods that allows the
programmer serialize and deserialize objects and more. There is a tutorial if you want to know details about its
methods and usages.

If you use Visual Studio, go to Tools/Nuget Package Manager/Manage Package to Solution/ and type "Newtonsoft" into
the search bar and install the package. If you don't have NuGet, this detailed tutorial might help you.

Section 18.3: C# Implementation


Before reading some code, it is important to undersand the main concepts that will help to program applications
using json.

Serialization: Process of converting a object into a stream of bytes that can be sent through applications.
The following code can be serialized and converted into the previous json.

Deserialization: Process of converting a json/stream of bytes into an object. Its exactly the opposite
process of serialization. The previous json can be deserialized into an C# object as demonstrated in
examples below.

To work this out, it is important to turn the json structure into classes in order to use processes already described.
If you use Visual Studio, you can turn a json into a class automatically just by selecting "Edit/Paste Special/Paste JSON
as Classes" and pasting the json structure.

[Link] – C# Notes for Professionals 178


using [Link];

class Author
{
[JsonProperty("id")] // Set the variable below to represent the json attribute
public int id; //"id"
[JsonProperty("name")]
public string name;
[JsonProperty("type")]
public string type;
[JsonProperty("books")]
public Book[] books;

public Author(int id, string name, string type, Book[] books) {


[Link] = id;
[Link] = name;
[Link]= type;
[Link] = books;
}
}

class Book
{
[JsonProperty("name")]
public string name;
[JsonProperty("date")]
public DateTime date;
}

Section 18.4: Serialization


static void Main(string[] args)
{
Book[] books = new Book[3];
Author author = new Author(89,"Aldous Huxley","Author",books);
string objectDeserialized = [Link](author);
//Converting author into json
}

The method ".SerializeObject" receives as parameter a type object, so you can put anything into it.

Section 18.5: Deserialization


You can receive a json from anywhere, a file or even a server so it is not included in the following code.

static void Main(string[] args)


{
string jsonExample; // Has the previous json
Author author = [Link]<Author>(jsonExample);
}

The method ".DeserializeObject" deserializes 'jsonExample' into an "Author" object. This is why it is important to set
the json variables in the classes definition, so the method access it in order to fill it.

Section 18.6: Serialization & De-Serialization Common Utilities


function
This sample used to common function for all type object serialization and deserialization.

[Link] – C# Notes for Professionals 179


using [Link];
using [Link];

namespace Framework
{
public static class IGUtilities
{
public static string Serialization(this T obj)
{
string data = [Link](obj);
return data;
}

public static T Deserialization(this string JsonData)


{
T copy = [Link](JsonData);
return copy;
}

public static T Clone(this T obj)


{
string data = [Link](obj);
T copy = [Link](data);
return copy;
}
}
}

[Link] – C# Notes for Professionals 180


Chapter 19: LINQ Queries
LINQ is an acronym which stands for Language INtegrated Query. It is a concept which integrates a query language
by offering a consistent model for working with data across various kinds of data sources and formats; you use the
same basic coding patterns to query and transform data in XML documents, SQL databases, [Link] Datasets,
.NET collections, and any other format for which a LINQ provider is available.

Section 19.1: Chaining methods


Many LINQ functions both operate on an IEnumerable<TSource> and also return an IEnumerable<TResult>. The
type parameters TSource and TResult may or may not refer to the same type, depending on the method in
question and any functions passed to it.

A few examples of this are

public static IEnumerable<TResult> Select<TSource, TResult>(


this IEnumerable<TSource> source,
Func<TSource, TResult> selector
)

public static IEnumerable<TSource> Where<TSource>(


this IEnumerable<TSource> source,
Func<TSource, int, bool> predicate
)

public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(


this IEnumerable<TSource> source,
Func<TSource, TKey> keySelector
)

While some method chaining may require an entire set to be worked prior to moving on, LINQ takes advantage of
deferred execution by using yield return MSDN which creates an Enumerable and an Enumerator behind the
scenes. The process of chaining in LINQ is essentially building an enumerable (iterator) for the original set -- which
is deferred -- until materialized by enumerating the enumerable.

This allows these functions to be fluently chained wiki, where one function can act directly on the result of another.
This style of code can be used to perform many sequence based operations in a single statement.

For example, it's possible to combine SELECT, Where and OrderBy to transform, filter and sort a sequence in a single
statement.

var someNumbers = { 4, 3, 2, 1 };

var processed = someNumbers


.Select(n => n * 2) // Multiply each number by 2
.Where(n => n != 6) // Keep all the results, except for 6
.OrderBy(n => n); // Sort in ascending order

Output:

2
4
8

[Link] – C# Notes for Professionals 181


Live Demo on .NET Fiddle

Any functions that both extend and return the generic IEnumerable<T> type can be used as chained clauses in a
single statement. This style of fluent programming is powerful, and should be considered when creating your own
extension methods.

Section 19.2: First, FirstOrDefault, Last, LastOrDefault, Single,


and SingleOrDefault
All six methods return a single value of the sequence type, and can be called with or without a predicate.

Depending on the number of elements that match the predicate or, if no predicate is supplied, the number of
elements in the source sequence, they behave as follows:

First()

Returns the first element of a sequence, or the first element matching the provided predicate.
If the sequence contains no elements, an InvalidOperationException is thrown with the message:
"Sequence contains no elements".
If the sequence contains no elements matching the provided predicate, an InvalidOperationException is
thrown with the message "Sequence contains no matching element".

Example

// Returns "a":
new[] { "a" }.First();

// Returns "a":
new[] { "a", "b" }.First();

// Returns "b":
new[] { "a", "b" }.First(x => [Link]("b"));

// Returns "ba":
new[] { "ba", "be" }.First(x => [Link]("b"));

// Throws InvalidOperationException:
new[] { "ca", "ce" }.First(x => [Link]("b"));

// Throws InvalidOperationException:
new string[0].First();

Live Demo on .NET Fiddle

FirstOrDefault()

Returns the first element of a sequence, or the first element matching the provided predicate.
If the sequence contains no elements, or no elements matching the provided predicate, returns the default
value of the sequence type using default(T).

Example

// Returns "a":
new[] { "a" }.FirstOrDefault();

// Returns "a":
new[] { "a", "b" }.FirstOrDefault();

[Link] – C# Notes for Professionals 182


// Returns "b":
new[] { "a", "b" }.FirstOrDefault(x => [Link]("b"));

// Returns "ba":
new[] { "ba", "be" }.FirstOrDefault(x => [Link]("b"));

// Returns null:
new[] { "ca", "ce" }.FirstOrDefault(x => [Link]("b"));

// Returns null:
new string[0].FirstOrDefault();

Live Demo on .NET Fiddle

Last()

Returns the last element of a sequence, or the last element matching the provided predicate.
If the sequence contains no elements, an InvalidOperationException is thrown with the message
"Sequence contains no elements."
If the sequence contains no elements matching the provided predicate, an InvalidOperationException is
thrown with the message "Sequence contains no matching element".

Example

// Returns "a":
new[] { "a" }.Last();

// Returns "b":
new[] { "a", "b" }.Last();

// Returns "a":
new[] { "a", "b" }.Last(x => [Link]("a"));

// Returns "be":
new[] { "ba", "be" }.Last(x => [Link]("b"));

// Throws InvalidOperationException:
new[] { "ca", "ce" }.Last(x => [Link]("b"));

// Throws InvalidOperationException:
new string[0].Last();

LastOrDefault()

Returns the last element of a sequence, or the last element matching the provided predicate.
If the sequence contains no elements, or no elements matching the provided predicate, returns the default
value of the sequence type using default(T).

Example

// Returns "a":
new[] { "a" }.LastOrDefault();

// Returns "b":
new[] { "a", "b" }.LastOrDefault();

// Returns "a":
new[] { "a", "b" }.LastOrDefault(x => [Link]("a"));

// Returns "be":

[Link] – C# Notes for Professionals 183


new[] { "ba", "be" }.LastOrDefault(x => [Link]("b"));

// Returns null:
new[] { "ca", "ce" }.LastOrDefault(x => [Link]("b"));

// Returns null:
new string[0].LastOrDefault();

Single()

If the sequence contains exactly one element, or exactly one element matching the provided predicate, that
element is returned.
If the sequence contains no elements, or no elements matching the provided predicate, an
InvalidOperationException is thrown with the message "Sequence contains no elements".
If the sequence contains more than one element, or more than one element matching the provided
predicate, an InvalidOperationException is thrown with the message "Sequence contains more than one
element".
Note: in order to evaluate whether the sequence contains exactly one element, at most two elements has to
be enumerated.

Example

// Returns "a":
new[] { "a" }.Single();

// Throws InvalidOperationException because sequence contains more than one element:


new[] { "a", "b" }.Single();

// Returns "b":
new[] { "a", "b" }.Single(x => [Link]("b"));

// Throws InvalidOperationException:
new[] { "a", "b" }.Single(x => [Link]("c"));

// Throws InvalidOperationException:
new string[0].Single();

// Throws InvalidOperationException because sequence contains more than one element:


new[] { "a", "a" }.Single();

SingleOrDefault()

If the sequence contains exactly one element, or exactly one element matching the provided predicate, that
element is returned.
If the sequence contains no elements, or no elements matching the provided predicate, default(T) is
returned.
If the sequence contains more than one element, or more than one element matching the provided
predicate, an InvalidOperationException is thrown with the message "Sequence contains more than one
element".
If the sequence contains no elements matching the provided predicate, returns the default value of the
sequence type using default(T).
Note: in order to evaluate whether the sequence contains exactly one element, at most two elements has to
be enumerated.

Example

// Returns "a":
new[] { "a" }.SingleOrDefault();

[Link] – C# Notes for Professionals 184


// returns "a"
new[] { "a", "b" }.SingleOrDefault(x => x == "a");

// Returns null:
new[] { "a", "b" }.SingleOrDefault(x => x == "c");

// Throws InvalidOperationException:
new[] { "a", "a" }.SingleOrDefault(x => x == "a");

// Throws InvalidOperationException:
new[] { "a", "b" }.SingleOrDefault();

// Returns null:
new string[0].SingleOrDefault();

Recommendations

Although you can use FirstOrDefault, LastOrDefault or SingleOrDefault to check whether a sequence
contains any items, Any or Count are more reliable. This is because a return value of default(T) from one of
these three methods doesn't prove that the sequence is empty, as the value of the first / last / single element
of the sequence could equally be default(T)

Decide on which methods fits your code's purpose the most. For instance, use Single only if you must
ensure that there is a single item in the collection matching your predicate — otherwise use First; as Single
throw an exception if the sequence has more than one matching element. This of course applies to the
"*OrDefault"-counterparts as well.

Regarding efficiency: Although it's often appropriate to ensure that there is only one item (Single) or, either
only one or zero (SingleOrDefault) items, returned by a query, both of these methods require more, and
often the entirety, of the collection to be examined to ensure there in no second match to the query. This is
unlike the behavior of, for example, the First method, which can be satisfied after finding the first match.

Section 19.3: Except


The Except method returns the set of items which are contained in the first collection but are not contained in the
second. The default IEqualityComparer is used to compare the items within the two sets. There is an overload
which accepts an IEqualityComparer as an argument.

Example:

int[] first = { 1, 2, 3, 4 };
int[] second = { 0, 2, 3, 5 };

IEnumerable<int> inFirstButNotInSecond = [Link](second);


// inFirstButNotInSecond = { 1, 4 }

Output:

1
4

Live Demo on .NET Fiddle

In this case .Except(second) excludes elements contained in the array second, namely 2 and 3 (0 and 5 are not
contained in the first array and are skipped).

[Link] – C# Notes for Professionals 185


Note that Except implies Distinct (i.e., it removes repeated elements). For example:

int[] third = { 1, 1, 1, 2, 3, 4 };

IEnumerable<int> inThirdButNotInSecond = [Link](second);


// inThirdButNotInSecond = { 1, 4 }

Output:

1
4

Live Demo on .NET Fiddle

In this case, the elements 1 and 4 are returned only once.

Implementing IEquatable or providing the function an IEqualityComparer will allow using a different method to
compare the elements. Note that the GetHashCode method should also be overridden so that it will return an
identical hash code for object that are identical according to the IEquatable implementation.

Example With IEquatable:

class Holiday : IEquatable<Holiday>


{
public string Name { get; set; }

public bool Equals(Holiday other)


{
return Name == [Link];
}

// GetHashCode must return true whenever Equals returns true.


public override int GetHashCode()
{
//Get hash code for the Name field if it is not null.
return Name?.GetHashCode() ?? 0;
}
}

public class Program


{
public static void Main()
{
List<Holiday> holidayDifference = new List<Holiday>();

List<Holiday> remoteHolidays = new List<Holiday>


{
new Holiday { Name = "Xmas" },
new Holiday { Name = "Hanukkah" },
new Holiday { Name = "Ramadan" }
};

List<Holiday> localHolidays = new List<Holiday>


{
new Holiday { Name = "Xmas" },
new Holiday { Name = "Ramadan" }
};

[Link] – C# Notes for Professionals 186


holidayDifference = remoteHolidays
.Except(localHolidays)
.ToList();

[Link](x => [Link]([Link]));


}
}

Output:

Hanukkah

Live Demo on .NET Fiddle

Section 19.4: SelectMany


The SelectMany linq method 'flattens' an IEnumerable<IEnumerable<T>> into an IEnumerable<T>. All of the T
elements within the IEnumerable instances contained in the source IEnumerable will be combined into a single
IEnumerable.

var words = new [] { "a,b,c", "d,e", "f" };


var splitAndCombine = [Link](x => [Link](','));
// returns { "a", "b", "c", "d", "e", "f" }

If you use a selector function which turns input elements into sequences, the result will be the elements of those
sequences returned one by one.

Note that, unlike SELECT(), the number of elements in the output doesn't need to be the same as were in the input.

More real-world example

class School
{
public Student[] Students { get; set; }
}

class Student
{
public string Name { get; set; }
}

var schools = new [] {


new School(){ Students = new [] { new Student { Name="Bob"}, new Student { Name="Jack"} }},
new School(){ Students = new [] { new Student { Name="Jim"}, new Student { Name="John"} }}
};

var allStudents = [Link](s=> [Link]);

foreach(var student in allStudents)


{
[Link]([Link]);
}

Output:

Bob

[Link] – C# Notes for Professionals 187


Jack
Jim
John

Live Demo on .NET Fiddle

Section 19.5: Any


Any is used to check if any element of a collection matches a condition or not.
see also: .All, Any and FirstOrDefault: best practice

1. Empty parameter

Any: Returns true if the collection has any elements and false if the collection is empty:

var numbers = new List<int>();


bool result = [Link](); // false

var numbers = new List<int>(){ 1, 2, 3, 4, 5};


bool result = [Link](); //true

2. Lambda expression as parameter

Any: Returns true if the collection has one or more elements that meet the condition in the lambda expression:

var arrayOfStrings = new string[] { "a", "b", "c" };


[Link](item => item == "a"); // true
[Link](item => item == "d"); // false

3. Empty collection

Any: Returns false if the collection is empty and a lambda expression is supplied:

var numbers = new List<int>();


bool result = [Link](i => i >= 0); // false

Note: Any will stop iteration of the collection as soon as it finds an element matching the condition. This means that
the collection will not necessarily be fully enumerated; it will only be enumerated far enough to find the first item
matching the condition.

Live Demo on .NET Fiddle

Section 19.6: JOINS


Joins are used to combine different lists or tables holding data via a common key.

Like in SQL, the following kinds of Joins are supported in LINQ:


Inner, Left, Right, Cross and Full Outer Joins.

The following two lists are used in the examples below:

var first = new List<string>(){ "a","b","c"}; // Left data


var second = new List<string>(){ "a", "c", "d"}; // Right data

[Link] – C# Notes for Professionals 188


(Inner) Join
var result = from f in first
join s in second on f equals s
select new { f, s };

var result = [Link](second,


f => f,
s => s,
(f, s) => new { f, s });

// Result: {"a","a"}
// {"c","c"}

Left outer join


var leftOuterJoin = from f in first
join s in second on f equals s into temp
from t in [Link]()
select new { First = f, Second = t};

// Or can also do:


var leftOuterJoin = from f in first
from s in [Link](x => x == f).DefaultIfEmpty()
select new { First = f, Second = s};

// Result: {"a","a"}
// {"b", null}
// {"c","c"}

// Left outer join method syntax


var leftOuterJoinFluentSyntax = [Link](second,
f => f,
s => s,
(f, s) => new { First = f, Second = s })
.SelectMany(temp => [Link](),
(f, s) => new { First = [Link], Second = s });

Right Outer Join


var rightOuterJoin = from s in second
join f in first on s equals f into temp
from t in [Link]()
select new {First=t,Second=s};

// Result: {"a","a"}
// {"c","c"}
// {null,"d"}

Cross Join
var CrossJoin = from f in first
from s in second
select new { f, s };

// Result: {"a","a"}
// {"a","c"}
// {"a","d"}
// {"b","a"}
// {"b","c"}
// {"b","d"}

[Link] – C# Notes for Professionals 189


// {"c","a"}
// {"c","c"}
// {"c","d"}

Full Outer Join


var fullOuterjoin = [Link](rightOuterJoin);

// Result: {"a","a"}
// {"b", null}
// {"c","c"}
// {null,"d"}

Practical example

The examples above have a simple data structure so you can focus on understanding the different LINQ joins
technically, but in the real world you would have tables with columns you need to join.

In the following example, there is just one class Region used, in reality you would join two or more different tables
which hold the same key (in this example first and second are joined via the common key ID).

Example: Consider the following data structure:

public class Region


{
public Int32 ID;
public string RegionDescription;

public Region(Int32 pRegionID, string pRegionDescription=null)


{
ID = pRegionID; RegionDescription = pRegionDescription;
}
}

Now prepare the data (i.e. populate with data):

// Left data
var first = new List<Region>()
{ new Region(1), new Region(3), new Region(4) };
// Right data
var second = new List<Region>()
{
new Region(1, "Eastern"), new Region(2, "Western"),
new Region(3, "Northern"), new Region(4, "Southern")
};

You can see that in this example first doesn't contain any region descriptions so you want to join them from
second. Then the inner join would look like:

// do the inner join


var result = from f in first
join s in second on [Link] equals [Link]
select new { [Link], [Link] };

// Result: {1,"Eastern"}
// {3, Northern}
// {4,"Southern"}

[Link] – C# Notes for Professionals 190


This result has created anonymous objects on the fly, which is fine, but we have already created a proper class - so
we can specify it: Instead of SELECT NEW { [Link], [Link] }; we can say SELECT NEW Region([Link],
[Link]);, which will return the same data but will create objects of type Region - that will maintain
compatibility with the other objects.

Live demo on .NET fiddle

Section 19.7: Skip and Take


The Skip method returns a collection excluding a number of items from the beginning of the source collection. The
number of items excluded is the number given as an argument. If there are less items in the collection than
specified in the argument then an empty collection is returned.

The Take method returns a collection containing a number of elements from the beginning of the source collection.
The number of items included is the number given as an argument. If there are less items in the collection than
specified in the argument then the collection returned will contain the same elements as the source collection.

var values = new [] { 5, 4, 3, 2, 1 };

var skipTwo = [Link](2); // { 3, 2, 1 }


var takeThree = [Link](3); // { 5, 4, 3 }
var skipOneTakeTwo = [Link](1).Take(2); // { 4, 3 }
var takeZero = [Link](0); // An IEnumerable<int> with 0 items

Live Demo on .NET Fiddle

Skip and Take are commonly used together to paginate results, for instance:

IEnumerable<T> GetPage<T>(IEnumerable<T> collection, int pageNumber, int resultsPerPage) {


int startIndex = (pageNumber - 1) * resultsPerPage;
return [Link](startIndex).Take(resultsPerPage);
}

Warning: LINQ to Entities only supports Skip on ordered queries. If you try to use Skip without ordering
you will get a NotSupportedException with the message "The method 'Skip' is only supported for sorted
input in LINQ to Entities. The method 'OrderBy' must be called before the method 'Skip'."

Section 19.8: Defining a variable inside a Linq query (let


keyword)
In order to define a variable inside a linq expression, you can use the let keyword. This is usually done in order to
store the results of intermediate sub-queries, for example:

int[] numbers = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

var aboveAverages = from number in numbers


let average = [Link]()
let nSquared = [Link](number,2)
where nSquared > average
select number;

[Link]("The average of the numbers is {0}.", [Link]());

foreach (int n in aboveAverages)

[Link] – C# Notes for Professionals 191


{
[Link]("Query result includes number {0} with square of {1}.", n, [Link](n,2));
}

Output:

The average of the numbers is 4.5.


Query result includes number 3 with square of 9.
Query result includes number 4 with square of 16.
Query result includes number 5 with square of 25.
Query result includes number 6 with square of 36.
Query result includes number 7 with square of 49.
Query result includes number 8 with square of 64.
Query result includes number 9 with square of 81.

View Demo

Section 19.9: Zip


The Zip extension method acts upon two collections. It pairs each element in the two series together based on
position. With a Func instance, we use Zip to handle elements from the two C# collections in pairs. If the series
differ in size, the extra elements of the larger series will be ignored.

To take an example from the book "C# in a Nutshell",

int[] numbers = { 3, 5, 7 };
string[] words = { "three", "five", "seven", "ignored" };
IEnumerable<string> zip = [Link](words, (n, w) => n + "=" + w);

Output:

3=three
5=five
7=seven

View Demo

Section 19.10: Range and Repeat


The Range and Repeat static methods on Enumerable can be used to generate simple sequences.

Range

[Link]() generates a sequence of integers given a starting value and a count.

// Generate a collection containing the numbers 1-100 ([1, 2, 3, ..., 98, 99, 100])
var range = [Link](1,100);

Live Demo on .NET Fiddle

Repeat

[Link] – C# Notes for Professionals 192


[Link]() generates a sequence of repeating elements given an element and the number of repetitions
required.

// Generate a collection containing "a", three times (["a","a","a"])


var repeatedValues = [Link]("a", 3);

Live Demo on .NET Fiddle

Section 19.11: Basics


LINQ is largely beneficial for querying collections (or arrays).

For example, given the following sample data:

var classroom = new Classroom


{
new Student { Name = "Alice", Grade = 97, HasSnack = true },
new Student { Name = "Bob", Grade = 82, HasSnack = false },
new Student { Name = "Jimmy", Grade = 71, HasSnack = true },
new Student { Name = "Greg", Grade = 90, HasSnack = false },
new Student { Name = "Joe", Grade = 59, HasSnack = false }
}

We can "query" on this data using LINQ syntax. For example, to retrieve all students who have a snack today:

var studentsWithSnacks = from s in [Link]


where [Link]
select s;

Or, to retrieve students with a grade of 90 or above, and only return their names, not the full Student object:

var topStudentNames = from s in [Link]


where [Link] >= 90
select [Link];

The LINQ feature is comprised of two syntaxes that perform the same functions, have nearly identical performance,
but are written very differently. The syntax in the example above is called query syntax. The following example,
however, illustrates method syntax. The same data will be returned as in the example above, but the way the
query is written is different.

var topStudentNames = [Link]


.Where(s => [Link] >= 90)
.Select(s => [Link]);

Section 19.12: All


All is used to check, if all elements of a collection match a condition or not.
see also: .Any

1. Empty parameter

All: is not allowed to be used with empty parameter.

2. Lambda expression as parameter

[Link] – C# Notes for Professionals 193


All: Returns true if all elements of collection satisfies the lambda expression and false otherwise:

var numbers = new List<int>(){ 1, 2, 3, 4, 5};


bool result = [Link](i => i < 10); // true
bool result = [Link](i => i >= 3); // false

3. Empty collection

All: Returns true if the collection is empty and a lambda expression is supplied:

var numbers = new List<int>();


bool result = [Link](i => i >= 0); // true

Note: All will stop iteration of the collection as soon as it finds an element not matching the condition. This means
that the collection will not necessarily be fully enumerated; it will only be enumerated far enough to find the first
item not matching the condition.

Section 19.13: Aggregate


Aggregate Applies an accumulator function over a sequence.

int[] intList = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int sum = [Link]((prevSum, current) => prevSum + current);
// sum = 55

At the first step prevSum = 1


At the second prevSum = prevSum(at the first step) + 2
At the i-th step prevSum = prevSum(at the (i-1) step) + i-th element of the array

string[] stringList = { "Hello", "World", "!" };


string joinedString = [Link]((prev, current) => prev + " " + current);
// joinedString = "Hello World !"

A second overload of Aggregate also receives an seed parameter which is the initial accumulator value. This can be
used to calculate multiple conditions on a collection without iterating it more than once.

List<int> items = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };

For the collection of items we want to calculate

1. The total .Count


2. The amount of even numbers
3. Collect each forth item

Using Aggregate it can be done like this:

var result = [Link](new { Total = 0, Even = 0, FourthItems = new List<int>() },


(accumelative,item) =>
new {
Total = [Link] + 1,
Even = [Link] + (item % 2 == 0 ? 1 : 0),
FourthItems = ([Link] + 1)%4 == 0 ?
new List<int>([Link]) { item } :
[Link]
});
// Result:

[Link] – C# Notes for Professionals 194


// Total = 12
// Even = 6
// FourthItems = [4, 8, 12]

Note that using an anonymous type as the seed one has to instantiate a new object each item because the properties are
read only. Using a custom class one can simply assign the information and no new is needed (only when giving the initial
seed parameter

Section 19.14: Distinct


Returns unique values from an IEnumerable. Uniqueness is determined using the default equality comparer.

int[] array = { 1, 2, 3, 4, 2, 5, 3, 1, 2 };

var distinct = [Link]();


// distinct = { 1, 2, 3, 4, 5 }

To compare a custom data type, we need to implement the IEquatable<T> interface and provide GetHashCode and
Equals methods for the type. Or the equality comparer may be overridden:

class SSNEqualityComparer : IEqualityComparer<Person> {


public bool Equals(Person a, Person b) => return [Link] == [Link];
public int GetHashCode(Person p) => [Link];
}

List<Person> people;

distinct = [Link](SSNEqualityComparer);

Section 19.15: SelectMany: Flattening a sequence of sequences


var sequenceOfSequences = new [] { new [] { 1, 2, 3 }, new [] { 4, 5 }, new [] { 6 } };
var sequence = [Link](x => x);
// returns { 1, 2, 3, 4, 5, 6 }

Use SelectMany() if you have, or you are creating a sequence of sequences, but you want the result as one long
sequence.

In LINQ Query Syntax:

var sequence = from subSequence in sequenceOfSequences


from item in subSequence
select item;

If you have a collection of collections and would like to be able to work on data from parent and child collection at
the same time, it is also possible with SelectMany.

Let's define simple classes

public class BlogPost


{
public int Id { get; set; }
public string Content { get; set; }
public List<Comment> Comments { get; set; }
}

[Link] – C# Notes for Professionals 195


public class Comment
{
public int Id { get; set; }
public string Content { get; set; }
}

Let's assume we have following collection.

List<BlogPost> posts = new List<BlogPost>()


{
new BlogPost()
{
Id = 1,
Comments = new List<Comment>()
{
new Comment()
{
Id = 1,
Content = "It's really great!",
},
new Comment()
{
Id = 2,
Content = "Cool post!"
}
}
},
new BlogPost()
{
Id = 2,
Comments = new List<Comment>()
{
new Comment()
{
Id = 3,
Content = "I don't think you're right",
},
new Comment()
{
Id = 4,
Content = "This post is a complete nonsense"
}
}
}
};

Now we want to select comments Content along with Id of BlogPost associated with this comment. In order to do
so, we can use appropriate SelectMany overload.

var commentsWithIds = [Link](p => [Link], (post, comment) => new { PostId = [Link],
CommentContent = [Link] });

Our commentsWithIds looks like this

{
PostId = 1,
CommentContent = "It's really great!"
},
{
PostId = 1,

[Link] – C# Notes for Professionals 196


CommentContent = "Cool post!"
},
{
PostId = 2,
CommentContent = "I don't think you're right"
},
{
PostId = 2,
CommentContent = "This post is a complete nonsense"
}

Section 19.16: GroupBy


GroupBy is an easy way to sort a IEnumerable<T> collection of items into distinct groups.

Simple Example

In this first example, we end up with two groups, odd and even items.

List<int> iList = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9 };


var grouped = [Link](x => x % 2 == 0);

//Groups iList into odd [13579] and even[2468] items

foreach(var group in grouped)


{
foreach (int item in group)
{
[Link](item); // 135792468 (first odd then even)
}
}

More Complex Example

Let's take grouping a list of people by age as an example. First, we'll create a Person object which has two
properties, Name and Age.

public class Person


{
public int Age {get; set;}
public string Name {get; set;}
}

Then we create our sample list of people with various names and ages.

List<Person> people = new List<Person>();


[Link](new Person{Age = 20, Name = "Mouse"});
[Link](new Person{Age = 30, Name = "Neo"});
[Link](new Person{Age = 40, Name = "Morpheus"});
[Link](new Person{Age = 30, Name = "Trinity"});
[Link](new Person{Age = 40, Name = "Dozer"});
[Link](new Person{Age = 40, Name = "Smith"});

Then we create a LINQ query to group our list of people by age.

var query = [Link](x => [Link]);

[Link] – C# Notes for Professionals 197


Doing so, we can see the Age for each group, and have a list of each person in the group.

foreach(var result in query)


{
[Link]([Link]);

foreach(var person in result)


[Link]([Link]);
}

This results in the following output:

20
Mouse
30
Neo
Trinity
40
Morpheus
Dozer
Smith

You can play with the live demo on .NET Fiddle

Section 19.17: Query collection by type / cast elements to


type
interface IFoo { }
class Foo : IFoo { }
class Bar : IFoo { }

var item0 = new Foo();


var item1 = new Foo();
var item2 = new Bar();
var item3 = new Bar();
var collection = new IFoo[] { item0, item1, item2, item3 };

Using OfType

var foos = [Link]<Foo>(); // result: IEnumerable<Foo> with item0 and item1


var bars = [Link]<Bar>(); // result: IEnumerable<Bar> item item2 and item3
var foosAndBars = [Link]<IFoo>(); // result: IEnumerable<IFoo> with all four items

Using Where

var foos = [Link](item => item is Foo); // result: IEnumerable<IFoo> with item0 and item1
var bars = [Link](item => item is Bar); // result: IEnumerable<IFoo> with item2 and item3

Using Cast

var bars = [Link]<Bar>(); // throws InvalidCastException on the 1st item


var foos = [Link]<Foo>(); // throws InvalidCastException on the 3rd item
var foosAndBars = [Link]<IFoo>(); // OK

[Link] – C# Notes for Professionals 198


Section 19.18: Enumerating the Enumerable
The IEnumerable<T> interface is the base interface for all generic enumerators and is a quintessential part of
understanding LINQ. At its core, it represents the sequence.

This underlying interface is inherited by all of the generic collections, such as Collection<T>, Array, List<T>,
Dictionary<TKey, TValue> Class, and HashSet<T>.

In addition to representing the sequence, any class that inherits from IEnumerable<T> must provide an
IEnumerator<T>. The enumerator exposes the iterator for the enumerable, and these two interconnected
interfaces and ideas are the source of the saying "enumerate the enumerable".

"Enumerating the enumerable" is an important phrase. The enumerable is simply a structure for how to iterate, it
does not hold any materialized objects. For example, when sorting, an enumerable may hold the criteria of the field
to sort, but using .OrderBy() in itself will return an IEnumerable<T> which only knows how to sort. Using a call
which will materialize the objects, as in iterate the set, is known as enumerating (for example .ToList()). The
enumeration process will use the the enumerable definition of how in order to move through the series and return
the relevant objects (in order, filtered, projected, etc.).

Only once the enumerable has been enumerated does it cause the materialization of the objects, which is when
metrics like time complexity (how long it should take related to series size) and spacial complexity (how much space
it should use related to series size) can be measured.

Creating your own class that inherits from IEnumerable<T> can be a little complicated depending on the underlying
series that needs to be enumerable. In general it is best to use one of the existing generic collections. That said, it is
also possible to inherit from the IEnumerable<T> interface without having a defined array as the underlying
structure.

For example, using the Fibonacci series as the underlying sequence. Note that the call to Where simply builds an
IEnumerable, and it is not until a call to enumerate that enumerable is made that any of the values are materialized.

void Main()
{
Fibonacci Fibo = new Fibonacci();
IEnumerable<long> quadrillionplus = [Link](i => i > 1000000000000);
[Link]("Enumerable built");
[Link]([Link](2).Sum());
[Link]([Link](2).First());

IEnumerable<long> fibMod612 = [Link](i => i % 612);


[Link]("Enumerable built");
[Link]([Link]());//smallest divisible by 612
}

public class Fibonacci : IEnumerable<long>


{
private int max = 90;

//Enumerator called typically from foreach


public IEnumerator GetEnumerator() {
long n0 = 1;
long n1 = 1;
[Link]("Enumerating the Enumerable");
for(int i = 0; i < max; i++){
yield return n0+n1;
n1 += n0;
n0 = n1-n0;

[Link] – C# Notes for Professionals 199


}
}

//Enumerable called typically from linq


IEnumerator<long> IEnumerable<long>.GetEnumerator() {
long n0 = 1;
long n1 = 1;
[Link]("Enumerating the Enumerable");
for(int i = 0; i < max; i++){
yield return n0+n1;
n1 += n0;
n0 = n1-n0;
}
}
}

Output

Enumerable built
Enumerating the Enumerable
4052739537881
Enumerating the Enumerable
4052739537881
Enumerable built
Enumerating the Enumerable
14930352

The strength in the second set (the fibMod612) is that even though we made the call to order our entire set of
Fibonacci numbers, since only one value was taken using .First() the time complexity was O(n) as only 1 value
needed to be compared during the ordering algorithm's execution. This is because our enumerator only asked for 1
value, and so the entire enumerable did not have to be materialized. Had we used .Take(5) instead of .First()
the enumerator would have asked for 5 values, and at most 5 values would need to be materialized. Compared to
needing to order an entire set and then take the first 5 values, the principle of saves a lot of execution time and
space.

Section 19.19: Using Range with various Linq methods


You can use the Enumerable class alongside Linq queries to convert for loops into Linq one liners.

Select Example

Opposed to doing this:

var asciiCharacters = new List<char>();


for (var x = 0; x < 256; x++)
{
[Link]((char)x);
}

You can do this:

var asciiCharacters = [Link](0, 256).Select(a => (char) a);

Where Example

In this example, 100 numbers will be generated and even ones will be extracted

[Link] – C# Notes for Professionals 200


var evenNumbers = [Link](1, 100).Where(a => a % 2 == 0);

Section 19.20: Where


Returns a subset of items which the specified predicate is true for them.

List<string> trees = new List<string>{ "Oak", "Birch", "Beech", "Elm", "Hazel", "Maple" };

Method syntax
// Select all trees with name of length 3
var shortTrees = [Link](tree => [Link] == 3); // Oak, Elm

Query syntax
var shortTrees = from tree in trees
where [Link] == 3
select tree; // Oak, Elm

Section 19.21: Using SelectMany instead of nested loops


Given 2 lists

var list1 = new List<string> { "a", "b", "c" };


var list2 = new List<string> { "1", "2", "3", "4" };

if you want to output all permutations you could use nested loops like

var result = new List<string>();


foreach (var s1 in list1)
foreach (var s2 in list2)
[Link]($"{s1}{s2}");

Using SelectMany you can do the same operation as

var result = [Link](x => [Link](y => $"{x}{y}", x, y)).ToList();

Section 19.22: Contains


MSDN:

Determines whether a sequence contains a specified element by using a specified IEqualityComparer<T>

List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };


var result1 = [Link](4); // true
var result2 = [Link](8); // false

List<int> secondNumberCollection = new List<int> { 4, 5, 6, 7 };


// Note that can use the Intersect method in this case
var result3 = [Link](item => [Link](item)); // will be true only
for 4,5

Using a user defined object:

[Link] – C# Notes for Professionals 201


public class Person
{
public string Name { get; set; }
}

List<Person> objects = new List<Person>


{
new Person { Name = "Nikki"},
new Person { Name = "Gilad"},
new Person { Name = "Phil"},
new Person { Name = "John"}
};

//Using the Person's Equals method - override Equals() and GetHashCode() - otherwise it
//will compare by reference and result will be false
var result4 = [Link](new Person { Name = "Phil" }); // true

Using the [Link](value, comparer) overload:

public class Compare : IEqualityComparer<Person>


{
public bool Equals(Person x, Person y)
{
return [Link] == [Link];
}
public int GetHashCode(Person codeh)
{
return [Link]();
}
}

var result5 = [Link](new Person { Name = "Phil" }, new Compare()); // true

A smart usage of Contains would be to replace multiple if clauses to a Contains call.

So instead of doing this:

if(status == 1 || status == 3 || status == 4)


{
//Do some business operation
}
else
{
//Do something else
}

Do this:

if(new int[] {1, 3, 4 }.Contains(status)


{
//Do some business operaion
}
else
{
//Do something else
}

[Link] – C# Notes for Professionals 202


Section 19.23: Joining multiple sequences
Consider entities Customer, Purchase and PurchaseItem as follows:

public class Customer


{
public string Id { get; set } // A unique Id that identifies customer
public string Name {get; set; }
}

public class Purchase


{
public string Id { get; set }
public string CustomerId {get; set; }
public string Description { get; set; }
}

public class PurchaseItem


{
public string Id { get; set }
public string PurchaseId {get; set; }
public string Detail { get; set; }
}

Consider following sample data for above entities:

var customers = new List<Customer>()


{
new Customer() {
Id = [Link]().ToString(),
Name = "Customer1"
},

new Customer() {
Id = [Link]().ToString(),
Name = "Customer2"
}
};

var purchases = new List<Purchase>()


{
new Purchase() {
Id = [Link]().ToString(),
CustomerId = customers[0].Id,
Description = "Customer1-Purchase1"
},

new Purchase() {
Id = [Link]().ToString(),
CustomerId = customers[0].Id,
Description = "Customer1-Purchase2"
},

new Purchase() {
Id = [Link]().ToString(),
CustomerId = customers[1].Id,
Description = "Customer2-Purchase1"
},

new Purchase() {
Id = [Link]().ToString(),

[Link] – C# Notes for Professionals 203


CustomerId = customers[1].Id,
Description = "Customer2-Purchase2"
}
};

var purchaseItems = new List<PurchaseItem>()


{
new PurchaseItem() {
Id = [Link]().ToString(),
PurchaseId= purchases[0].Id,
Detail = "Purchase1-PurchaseItem1"
},

new PurchaseItem() {
Id = [Link]().ToString(),
PurchaseId= purchases[1].Id,
Detail = "Purchase2-PurchaseItem1"
},

new PurchaseItem() {
Id = [Link]().ToString(),
PurchaseId= purchases[1].Id,
Detail = "Purchase2-PurchaseItem2"
},

new PurchaseItem() {
Id = [Link]().ToString(),
PurchaseId= purchases[3].Id,
Detail = "Purchase3-PurchaseItem1"
}
};

Now, consider below linq query:

var result = from c in customers


join p in purchases on [Link] equals [Link] // first join
join pi in purchaseItems on [Link] equals [Link] // second join
select new
{
[Link], [Link], [Link]
};

To output the result of above query:

foreach(var resultItem in result)


{
[Link]($"{[Link]}, {[Link]}, {[Link]}");
}

The output of the query would be:

Customer1, Customer1-Purchase1, Purchase1-PurchaseItem1

Customer1, Customer1-Purchase2, Purchase2-PurchaseItem1

Customer1, Customer1-Purchase2, Purchase2-PurchaseItem2

Customer2, Customer2-Purchase2, Purchase3-PurchaseItem1

[Link] – C# Notes for Professionals 204


Live Demo on .NET Fiddle

Section 19.24: Joining on multiple keys


PropertyInfo[] stringProps = typeof (string).GetProperties();//string properties
PropertyInfo[] builderProps = typeof(StringBuilder).GetProperties();//stringbuilder properties

var query =
from s in stringProps
join b in builderProps
on new { [Link], [Link] } equals new { [Link], [Link] }
select new
{
[Link],
[Link],
StringToken = [Link],
StringBuilderToken = [Link]
};

Note that anonymous types in above join must contain same properties since objects are considered equal only if
all their properties are equal. Otherwise query won't compile.

Section 19.25: ToLookup

ToLookup returns a data structure that allows indexing. It is an extension method. It produces an ILookup
instance that can be indexed or enumerated using a foreach-loop. The entries are combined into
groupings at each key. - dotnetperls

string[] array = { "one", "two", "three" };


//create lookup using string length as key
var lookup = [Link](item => [Link]);

//join the values whose lengths are 3


[Link]([Link](",",lookup[3]));
//output: one,two

Another Example:

int[] array = { 1,2,3,4,5,6,7,8 };


//generate lookup for odd even numbers (keys will be 0 and 1)
var lookup = [Link](item => item % 2);

//print even numbers after joining


[Link]([Link](",",lookup[0]));
//output: 2,4,6,8

//print odd numbers after joining


[Link]([Link](",",lookup[1]));
//output: 1,3,5,7

Section 19.26: SkipWhile


SkipWhile() is used to exclude elements until first non-match (this might be counter intuitive to most)

int[] list = { 42, 42, 6, 6, 6, 42 };

[Link] – C# Notes for Professionals 205


var result = [Link](i => i == 42);
// Result: 6, 6, 6, 42

Section 19.27: Query Ordering - OrderBy() ThenBy()


OrderByDescending() ThenByDescending()
string[] names= { "mark", "steve", "adam" };

Ascending:

Query Syntax

var sortedNames =
from name in names
orderby name
select name;

Method Syntax

var sortedNames = [Link](name => name);

sortedNames contains the names in following order: "adam","mark","steve"

Descending:

Query Syntax

var sortedNames =
from name in names
orderby name descending
select name;

Method Syntax

var sortedNames = [Link](name => name);

sortedNames contains the names in following order: "steve","mark","adam"

Order by several fields

Person[] people =
{
new Person { FirstName = "Steve", LastName = "Collins", Age = 30},
new Person { FirstName = "Phil" , LastName = "Collins", Age = 28},
new Person { FirstName = "Adam" , LastName = "Ackerman", Age = 29},
new Person { FirstName = "Adam" , LastName = "Ackerman", Age = 15}
};

Query Syntax

var sortedPeople = from person in people


orderby [Link], [Link], [Link] descending
select person;

Method Syntax

[Link] – C# Notes for Professionals 206


sortedPeople = [Link](person => [Link])
.ThenBy(person => [Link])
.ThenByDescending(person => [Link]);

Result

1. Adam Ackerman 29
2. Adam Ackerman 15
3. Phil Collins 28
4. Steve Collins 30

Section 19.28: Sum


The [Link] extension method calculates the sum of numeric values.

In case the collection's elements are themselves numbers, you can calculate the sum directly.

int[] numbers = new int[] { 1, 4, 6 };


[Link]( [Link]() ); //outputs 11

In case the type of the elements is a complex type, you can use a lambda expression to specify the value that
should be calculated:

var totalMonthlySalary = [Link]( employee => [Link] );

Sum extension method can calculate with the following types:

Int32
Int64
Single
Double
Decimal

In case your collection contains nullable types, you can use the null-coalescing operator to set a default value for
null elements:

int?[] numbers = new int?[] { 1, null, 6 };


[Link]( [Link]( number => number ?? 0 ) ); //outputs 7

Section 19.29: GroupBy one or multiple fields


Lets assume we have some Film model:

public class Film {


public string Title { get; set; }
public string Category { get; set; }
public int Year { get; set; }
}

Group by Category property:

foreach (var grp in [Link](f => [Link])) {


var groupCategory = [Link];
var numberOfFilmsInCategory = [Link]();

[Link] – C# Notes for Professionals 207


}

Group by Category and Year:

foreach (var grp in [Link](f => new { Category = [Link], Year = [Link] })) {
var groupCategory = [Link];
var groupYear = [Link];
var numberOfFilmsInCategory = [Link]();
}

Section 19.30: OrderBy

Orders a collection by a specified value.

When the value is an integer, double or float it starts with the minimum value, which means that you get first the
negative values, than zero and afterwords the positive values (see Example 1).

When you order by a char the method compares the ascii values of the chars to sort the collection (see Example 2).

When you sort strings the OrderBy method compares them by taking a look at their CultureInfo but normaly
starting with the first letter in the alphabet (a,b,c...).

This kind of order is called ascending, if you want it the other way round you need descending (see
OrderByDescending).

Example 1:

int[] numbers = {2, 1, 0, -1, -2};


IEnumerable<int> ascending = [Link](x => x);
// returns {-2, -1, 0, 1, 2}

Example 2:

char[] letters = {' ', '!', '?', '[', '{', '+', '1', '9', 'a', 'A', 'b', 'B', 'y', 'Y', 'z', 'Z'};
IEnumerable<char> ascending = [Link](x => x);
// returns { ' ', '!', '+', '1', '9', '?', 'A', 'B', 'Y', 'Z', '[', 'a', 'b', 'y', 'z', '{' }

Example:

class Person
{
public string Name { get; set; }
public int Age { get; set; }
}

var people = new[]


{
new Person {Name = "Alice", Age = 25},
new Person {Name = "Bob", Age = 21},
new Person {Name = "Carol", Age = 43}
};
var youngestPerson = [Link](x => [Link]).First();
var name = [Link]; // Bob

[Link] – C# Notes for Professionals 208


Section 19.31: Any and First(OrDefault) - best practice
I won't explain what Any and FirstOrDefault does because there are already two good example about them. See
Any and First, FirstOrDefault, Last, LastOrDefault, Single, and SingleOrDefault for more information.

A pattern I often see in code which should be avoided is

if ([Link](t=>[Link] == "Bob"))
{
var myFoo = [Link](t=>[Link] == "Bob");
//Do stuff
}

It could be written more efficiently like this

var myFoo = [Link](t=>[Link] == "Bob");


if (myFoo != null)
{
//Do stuff
}

By using the second example, the collection is searched only once and give the same result as the first one. The
same idea can be applied to Single.

Section 19.32: GroupBy Sum and Count


Let's take a sample class:

public class Transaction


{
public string Category { get; set; }
public DateTime Date { get; set; }
public decimal Amount { get; set; }
}

Now, let us consider a list of transactions:

var transactions = new List<Transaction>


{
new Transaction { Category = "Saving Account", Amount = 56, Date = [Link](1) },
new Transaction { Category = "Saving Account", Amount = 10, Date = [Link](-10)
},
new Transaction { Category = "Credit Card", Amount = 15, Date = [Link](1) },
new Transaction { Category = "Credit Card", Amount = 56, Date = [Link] },
new Transaction { Category = "Current Account", Amount = 100, Date = [Link](5)
},
};

If you want to calculate category wise sum of amount and count, you can use GroupBy as follows:

var summaryApproach1 = [Link](t => [Link])


.Select(t => new
{
Category = [Link],
Count = [Link](),
Amount = [Link](ta => [Link]),
}).ToList();

[Link] – C# Notes for Professionals 209


[Link]("-- Summary: Approach 1 --");
[Link](
row => [Link]($"Category: {[Link]}, Amount: {[Link]}, Count:
{[Link]}"));

Alternatively, you can do this in one step:

var summaryApproach2 = [Link](t => [Link], (key, t) =>


{
var transactionArray = t as Transaction[] ?? [Link]();
return new
{
Category = key,
Count = [Link],
Amount = [Link](ta => [Link]),
};
}).ToList();

[Link]("-- Summary: Approach 2 --");


[Link](
row => [Link]($"Category: {[Link]}, Amount: {[Link]}, Count: {[Link]}"));

Output for both the above queries would be same:

Category: Saving Account, Amount: 66, Count: 2

Category: Credit Card, Amount: 71, Count: 2

Category: Current Account, Amount: 100, Count: 1

Live Demo in .NET Fiddle

Section 19.33: SequenceEqual


SequenceEqual is used to compare two IEnumerable<T> sequences with each other.

int[] a = new int[] {1, 2, 3};


int[] b = new int[] {1, 2, 3};
int[] c = new int[] {1, 3, 2};

bool returnsTrue = [Link](b);


bool returnsFalse = [Link](c);

Section 19.34: ElementAt and ElementAtOrDefault


ElementAt will return the item at index n. If n is not within the range of the enumerable, throws an
ArgumentOutOfRangeException.

int[] numbers = { 1, 2, 3, 4, 5 };
[Link](2); // 3
[Link](10); // throws ArgumentOutOfRangeException

ElementAtOrDefault will return the item at index n. If n is not within the range of the enumerable, returns a
default(T).

[Link] – C# Notes for Professionals 210


int[] numbers = { 1, 2, 3, 4, 5 };
[Link](2); // 3
[Link](10); // 0 = default(int)

Both ElementAt and ElementAtOrDefault are optimized for when the source is an IList<T> and normal indexing
will be used in those cases.

Note that for ElementAt, if the provided index is greater than the size of the IList<T>, the list should (but is
technically not guaranteed to) throw an ArgumentOutOfRangeException.

Section 19.35: DefaultIfEmpty


DefaultIfEmpty is used to return a Default Element if the Sequence contains no elements. This Element can be the
Default of the Type or a user defined instance of that Type. Example:

var chars = new List<string>() { "a", "b", "c", "d" };

[Link]("N/A").FirstOrDefault(); // returns "a";

[Link](str => [Link] > 1)


.DefaultIfEmpty("N/A").FirstOrDefault(); // return "N/A"

[Link](str => [Link] > 1)


.DefaultIfEmpty().First(); // returns null;

Usage in Left Joins:

With DefaultIfEmpty the traditional Linq Join can return a default object if no match was found. Thus acting as a
SQL's Left Join. Example:

var leftSequence = new List<int>() { 99, 100, 5, 20, 102, 105 };


var rightSequence = new List<char>() { 'a', 'b', 'c', 'i', 'd' };

var numbersAsChars = from l in leftSequence


join r in rightSequence
on l equals (int)r into leftJoin
from result in [Link]('?')
select new
{
Number = l,
Character = result
};

foreach(var item in numbersAsChars)


{
[Link]("Num = {0} ** Char = {1}", [Link], [Link]);
}

output:

Num = 99 Char = c
Num = 100 Char = d
Num = 5 Char = ?
Num = 20 Char = ?
Num = 102 Char = ?
Num = 105 Char = i

In the case where a DefaultIfEmpty is used (without specifying a default value) and that will result will no matching

[Link] – C# Notes for Professionals 211


items on the right sequence one must make sure that the object is not null before accessing its properties.
Otherwise it will result in a NullReferenceException. Example:

var leftSequence = new List<int> { 1, 2, 5 };


var rightSequence = new List<dynamic>()
{
new { Value = 1 },
new { Value = 2 },
new { Value = 3 },
new { Value = 4 },
};

var numbersAsChars = (from l in leftSequence


join r in rightSequence
on l equals [Link] into leftJoin
from result in [Link]()
select new
{
Left = l,
// 5 will not have a matching object in the right so result
// will be equal to null.
// To avoid an error use:
// - C# 6.0 or above - ?.
// - Under - result == null ? 0 : [Link]
Right = result?.Value
}).ToList();

Section 19.36: ToDictionary


The ToDictionary() LINQ method can be used to generate a Dictionary<TKey, TElement> collection based on a
given IEnumerable<T> source.

IEnumerable<User> users = GetUsers();


Dictionary<int, User> usersById = [Link](x => [Link]);

In this example, the single argument passed to ToDictionary is of type Func<TSource, TKey>, which returns the
key for each element.

This is a concise way to perform the following operation:

Dictionary<int, User> usersById = new Dictionary<int User>();


foreach (User u in users)
{
[Link]([Link], u);
}

You can also pass a second parameter to the ToDictionary method, which is of type Func<TSource, TElement>
and returns the Value to be added for each entry.

IEnumerable<User> users = GetUsers();


Dictionary<int, string> userNamesById = [Link](x => [Link], x => [Link]);

It is also possible to specify the IComparer that is used to compare key values. This can be useful when the key is a
string and you want it to match case-insensitive.

IEnumerable<User> users = GetUsers();


Dictionary<string, User> usersByCaseInsenstiveName = [Link](x => [Link],

[Link] – C# Notes for Professionals 212


[Link]);

var user1 = usersByCaseInsenstiveName["john"];


var user2 = usersByCaseInsenstiveName["JOHN"];
user1 == user2; // Returns true

Note: the ToDictionary method requires all keys to be unique, there must be no duplicate keys. If there are, then
an exception is thrown: ArgumentException: An item with the same key has already been added. If you have
a scenario where you know that you will have multiple elements with the same key, then you are better off using
ToLookup instead.

Section 19.37: Concat


Merges two collections (without removing duplicates)

List<int> foo = new List<int> { 1, 2, 3 };


List<int> bar = new List<int> { 3, 4, 5 };

// Through Enumerable static class


var result = [Link](foo, bar).ToList(); // 1,2,3,3,4,5

// Through extension method


var result = [Link](bar).ToList(); // 1,2,3,3,4,5

Section 19.38: Build your own Linq operators for


IEnumerable<T>
One of the great things about Linq is that it is so easy to extend. You just need to create an extension method
whose argument is IEnumerable<T>.

public namespace MyNamespace


{
public static class LinqExtensions
{
public static IEnumerable<List<T>> Batch<T>(this IEnumerable<T> source, int batchSize)
{
var batch = new List<T>();
foreach (T item in source)
{
[Link](item);
if ([Link] == batchSize)
{
yield return batch;
batch = new List<T>();
}
}
if ([Link] > 0)
yield return batch;
}
}
}

This example splits the items in an IEnumerable<T> into lists of a fixed size, the last list containing the remainder of
the items. Notice how the object to which the extension method is applied is passed in (argument source) as the
initial argument using the this keyword. Then the yield keyword is used to output the next item in the output
IEnumerable<T> before continuing with execution from that point (see yield keyword).

[Link] – C# Notes for Professionals 213


This example would be used in your code like this:

//using MyNamespace;
var items = new List<int> { 2, 3, 4, 5, 6 };
foreach (List<int> sublist in [Link](3))
{
// do something
}

On the first loop, sublist would be {2, 3, 4} and on the second {5, 6}.

Custom LinQ methods can be combined with standard LinQ methods too. e.g.:

//using MyNamespace;
var result = [Link](0, 13) // generate a list
.Where(x => x%2 == 0) // filter the list or do something other
.Batch(3) // call our extension method
.ToList() // call other standard methods

This query will return even numbers grouped in batches with a size of 3: {0, 2, 4}, {6, 8, 10}, {12}

Remember you need a using MyNamespace; line in order to be able to access the extension method.

Section 19.39: Select - Transforming elements


Select allows you to apply a transformation to every element in any data structure implementing IEnumerable.

Getting the first character of each string in the following list:

List<String> trees = new List<String>{ "Oak", "Birch", "Beech", "Elm", "Hazel", "Maple" };

Using regular (lambda) syntax

//The below select stament transforms each element in tree into its first character.
IEnumerable<String> initials = [Link](tree => [Link](0, 1));
foreach (String initial in initials) {
[Link](initial);
}

Output:

O
B
B
E
H
M

Live Demo on .NET Fiddle

Using LINQ Query Syntax

initials = from tree in trees


select [Link](0, 1);

[Link] – C# Notes for Professionals 214


Section 19.40: OrderByDescending

Orders a collection by a specified value.

When the value is an integer, double or float it starts with the maximal value, which means that you get first the
positive values, than zero and afterwords the negative values (see Example 1).

When you order by a char the method compares the ascii values of the chars to sort the collection (see Example 2).

When you sort strings the OrderBy method compares them by taking a look at their CultureInfo but normaly
starting with the last letter in the alphabet (z,y,x,...).

This kind of order is called descending, if you want it the other way round you need ascending (see OrderBy).

Example 1:

int[] numbers = {-2, -1, 0, 1, 2};


IEnumerable<int> descending = [Link](x => x);
// returns {2, 1, 0, -1, -2}

Example 2:

char[] letters = {' ', '!', '?', '[', '{', '+', '1', '9', 'a', 'A', 'b', 'B', 'y', 'Y', 'z', 'Z'};
IEnumerable<char> descending = [Link](x => x);
// returns { '{', 'z', 'y', 'b', 'a', '[', 'Z', 'Y', 'B', 'A', '?', '9', '1', '+', '!', ' ' }

Example 3:

class Person
{
public string Name { get; set; }
public int Age { get; set; }
}

var people = new[]


{
new Person {Name = "Alice", Age = 25},
new Person {Name = "Bob", Age = 21},
new Person {Name = "Carol", Age = 43}
};
var oldestPerson = [Link](x => [Link]).First();
var name = [Link]; // Carol

Section 19.41: Union


Merges two collections to create a distinct collection using the default equality comparer

int[] numbers1 = { 1, 2, 3 };
int[] numbers2 = { 2, 3, 4, 5 };

var allElement = [Link](numbers2); // AllElement now contains 1,2,3,4,5

Live Demo on .NET Fiddle

[Link] – C# Notes for Professionals 215


Section 19.42: GroupJoin with outer range variable
Customer[] customers = [Link]();
Purchase[] purchases = [Link]();

var groupJoinQuery =
from c in customers
join p in purchases on [Link] equals [Link]
into custPurchases
select new
{
CustName = [Link],
custPurchases
};

Section 19.43: Linq Quantifiers


Quantifier operations return a Boolean value if some or all of the elements in a sequence satisfy a condition. In this
article, we will see some common LINQ to Objects scenarios where we can use these operators. There are 3
Quantifiers operations that can be used in LINQ:

All – used to determine whether all the elements in a sequence satisfy a condition. Eg:

int[] array = { 10, 20, 30 };

// Are all elements >= 10? YES


[Link](element => element >= 10);

// Are all elements >= 20? NO


[Link](element => element >= 20);

// Are all elements < 40? YES


[Link](element => element < 40);

Any - used to determine whether any elements in a sequence satisfy a condition. Eg:

int[] query=new int[] { 2, 3, 4 }


[Link] (n => n == 3);

Contains - used to determine whether a sequence contains a specified element. Eg:

//for int array


int[] query =new int[] { 1,2,3 };
[Link](1);

//for string array


string[] query={"Tom","grey"};
[Link]("Tom");

//for a string
var stringValue="hello";
[Link]("h");

Section 19.44: TakeWhile


TakeWhile returns elements from a sequence as long as the condition is true

[Link] – C# Notes for Professionals 216


int[] list = { 1, 10, 40, 50, 44, 70, 4 };
var result = [Link](item => item < 50).ToList();
// result = { 1, 10, 40 }

Section 19.45: Reverse


Inverts the order of the elements in a sequence.
If there is no items throws a ArgumentNullException: source is null.

Example:

// Create an array.
int[] array = { 1, 2, 3, 4 }; //Output:
// Call reverse extension method on the array. //4
var reverse = [Link](); //3
// Write contents of array to screen. //2
foreach (int value in reverse) //1
[Link](value);

Live code example

Remeber that Reverse() may work diffrent depending on the chain order of your LINQ statements.

//Create List of chars


List<int> integerlist = new List<int>() { 1, 2, 3, 4, 5, 6 };

//Reversing the list then taking the two first elements


IEnumerable<int> reverseFirst = [Link]<int>().Take(2);

//Taking 2 elements and then reversing only thos two


IEnumerable<int> reverseLast = [Link](2).Reverse();

//reverseFirst output: 6, 5
//reverseLast output: 2, 1

Live code example

Reverse() works by buffering everything then walk through it backwards, whitch is not very efficient, but neither is
OrderBy from that perspective.

In LINQ-to-Objects, there are buffering operations (Reverse, OrderBy, GroupBy, etc) and non-buffering operations
(Where, Take, Skip, etc).

Example: Non-buffering Reverse extention

public static IEnumerable<T> Reverse<T>(this IList<T> list) {


for (int i = [Link] - 1; i >= 0; i--)
yield return list[i];
}

Live code example

This method can encounter problems if u mutate the list while iterating.

[Link] – C# Notes for Professionals 217


Section 19.46: Count and LongCount
Count returns the number of elements in an IEnumerable<T>. Count also exposes an optional predicate parameter
that allows you to filter the elements you want to count.

int[] array = { 1, 2, 3, 4, 2, 5, 3, 1, 2 };

int n = [Link](); // returns the number of elements in the array


int x = [Link](i => i > 2); // returns the number of elements in the array greater than 2

LongCount works the same way as Count but has a return type of long and is used for counting IEnumerable<T>
sequences that are longer than [Link]

int[] array = GetLargeArray();

long n = [Link](); // returns the number of elements in the array


long x = [Link](i => i > 100); // returns the number of elements in the array greater than
100

Section 19.47: Incrementally building a query


Because LINQ uses deferred execution, we can have a query object that doesn't actually contain the values, but
will return the values when evaluated. We can thus dynamically build the query based on our control flow, and
evaluate it once we are finished:

IEnumerable<VehicleModel> BuildQuery(int vehicleType, SearchModel search, int start = 1, int count


= -1) {
IEnumerable<VehicleModel> query = _entities.Vehicles
.Where(x => [Link] && [Link] == vehicleType)
.Select(x => new VehicleModel {
Id = [Link],
Year = [Link],
Class = [Link],
Make = [Link],
Model = [Link],
Cylinders = [Link] ?? 0
});

We can conditionally apply filters:

if (![Link]("all", [Link]))
query = [Link](v => [Link]([Link]));

if (![Link]("all", [Link])) {
query = [Link](v => [Link]([Link]));
}

if (![Link]("all", [Link])) {
query = [Link](v => [Link]([Link]));
}

if (![Link]("all", [Link])) {
decimal minCylinders = 0;
decimal maxCylinders = 0;
switch ([Link]) {
case "2-4":
maxCylinders = 4;
break;

[Link] – C# Notes for Professionals 218


case "5-6":
minCylinders = 5;
maxCylinders = 6;
break;
case "8":
minCylinders = 8;
maxCylinders = 8;
break;
case "10+":
minCylinders = 10;
break;
}
if (minCylinders > 0) {
query = [Link](v => [Link] >= minCylinders);
}
if (maxCylinders > 0) {
query = [Link](v => [Link] <= maxCylinders);
}
}

We can add a sort order to the query based on a condition:

switch ([Link]()) {
case "make_model":
query = [Link](v => [Link]).ThenBy(v => [Link]);
break;
case "year":
query = [Link](v => [Link]);
break;
case "engine_size":
query = [Link](v => [Link]).ThenBy(v => [Link]);
break;
default:
query = [Link](v => [Link]); //The default sorting.
}

Our query can be defined to start from a given point:

query = [Link](start - 1);

and defined to return a specific number of records:

if (count > -1) {


query = [Link](count);
}
return query;
}

Once we have the query object, we can evaluate the results with a foreach loop, or one of the LINQ methods that
returns a set of values, such as ToList or ToArray:

SearchModel sm;

// populate the search model here


// ...

List<VehicleModel> list = BuildQuery(5, sm).ToList();

[Link] – C# Notes for Professionals 219


Section 19.48: Select with Func<TSource, int, TResult> selector
- Use to get ranking of elements
On of the overloads of the SELECT extension methods also passes the index of the current item in the collection
being SELECTed. These are a few uses of it.

Get the "row number" of the items

var rowNumbers = [Link](item => item.Property1)


.ThenBy(item => item.Property2)
.ThenByDescending(item => item.Property3)
.Select((item, index) => new { Item = item, RowNumber = index })
.ToList();

Get the rank of an item within its group

var rankInGroup = [Link](item => item.Property1)


.OrderBy(group => [Link])
.SelectMany(group => [Link](item => item.Property2)
.ThenByDescending(item => item.Property3)
.Select((item, index) => new
{
Item = item,
RankInGroup = index
})).ToList();

Get the ranking of groups (also known in Oracle as dense_rank)

var rankOfBelongingGroup = [Link](item => item.Property1)


.OrderBy(group => [Link])
.Select((group, index) => new
{
Items = group,
Rank = index
})
.SelectMany(v => [Link], (s, i) => new
{
Item = i,
DenseRank = [Link]
}).ToList();

For testing this you can use:

public class SomeObject


{
public int Property1 { get; set; }
public int Property2 { get; set; }
public int Property3 { get; set; }

public override string ToString()


{
return [Link](", ", Property1, Property2, Property3);
}
}

And data:

List<SomeObject> collection = new List<SomeObject>

[Link] – C# Notes for Professionals 220


{
new SomeObject { Property1 = 1, Property2 = 1, Property3 = 1},
new SomeObject { Property1 = 1, Property2 = 2, Property3 = 1},
new SomeObject { Property1 = 1, Property2 = 2, Property3 = 2},
new SomeObject { Property1 = 2, Property2 = 1, Property3 = 1},
new SomeObject { Property1 = 2, Property2 = 2, Property3 = 1},
new SomeObject { Property1 = 2, Property2 = 2, Property3 = 1},
new SomeObject { Property1 = 2, Property2 = 3, Property3 = 1}
};

[Link] – C# Notes for Professionals 221


Chapter 20: C# 7.0 Features
C# 7.0 is the seventh version of C#. This version contains some new features: language support for Tuples, local
functions, out var declarations, digit separators, binary literals, pattern matching, throw expressions, ref return
and ref local and extended expression bodied members list.

Official reference: What's new in C# 7

Section 20.1: Language support for Tuples


Basics

A tuple is an ordered, finite list of elements. Tuples are commonly used in programming as a means to work with
one single entity collectively instead of individually working with each of the tuple's elements, and to represent
individual rows (ie. "records") in a relational database.

In C# 7.0, methods can have multiple return values. Behind the scenes, the compiler will use the new ValueTuple
struct.

public (int sum, int count) GetTallies()


{
return (1, 2);
}

Side note: for this to work in Visual Studio 2017, you need to get the [Link] package.

If a tuple-returning method result is assigned to a single variable you can access the members by their defined
names on the method signature:

var result = GetTallies();


// > [Link]
// 1
// > [Link]
// 2

Tuple Deconstruction

Tuple deconstruction separates a tuple into its parts.

For example, invoking GetTallies and assigning the return value to two separate variables deconstructs the tuple
into those two variables:

(int tallyOne, int tallyTwo) = GetTallies();

var also works:

(var s, var c) = GetTallies();

You can also use shorter syntax, with var outside of ():

var (s, c) = GetTallies();

You can also deconstruct into existing variables:

int s, c;

[Link] – C# Notes for Professionals 222


(s, c) = GetTallies();

Swapping is now much simpler (no temp variable needed):

(b, a) = (a, b);

Interestingly, any object can be deconstructed by defining a Deconstruct method in the class:

class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }

public void Deconstruct(out string firstName, out string lastName)


{
firstName = FirstName;
lastName = LastName;
}
}

var person = new Person { FirstName = "John", LastName = "Smith" };


var (localFirstName, localLastName) = person;

In this case, the (localFirstName, localLastName) = person syntax is invoking Deconstruct on the person.

Deconstruction can even be defined in an extension method. This is equivalent to the above:

public static class PersonExtensions


{
public static void Deconstruct(this Person person, out string firstName, out string lastName)
{
firstName = [Link];
lastName = [Link];
}
}

var (localFirstName, localLastName) = person;

An alternative approach for the Person class is to define the Name itself as a Tuple. Consider the following:

class Person
{
public (string First, string Last) Name { get; }

public Person((string FirstName, string LastName) name)


{
Name = name;
}
}

Then you can instantiate a person like so (where we can take a tuple as an argument):

var person = new Person(("Jane", "Smith"));

var firstName = [Link]; // "Jane"


var lastName = [Link]; // "Smith"

Tuple Initialization

[Link] – C# Notes for Professionals 223


You can also arbitrarily create tuples in code:

var name = ("John", "Smith");


[Link](name.Item1);
// Outputs John

[Link](name.Item2);
// Outputs Smith

When creating a tuple, you can assign ad-hoc item names to the members of the tuple:

var name = (first: "John", middle: "Q", last: "Smith");


[Link]([Link]);
// Outputs John

Type inference

Multiple tuples defined with the same signature (matching types and count) will be inferred as matching types. For
example:

public (int sum, double average) Measure(List<int> items)


{
var stats = (sum: 0, average: 0d);
[Link] = [Link]();
[Link] = [Link]();
return stats;
}

stats can be returned since the declaration of the stats variable and the method's return signature are a match.

Reflection and Tuple Field Names

Member names do not exist at runtime. Reflection will consider tuples with the same number and types of
members the same even if member names do not match. Converting a tuple to an object and then to a tuple with
the same member types, but different names, will not cause an exception either.

While the ValueTuple class itself does not preserve information for member names the information is available
through reflection in a TupleElementNamesAttribute. This attribute is not applied to the tuple itself but to method
parameters, return values, properties and fields. This allows tuple item names to be preserved across assemblies
i.e. if a method returns (string name, int count) the names name and count will be available to callers of the method
in another assembly because the return value will be marked with TupleElementNameAttribute containing the
values "name" and "count".

Use with generics and async

The new tuple features (using the underlying ValueTuple type) fully support generics and can be used as generic
type parameter. That makes it possible to use them with the async/await pattern:

public async Task<(string value, int count)> GetValueAsync()


{
string fooBar = await _stackoverflow.GetStringAsync();
int num = await _stackoverflow.GetIntAsync();

return (fooBar, num);


}

Use with collections

[Link] – C# Notes for Professionals 224


It may become beneficial to have a collection of tuples in (as an example) a scenario where you're attempting to
find a matching tuple based on conditions to avoid code branching.

Example:

private readonly List<Tuple<string, string, string>> labels = new List<Tuple<string, string,


string>>()
{
new Tuple<string, string, string>("test1", "test2", "Value"),
new Tuple<string, string, string>("test1", "test1", "Value2"),
new Tuple<string, string, string>("test2", "test2", "Value3"),
};

public string FindMatchingValue(string firstElement, string secondElement)


{
var result = labels
.Where(w => w.Item1 == firstElement && w.Item2 == secondElement)
.FirstOrDefault();

if (result == null)
throw new ArgumentException("combo not found");

return result.Item3;
}

With the new tuples can become:

private readonly List<(string firstThingy, string secondThingyLabel, string foundValue)> labels =


new List<(string firstThingy, string secondThingyLabel, string foundValue)>()
{
("test1", "test2", "Value"),
("test1", "test1", "Value2"),
("test2", "test2", "Value3"),
}

public string FindMatchingValue(string firstElement, string secondElement)


{
var result = labels
.Where(w => [Link] == firstElement && [Link] == secondElement)
.FirstOrDefault();

if (result == null)
throw new ArgumentException("combo not found");

return [Link];
}

Though the naming on the example tuple above is pretty generic, the idea of relevant labels allows for a deeper
understanding of what is being attempted in the code over referencing "item1", "item2", and "item3".

Differences between ValueTuple and Tuple

The primary reason for introduction of ValueTuple is performance.

Type name ValueTuple Tuple


Class or structure struct class
Mutability (changing values after creation) mutable immutable
Naming members and other language support yes no (TBD)

[Link] – C# Notes for Professionals 225


References

Original Tuples language feature proposal on GitHub


A runnable VS 15 solution for C# 7.0 features
NuGet Tuple Package

Section 20.2: Local functions


Local functions are defined within a method and aren't available outside of it. They have access to all local variables
and support iterators, async/await and lambda syntax. This way, repetitions specific to a function can be
functionalized without crowding the class. As a side effect, this improves intellisense suggestion performance.

Example
double GetCylinderVolume(double radius, double height)
{
return getVolume();

double getVolume()
{
// You can declare inner-local functions in a local function
double GetCircleArea(double r) => [Link] * r * r;

// ALL parents' variables are accessible even though parent doesn't have any input.
return GetCircleArea(radius) * height;
}
}

Local functions considerably simplify code for LINQ operators, where you usually have to separate argument
checks from actual logic to make argument checks instant, not delayed until after iteration started.

Example
public static IEnumerable<TSource> Where<TSource>(
this IEnumerable<TSource> source,
Func<TSource, bool> predicate)
{
if (source == null) throw new ArgumentNullException(nameof(source));
if (predicate == null) throw new ArgumentNullException(nameof(predicate));

return iterator();

IEnumerable<TSource> iterator()
{
foreach (TSource element in source)
if (predicate(element))
yield return element;
}
}

Local functions also support the async and await keywords.

Example
async Task WriteEmailsAsync()
{
var emailRegex = new Regex(@"(?i)[a-z0-9_.+-]+@[a-z0-9-]+\.[a-z0-9-.]+");
IEnumerable<string> emails1 = await getEmailsFromFileAsync("[Link]");
IEnumerable<string> emails2 = await getEmailsFromFileAsync("[Link]");
await writeLinesToFileAsync([Link](emails2), "[Link]");

[Link] – C# Notes for Professionals 226


async Task<IEnumerable<string>> getEmailsFromFileAsync(string fileName)
{
string text;

using (StreamReader reader = [Link](fileName))


{
text = await [Link]();
}

return from Match emailMatch in [Link](text) select [Link];


}

async Task writeLinesToFileAsync(IEnumerable<string> lines, string fileName)


{
using (StreamWriter writer = [Link](fileName))
{
foreach (string line in lines)
{
await [Link](line);
}
}
}
}

One important thing that you may have noticed is that local functions can be defined under the return statement,
they do not need to be defined above it. Additionally, local functions typically follow the "lowerCamelCase" naming
convention as to more easily differentiate themselves from class scope functions.

Section 20.3: out var declaration


A common pattern in C# is using bool TryParse(object input, out object value) to safely parse objects.

The out var declaration is a simple feature to improve readability. It allows a variable to be declared at the same
time that is it passed as an out parameter.

A variable declared this way is scoped to the remainder of the body at the point in which it is declared.

Example

Using TryParse prior to C# 7.0, you must declare a variable to receive the value before calling the function:

Version < 7.0


int value;
if ([Link](input, out value))
{
Foo(value); // ok
}
else
{
Foo(value); // value is zero
}

Foo(value); // ok

In C# 7.0, you can inline the declaration of the variable passed to the out parameter, eliminating the need for a
separate variable declaration:

Version ≥ 7.0
if ([Link](input, out var value))

[Link] – C# Notes for Professionals 227


{
Foo(value); // ok
}
else
{
Foo(value); // value is zero
}

Foo(value); // still ok, the value in scope within the remainder of the body

If some of the parameters that a function returns in out is not needed you can use the discard operator _.

[Link](out var x, out _); // I only care about x

An out var declaration can be used with any existing function which already has out parameters. The function
declaration syntax remains the same, and no additional requirements are needed to make the function compatible
with an out var declaration. This feature is simply syntactic sugar.

Another feature of out var declaration is that it can be used with anonymous types.

Version ≥ 7.0
var a = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
var groupedByMod2 = [Link](x => new
{
Source = x,
Mod2 = x % 2
})
.GroupBy(x => x.Mod2)
.ToDictionary(g => [Link], g => [Link]());
if ([Link](1, out var oddElements))
{
[Link]([Link]);
}

In this code we create a Dictionary with int key and array of anonymous type value. In the previous version of C#
it was impossible to use TryGetValue method here since it required you to declare the out variable (which is of
anonymous type!). However, with out var we do not need to explicitly specify the type of the out variable.

Limitations

Note that out var declarations are of limited use in LINQ queries as expressions are interpreted as expression
lambda bodies, so the scope of the introduced variables is limited to these lambdas. For example, the following
code will not work:

var nums =
from item in seq
let success = [Link](item, out var tmp)
select success ? tmp : 0; // Error: The name 'tmp' does not exist in the current context

References

Original out var declaration proposal on GitHub

Section 20.4: Pattern Matching


Pattern matching extensions for C# enable many of the benefits of pattern matching from functional languages,
but in a way that smoothly integrates with the feel of the underlying language

[Link] – C# Notes for Professionals 228


switch expression

Pattern matching extends the switch statement to switch on types:

class Geometry {}

class Triangle : Geometry


{
public int Width { get; set; }
public int Height { get; set; }
public int Base { get; set; }
}

class Rectangle : Geometry


{
public int Width { get; set; }
public int Height { get; set; }
}

class Square : Geometry


{
public int Width { get; set; }
}

public static void PatternMatching()


{
Geometry g = new Square { Width = 5 };

switch (g)
{
case Triangle t:
[Link]($"{[Link]} {[Link]} {[Link]}");
break;
case Rectangle sq when [Link] == [Link]:
[Link]($"Square rectangle: {[Link]} {[Link]}");
break;
case Rectangle r:
[Link]($"{[Link]} {[Link]}");
break;
case Square s:
[Link]($"{[Link]}");
break;
default:
[Link]("<other>");
break;
}
}

is expression

Pattern matching extends the is operator to check for a type and declare a new variable at the same time.

Example
Version < 7.0
string s = o as string;
if(s != null)
{
// do something with s
}

[Link] – C# Notes for Professionals 229


can be rewritten as:

Version ≥ 7.0
if(o is string s)
{
//Do something with s
};

Also note that the scope of the pattern variable s is extended to outside the if block reaching the end of the
enclosing scope, example:

if(someCondition)
{
if(o is string s)
{
//Do something with s
}
else
{
// s is unassigned here, but accessible
}

// s is unassigned here, but accessible


}
// s is not accessible here

Section 20.5: Digit separators


The underscore _ may be used as a digit separator. Being able to group digits in large numeric literals has a
significant impact on readability.

The underscore may occur anywhere in a numeric literal except as noted below. Different groupings may make
sense in different scenarios or with different numeric bases.

Any sequence of digits may be separated by one or more underscores. The _ is allowed in decimals as well as
exponents. The separators have no semantic impact - they are simply ignored.

int bin = 0b1001_1010_0001_0100;


int hex = 0x1b_a0_44_fe;
int dec = 33_554_432;
int weird = 1_2__3___4____5_____6______7_______8________9;
double real = 1_000.111_1e-1_000;

Where the _ digit separator may not be used:

at the beginning of the value (_121)


at the end of the value (121_ or 121.05_)
next to the decimal (10_.0)
next to the exponent character (1.1e_1)
next to the type specifier (10_f)
immediately following the 0x or 0b in binary and hexadecimal literals (might be changed to allow e.g.
0b_1001_1000)

Section 20.6: Binary literals


The 0b prefix can be used to represent Binary literals.

[Link] – C# Notes for Professionals 230


Binary literals allow constructing numbers from zeroes and ones, which makes seeing which bits are set in the
binary representation of a number much easier. This can be useful for working with binary flags.

The following are equivalent ways of specifying an int with value 34 (=25 + 21):

// Using a binary literal:


// bits: 76543210
int a1 = 0b00100010; // binary: explicitly specify bits

// Existing methods:
int a2 = 0x22; // hexadecimal: every digit corresponds to 4 bits
int a3 = 34; // decimal: hard to visualise which bits are set
int a4 = (1 << 5) | (1 << 1); // bitwise arithmetic: combining non-zero bits

Flags enumerations

Before, specifying flag values for an enum could only be done using one of the three methods in this example:

[Flags]
public enum DaysOfWeek
{
// Previously available methods:
// decimal hex bit shifting
Monday = 1, // = 0x01 = 1 << 0
Tuesday = 2, // = 0x02 = 1 << 1
Wednesday = 4, // = 0x04 = 1 << 2
Thursday = 8, // = 0x08 = 1 << 3
Friday = 16, // = 0x10 = 1 << 4
Saturday = 32, // = 0x20 = 1 << 5
Sunday = 64, // = 0x40 = 1 << 6

Weekdays = Monday | Tuesday | Wednesday | Thursday | Friday,


Weekends = Saturday | Sunday
}

With binary literals it is more obvious which bits are set, and using them does not require understanding
hexadecimal numbers and bitwise arithmetic:

[Flags]
public enum DaysOfWeek
{
Monday = 0b00000001,
Tuesday = 0b00000010,
Wednesday = 0b00000100,
Thursday = 0b00001000,
Friday = 0b00010000,
Saturday = 0b00100000,
Sunday = 0b01000000,

Weekdays = Monday | Tuesday | Wednesday | Thursday | Friday,


Weekends = Saturday | Sunday
}

Section 20.7: throw expressions


C# 7.0 allows throwing as an expression in certain places:

class Person
{

[Link] – C# Notes for Professionals 231


public string Name { get; }

public Person(string name) => Name = name ?? throw new ArgumentNullException(nameof(name));

public string GetFirstName()


{
var parts = [Link](' ');
return ([Link] > 0) ? parts[0] : throw new InvalidOperationException("No name!");
}

public string GetLastName() => throw new NotImplementedException();


}

Prior to C# 7.0, if you wanted to throw an exception from an expression body you would have to:

var spoons = "dinner,desert,soup".Split(',');

var spoonsArray = [Link] > 0 ? spoons : null;

if (spoonsArray == null)
{
throw new Exception("There are no spoons");
}

Or

var spoonsArray = [Link] > 0


? spoons
: new Func<string[]>(() =>
{
throw new Exception("There are no spoons");
})();

In C# 7.0 the above is now simplified to:

var spoonsArray = [Link] > 0 ? spoons : throw new Exception("There are no spoons");

Section 20.8: Extended expression bodied members list


C# 7.0 adds accessors, constructors and finalizers to the list of things that can have expression bodies:

class Person
{
private static ConcurrentDictionary<int, string> names = new ConcurrentDictionary<int,
string>();

private int id = GetId();

public Person(string name) => [Link](id, name); // constructors

~Person() => [Link](id, out _); // finalizers

public string Name


{
get => names[id]; // getters
set => names[id] = value; // setters
}
}

[Link] – C# Notes for Professionals 232


Also see the out var declaration section for the discard operator.

Section 20.9: ref return and ref local


Ref returns and ref locals are useful for manipulating and returning references to blocks of memory instead of
copying memory without resorting to unsafe pointers.

Ref Return
public static ref TValue Choose<TValue>(
Func<bool> condition, ref TValue left, ref TValue right)
{
return condition() ? ref left : ref right;
}

With this you can pass two values by reference with one of them being returned based on some condition:

Matrix3D left = …, right = …;


Choose(chooser, ref left, ref right).M20 = 1.0;

Ref Local
public static ref int Max(ref int first, ref int second, ref int third)
{
ref int max = first > second ? ref first : ref second;
return max > third ? ref max : ref third;
}

int a = 1, b = 2, c = 3;
Max(ref a, ref b, ref c) = 4;
[Link](a == 1); // true
[Link](b == 2); // true
[Link](c == 4); // true

Unsafe Ref Operations

In [Link] a set of unsafe operations have been defined that allow you to
manipulate ref values as if they were pointers, basically.

For example, reinterpreting a memory address (ref) as a different type:

byte[] b = new byte[4] { 0x42, 0x42, 0x42, 0x42 };

ref int r = ref [Link]<byte, int>(ref b[0]);


[Link](0x42424242, r);

0x0EF00EF0;
[Link](0xFE, b[0] | b[1] | b[2] | b[3]);

Beware of endianness when doing this, though, e.g. check [Link] if needed and handle
accordingly.

Or iterate over an array in an unsafe manner:

int[] a = new int[] { 0x123, 0x234, 0x345, 0x456 };

ref int r1 = ref [Link](ref a[0], 1);


[Link](0x234, r1);

ref int r2 = ref [Link](ref r1, 2);

[Link] – C# Notes for Professionals 233


[Link](0x456, r2);

ref int r3 = ref [Link](ref r2, -3);


[Link](0x123, r3);

Or the similar Subtract:

string[] a = new string[] { "abc", "def", "ghi", "jkl" };

ref string r1 = ref [Link](ref a[0], -2);


[Link]("ghi", r1);

ref string r2 = ref [Link](ref r1, -1);


[Link]("jkl", r2);

ref string r3 = ref [Link](ref r2, 3);


[Link]("abc", r3);

Additionally, one can check if two ref values are the same i.e. same address:

long[] a = new long[2];

[Link]([Link](ref a[0], ref a[0]));


[Link]([Link](ref a[0], ref a[1]));

Links

Roslyn Github Issue

[Link] on github

Section 20.10: ValueTask<T>


Task<T> is a class and causes the unnecessary overhead of its allocation when the result is immediately available.

ValueTask<T> is a structure and has been introduced to prevent the allocation of a Task object in case the result of
the async operation is already available at the time of awaiting.

So ValueTask<T> provides two benefits:

1. Performance increase

Here's a Task<T> example:

Requires heap allocation


Takes 120ns with JIT

async Task<int> TestTask(int d)


{
await [Link](d);
return 10;
}

Here's the analog ValueTask<T> example:

No heap allocation if the result is known synchronously (which it is not in this case because of the
[Link], but often is in many real-world async/await scenarios)
Takes 65ns with JIT

[Link] – C# Notes for Professionals 234


async ValueTask<int> TestValueTask(int d)
{
await [Link](d);
return 10;
}

2. Increased implementation flexibility

Implementations of an async interface wishing to be synchronous would otherwise be forced to use either
[Link] or [Link] (resulting in the performance penalty discussed above). Thus there's some pressure
against synchronous implementations.

But with ValueTask<T>, implementations are more free to choose between being synchronous or asynchronous
without impacting callers.

For example, here's an interface with an asynchronous method:

interface IFoo<T>
{
ValueTask<T> BarAsync();
}

...and here's how that method might be called:

IFoo<T> thing = getThing();


var x = await [Link]();

With ValueTask, the above code will work with either synchronous or asynchronous implementations:

Synchronous implementation:
class SynchronousFoo<T> : IFoo<T>
{
public ValueTask<T> BarAsync()
{
var value = default(T);
return new ValueTask<T>(value);
}
}

Asynchronous implementation
class AsynchronousFoo<T> : IFoo<T>
{
public async ValueTask<T> BarAsync()
{
var value = default(T);
await [Link](1);
return value;
}
}

Notes

Although ValueTask struct was being planned to be added to C# 7.0, it has been kept as another library for the time
being. ValueTask<T> [Link] package can be downloaded from Nuget Gallery

[Link] – C# Notes for Professionals 235


Chapter 21: C# 6.0 Features
This sixth iteration of the C# language is provided by the Roslyn compiler. This compiler came out with version 4.6
of the .NET Framework, however it can generate code in a backward compatible manner to allow targeting earlier
framework versions. C# version 6 code can be compiled in a fully backwards compatible manner to .NET 4.0. It can
also be used for earlier frameworks, however some features that require additional framework support may not
function correctly.

Section 21.1: Exception filters


Exception filters give developers the ability to add a condition (in the form of a boolean expression) to a catch block,
allowing the catch to execute only if the condition evaluates to true.

Exception filters allow the propagation of debug information in the original exception, where as using an if
statement inside a catch block and re-throwing the exception stops the propagation of debug information in the
original exception. With exception filters, the exception continues to propagate upwards in the call stack unless the
condition is met. As a result, exception filters make the debugging experience much easier. Instead of stopping on
the throw statement, the debugger will stop on the statement throwing the exception, with the current state and all
local variables preserved. Crash dumps are affected in a similar way.

Exception filters have been supported by the CLR since the beginning and they've been accessible from
[Link] and F# for over a decade by exposing a part of the CLR's exception handling model. Only after the
release of C# 6.0 has the functionality also been available for C# developers.

Using exception filters

Exception filters are utilized by appending a when clause to the catch expression. It is possible to use any
expression returning a bool in a when clause (except await). The declared Exception variable ex is accessible from
within the when clause:

var SqlErrorToIgnore = 123;


try
{
DoSQLOperations();
}
catch (SqlException ex) when ([Link] != SqlErrorToIgnore)
{
throw new Exception("An error occurred accessing the database", ex);
}

Multiple catch blocks with when clauses may be combined. The first when clause returning true will cause the
exception to be caught. Its catch block will be entered, while the other catch clauses will be ignored (their when
clauses won't be evaluated). For example:

try
{ ... }
catch (Exception ex) when (someCondition) //If someCondition evaluates to true,
//the rest of the catches are ignored.
{ ... }
catch (NotImplementedException ex) when (someMethod()) //someMethod() will only run if
//someCondition evaluates to false
{ ... }

[Link] – C# Notes for Professionals 236


catch(Exception ex) // If both when clauses evaluate to false
{ ... }

Risky when clause

Caution

It can be risky to use exception filters: when an Exception is thrown from within the when clause, the
Exception from the when clause is ignored and is treated as false. This approach allows developers to
write when clause without taking care of invalid cases.

The following example illustrates such a scenario:

public static void Main()


{
int a = 7;
int b = 0;
try
{
DoSomethingThatMightFail();
}
catch (Exception ex) when (a / b == 0)
{
// This block is never reached because a / b throws an ignored
// DivideByZeroException which is treated as false.
}
catch (Exception ex)
{
// This block is reached since the DivideByZeroException in the
// previous when clause is ignored.
}
}

public static void DoSomethingThatMightFail()


{
// This will always throw an ArgumentNullException.
[Link](null);
}

View Demo

Note that exception filters avoid the confusing line number problems associated with using throw when failing code
is within the same function. For example in this case the line number is reported as 6 instead of 3:

1. int a = 0, b = 0;
2. try {
3. int c = a / b;
4. }
5. catch (DivideByZeroException) {
6. throw;
7. }

The exception line number is reported as 6 because the error was caught and re-thrown with the throw statement
on line 6.

The same does not happen with exception filters:

[Link] – C# Notes for Professionals 237


1. int a = 0, b = 0;
2. try {
3. int c = a / b;
4. }
5. catch (DivideByZeroException) when (a != 0) {
6. throw;
7. }

In this example a is 0 then catch clause is ignored but 3 is reported as line number. This is because they do not
unwind the stack. More specifically, the exception is not caught on line 5 because a in fact does equal 0 and thus
there is no opportunity for the exception to be re-thrown on line 6 because line 6 does not execute.

Logging as a side effect

Method calls in the condition can cause side effects, so exception filters can be used to run code on exceptions
without catching them. A common example that takes advantage of this is a Log method that always returns false.
This allows tracing log information while debugging without the need to re-throw the exception.

Be aware that while this seems to be a comfortable way of logging, it can be risky, especially if 3rd party
logging assemblies are used. These might throw exceptions while logging in non-obvious situations that
may not be detected easily (see Risky when(...) clause above).

try
{
DoSomethingThatMightFail(s);
}
catch (Exception ex)

(Log(ex, "An error occurred")) { // This catch block will never be reached } // ... static bool Log(Exception ex, string
message, params object[] args) { [Link](message, args); return false; }

View Demo

The common approach in previous versions of C# was to log and re-throw the exception.

Version < 6.0


try
{
DoSomethingThatMightFail(s);
}
catch (Exception ex)
{
Log(ex, "An error occurred");
throw;
}

// ...

static void Log(Exception ex, string message, params object[] args)


{
[Link](message, args);
}

View Demo

[Link] – C# Notes for Professionals 238


The finally block

The finally block executes every time whether the exception is thrown or not. One subtlety with expressions in
when is exception filters are executed further up the stack before entering the inner finally blocks. This can cause
unexpected results and behaviors when code attempts to modify global state (like the current thread's user or
culture) and set it back in a finally block.

Example: finally block


private static bool Flag = false;

static void Main(string[] args)


{
[Link]("Start");
try
{
SomeOperation();
}
catch (Exception) when (EvaluatesTo())
{
[Link]("Catch");
}
finally
{
[Link]("Outer Finally");
}
}

private static bool EvaluatesTo()


{
[Link]($"EvaluatesTo: {Flag}");
return true;
}

private static void SomeOperation()


{
try
{
Flag = true;
throw new Exception("Boom");
}
finally
{
Flag = false;
[Link]("Inner Finally");
}
}

Produced Output:

Start
EvaluatesTo: True
Inner Finally
Catch
Outer Finally

View Demo

[Link] – C# Notes for Professionals 239


In the example above, if the method SomeOperation does not wish to "leak" the global state changes to caller's when
clauses, it should also contain a catch block to modify the state. For example:

private static void SomeOperation()


{
try
{
Flag = true;
throw new Exception("Boom");
}
catch
{
Flag = false;
throw;
}
finally
{
Flag = false;
[Link]("Inner Finally");
}
}

It is also common to see IDisposable helper classes leveraging the semantics of using blocks to achieve the same
goal, as [Link] will always be called before an exception called within a using block starts bubbling
up the stack.

Section 21.2: String interpolation


String interpolation allows the developer to combine variables and text to form a string.

Basic Example

Two int variables are created: foo and bar.

int foo = 34;


int bar = 42;

string resultString = $"The foo is {foo}, and the bar is {bar}.";

[Link](resultString);

Output:

The foo is 34, and the bar is 42.

View Demo

Braces within strings can still be used, like this:

var foo = 34;


var bar = 42;

// String interpolation notation (new style)


[Link]($"The foo is

o}}, and the bar is {{bar}}.");

[Link] – C# Notes for Professionals 240


This produces the following output:

The foo is {foo}, and the bar is {bar}.

Using interpolation with verbatim string literals

Using @ before the string will cause the string to be interpreted verbatim. So, e.g. Unicode characters or line breaks
will stay exactly as they've been typed. However, this will not effect the expressions in an interpolated string as
shown in the following example:

[Link]($@"In case it wasn't clear:


\u00B9
The foo
is

}, and the bar is {bar}."); Output:

In case it wasn't clear:


\u00B9
The foo
is 34,
and the bar
is 42.

View Demo

Expressions

With string interpolation, expressions within curly braces {} can also be evaluated. The result will be inserted at the
corresponding location within the string. For example, to calculate the maximum of foo and bar and insert it, use
[Link] within the curly braces:[Link]($"And the greater one is: [Link](foo, bar) }");

Output:

And the greater one is: 42

Note: Any leading or trailing whitespace (including space, tab and CRLF/newline) between the curly brace and the
expression is completely ignored and not included in the output

View Demo

As another example, variables can be formatted as a currency:[Link]($"Foo formatted as a


currency to 4 decimal places: :c4}");

Output:

Foo formatted as a currency to 4 decimal places: $34.0000

[Link] – C# Notes for Professionals 241


View Demo

Or they can be formatted as dates:[Link]($"Today is: [Link]:dddd, MMMM dd - yyyy}");

Output:

Today is: Monday, July, 20 - 2015

View Demo

Statements with a Conditional (Ternary) Operator can also be evaluated within the interpolation. However, these
must be wrapped in parentheses, since the colon is otherwise used to indicate formatting as shown above:

[Link]($"{(foo > bar ? "Foo is larger than bar!" : "Bar is larger than foo!")}");

Output:

Bar is larger than foo!

View Demo

Conditional expressions and format specifiers can be mixed:

[Link]($"Environment: {(Environment.Is64BitProcess ? 64 : 32):00'-bit'} process");

Output:

Environment: 32-bit process

Escape sequences

Escaping backslash (\) and quote (") characters works exactly the same in interpolated strings as in non-
interpolated strings, for both verbatim and non-verbatim string literals:

[Link]($"Foo is: }. In a non-verbatim string, we need to escape \" and \\ with backslashes.");
[Link]($@"Foo is: {foo}. In a verbatim string, we need to escape "" with an extra quote, but we don't
need to escape \");

Output:

Foo is 34. In a non-verbatim string, we need to escape " and \ with backslashes.
Foo is 34. In a verbatim string, we need to escape " with an extra quote, but we don't need to escape \

To include a curly brace { or } in an interpolated string, use two curly braces {{ or }}:$"{{foo}} is: }"

Output:

{foo} is: 34

[Link] – C# Notes for Professionals 242


View Demo

FormattableString type

The type of a $"..." string interpolation expression is not always a simple string. The compiler decides which type
to assign depending on the context:string s = $"hello, e}"; [Link] s = $"Hello, {name}";
[Link] s = $"Hello, {name}";

This is also the order of type preference when the compiler needs to choose which overloaded method is going to
be called.

A new type, [Link], represents a composite format string, along with the arguments to be
formatted. Use this to write applications that handle the interpolation arguments specifically:

public void AddLogItem(FormattableString formattableString)


{
foreach (var arg in [Link]())
{
// do something to interpolation argument 'arg'
}

// use the standard interpolation and the current culture info


// to get an ordinary String:
var formatted = [Link]();

// ...
}

Call the above method with:AddLogItem($"The foo is }, and the bar is {bar}."); For example, one could choose not
to incur the performance cost of formatting the string if the logging level was already going to filter out the log item.

Implicit conversions

There are implicit type conversions from an interpolated string:var s = $"Foo: }"; [Link] s = $"Foo:
{foo}"; You can also produce an IFormattable variable that allows you to convert the string with invariant
context:var s = $"Bar: }"; [Link] s = $"Bar: {bar}";

Current and Invariant Culture Methods

If code analysis is turned on, interpolated strings will all produce warning CA1305 (Specify IFormatProvider). A
static method may be used to apply current culture.

public static class Culture


{
public static string Current(FormattableString formattableString)
{
return formattableString?.ToString([Link]);
}
public static string Invariant(FormattableString formattableString)
{
return formattableString?.ToString([Link]);
}
}

Then, to produce a correct string for the current culture, just use the expression:[Link]($"interpolated
eof(string).Name} string.") [Link]($"interpolated {typeof(string).Name} string.") Note: Current and

[Link] – C# Notes for Professionals 243


Invariant cannot be created as extension methods because, by default, the compiler assigns type String to
interpolated string expression which causes the following code to fail to compile:

$"interpolated {typeof(string).Name} string.".Current();

FormattableString class already contains Invariant() method, so the simplest way of switching to invariant
culture is by relying on using static:using static [Link];p>string invariant =
Invariant($"Now = {[Link]}"); string current = $"Now = {[Link]}";

Behind the scenes

Interpolated strings are just a syntactic sugar for [Link](). The compiler (Roslyn) will turn it into a
[Link] behind the scenes:

var text = $"Hello {name + lastName}";

The above will be converted to something like this:

string text = [Link]("Hello {0}", new object[] {


name + lastName
});

String Interpolation and Linq

It's possible to use interpolated strings in Linq statements to increase readability further.

var fooBar = (from DataRow x in [Link]


select [Link]("{0}{1}", x["foo"], x["bar"])).ToList();

Can be re-written as:

var fooBar = (from DataRow x in [Link]


select $"{x["foo"]}{x["bar"]}").ToList();

Reusable Interpolated Strings

With [Link], you can create reusable format strings:

public const string ErrorFormat = "Exception caught:\r\n{0}";

// ...

[Link]([Link](ErrorFormat, ex));

Interpolated strings, however, will not compile with placeholders referring to non-existent variables. The following
will not compile:

public const string ErrorFormat = $"Exception caught:\r\n{error}";


// CS0103: The name 'error' does not exist in the current context

Instead, create a Func<> which consumes variables and returns a String:

public static Func<Exception, string> FormatError =


error => $"Exception caught:\r\n{error}";

// ...

[Link] – C# Notes for Professionals 244


[Link](FormatError(ex));

String interpolation and localization

If you’re localizing your application you may wonder if it is possible to use string interpolation along with
localization. Indeed, it would be nice to have the possibility to store in resource files Strings like:"My name is e}
{middlename} {surname}" instead of the much less readable:

"My name is {0} {1} {2}"

String interpolation process occurs at compile time, unlike formatting string with [Link] which occurs at
runtime. Expressions in an interpolated string must reference names in the current context and need to be stored
in resource files. That means that if you want to use localization you have to do it like:

var FirstName = "John";

// method using different resource file "strings"


// for French ("[Link]"), German ("[Link]"),
// and English ("[Link]")
void ShowMyNameLocalized(string name, string middlename = "", string surname = "")
{
// get localized string
var localizedMyNameIs = [Link];
// insert spaces where necessary
name = ([Link](name) ? "" : name + " ");
middlename = ([Link](middlename) ? "" : middlename + " ");
surname = ([Link](surname) ? "" : surname + " ");
// display it
[Link]($"{localizedMyNameIs} {name}{middlename}{surname}".Trim());
}

// switch to French and greet John


[Link] = [Link]("fr-FR");
ShowMyNameLocalized(FirstName);

// switch to German and greet John


[Link] = [Link]("de-DE");
ShowMyNameLocalized(FirstName);

// switch to US English and greet John


[Link] = [Link]("en-US");
ShowMyNameLocalized(FirstName);

If the resource strings for the languages used above are correctly stored in the individual resource files, you should
get the following output:

Bonjour, mon nom est John


Hallo, mein Name ist John
Hello, my name is John

Note that this implies that the name follows the localized string in every language. If that is not the case, you need
to add placeholders to the resource strings and modify the function above or you need to query the culture info in
the function and provide a switch case statement containing the different cases. For more details about resource
files, see How to use localization in C#.

[Link] – C# Notes for Professionals 245


It is a good practice to use a default fallback language most people will understand, in case a translation is not
available. I suggest to use English as default fallback language.

Recursive interpolation

Although not very useful, it is allowed to use an interpolated string recursively inside another's curly brackets:

[Link]($"String has {$"My class is called {nameof(MyClass)}.".Length} chars:");


[Link]($"My class is called {nameof(MyClass)}.");

Output:

String has 27 chars:

My class is called MyClass.

Section 21.3: Auto-property initializers


Introduction

Properties can be initialized with the = operator after the closing }. The Coordinate class below shows the available
options for initializing a property:

Version ≥ 6.0
public class Coordinate
{
public int X { get; set; } = 34; // get or set auto-property with initializer

public int Y { get; } = 89; // read-only auto-property with initializer


}

Accessors With Different Visibility

You can initialize auto-properties that have different visibility on their accessors. Here’s an example with a
protected setter:

public string Name { get; protected set; } = "Cheeze";

The accessor can also be internal, internal protected, or private.

Read-Only Properties

In addition to flexibility with visibility, you can also initialize read-only auto-properties. Here’s an example:

public List<string> Ingredients { get; } =


new List<string> { "dough", "sauce", "cheese" };

This example also shows how to initialize a property with a complex type. Also, auto-properties can’t be write-only,
so that also precludes write-only initialization.

[Link] – C# Notes for Professionals 246


Old style (pre C# 6.0)

Before C# 6, this required much more verbose code. We were using one extra variable called backing property for
the property to give default value or to initialize the public property like below,

Version < 6.0


public class Coordinate
{
private int _x = 34;
public int X { get { return _x; } set { _x = value; } }

private readonly int _y = 89;


public int Y { get { return _y; } }

private readonly int _z;


public int Z { get { return _z; } }

public Coordinate()
{
_z = 42;
}
}

Note: Before C# 6.0, you could still initialize read and write auto implemented properties (properties with a getter and a
setter) from within the constructor, but you could not initialize the property inline with its declaration

View Demo

Usage

Initializers must evaluate to static expressions, just like field initializers. If you need to reference non-static
members, you can either initialize properties in constructors like before, or use expression-bodied properties. Non-
static expressions, like the one below (commented out), will generate a compiler error:

// public decimal X { get; set; } = InitMe(); // generates compiler error

decimal InitMe() { return 4m; }

But static methods can be used to initialize auto-properties:

public class Rectangle


{
public double Length { get; set; } = 1;
public double Width { get; set; } = 1;
public double Area { get; set; } = CalculateArea(1, 1);

public static double CalculateArea(double length, double width)


{
return length * width;
}
}

This method can also be applied to properties with different level of accessors:

public short Type { get; private set; } = 15;

The auto-property initializer allows assignment of properties directly within their declaration. For read-only

[Link] – C# Notes for Professionals 247


properties, it takes care of all the requirements required to ensure the property is immutable. Consider, for
example, the FingerPrint class in the following example:

public class FingerPrint


{
public DateTime TimeStamp { get; } = [Link];

public string User { get; } =


[Link];

public string Process { get; } =


[Link]().ProcessName;
}

View Demo

Cautionary notes

Take care to not confuse auto-property or field initializers with similar-looking expression-body methods which
make use of => as opposed to =, and fields which do not include { get; }.

For example, each of the following declarations are different.

public class UserGroupDto


{
// Read-only auto-property with initializer:
public ICollection<UserDto> Users1 { get; } = new HashSet<UserDto>();

// Read-write field with initializer:


public ICollection<UserDto> Users2 = new HashSet<UserDto>();

// Read-only auto-property with expression body:


public ICollection<UserDto> Users3 => new HashSet<UserDto>();
}

Missing { get; } in the property declaration results in a public field. Both read-only auto-property Users1 and
read-write field Users2 are initialized only once, but a public field allows changing collection instance from outside
the class, which is usually undesirable. Changing a read-only auto-property with expression body to read-only
property with initializer requires not only removing > from =>, but adding { get; }.

The different symbol (=> instead of =) in Users3 results in each access to the property returning a new instance of
the HashSet<UserDto> which, while valid C# (from the compiler's point of view) is unlikely to be the desired
behavior when used for a collection member.

The above code is equivalent to:

public class UserGroupDto


{
// This is a property returning the same instance
// which was created when the UserGroupDto was instantiated.
private ICollection<UserDto> _users1 = new HashSet<UserDto>();
public ICollection<UserDto> Users1 { get { return _users1; } }

// This is a field returning the same instance


// which was created when the UserGroupDto was instantiated.
public virtual ICollection<UserDto> Users2 = new HashSet<UserDto>();

[Link] – C# Notes for Professionals 248


// This is a property which returns a new HashSet<UserDto> as
// an ICollection<UserDto> on each call to it.
public ICollection<UserDto> Users3 { get { return new HashSet<UserDto>(); } }
}

Section 21.4: Null propagation


The ?. operator and ?[...] operator are called the null-conditional operator. It is also sometimes referred to by
other names such as the safe navigation operator.

This is useful, because if the . (member accessor) operator is applied to an expression that evaluates to null, the
program will throw a NullReferenceException. If the developer instead uses the ?. (null-conditional) operator, the
expression will evaluate to null instead of throwing an exception.

Note that if the ?. operator is used and the expression is non-null, ?. and . are equivalent.

Basics
var teacherName = [Link]().Name;
// throws NullReferenceException if GetTeacher() returns null

View Demo

If the classroom does not have a teacher, GetTeacher() may return null. When it is null and the Name property is
accessed, a NullReferenceException will be thrown.

If we modify this statement to use the ?. syntax, the result of the entire expression will be null:

var teacherName = [Link]()?.Name;


// teacherName is null if GetTeacher() returns null

View Demo

Subsequently, if classroom could also be null, we could also write this statement as:

var teacherName = classroom?.GetTeacher()?.Name;


// teacherName is null if GetTeacher() returns null OR classroom is null

View Demo

This is an example of short-circuiting: When any conditional access operation using the null-conditional operator
evaluates to null, the entire expression evaluates to null immediately, without processing the rest of the chain.

When the terminal member of an expression containing the null-conditional operator is of a value type, the
expression evaluates to a Nullable<T> of that type and so cannot be used as a direct replacement for the
expression without ?..

bool hasCertification = [Link]().HasCertification;


// compiles without error but may throw a NullReferenceException at runtime

bool hasCertification = classroom?.GetTeacher()?.HasCertification;


// compile time error: implicit conversion from bool? to bool not allowed

bool? hasCertification = classroom?.GetTeacher()?.HasCertification;


// works just fine, hasCertification will be null if any part of the chain is null

[Link] – C# Notes for Professionals 249


bool hasCertification = classroom?.GetTeacher()?.[Link]();
// must extract value from nullable to assign to a value type variable

Use with the Null-Coalescing Operator (??)

You can combine the null-conditional operator with the Null-coalescing Operator (??) to return a default value if the
expression resolves to null. Using our example above:

var teacherName = classroom?.GetTeacher()?.Name ?? "No Name";


// teacherName will be "No Name" when GetTeacher()
// returns null OR classroom is null OR Name is null

Use with Indexers

The null-conditional operator can be used with indexers:

var firstStudentName = classroom?.Students?[0]?.Name;

In the above example:

The first ?. ensures that classroom is not null.


The second ? ensures that the entire Students collection is not null.
The third ?. after the indexer ensures that the [0] indexer did not return a null object. It should be noted
that this operation can still throw an I