100% found this document useful (5 votes)
1K views1,008 pages

Csharp Language PDF

Uploaded by

Pralay Biswas
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 (5 votes)
1K views1,008 pages

Csharp Language PDF

Uploaded by

Pralay Biswas
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
You are on page 1/ 1008

C# Language

#c#
Table of Contents
About 1

Chapter 1: Getting started with C# Language 2

Remarks 2

Versions 2

Examples 2

Creating a new console application (Visual Studio) 2

Explanation 3

Using the command line 3

Creating a new project in Visual Studio (console application) and Running it in Debug mode 5

Creating a new program using Mono 9

Creating a new program using .NET Core 10

Command Prompt output 11

Creating a new query using LinqPad 11

Creating a new project using Xamarin Studio 15

Chapter 2: .NET Compiler Platform (Roslyn) 22

Examples 22

Create workspace from MSBuild project 22

Syntax tree 22

Semantic model 22

Chapter 3: Access Modifiers 24

Remarks 24

Examples 24

public 24

private 24

internal 25

protected 25

protected internal 26

Access Modifiers Diagrams 28

Chapter 4: Access network shared folder with username and password 30

Introduction 30
Examples 30

Code to access network shared file 30

Chapter 5: Accessing Databases 33

Examples 33

ADO.NET Connections 33

Common Data Provider Classes 33

Common Access Pattern for ADO.NET Connections 33

Entity Framework Connections 34

Executing Entity Framework Queries 35

Connection Strings 35

Storing Your Connection String 36

Different Connections for Different Providers 36

Chapter 6: Action Filters 37

Examples 37

Custom Action Filters 37

Chapter 7: Aliases of built-in types 39

Examples 39

Built-In Types Table 39

Chapter 8: An overview of c# collections 41

Examples 41

HashSet 41

SortedSet 41

T[ ] (Array of T) 41

List 42

Dictionary 42

Duplicate key when using collection initialization 43

Stack 43

LinkedList 43

Queue 44

Chapter 9: Anonymous types 45

Examples 45
Creating an anonymous type 45

Anonymous vs dynamic 45

Generic methods with anonymous types 46

Instantiating generic types with anonymous types 46

Anonymous type equality 46

Implicitly typed arrays 47

Chapter 10: Arrays 48

Syntax 48

Remarks 48

Examples 48

Array covariance 49

Getting and setting array values 49

Declaring an array 49

Iterate over an array 50

Multi-dimensional arrays 51

Jagged arrays 51

Checking if one array contains another array 52

Initializing an array filled with a repeated non-default value 53

Copying arrays 54

Creating an array of sequential numbers 54

Usage: 55

Comparing arrays for equality 55

Arrays as IEnumerable<> instances 55

Chapter 11: ASP.NET Identity 57

Introduction 57

Examples 57

How to implement password reset token in asp.net identity using user manager. 57

Chapter 12: AssemblyInfo.cs Examples 61

Remarks 61

Examples 61

[AssemblyTitle] 61

[AssemblyProduct] 61
Global and local AssemblyInfo 61

[AssemblyVersion] 62

Reading Assembly Attributes 62

Automated versioning 62

Common fields 63

[AssemblyConfiguration] 63

[InternalsVisibleTo] 63

[AssemblyKeyFile] 64

Chapter 13: Async/await, Backgroundworker, Task and Thread Examples 65

Remarks 65

Examples 65

ASP.NET Configure Await 65

Blocking 65

ConfigureAwait 66

Async/await 67

BackgroundWorker 68

Task 69

Thread 70

Task "run and forget" extension 71

Chapter 14: Async-Await 72

Introduction 72

Remarks 72

Examples 72

Simple consecutive calls 72

Try/Catch/Finally 72

Web.config setup to target 4.5 for correct async behaviour. 73

Concurrent calls 74

Await operator and async keyword 75

Returning a Task without await 76

Blocking on async code can cause deadlocks 77

Async/await will only improve performance if it allows the machine to do additional work 78

Chapter 15: Asynchronous Socket 80


Introduction 80

Remarks 80

Examples 81

Asynchronous Socket (Client / Server) example. 81

Chapter 16: Attributes 89

Examples 89

Creating a custom attribute 89

Using an attribute 89

Reading an attribute 89

DebuggerDisplay Attribute 90

Caller info attributes 91

Reading an attribute from interface 92

Obsolete Attribute 93

Chapter 17: BackgroundWorker 94

Syntax 94

Remarks 94

Examples 94

Assigning Event Handlers to a BackgroundWorker 94

Assigning Properties to a BackgroundWorker 95

Creating a new BackgroundWorker instance 95

Using a BackgroundWorker to complete a task. 96

The result is the following... 97

Chapter 18: BigInteger 98

Remarks 98

When To Use 98

Alternatives 98

Examples 98

Calculate the First 1,000-Digit Fibonacci Number 98

Chapter 19: Binary Serialization 100

Remarks 100

Examples 100

Making an object serializable 100


Controlling serialization behavior with attributes 100

Adding more control by implementing ISerializable 101

Serialization surrogates (Implementing ISerializationSurrogate) 102

Serialization Binder 104

Some gotchas in backward compatibility 106

Chapter 20: BindingList 109

Examples 109

Avoiding N*2 iteration 109

Add item to list 109

Chapter 21: Built-in Types 110

Examples 110

Immutable reference type - string 110

Value type - char 110

Value type - short, int, long (signed 16 bit, 32 bit, 64 bit integers) 110

Value type - ushort, uint, ulong (unsigned 16 bit, 32 bit, 64 bit integers) 111

Value type - bool 111

Comparisons with boxed value types 112

Conversion of boxed value types 112

Chapter 22: C# 3.0 Features 113

Remarks 113

Examples 113

Implicitly typed variables (var) 113

Language Integrated Queries (LINQ) 113

Lambda expresions 114

Anonymous types 115

Chapter 23: C# 4.0 Features 117

Examples 117

Optional parameters and named arguments 117

Variance 118

Optional ref keyword when using COM 118

Dynamic member lookup 118

Chapter 24: C# 5.0 Features 120


Syntax 120

Parameters 120

Remarks 120

Examples 120

Async & Await 120

Caller Information Attributes 122

Chapter 25: C# 6.0 Features 123

Introduction 123

Remarks 123

Examples 123

Operator nameof 123

Workaround for previous versions (more detail) 124

Expression-bodied function members 125

Properties 125

Indexers 125

Methods 126

Operators 126

Limitations 127

Exception filters 127

Using exception filters 128

Risky when clause 128

Logging as a side effect 130

The finally block 131

Example: finally block 131

Auto-property initializers 132

Introduction 132

Accessors With Different Visibility 132

Read-Only Properties 133

Old style (pre C# 6.0) 133

Usage 133

Cautionary notes 134


Index initializers 135

String interpolation 137

Basic Example 137

Using interpolation with verbatim string literals 138

Expressions 138

Escape sequences 140

FormattableString type 140

Implicit conversions 141

Current and Invariant Culture Methods 141

Behind the scenes 142

String Interpolation and Linq 142

Reusable Interpolated Strings 143

String interpolation and localization 143

Recursive interpolation 144

Await in catch and finally 145

Null propagation 146

Basics 146

Use with the Null-Coalescing Operator (??) 147

Use with Indexers 147

Use with void Functions 147

Use with Event Invocation 148

Limitations 148

Gotchas 148

Using static type 150

Improved overload resolution 150

Minor changes and bugfixes 151

Using an extension method for collection initialization 152

Disable Warnings Enhancements 153

Chapter 26: C# 7.0 Features 154

Introduction 154
Examples 154

out var declaration 154

Example 154

Limitations 155

References 156

Binary literals 156

Flags enumerations 156

Digit separators 157

Language support for Tuples 157

Basics 157

Tuple Deconstruction 158

Tuple Initialization 159

h11 160

Type inference 160

Reflection and Tuple Field Names 160

Use with generics and async 160

Use with collections 161

Differences between ValueTuple and Tuple 162

References 162

Local functions 162

Example 162

Example 163

Example 163

Pattern Matching 164

switch expression 164

is expression 165

Example 165

ref return and ref local 166

Ref Return 166

Ref Local 166


Unsafe Ref Operations 166

Links 167

throw expressions 167

Extended expression bodied members list 168

ValueTask 169

1. Performance increase 169

2. Increased implementation flexibility 169

Synchronous implementation: 170

Asynchronous implementation 170

Notes 170

Chapter 27: C# Authentication handler 172

Examples 172

Authentication handler 172

Chapter 28: C# Script 174

Examples 174

Simple code evaluation 174

Chapter 29: Caching 175

Examples 175

MemoryCache 175

Chapter 30: Casting 176

Remarks 176

Examples 176

Cast an object to a base type 176

Explicit Casting 177

Safe Explicit Casting (`as` operator) 177

Implicit Casting 177

Checking compatibility without casting 177

Explicit Numeric Conversions 178

Conversion Operators 178

LINQ Casting operations 179

Chapter 31: Checked and Unchecked 181


Syntax 181

Examples 181

Checked and Unchecked 181

Checked and Unchecked as a scope 181

Chapter 32: CLSCompliantAttribute 182

Syntax 182

Parameters 182

Remarks 182

Examples 182

Access Modifier to which CLS rules apply 182

Violation of CLS rule: Unsigned types / sbyte 183

Violation of CLS rule: Same naming 184

Violation of CLS rule: Identifier _ 184

Violation of CLS rule: Inherit from non CLSComplaint class 185

Chapter 33: Code Contracts 186

Syntax 186

Remarks 186

Examples 186

Preconditions 186

Postconditions 187

Invariants 187

Defining Contracts on Interface 188

Chapter 34: Code Contracts and Assertions 191

Examples 191

Assertions to check logic should always be true 191

Chapter 35: Collection Initializers 192

Remarks 192

Examples 192

Collection initializers 192

C# 6 Index Initializers 192

Dictionary Initialization 193

Collection initializers in custom classes 194


Collection Initializers with Parameter Arrays 194

Using collection initializer inside object initializer 195

Chapter 36: Comments and regions 197

Examples 197

Comments 197

Single line comments 197

Multi line or delimited comments 197

Regions 198

Documentation comments 199

Chapter 37: Common String Operations 201

Examples 201

Splitting a String by specific character 201

Getting Substrings of a given string 201

Determine whether a string begins with a given sequence 201

Trimming Unwanted Characters Off the Start and/or End of Strings. 201

String.Trim() 201

String.TrimStart() and String.TrimEnd() 202

Formatting a string 202

Joining an array of strings into a new one 202

Padding a string to a fixed length 202

Construct a string from Array 202

Formatting using ToString 203

Getting x characters from the right side of a string 203

Checking for empty String using String.IsNullOrEmpty() and String.IsNullOrWhiteSpace() 205

Getting a char at specific index and enumerating the string 206

Convert Decimal Number to Binary,Octal and Hexadecimal Format 206

Splitting a String by another string 207

Correctly reversing a string 207

Replacing a string within a string 209

Changing the case of characters within a String 209

Concatenate an array of strings into a single string 209

String Concatenation 210


Chapter 38: Conditional Statements 211

Examples 211

If-Else Statement 211

If-Else If-Else Statement 211

Switch statements 212

If statement conditions are standard boolean expressions and values 213

Chapter 39: Constructors and Finalizers 215

Introduction 215

Remarks 215

Examples 215

Default Constructor 215

Calling a constructor from another constructor 216

Static constructor 217

Calling the base class constructor 218

Finalizers on derived classes 219

Singleton constructor pattern 219

Forcing a static constructor to be called 220

Calling virtual methods in constructor 220

Generic Static Constructors 221

Exceptions in static constructors 221

Constructor and Property Initialization 222

Chapter 40: Creating a Console Application using a Plain-Text Editor and the C# Compiler ( 225

Examples 225

Creating a Console application using a Plain-Text Editor and the C# Compiler 225

Saving the Code 225

Compiling the Source Code 225

Chapter 41: Creating Own MessageBox in Windows Form Application 227

Introduction 227

Syntax 227

Examples 227

Creating Own MessageBox Control. 227

How to use own created MessageBox control in another Windows Form application. 229
Chapter 42: Creational Design Patterns 231

Remarks 231

Examples 231

Singleton Pattern 231

Factory Method pattern 233

Builder Pattern 235

Prototype Pattern 239

Abstract Factory Pattern 241

Chapter 43: Cryptography (System.Security.Cryptography) 245

Examples 245

Modern Examples of Symmetric Authenticated Encryption of a string 245

Introduction to Symmetric and Asymmetric Encryption 256

Symmetric Encryption 257

Asymmetric Encryption 257

Password Hashing 258

Simple Symmetric File Encryption 258

Cryptographically Secure Random Data 259

Fast Asymmetric File Encryption 260

Chapter 44: Data Annotation 266

Examples 266

DisplayNameAttribute (display attribute) 266

EditableAttribute (data modeling attribute) 267

Validation Attributes 269

Example: RequiredAttribute 269

Example: StringLengthAttribute 269

Example: RangeAttribute 269

Example: CustomValidationAttribute 270

Creating a custom validation attribute 270

Data Annotation Basics 271

Usage 271

Manually Execute Validation Attributes 271

Validation Context 271


Validate an Object and All of its Properties 272

Validate a Property of an Object 272

And More 272

Chapter 45: DateTime Methods 273

Examples 273

DateTime.Add(TimeSpan) 273

DateTime.AddDays(Double) 273

DateTime.AddHours(Double) 273

DateTime.AddMilliseconds(Double) 273

DateTime.Compare(DateTime t1, DateTime t2 ) 274

DateTime.DaysInMonth(Int32,Int32) 274

DateTime.AddYears(Int32) 274

Pure functions warning when dealing with DateTime 275

DateTime.Parse(String) 275

DateTime.TryParse(String, DateTime) 275

Parse and TryParse with culture info 276

DateTime as initializer in for-loop 276

DateTime ToString, ToShortDateString, ToLongDateString and ToString formatted 276

Current Date 277

DateTime Formating 277

DateTime.ParseExact(String,String,IFormatProvider) 278

DateTime.TryParseExact(String,String,IFormatProvider,DateTimeStyles,DateTime) 279

Chapter 46: Delegates 282

Remarks 282

Summary 282

In-built delegate types: Action<...>, Predicate<T> and Func<...,TResult> 282

Custom delegate types 282

Invoking delegates 282

Assigning to delegates 282

Combining delegates 282

Examples 283

Underlying references of named method delegates 283


Declaring a delegate type 283

The Func, Action and Predicate delegate types 285

Assigning a named method to a delegate 286

Delegate Equality 286

Assigning to a delegate by lambda 286

Passing delegates as parameters 287

Combine Delegates (Multicast Delegates) 287

Safe invoke multicast delegate 289

Closure inside a delegate 290

Encapsulating transformations in funcs 290

Chapter 47: Dependency Injection 292

Remarks 292

Examples 292

Dependency injection using MEF 292

Dependency Injection C# and ASP.NET with Unity 294

Chapter 48: Diagnostics 298

Examples 298

Debug.WriteLine 298

Redirecting log output with TraceListeners 298

Chapter 49: Dynamic type 299

Remarks 299

Examples 299

Creating a dynamic variable 299

Returning dynamic 299

Creating a dynamic object with properties 300

Handling Specific Types Unknown at Compile Time 300

Chapter 50: Enum 302

Introduction 302

Syntax 302

Remarks 302

Examples 302

Get all the members values of an enum 302


Enum as flags 303

Test flags-style enum values with bitwise logic 305

Enum to string and back 305

Default value for enum == ZERO 306

Enum basics 307

Bitwise Manipulation using enums 308

Using << notation for flags 308

Adding additional description information to an enum value 309

Add and remove values from flagged enum 310

Enums can have unexpected values 310

Chapter 51: Equality Operator 312

Examples 312

Equality kinds in c# and equality operator 312

Chapter 52: Equals and GetHashCode 313

Remarks 313

Examples 313

Default Equals behavior. 313

Writing a good GetHashCode override 314

Override Equals and GetHashCode on custom types 315

Equals and GetHashCode in IEqualityComparator 316

Chapter 53: Events 318

Introduction 318

Parameters 318

Remarks 318

Examples 319

Declaring and Raising Events 319

Declaring an Event 319

Raising the Event 319

Standard Event Declaration 320

Anonymous Event Handler Declaration 321

Non-Standard Event Declaration 322

Creating custom EventArgs containing additional data 322


Creating cancelable event 324

Event Properties 325

Chapter 54: Exception Handling 327

Examples 327

Basic Exception Handling 327

Handling specific exception types 327

Using the exception object 327

Finally block 329

Implementing IErrorHandler for WCF Services 330

Creating Custom Exceptions 333

Creating Custom Exception Class 333

re-throwing 333

serialization 334

Using the ParserException 334

Security Concerns 335

Conclusion 335

Exception Anti-patterns 336

Swallowing Exceptions 336

Baseball Exception Handling 336

catch (Exception) 337

Aggregate exceptions / multiple exceptions from one method 338

Nesting of Exceptions & try catch blocks. 339

Best Practices 340

Cheatsheet 340

DO NOT manage business logic with exceptions. 340

DO NOT re-throw Exceptions 341

DO NOT absorb exceptions with no logging 341

Do not catch exceptions that you cannot handle 342

Unhandled and Thread Exception 342

Throwing an exception 343

Chapter 55: Expression Trees 344


Introduction 344

Syntax 344

Parameters 344

Remarks 344

Intro to Expression Trees 344

Where we came from 344

How to avoid flow inversion's memory and latency problems 344

Expression trees save the day 345

Creating expression trees 345

Expression Trees and LINQ 346

Notes 346

Examples 346

Creating Expression Trees by Using the API 346

Compiling Expression Trees 346

Parsing Expression Trees 347

Create Expression Trees with a lambda expression 347

Understanding the expressions API 347

Expression Tree Basic 348

Examining the Structure of an Expression using Visitor 349

Chapter 56: Extension Methods 351

Syntax 351

Parameters 351

Remarks 351

Examples 352

Extension methods - overview 352

Explicitly using an extension method 355

When to call extension methods as static methods 355

Using static 356

Null checking 356

Extension methods can only see public (or internal) members of the extended class 356

Generic Extension Methods 357


Extension methods dispatch based on static type 358

Extension methods aren't supported by dynamic code. 360

Extension methods as strongly typed wrappers 361

Extension methods for chaining 361

Extension methods in combination with interfaces 362

IList Extension Method Example: Comparing 2 Lists 362

Extension methods with Enumeration 363

Extensions and interfaces together enable DRY code and mixin-like functionality 365

Extension methods for handling special cases 365

Using Extension methods with Static methods and Callbacks 366

Extension methods on Interfaces 368

Using Extension methods to create beautiful mapper classes 368

Using Extension methods to build new collection types (e.g. DictList) 369

Chapter 57: File and Stream I/O 371

Introduction 371

Syntax 371

Parameters 371

Remarks 371

Examples 372

Reading from a file using the System.IO.File class 372

Writing lines to a file using the System.IO.StreamWriter class 372

Writing to a file using the System.IO.File class 372

Lazily reading a file line-by-line via an IEnumerable 373

Create File 373

Copy File 374

Move File 374

Delete File 375

Files and Directories 375

Async write text to a file using StreamWriter 375

Chapter 58: FileSystemWatcher 376

Syntax 376

Parameters 376
Examples 376

Basic FileWatcher 376

IsFileReady 377

Chapter 59: Func delegates 378

Syntax 378

Parameters 378

Examples 378

Without parameters 378

With multiple variables 379

Lambda & anonymous methods 379

Covariant & Contravariant Type Parameters 380

Chapter 60: Function with multiple return values 381

Remarks 381

Examples 381

"anonymous object" + "dynamic keyword" solution 381

Tuple solution 381

Ref and Out Parameters 382

Chapter 61: Functional Programming 383

Examples 383

Func and Action 383

Immutability 383

Avoid Null References 385

Higher-Order Functions 386

Immutable collections 386

Creating and adding items 386

Creating using the builder 386

Creating from an existing IEnumerable 387

Chapter 62: Garbage Collector in .Net 388

Examples 388

Large Object Heap compaction 388

Weak References 388

Chapter 63: Generating Random Numbers in C# 391


Syntax 391

Parameters 391

Remarks 391

Examples 391

Generate a random int 391

Generate a Random double 392

Generate a random int in a given range 392

Generating the same sequence of random numbers over and over again 392

Create multiple random class with different seeds simultaneously 392

Generate a random character 393

Generate a number that is a percentage of a max value 393

Chapter 64: Generic Lambda Query Builder 394

Remarks 394

Examples 394

QueryFilter class 394

GetExpression Method 395

GetExpression Private overload 396

For one filter: 396

For two filters: 397

ConstantExpression Method 397

Usage 398

Output: 398

Chapter 65: Generics 399

Syntax 399

Parameters 399

Remarks 399

Examples 399

Type Parameters (Classes) 399

Type Parameters (Methods) 400

Type Parameters (Interfaces) 400

Implicit type inference (methods) 401

Type constraints (classes and interfaces) 402


Type constraints (class and struct) 403

Type constraints (new-keyword) 404

Type inference (classes) 404

Reflecting on type parameters 405

Explicit type parameters 405

Using generic method with an interface as a constraint type. 406

Covariance 407

Contravariance 408

Invariance 409

Variant interfaces 410

Variant delegates 411

Variant types as parameters and return values 411

Checking equality of generic values. 412

Generic type casting 412

Configuration reader with generic type casting 413

Chapter 66: Getting Started: Json with C# 415

Introduction 415

Examples 415

Simple Json Example 415

First things First: Library to work with Json 415

C# Implementation 415

Serialization 416

Deserialization 416

Serialization & De-Serialization Common Utilities function 417

Chapter 67: Guid 418

Introduction 418

Remarks 418

Examples 418

Getting the string representation of a Guid 418

Creating a Guid 418

Declaring a nullable GUID 419

Chapter 68: Handling FormatException when converting string to other types 420
Examples 420

Converting string to integer 420

Chapter 69: Hash Functions 422

Remarks 422

Examples 422

MD5 422

SHA1 423

SHA256 423

SHA384 424

SHA512 424

PBKDF2 for Password Hashing 425

Complete Password Hashing Solution using Pbkdf2 426

Chapter 70: How to use C# Structs to create a Union type (Similar to C Unions) 430

Remarks 430

Examples 430

C-Style Unions in C# 430

Union Types in C# can also contain Struct fields 431

Chapter 71: ICloneable 433

Syntax 433

Remarks 433

Examples 433

Implementing ICloneable in a class 433

Implementing ICloneable in a struct 434

Chapter 72: IComparable 436

Examples 436

Sort versions 436

Chapter 73: IDisposable interface 438

Remarks 438

Examples 438

In a class that contains only managed resources 438

In a class with managed and unmanaged resources 438

IDisposable, Dispose 439


In an inherited class with managed resources 440

using keyword 440

Chapter 74: IEnumerable 442

Introduction 442

Remarks 442

Examples 442

IEnumerable 442

IEnumerable with custom Enumerator 442

Chapter 75: ILGenerator 444

Examples 444

Creates a DynamicAssembly that contains a UnixTimestamp helper method 444

Create method override 446

Chapter 76: Immutability 447

Examples 447

System.String class 447

Strings and immutability 447

Chapter 77: Implementing Decorator Design Pattern 449

Remarks 449

Examples 449

Simulating cafeteria 449

Chapter 78: Implementing Flyweight Design Pattern 451

Examples 451

Implementing map in RPG game 451

Chapter 79: Import Google Contacts 454

Remarks 454

Examples 454

Requirements 454

Source code in the controller 454

Source code in the view. 457

Chapter 80: Including Font Resources 458

Parameters 458
Examples 458

Instantiate 'Fontfamily' from Resources 458

Integration method 458

Usage with a 'Button' 459

Chapter 81: Indexer 460

Syntax 460

Remarks 460

Examples 460

A simple indexer 460

Indexer with 2 arguments and interface 460

Overloading the indexer to create a SparseArray 461

Chapter 82: Inheritance 462

Syntax 462

Remarks 462

Examples 462

Inheriting from a base class 462

Inheriting from a class and implementing an interface 463

Inheriting from a class and implementing multiple interfaces 463

Testing and navigating inheritance 464

Extending an abstract base class 465

Constructors In A Subclass 465

Inheritance. Constructors' calls sequence 466

Inheriting methods 468

Inheritance Anti-patterns 469

Improper Inheritance 469

Base class with recursive type specification 470

Chapter 83: Initializing Properties 473

Remarks 473

Examples 473

C# 6.0: Initialize an Auto-Implemented Property 473

Initializing Property with a Backing Field 473

Initializing Property in Constructor 473


Property Initialization during object instantiation 473

Chapter 84: INotifyPropertyChanged interface 475

Remarks 475

Examples 475

Implementing INotifyPropertyChanged in C# 6 475

INotifyPropertyChanged With Generic Set Method 476

Chapter 85: Interfaces 478

Examples 478

Implementing an interface 478

Implementing multiple interfaces 478

Explicit interface implementation 479

Hint: 480

Note: 480

Why we use interfaces 480

Interface Basics 482

"Hiding" members with Explicit Implementation 484

IComparable as an Example of Implementing an Interface 485

Chapter 86: Interoperability 487

Remarks 487

Examples 487

Import function from unmanaged C++ DLL 487

Finding the dynamic library 487

Simple code to expose class for com 488

C++ name mangling 488

Calling conventions 489

Dynamic loading and unloading of unmanaged DLLs 490

Dealing with Win32 Errors 491

Pinned Object 492

Reading structures with Marshal 493

Chapter 87: IQueryable interface 495

Examples 495
Translating a LINQ query to a SQL query 495

Chapter 88: Iterators 496

Remarks 496

Examples 496

Simple Numeric Iterator Example 496

Creating Iterators Using Yield 496

Chapter 89: Keywords 499

Introduction 499

Remarks 499

Examples 501

stackalloc 501

volatile 502

fixed 504

Fixed Variables 504

Fixed Array Size 504

default 504

readonly 505

as 506

is 507

typeof 508

const 508

namespace 510

try, catch, finally, throw 510

continue 511

ref, out 512

checked, unchecked 513

goto 515

goto as a: 515

Label: 515

Case statement: 515

Exception Retry 515

enum 516
base 517

foreach 519

params 520

break 521

abstract 522

float, double, decimal 524

float 524

double 524

decimal 524

uint 525

this 525

for 526

while 527

return 529

in 529

using 529

sealed 530

sizeof 530

static 531

Drawbacks 533

int 533

long 533

ulong 533

dynamic 534

virtual, override, new 535

virtual and override 535

new 536

The usage of override is not optional 537

Derived classes can introduce polymorphism 537

Virtual methods cannot be private 538

async, await 538


char 539

lock 540

null 541

internal 542

where 543

The previous examples show generic constraints on a class definition, but constraints can 545

extern 545

bool 546

when 546

unchecked 547

When is this useful? 547

void 547

if, if...else, if... else if 548

Important to note that if a condition is met in the above example , the control skips othe 549

do 549

operator 550

struct 551

switch 553

interface 553

unsafe 554

implicit 556

true, false 556

string 557

ushort 557

sbyte 557

var 558

delegate 559

event 560

partial 560

Chapter 90: Lambda expressions 563

Remarks 563

Examples 563
Passing a Lambda Expression as a Parameter to a Method 563

Lambda Expressions as Shorthand for Delegate Initialization 563

Lambdas for both `Func` and `Action` 563

Lambda Expressions with Multiple Parameters or No Parameters 564

Put Multiple Statements in a Statement Lambda 564

Lambdas can be emitted both as `Func` and `Expression` 564

Lambda Expression as an Event Handler 565

Chapter 91: Lambda Expressions 567

Remarks 567

Closures 567

Examples 567

Basic lambda expressions 567

Basic lambda expressions with LINQ 568

Using lambda syntax to create a closure 568

Lambda syntax with statement block body 569

Lambda expressions with System.Linq.Expressions 569

Chapter 92: LINQ Queries 570

Introduction 570

Syntax 570

Remarks 572

Examples 572

Where 572

Method syntax 572

Query syntax 573

Select - Transforming elements 573

Chaining methods 573

Range and Repeat 574

Range 574

Repeat 575

Skip and Take 575

First, FirstOrDefault, Last, LastOrDefault, Single, and SingleOrDefault 576

First() 576
FirstOrDefault() 576

Last() 577

LastOrDefault() 577

Single() 578

SingleOrDefault() 578

Recommendations 579

Except 580

SelectMany: Flattening a sequence of sequences 581

SelectMany 583

All 584

1. Empty parameter 584

2. Lambda expression as parameter 584

3. Empty collection 584

Query collection by type / cast elements to type 585

Union 585

JOINS 586

(Inner) Join 586

Left outer join 586

Right Outer Join 586

Cross Join 587

Full Outer Join 587

Practical example 587

Distinct 588

GroupBy one or multiple fields 589

Using Range with various Linq methods 589

Query Ordering - OrderBy() ThenBy() OrderByDescending() ThenByDescending() 590

Basics 591

GroupBy 592

Simple Example 592

More Complex Example 592

Any 593
1. Empty parameter 593

2. Lambda expression as parameter 593

3. Empty collection 593

ToDictionary 594

Aggregate 595

Defining a variable inside a Linq query (let keyword) 595

SkipWhile 596

DefaultIfEmpty 596

Usage in Left Joins: 597

SequenceEqual 598

Count and LongCount 598

Incrementally building a query 598

Zip 600

GroupJoin with outer range variable 600

ElementAt and ElementAtOrDefault 601

Linq Quantifiers 601

Joining multiple sequences 602

Joining on multiple keys 604

Select with Func selector - Use to get ranking of elements 604

TakeWhile 606

Sum 606

ToLookup 606

Build your own Linq operators for IEnumerable 607

Using SelectMany instead of nested loops 608

Any and First(OrDefault) - best practice 608

GroupBy Sum and Count 609

Reverse 610

Enumerating the Enumerable 611

OrderBy 613

OrderByDescending 614

Concat 615

Contains 615

Chapter 93: Linq to Objects 617


Introduction 617

Examples 617

How LINQ to Object executes queries 617

Using LINQ to Objects in C# 617

Chapter 94: LINQ to XML 622

Examples 622

Read XML using LINQ to XML 622

Chapter 95: Literals 624

Syntax 624

Examples 624

int literals 624

uint literals 624

string literals 624

char literals 625

byte literals 625

sbyte literals 625

decimal literals 625

double literals 625

float literals 625

long literals 626

ulong literal 626

short literal 626

ushort literal 626

bool literals 626

Chapter 96: Lock Statement 627

Syntax 627

Remarks 627

Examples 628

Simple usage 628

Throwing exception in a lock statement 628

Return in a lock statement 629

Using instances of Object for lock 629


Anti-Patterns and gotchas 629

Locking on an stack-allocated / local variable 629

Assuming that locking restricts access to the synchronizing object itself 630

Expecting subclasses to know when to lock 630

Locking on a boxed ValueType variable does not synchronize 632

Using locks unnecessarily when a safer alternative exists 633

Chapter 97: Looping 635

Examples 635

Looping styles 635

break 636

Foreach Loop 637

While loop 638

For Loop 638

Do - While Loop 639

Nested loops 640

continue 640

Chapter 98: Making a variable thread safe 641

Examples 641

Controlling access to a variable in a Parallel.For loop 641

Chapter 99: Methods 642

Examples 642

Declaring a Method 642

Calling a Method 642

Parameters and Arguments 643

Return Types 643

Default Parameters 644

Method overloading 644

Anonymous method 646

Access rights 646

Chapter 100: Microsoft.Exchange.WebServices 648

Examples 648

Retrieve Specified User's Out of Office Settings 648


Update Specific User's Out of Office Settings 649

Chapter 101: Named and Optional Arguments 651

Remarks 651

Examples 651

Named Arguments 651

Optional Arguments 653

Chapter 102: Named Arguments 656

Examples 656

Named Arguments can make your code more clear 656

Named arguments and optional paramaters 656

Argument order is not necessary 657

Named Arguments avoids bugs on optional parameters 657

Chapter 103: nameof Operator 659

Introduction 659

Syntax 659

Examples 659

Basic usage: Printing a variable name 659

Printing a parameter name 659

Raising PropertyChanged event 660

Handling PropertyChanged events 660

Applied to a generic type parameter 661

Applied to qualified identifiers 662

Argument Checking and Guard Clauses 662

Strongly typed MVC action links 663

Chapter 104: Naming Conventions 664

Introduction 664

Remarks 664

Choose easily readable identifier names 664

Favor readability over brevity 664

Do not use Hungarian notation 664

Abbreviations and acronyms 664

Examples 664
Capitalization conventions 664

Pascal Casing 665

Camel Casing 665

Uppercase 665

Rules 665

Interfaces 666

Private fields 666

Camel case 666

Camel case with underscore 666

Namespaces 667

Enums 667

Use a singular name for most Enums 667

Use a plural name for Enum types that are bit fields 667

Do not add 'enum' as a suffix 667

Do not use the enum name in each entry 668

Exceptions 668

Add 'exception' as a suffix 668

Chapter 105: Networking 669

Syntax 669

Remarks 669

Examples 669

Basic TCP Communication Client 669

Download a file from a web server 669

Async TCP Client 670

Basic UDP Client 671

Chapter 106: Nullable types 673

Syntax 673

Remarks 673

Examples 673

Initialising a nullable 674

Check if a Nullable has a value 674

Get the value of a nullable type 674


Getting a default value from a nullable 675

Check if a generic type parameter is a nullable type 675

Default value of nullable types is null 675

Effective usage of underlying Nullable argument 676

Chapter 107: Null-Coalescing Operator 678

Syntax 678

Parameters 678

Remarks 678

Examples 678

Basic usage 678

Null fall-through and chaining 679

Null coalescing operator with method calls 680

Use existing or create new 680

Lazy properties initialization with null coalescing operator 681

Thread safety 681

C# 6 Syntactic Sugar using expression bodies 681

Example in the MVVM pattern 681

Chapter 108: Null-conditional Operators 682

Syntax 682

Remarks 682

Examples 682

Null-Conditional Operator 682

Chaining the Operator 683

Combining with the Null-Coalescing Operator 683

The Null-Conditional Index 683

Avoiding NullReferenceExceptions 683

Null-conditional Operator can be used with Extension Method 684

Chapter 109: NullReferenceException 685

Examples 685

NullReferenceException explained 685

Chapter 110: O(n) Algorithm for circular rotation of an array 687


Introduction 687

Examples 687

Example of a generic method that rotates an array by a given shift 687

Chapter 111: Object initializers 689

Syntax 689

Remarks 689

Examples 689

Simple usage 689

Usage with anonymous types 689

Usage with non-default constructors 690

Chapter 112: Object Oriented Programming In C# 691

Introduction 691

Examples 691

Classes: 691

Chapter 113: ObservableCollection 692

Examples 692

Initialize ObservableCollection 692

Chapter 114: Operators 693

Introduction 693

Syntax 693

Parameters 693

Remarks 693

Operator Precedence 693

Examples 695

Overloadable Operators 695

Relational Operators 697

Short-circuiting Operators 699

sizeof 700

Overloading equality operators 700

Class Member Operators: Member Access 701

Class Member Operators: Null Conditional Member Access 702

Class Member Operators: Function Invocation 702


Class Member Operators: Aggregate Object Indexing 702

Class Member Operators: Null Conditional Indexing 702

"Exclusive or" Operator 702

Bit-Shifting Operators 702

Implicit Cast and Explicit Cast Operators 703

Binary operators with assignment 704

? : Ternary Operator 704

typeof 706

default Operator 706

Value Type (where T : struct) 706

Reference Type (where T : class) 707

nameof Operator 707

?. (Null Conditional Operator) 707

Postfix and Prefix increment and decrement 708

=> Lambda operator 708

Assignment operator '=' 709

?? Null-Coalescing Operator 709

Chapter 115: Overflow 711

Examples 711

Integer overflow 711

Overflow during operation 711

Ordering matters 711

Chapter 116: Overload Resolution 713

Remarks 713

Examples 713

Basic Overloading Example 713

"params" is not expanded, unless necessary. 714

Passing null as one of the arguments 714

Chapter 117: Parallel LINQ (PLINQ) 716

Syntax 716

Examples 718

Simple example 718


WithDegreeOfParallelism 718

AsOrdered 718

AsUnordered 719

Chapter 118: Partial class and methods 720

Introduction 720

Syntax 720

Remarks 720

Examples 720

Partial classes 720

Partial methods 721

Partial classes inheriting from a base class 721

Chapter 119: Performing HTTP requests 723

Examples 723

Creating and sending an HTTP POST request 723

Creating and sending an HTTP GET request 723

Error handling of specific HTTP response codes (such as 404 Not Found) 724

Sending asynchronous HTTP POST request with JSON body 724

Sending asynchronous HTTP GET request and reading JSON request 725

Retrieve HTML for Web Page (Simple) 725

Chapter 120: Pointers 726

Remarks 726

Pointers and unsafe 726

Undefined behavior 726

Types that support pointers 726

Examples 726

Pointers for array access 726

Pointer arithmetic 727

The asterisk is part of the type 727

void* 728

Member access using -> 728

Generic pointers 729

Chapter 121: Pointers & Unsafe Code 730


Examples 730

Introduction to unsafe code 730

Retrieving the Data Value Using a Pointer 731

Passing Pointers as Parameters to Methods 731

Accessing Array Elements Using a Pointer 732

Compiling Unsafe Code 733

Chapter 122: Polymorphism 734

Examples 734

Another Polymorphism Example 734

Types of Polymorphism 735

Ad hoc polymorphism 735

Subtyping 736

Chapter 123: Preprocessor directives 738

Syntax 738

Remarks 738

Conditional Expressions 738

Examples 739

Conditional Expressions 739

Generating Compiler Warnings and Errors 739

Defining and Undefining Symbols 740

Region Blocks 741

Other Compiler Instructions 741

Line 741

Pragma Checksum 741

Using the Conditional attribute 742

Disabling and Restoring Compiler Warnings 742

Custom Preprocessors at project level 743

Chapter 124: Properties 745

Remarks 745

Examples 745

Various Properties in Context 745


Public Get 746

Public Set 746

Accessing Properties 746

Default Values for Properties 748

Auto-implemented properties 748

Read-only properties 749

Declaration 749

Using read-only properties to create immutable classes 749

Chapter 125: Reactive Extensions (Rx) 751

Examples 751

Observing TextChanged event on a TextBox 751

Streaming Data from Database with Observable 751

Chapter 126: Read & Understand Stacktraces 753

Introduction 753

Examples 753

Stack trace for a simple NullReferenceException in Windows Forms 753

Chapter 127: Reading and writing .zip files 755

Syntax 755

Parameters 755

Examples 755

Writing to a zip file 755

Writing Zip Files in-memory 755

Get files from a Zip file 756

The following example shows how to open a zip archive and extract all .txt files to a fold 756

Chapter 128: Recursion 758

Remarks 758

Examples 758

Recursively describe an object structure 758

Recursion in plain English 759

Using Recursion to Get Directory Tree 760

Fibonacci Sequence 762

Factorial calculation 763


PowerOf calculation 763

Chapter 129: Reflection 765

Introduction 765

Remarks 765

Examples 765

Get a System.Type 765

Get the members of a type 765

Get a method and invoke it 766

Getting and setting properties 767

Custom Attributes 767

Looping through all the properties of a class 769

Determining generic arguments of instances of generic types 769

Get a generic method and invoke it 770

Create an instance of a Generic Type and invoke it's method 771

Instantiating classes that implement an interface (e.g. plugin activation) 771

Creating an instance of a Type 771

With Activator class 772

Without Activator class 772

Get a Type by name with namespace 775

Get a Strongly-Typed Delegate to a Method or Property via Reflection 776

Chapter 130: Regex Parsing 777

Syntax 777

Parameters 777

Remarks 777

Examples 778

Single match 778

Multiple matches 778

Chapter 131: Runtime Compile 779

Examples 779

RoslynScript 779

CSharpCodeProvider 779

Chapter 132: Singleton Implementation 780


Examples 780

Statically Initialized Singleton 780

Lazy, thread-safe Singleton (using Double Checked Locking) 780

Lazy, thread-safe Singleton (using Lazy) 781

Lazy, thread safe singleton (for .NET 3.5 or older, alternate implementation) 781

Disposing of the Singleton instance when it is no longer needed 782

Chapter 133: Static Classes 784

Examples 784

Static keyword 784

Static Classes 784

Static class lifetime 785

Chapter 134: Stopwatches 787

Syntax 787

Remarks 787

Examples 787

Creating an Instance of a Stopwatch 787

IsHighResolution 787

Chapter 135: Stream 789

Examples 789

Using Streams 789

Chapter 136: String Concatenate 791

Remarks 791

Examples 791

+ Operator 791

Concatenate strings using System.Text.StringBuilder 791

Concat string array elements using String.Join 791

Concatenation of two strings using $ 792

Chapter 137: String Escape Sequences 793

Syntax 793

Remarks 793

Examples 793

Unicode character escape sequences 793


Escaping special symbols in character literals 793

Escaping special symbols in string literals 794

Unrecognized escape sequences produce compile-time errors 794

Using escape sequences in identifiers 794

Chapter 138: String Interpolation 796

Syntax 796

Remarks 796

Examples 796

Expressions 796

Format dates in strings 796

Simple Usage 797

Behind the scenes 797

Padding the output 797

Left Padding 797

Right Padding 798

Padding with Format Specifiers 798

Formatting numbers in strings 798

Chapter 139: String Manipulation 800

Examples 800

Changing the case of characters within a String 800

Finding a string within a string 800

Removing (Trimming) white-space from a string 801

Replacing a string within a string 801

Splitting a string using a delimiter 801

Concatenate an array of strings into a single string 802

String Concatenation 802

Chapter 140: String.Format 803

Introduction 803

Syntax 803

Parameters 803

Remarks 803

Examples 803
Places where String.Format is 'embedded' in the framework 803

Using custom number format 804

Create a custom format provider 804

Align left/ right, pad with spaces 805

Numeric formats 805

Currency Formatting 805

Precision 805

Currency Symbol 806

Position of Currency Symbol 806

Custom Decimal Separator 806

Since C# 6.0 806

Escaping curly brackets inside a String.Format() expression 807

Date Formatting 807

ToString() 809

Relationship with ToString() 809

Caveats & Formatting Restrictions 810

Chapter 141: StringBuilder 811

Examples 811

What a StringBuilder is and when to use one 811

Use StringBuilder to create string from a large number of records 812

Chapter 142: Structs 813

Remarks 813

Examples 813

Declaring a struct 813

Struct usage 814

Struct implementing interface 815

Structs are copied on assignment 815

Chapter 143: Structural Design Patterns 817

Introduction 817

Examples 817

Adapter Design Pattern 817

Chapter 144: Synchronization Context in Async-Await 821


Examples 821

Pseudocode for async/await keywords 821

Disabling synchronization context 821

Why SynchronizationContext is so important? 822

Chapter 145: System.DirectoryServices.Protocols.LdapConnection 824

Examples 824

Authenticated SSL LDAP connection, SSL cert does not match reverse DNS 824

Super Simple anonymous LDAP 825

Chapter 146: System.Management.Automation 826

Remarks 826

Examples 826

Invoke simple synchronous pipeline 826

Chapter 147: T4 Code Generation 828

Syntax 828

Examples 828

Runtime Code Generation 828

Chapter 148: Task Parallel Library 829

Examples 829

Parallel.ForEach 829

Parallel.For 829

Parallel.Invoke 830

An async cancellable polling Task that waits between iterations 830

A cancellable polling Task using CancellationTokenSource 831

Async version of PingUrl 832

Chapter 149: Task Parallel Library (TPL) Dataflow Constructs 833

Examples 833

JoinBlock 833

BroadcastBlock 834

WriteOnceBlock 835

BatchedJoinBlock 836

TransformBlock 836

ActionBlock 837
TransformManyBlock 838

BatchBlock 839

BufferBlock 840

Chapter 150: Threading 842

Remarks 842

Examples 842

Simple Complete Threading Demo 842

Simple Complete Threading Demo using Tasks 843

Explicit Task Parallism 844

Implicit Task Parallelism 844

Creating and Starting a Second Thread 844

Starting a thread with parameters 845

Creating One Thread Per Processor 845

Avoiding Reading and Writing Data Simultaneously 845

Parallel.ForEach Loop 847

Deadlocks (two threads waiting on eachother) 847

Deadlocks (hold resource and wait) 849

Chapter 151: Timers 852

Syntax 852

Remarks 852

Examples 852

Multithreaded Timers 852

Features: 853

Creating an Instance of a Timer 854

Assigning the "Tick" event handler to a Timer 854

Example: Using a Timer to perform a simple countdown. 854

Chapter 152: Tuples 857

Examples 857

Creating tuples 857

Accessing tuple elements 857

Comparing and sorting Tuples 857

Return multiple values from a method 858


Chapter 153: Type Conversion 859

Remarks 859

Examples 859

MSDN implicit operator example 859

Explicit Type Conversion 860

Chapter 154: Unsafe Code in .NET 861

Remarks 861

Examples 861

Unsafe Array Index 861

Using unsafe with arrays 862

Using unsafe with strings 862

Chapter 155: Using Directive 864

Remarks 864

Examples 864

Basic Usage 864

Reference a Namespace 864

Associate an Alias with a Namespace 864

Access Static Members of a Class 865

Associate an Alias to Resolve Conflicts 865

Using alias directives 866

Chapter 156: Using json.net 867

Introduction 867

Examples 867

Using JsonConverter on simple values 867

JSON (http://www.omdbapi.com/?i=tt1663662) 867

Movie Model 868

RuntimeSerializer 868

Calling It 869

Collect all fields of JSON object 869

Chapter 157: Using SQLite in C# 872

Examples 872
Creating simple CRUD using SQLite in C# 872

Executing Query 876

Chapter 158: Using Statement 877

Introduction 877

Syntax 877

Remarks 877

Examples 877

Using Statement Basics 877

Returning from using block 878

Multiple using statements with one block 879

Gotcha: returning the resource which you are disposing 880

Using statements are null-safe 880

Gotcha: Exception in Dispose method masking other errors in Using blocks 881

Using Statements and Database Connections 881

Common IDisposable Data Classes 882

Common Access Pattern for ADO.NET Connections 882

Using Statements with DataContexts 883

Using Dispose Syntax to define custom scope 883

Executing code in constraint context 884

Chapter 159: Value type vs Reference type 886

Syntax 886

Remarks 886

Introduction 886

Value types 886

Reference types 886

Major Differences 886

Value types exist on the stack, reference types exist on the heap 886

Value types don't change when you change them in a method, reference types do 887

Value types cannot be null, reference types can 887

Examples 887

Changing values elsewhere 887

Passing by reference 888


Passing by reference using ref keyword. 889

Assignment 890

Difference with method parameters ref and out 890

ref vs out parameters 891

Chapter 160: Verbatim Strings 893

Syntax 893

Remarks 893

Examples 893

Multiline Strings 893

Escaping Double Quotes 894

Interpolated Verbatim Strings 894

Verbatim strings instruct the compiler to not use character escapes 894

Chapter 161: Windows Communication Foundation 896

Introduction 896

Examples 896

Getting started sample 896

Chapter 162: XDocument and the System.Xml.Linq namespace 899

Examples 899

Generate an XML document 899

Modify XML File 899

Generate an XML document using fluent syntax 901

Chapter 163: XML Documentation Comments 902

Remarks 902

Examples 902

Simple method annotation 902

Interface and class documentation comments 902

Method documentation comment with param and returns elements 903

Generating XML from documentation comments 903

Referencing another class in documentation 905

Chapter 164: XmlDocument and the System.Xml namespace 907

Examples 907

Basic XML document interaction 907


Reading from XML document 907

XmlDocument vs XDocument (Example and comparison) 908

Chapter 165: Yield Keyword 911

Introduction 911

Syntax 911

Remarks 911

Examples 911

Simple Usage 911

More Pertinent Usage 912

Early Termination 912

Correctly checking arguments 913

Return another Enumerable within a method returning Enumerable 915

Lazy Evaluation 915

Try...finally 916

Using yield to create an IEnumerator when implementing IEnumerable 917

Eager evaluation 918

Lazy Evaluation Example: Fibonacci Numbers 918

The difference between break and yield break 919

Credits 921
About
You can share this PDF with anyone you feel could benefit from it, downloaded the latest version
from: csharp-language

It is an unofficial and free C# Language ebook created for educational purposes. All the content is
extracted from Stack Overflow Documentation, which is written by many hardworking individuals at
Stack Overflow. It is neither affiliated with Stack Overflow nor official C# Language.

The content is released under Creative Commons BY-SA, and the list of contributors to each
chapter are provided in the credits section at the end of this book. Images may be copyright of
their respective owners unless otherwise specified. All trademarks and registered trademarks are
the property of their respective company owners.

Use the content presented in this book at your own risk; it is not guaranteed to be correct nor
accurate, please send your feedback and corrections to [email protected]

https://riptutorial.com/ 1
Chapter 1: Getting started with C# Language
Remarks
C# is a multi-paradigm, C-descendant programming language from Microsoft. C# is a managed
language that compiles to CIL, intermediate bytecode which can be executed on Windows, Mac
OS X and Linux.

Versions 1.0, 2.0 and 5.0 were standardized by ECMA (as ECMA-334), and standardization efforts
for modern C# are underway.

Versions

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

Examples
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 Program.cs in the Solution Explorer
5. Add the following code to Main():

public class Program


{
public static void Main()
{
// Prints a message to the console.

https://riptutorial.com/ 2
System.Console.WriteLine("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. */
System.Console.ReadKey();
}
}

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.

• System.Console.WriteLine("Hello, world!"); method prints a given data (in this example,


Hello, world!) as an output in the console window.

• System.Console.ReadKey(), 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 csc.exe (the C# compiler), both part of the
Microsoft Build Tools package.

To compile this example, run the following command in the same directory where HelloWorld.cs is
located:

%WINDIR%\Microsoft.NET\Framework64\v4.0.30319\csc.exe HelloWorld.cs

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 HelloWorld.cs file in

https://riptutorial.com/ 3
HelloWorld namespace)

%WINDIR%\Microsoft.NET\Framework64\v4.0.30319\csc.exe HelloWorld.cs /main:HelloWorld.ClassA

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 csc.exe Framework paths by running the following commands (the first for 32-
bit Frameworks):

dir %WINDIR%\Microsoft.NET\Framework\csc.exe /s/b


dir %WINDIR%\Microsoft.NET\Framework64\csc.exe /s/b

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

HelloWorld.exe

This will produce:

Hello, world!

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

https://riptutorial.com/ 4
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
VisualStudio.com. 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

https://riptutorial.com/ 5
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:

https://riptutorial.com/ 6
https://riptutorial.com/ 7
(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.)

7. Write code. You can now update your Program.cs 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 Program.cs:
(make sure it's inside the braces)

: (make sure it's inside the braces)

Console.WriteLine("Hello world!");
Console.Read();

Why Console.Read()? 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
Console.Read();, 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)
{
Console.WriteLine("Hello world!");
Console.Read();
}
}
}

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:

https://riptutorial.com/ 8
9. Stop the program. To close the program, just press any key on your keyboard. The
Console.Read() 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.

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 HelloWorld.cs and copy the following content
into it:

public class Program


{
public static void Main()
{
System.Console.WriteLine("Hello, world!");
System.Console.WriteLine("Press any key to exit..");
System.Console.Read();
}
}

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
HelloWorld.cs:

https://riptutorial.com/ 9
mcs -out:HelloWorld.exe HelloWorld.cs

The resulting HelloWorld.exe can then be executed with:

mono HelloWorld.exe

which will produce the output:

Hello, world!
Press any key to exit..

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="Microsoft.NET.Sdk">

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

</Project>

• Program.cs

using System;

namespace hello_world
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");

https://riptutorial.com/ 10
}
}
}

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 for Debug or dotnet run


run
.\bin\Release\netcoreapp1.1\hello_world.dll for Release.

Command Prompt output

Creating a new query using LinqPad

https://riptutorial.com/ 11
LinqPad is a great tool that allows you to learn and test features of .Net languages (C#, F# and
VB.Net.)

1. Install LinqPad

2. Create a new Query (Ctrl + N)

3. Under language, select "C# statements"

https://riptutorial.com/ 12
4. Type the following code and hit run (F5)

string hw = "Hello World";

hw.Dump(); //or Console.WriteLine(hw);

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.

https://riptutorial.com/ 13
Notes:

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

https://riptutorial.com/ 14
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.

Creating a new project using Xamarin Studio

1. Download and install Xamarin Studio Community.


2. Open Xamarin Studio.
3. Click File → New → Solution.

https://riptutorial.com/ 15
4. Click .NET → Console Project and choose C#.
5. Click Next to proceed.

https://riptutorial.com/ 16
6. Enter the Project Name and Browse... for a Location to Save and then click Create.

https://riptutorial.com/ 17
7. The newly created project will look similar to:

https://riptutorial.com/ 18
8. This is the code in the Text Editor:

using System;

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

https://riptutorial.com/ 19
}

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

10. Following is the Output:

https://riptutorial.com/ 20
Read Getting started with C# Language online: https://riptutorial.com/csharp/topic/15/getting-
started-with-csharp-language

https://riptutorial.com/ 21
Chapter 2: .NET Compiler Platform (Roslyn)
Examples
Create workspace from MSBuild project

First obtain the Microsoft.CodeAnalysis.CSharp.Workspaces nuget before continuing.

var workspace = Microsoft.CodeAnalysis.MSBuild.MSBuildWorkspace.Create();


var project = await workspace.OpenProjectAsync(projectFilePath);
var compilation = await project.GetCompilationAsync();

foreach (var diagnostic in compilation.GetDiagnostics()


.Where(d => d.Severity == Microsoft.CodeAnalysis.DiagnosticSeverity.Error))
{
Console.WriteLine(diagnostic);
}

To load existing code to the workspace, compile and report errors. Afterwards the code will be
located in memory. From here, both the syntactic and semantic side will be available to work with.

Syntax tree

A Syntax Tree is an immutable data structure representing the program as a tree of names,
commands and marks (as previously configured in the editor.)

For example, assume a Microsoft.CodeAnalysis.Compilation instance named compilation has been


configured. There are multiple ways to list the names of every variable declared in the loaded
code. To do so naively, take all pieces of syntax in every document (the DescendantNodes method)
and use Linq to select nodes that describe variable declaration:

foreach (var syntaxTree in compilation.SyntaxTrees)


{
var root = await syntaxTree.GetRootAsync();
var declaredIdentifiers = root.DescendantNodes()
.Where(an => an is VariableDeclaratorSyntax)
.Cast<VariableDeclaratorSyntax>()
.Select(vd => vd.Identifier);

foreach (var di in declaredIdentifiers)


{
Console.WriteLine(di);
}
}

Every type of C# construct with a corresponding type will exist in the syntax tree. To quickly find
specific types, use the Syntax Visualizer window from Visual Studio. This will interpret the current
opened document as a Roslyn syntax tree.

Semantic model

https://riptutorial.com/ 22
A Semantic Model offers a deeper level of interpretation and insight of code compare to a syntax
tree. Where syntax trees can tell the names of variables, semantic models also give the type and
all references. Syntax trees notice method calls, but semantic models give references to the
precise location the method is declared (after overload resolution has been applied.)

var workspace = Microsoft.CodeAnalysis.MSBuild.MSBuildWorkspace.Create();


var sln = await workspace.OpenSolutionAsync(solutionFilePath);
var project = sln.Projects.First();
var compilation = await project.GetCompilationAsync();

foreach (var syntaxTree in compilation.SyntaxTrees)


{
var root = await syntaxTree.GetRootAsync();

var declaredIdentifiers = root.DescendantNodes()


.Where(an => an is VariableDeclaratorSyntax)
.Cast<VariableDeclaratorSyntax>();

foreach (var di in declaredIdentifiers)


{
Console.WriteLine(di.Identifier);
// => "root"

var variableSymbol = compilation


.GetSemanticModel(syntaxTree)
.GetDeclaredSymbol(di) as ILocalSymbol;

Console.WriteLine(variableSymbol.Type);
// => "Microsoft.CodeAnalysis.SyntaxNode"

var references = await SymbolFinder.FindReferencesAsync(variableSymbol, sln);


foreach (var reference in references)
{
foreach (var loc in reference.Locations)
{
Console.WriteLine(loc.Location.SourceSpan);
// => "[1375..1379)"
}
}
}
}

This outputs a list of local variables using a syntax tree. Then it consults the semantic model to get
the full type name and find all references of every variable.

Read .NET Compiler Platform (Roslyn) online: https://riptutorial.com/csharp/topic/4886/-net-


compiler-platform--roslyn-

https://riptutorial.com/ 23
Chapter 3: Access Modifiers
Remarks
If the access modifier is omitted,

• classes are by default internal


• methods are by deault private
• getters and setters inherit the modifier of the property, by default this is private

Access modifiers on setters or getters of properties can only restrict access, not widen it: public
string someProperty {get; private set;}

Examples
public

The public keyword makes a class (including nested classes), property, method or field available
to every consumer:

public class Foo()


{
public string SomeProperty { get; set; }

public class Baz


{
public int Value { get; set; }
}
}

public class Bar()


{
public Bar()
{
var myInstance = new Foo();
var someValue = foo.SomeProperty;
var myNestedInstance = new Foo.Baz();
var otherValue = myNestedInstance.Value;
}
}

private

The private keyword marks properties, methods, fields and nested classes for use inside the class
only:

public class Foo()


{
private string someProperty { get; set; }

https://riptutorial.com/ 24
private class Baz
{
public string Value { get; set; }
}

public void Do()


{
var baz = new Baz { Value = 42 };
}
}

public class Bar()


{
public Bar()
{
var myInstance = new Foo();

// Compile Error - not accessible due to private modifier


var someValue = foo.someProperty;
// Compile Error - not accessible due to private modifier
var baz = new Foo.Baz();
}
}

internal

The internal keyword makes a class (including nested classes), property, method or field available
to every consumer in the same assembly:

internal class Foo


{
internal string SomeProperty {get; set;}
}

internal class Bar


{
var myInstance = new Foo();
internal string SomeField = foo.SomeProperty;

internal class Baz


{
private string blah;
public int N { get; set; }
}
}

This can be broken to allow a testing assembly to access the code via adding code to
AssemblyInfo.cs file:

using System.Runtime.CompilerServices;

[assembly:InternalsVisibleTo("MyTests")]

protected

The protected keyword marks field, methods properties and nested classes for use inside the

https://riptutorial.com/ 25
same class and derived classes only:

public class Foo()


{
protected void SomeFooMethod()
{
//do something
}

protected class Thing


{
private string blah;
public int N { get; set; }
}
}

public class Bar() : Foo


{
private void someBarMethod()
{
SomeFooMethod(); // inside derived class
var thing = new Thing(); // can use nested class
}
}

public class Baz()


{
private void someBazMethod()
{
var foo = new Foo();
foo.SomeFooMethod(); //not accessible due to protected modifier
}
}

protected internal

The protected internal keyword marks field, methods, properties and nested classes for use
inside the same assembly or derived classes in another assembly:

Assembly 1

public class Foo


{
public string MyPublicProperty { get; set; }
protected internal string MyProtectedInternalProperty { get; set; }

protected internal class MyProtectedInternalNestedClass


{
private string blah;
public int N { get; set; }
}
}

public class Bar


{
void MyMethod1()
{
Foo foo = new Foo();

https://riptutorial.com/ 26
var myPublicProperty = foo.MyPublicProperty;
var myProtectedInternalProperty = foo.MyProtectedInternalProperty;
var myProtectedInternalNestedInstance =
new Foo.MyProtectedInternalNestedClass();
}
}

Assembly 2

public class Baz : Foo


{
void MyMethod1()
{
var myPublicProperty = MyPublicProperty;
var myProtectedInternalProperty = MyProtectedInternalProperty;
var thing = new MyProtectedInternalNestedClass();
}

void MyMethod2()
{
Foo foo = new Foo();
var myPublicProperty = foo.MyPublicProperty;

// Compile Error
var myProtectedInternalProperty = foo.MyProtectedInternalProperty;
// Compile Error
var myProtectedInternalNestedInstance =
new Foo.MyProtectedInternalNestedClass();
}

public class Qux


{
void MyMethod1()
{
Baz baz = new Baz();
var myPublicProperty = baz.MyPublicProperty;

// Compile Error
var myProtectedInternalProperty = baz.MyProtectedInternalProperty;
// Compile Error
var myProtectedInternalNestedInstance =
new Baz.MyProtectedInternalNestedClass();
}

void MyMethod2()
{
Foo foo = new Foo();
var myPublicProperty = foo.MyPublicProperty;

//Compile Error
var myProtectedInternalProperty = foo.MyProtectedInternalProperty;
// Compile Error
var myProtectedInternalNestedInstance =
new Foo.MyProtectedInternalNestedClass();
}
}

https://riptutorial.com/ 27
Access Modifiers Diagrams

Here are all access modifiers in venn diagrams, from more limiting to more accessible:

Access Modifier Diagram

private

internal

protected

protected internal

https://riptutorial.com/ 28
Access Modifier Diagram

public

Below you could find more information.

Read Access Modifiers online: https://riptutorial.com/csharp/topic/960/access-modifiers

https://riptutorial.com/ 29
Chapter 4: Access network shared folder with
username and password
Introduction
Accessing network share file using PInvoke.

Examples
Code to access network shared file

public class NetworkConnection : IDisposable


{
string _networkName;

public NetworkConnection(string networkName,


NetworkCredential credentials)
{
_networkName = networkName;

var netResource = new NetResource()


{
Scope = ResourceScope.GlobalNetwork,
ResourceType = ResourceType.Disk,
DisplayType = ResourceDisplaytype.Share,
RemoteName = networkName
};

var userName = string.IsNullOrEmpty(credentials.Domain)


? credentials.UserName
: string.Format(@"{0}\{1}", credentials.Domain, credentials.UserName);

var result = WNetAddConnection2(


netResource,
credentials.Password,
userName,
0);

if (result != 0)
{
throw new Win32Exception(result);
}
}

~NetworkConnection()
{
Dispose(false);
}

public void Dispose()


{
Dispose(true);
GC.SuppressFinalize(this);

https://riptutorial.com/ 30
}

protected virtual void Dispose(bool disposing)


{
WNetCancelConnection2(_networkName, 0, true);
}

[DllImport("mpr.dll")]
private static extern int WNetAddConnection2(NetResource netResource,
string password, string username, int flags);

[DllImport("mpr.dll")]
private static extern int WNetCancelConnection2(string name, int flags,
bool force);
}

[StructLayout(LayoutKind.Sequential)]
public class NetResource
{
public ResourceScope Scope;
public ResourceType ResourceType;
public ResourceDisplaytype DisplayType;
public int Usage;
public string LocalName;
public string RemoteName;
public string Comment;
public string Provider;
}

public enum ResourceScope : int


{
Connected = 1,
GlobalNetwork,
Remembered,
Recent,
Context
};

public enum ResourceType : int


{
Any = 0,
Disk = 1,
Print = 2,
Reserved = 8,
}

public enum ResourceDisplaytype : int


{
Generic = 0x0,
Domain = 0x01,
Server = 0x02,
Share = 0x03,
File = 0x04,
Group = 0x05,
Network = 0x06,
Root = 0x07,
Shareadmin = 0x08,
Directory = 0x09,
Tree = 0x0a,
Ndscontainer = 0x0b
}

https://riptutorial.com/ 31
Read Access network shared folder with username and password online:
https://riptutorial.com/csharp/topic/9627/access-network-shared-folder-with-username-and-
password

https://riptutorial.com/ 32
Chapter 5: Accessing Databases
Examples
ADO.NET Connections

ADO.NET Connections are one of the simplest ways to connect to a database from a C#
application. They rely on the use of a provider and a connection string that points to your database
to perform queries against.

Common Data Provider Classes


Many of the following are classes that are commonly used to query databases and their related
namespaces :

• SqlConnection,SqlCommand,SqlDataReader from System.Data.SqlClient


• OleDbConnection,OleDbCommand,OleDbDataReader from System.Data.OleDb
• MySqlConnection, MySqlCommand, MySqlDbDataReader from MySql.Data

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 ADO.NET Connections


A common pattern that can be used when accessing your data through an ADO.NET 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
connection.Open();

// Add your parameters here if necessary

// Execute your query as a reader (again scoped with a using statement)


using(var reader = command.ExecuteReader())
{
// Iterate through your results here
}
}
}

https://riptutorial.com/ 33
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))
{
connection.Open();

// Add parameters here

// Perform your update


command.ExecuteNonQuery();
}
}

You can even program against a set of common interfaces and not have to worry about the
provider specific classes. The core interfaces provided by ADO.NET are:

• IDbConnection - for managing database connections


• IDbCommand - for running SQL commands
• IDbTransaction - for managing transactions
• IDataReader - for reading data returned by a command
• IDataAdapter - for channeling data to and from datasets

var connectionString = "{your-connection-string}";


var providerName = "{System.Data.SqlClient}"; //for Oracle use
"Oracle.ManagedDataAccess.Client"
//most likely you will get the above two from ConnectionStringSettings object

var factory = DbProviderFactories.GetFactory(providerName);

using(var connection = new factory.CreateConnection()) {


connection.ConnectionString = connectionString;
connection.Open();

using(var command = new connection.CreateCommand()) {


command.CommandText = "{sql-query}"; //this needs to be tailored for each database
system

using(var reader = command.ExecuteReader()) {


while(reader.Read()) {
...
}
}
}
}

Entity Framework Connections

Entity Framework exposes abstraction classes that are used to interact with underlying databases
in the form of classes like DbContext. These contexts generally consist of DbSet<T> properties that
expose the available collections that can be queried :

https://riptutorial.com/ 34
public class ExampleContext: DbContext
{
public virtual DbSet<Widgets> Widgets { get; set; }
}

The DbContext itself will handle making the connections with the databases and will generally read
the appropriate Connection String data from a configuration to determine how to establish the
connections :

public class ExampleContext: DbContext


{
// The parameter being passed in to the base constructor indicates the name of the
// connection string
public ExampleContext() : base("ExampleContextEntities")
{
}

public virtual DbSet<Widgets> Widgets { get; set; }


}

Executing Entity Framework Queries


Actually executing an Entity Framework query can be quite easy and simply requires you to create
an instance of the context and then use the available properties on it to pull or access your data

using(var context = new ExampleContext())


{
// Retrieve all of the Widgets in your database
var data = context.Widgets.ToList();
}

Entity Framework also provides an extensive change-tracking system that can be used to handle
updating entries within your database by simply calling the SaveChanges() method to push changes
to the database :

using(var context = new ExampleContext())


{
// Grab the widget you wish to update
var widget = context.Widgets.Find(w => w.Id == id);
// If it exists, update it
if(widget != null)
{
// Update your widget and save your changes
widget.Updated = DateTime.UtcNow;
context.SaveChanges();
}
}

Connection Strings

A Connection String is a string that specifies information about a particular data source and how to
go about connecting to it by storing credentials, locations, and other information.

https://riptutorial.com/ 35
Server=myServerAddress;Database=myDataBase;User Id=myUsername;Password=myPassword;

Storing Your Connection String


Typically, a connection string will be stored within a configuration file (such as an app.config or
web.config within ASP.NET applications). The following is an example of what a local connection
might look like within one of these files :

<connectionStrings>
<add name="WidgetsContext" providerName="System.Data.SqlClient"
connectionString="Server=.\SQLEXPRESS;Database=Widgets;Integrated Security=True;"/>
</connectionStrings>

<connectionStrings>
<add name="WidgetsContext" providerName="System.Data.SqlClient"
connectionString="Server=.\SQLEXPRESS;Database=Widgets;Integrated Security=SSPI;"/>
</connectionStrings>

This will allow your application to access the connection string programatically through
WidgetsContext. Although both Integrated Security=SSPI and Integrated Security=True perform the
same function;Integrated Security=SSPI is preferred since works with both SQLClient & OleDB
provider where as Integrated Security=true throws an exception when used with the OleDb
provider.

Different Connections for Different Providers


Each data provider (SQL Server, MySQL, Azure, etc.) all feature their own flavor of syntax for their
connection strings and expose different available properties. ConnectionStrings.com is an
incredibly useful resource if you are unsure about what yours should look like.

Read Accessing Databases online: https://riptutorial.com/csharp/topic/4811/accessing-databases

https://riptutorial.com/ 36
Chapter 6: Action Filters
Examples
Custom Action Filters

We write custom action filters for various reasons. We may have a custom action filter for logging,
or for saving data to database before any action execution. We could also have one for fetching
data from the database and setting it as the global values of the application.

To create a custom action filter, we need to perform the following tasks:

1. Create a class
2. Inherit it from ActionFilterAttribute class

Override at least one of the following methods:

OnActionExecuting – This method is called before a controller action is executed.

OnActionExecuted – This method is called after a controller action is executed.

OnResultExecuting – This method is called before a controller action result is executed.

OnResultExecuted – This method is called after a controller action result is executed.

The filter can be created as shown in the listing below:

using System;

using System.Diagnostics;

using System.Web.Mvc;

namespace WebApplication1
{

public class MyFirstCustomFilter : ActionFilterAttribute


{
public override void OnResultExecuting(ResultExecutingContext filterContext)
{
//You may fetch data from database here
filterContext.Controller.ViewBag.GreetMesssage = "Hello Foo";
base.OnResultExecuting(filterContext);
}

public override void OnActionExecuting(ActionExecutingContext filterContext)


{
var controllerName = filterContext.RouteData.Values["controller"];
var actionName = filterContext.RouteData.Values["action"];
var message = String.Format("{0} controller:{1} action:{2}",
"onactionexecuting", controllerName, actionName);

https://riptutorial.com/ 37
Debug.WriteLine(message, "Action Filter Log");
base.OnActionExecuting(filterContext);
}
}
}

Read Action Filters online: https://riptutorial.com/csharp/topic/1505/action-filters

https://riptutorial.com/ 38
Chapter 7: Aliases of built-in types
Examples
Built-In Types Table

The following table shows the keywords for built-in C# types, which are aliases of predefined types
in the System namespaces.

C# Type .NET Framework Type

bool System.Boolean

byte System.Byte

sbyte System.SByte

char System.Char

decimal System.Decimal

double System.Double

float System.Single

int System.Int32

uint System.UInt32

long System.Int64

ulong System.UInt64

object System.Object

short System.Int16

ushort System.UInt16

string System.String

The C# type keywords and their aliases are interchangeable. For example, you can declare an
integer variable by using either of the following declarations:

int number = 123;


System.Int32 number = 123;

https://riptutorial.com/ 39
Read Aliases of built-in types online: https://riptutorial.com/csharp/topic/1862/aliases-of-built-in-
types

https://riptutorial.com/ 40
Chapter 8: An overview of c# collections
Examples
HashSet

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 = validStoryPointValues.Contains(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 = validStoryPointValues.Contains(8); // O(n)

HashSet.Contains uses a hash table, so that lookups are extremely fast, regardless of the number
of items in the collection.

SortedSet

// create an empty set


var mySet = new SortedSet<int>();

// add something
// note that we add 2 before we add 1
mySet.Add(2);
mySet.Add(1);

// enumerate through the set


foreach(var item in mySet)
{
Console.WriteLine(item);
}

// output:
// 1
// 2

T[ ] (Array of T)

// create an array with 2 elements


var myArray = new [] { "one", "two" };

// enumerate through the array


foreach(var item in myArray)
{
Console.WriteLine(item);
}

https://riptutorial.com/ 41
// 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)
{
Console.WriteLine(item);
}

// output:
// something else
// two

List

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

using System.Collections.Generic;

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


list.Add(6);
Console.WriteLine(list.Count); // 6
list.RemoveAt(3);
Console.WriteLine(list.Count); // 5
Console.WriteLine(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.

Dictionary

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

using System.Collections.Generic;

var people = new Dictionary<string, int>


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

// Reading data
Console.WriteLine(people["John"]); // 30
Console.WriteLine(people["George"]); // throws KeyNotFoundException

int age;
if (people.TryGetValue("Mary", out age))
{
Console.WriteLine(age); // 35
}

https://riptutorial.com/ 42
// Adding and changing data
people["John"] = 40; // Overwriting values this way is ok
people.Add("John", 40); // Throws ArgumentException since "John" already exists

// Iterating through contents


foreach(KeyValuePair<string, int> person in people)
{
Console.WriteLine("Name={0}, Age={1}", person.Key, person.Value);
}

foreach(string name in people.Keys)


{
Console.WriteLine("Name={0}", name);
}

foreach(int age in people.Values)


{
Console.WriteLine("Age={0}", age);
}

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

Stack

// Initialize a stack object of integers


var stack = new Stack<int>();

// add some data


stack.Push(3);
stack.Push(5);
stack.Push(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.


Console.WriteLine(stack.Peek()); // prints 8

// Pop removes the top element of the stack and returns it.
Console.WriteLine(stack.Pop()); // prints 8
Console.WriteLine(stack.Pop()); // prints 5
Console.WriteLine(stack.Pop()); // prints 3

LinkedList

https://riptutorial.com/ 43
// initialize a LinkedList of integers
LinkedList list = new LinkedList<int>();

// add some numbers to our list.


list.AddLast(3);
list.AddLast(5);
list.AddLast(8);

// the list currently is 3, 5, 8

list.AddFirst(2);
// the list now is 2, 3, 5, 8

list.RemoveFirst();
// the list is now 3, 5, 8

list.RemoveLast();
// the list is now 3, 5

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.

Queue

// Initalize a new queue of integers


var queue = new Queue<int>();

// Add some data


queue.Enqueue(6);
queue.Enqueue(4);
queue.Enqueue(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.


Console.WriteLine(queue.Peek()); // prints 6

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


Console.WriteLine(queue.Dequeue()); // prints 6
Console.WriteLine(queue.Dequeue()); // prints 4
Console.WriteLine(queue.Dequeue()); // prints 9

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

Read An overview of c# collections online: https://riptutorial.com/csharp/topic/2344/an-overview-


of-csharp-collections

https://riptutorial.com/ 44
Chapter 9: Anonymous types
Examples
Creating an anonymous type

Since anonymous types are not named, variables of those types must be implicitly typed (var).

var anon = new { Foo = 1, Bar = 2 };


// anon.Foo == 1
// anon.Bar == 2

If the member names are not specified, they are set to the name of the property/variable used to
initialize the object.

int foo = 1;
int bar = 2;
var anon2 = new { foo, bar };
// anon2.foo == 1
// anon2.bar == 2

Note that names can only be omitted when the expression in the anonymous type declaration is a
simple property access; for method calls or more complex expressions, a property name must be
specified.

string foo = "some string";


var anon3 = new { foo.Length };
// anon3.Length == 11
var anon4 = new { foo.Length <= 10 ? "short string" : "long string" };
// compiler error - Invalid anonymous type member declarator.
var anon5 = new { Description = foo.Length <= 10 ? "short string" : "long string" };
// OK

Anonymous vs dynamic

Anonymous types allow the creation of objects without having to explicitly define their types ahead
of time, while maintaining static type checking.

var anon = new { Value = 1 };


Console.WriteLine(anon.Id); // compile time error

Conversely, dynamic has dynamic type checking, opting for runtime errors, instead of compile-time
errors.

dynamic val = "foo";


Console.WriteLine(val.Id); // compiles, but throws runtime error

https://riptutorial.com/ 45
Generic methods with anonymous types

Generic methods allow the use of anonymous types through type inference.

void Log<T>(T obj) {


// ...
}
Log(new { Value = 10 });

This means LINQ expressions can be used with anonymous types:

var products = new[] {


new { Amount = 10, Id = 0 },
new { Amount = 20, Id = 1 },
new { Amount = 15, Id = 2 }
};
var idsByAmount = products.OrderBy(x => x.Amount).Select(x => x.Id);
// idsByAmount: 0, 2, 1

Instantiating generic types with anonymous types

Using generic constructors would require the anonymous types to be named, which is not
possible. Alternatively, generic methods may be used to allow type inference to occur.

var anon = new { Foo = 1, Bar = 2 };


var anon2 = new { Foo = 5, Bar = 10 };
List<T> CreateList<T>(params T[] items) {
return new List<T>(items);
}

var list1 = CreateList(anon, anon2);

In the case of List<T>, implicitly typed arrays may be converted to a List<T> through the ToList
LINQ method:

var list2 = new[] {anon, anon2}.ToList();

Anonymous type equality

Anonymous type equality is given by the Equals instance method. Two objects are equal if they
have the same type and equal values (through a.Prop.Equals(b.Prop)) for every property.

var anon = new { Foo = 1, Bar = 2 };


var anon2 = new { Foo = 1, Bar = 2 };
var anon3 = new { Foo = 5, Bar = 10 };
var anon3 = new { Foo = 5, Bar = 10 };
var anon4 = new { Bar = 2, Foo = 1 };
// anon.Equals(anon2) == true
// anon.Equals(anon3) == false
// anon.Equals(anon4) == false (anon and anon4 have different types, see below)

https://riptutorial.com/ 46
Two anonymous types are considered the same if and only if their properties have the same name
and type and appear in the same order.

var anon = new { Foo = 1, Bar = 2 };


var anon2 = new { Foo = 7, Bar = 1 };
var anon3 = new { Bar = 1, Foo = 3 };
var anon4 = new { Fa = 1, Bar = 2 };
// anon and anon2 have the same type
// anon and anon3 have diferent types (Bar and Foo appear in different orders)
// anon and anon4 have different types (property names are different)

Implicitly typed arrays

Arrays of anonymous types may be created with implicit typing.

var arr = new[] {


new { Id = 0 },
new { Id = 1 }
};

Read Anonymous types online: https://riptutorial.com/csharp/topic/765/anonymous-types

https://riptutorial.com/ 47
Chapter 10: Arrays
Syntax
• Declaring an array:

<type>[] <name>;

• Declaring two-dimensional array:

<type>[,] <name> = new <type>[<value>, <value>];

• Declaring a Jagged Array:

<type>[] <name> = new <type>[<value>];

• Declaring a subarray for a Jagged Array:

<name>[<value>] = new <type>[<value>];

• Initializing an array without values:

<name> = new <type>[<length>];

• Initializing an array with values:

<name> = new <type>[] {<value>, <value>, <value>, ...};

• Initializing a two-dimensional array with values:

<name> = new <type>[,] { {<value>, <value>}, {<value>, <value>}, ...};

• Accessing an element at index i:

<name>[i]

• Getting the array's length:

<name>.Length

Remarks
In C#, an array is a reference type, which means it is nullable.

An array has a fixed length, which means you cant .Add() to it or .Remove() from it. In order to use
these, you would need a dynamic array - List or ArrayList.

Examples

https://riptutorial.com/ 48
Array covariance

string[] strings = new[] {"foo", "bar"};


object[] objects = strings; // implicit conversion from string[] to object[]

This conversion is not type-safe. The following code will raise a runtime exception:

string[] strings = new[] {"Foo"};


object[] objects = strings;

objects[0] = new object(); // runtime exception, object is not string


string str = strings[0]; // would have been bad if above assignment had succeeded

Getting and setting array values

int[] arr = new int[] { 0, 10, 20, 30};

// Get
Console.WriteLine(arr[2]); // 20

// Set
arr[2] = 100;

// Get the updated value


Console.WriteLine(arr[2]); // 100

Declaring an array

An array can be declared and filled with the default value using square bracket ([]) initialization
syntax. For example, creating an array of 10 integers:

int[] arr = new int[10];

Indices in C# are zero-based. The indices of the array above will be 0-9. For example:

int[] arr = new int[3] {7,9,4};


Console.WriteLine(arr[0]); //outputs 7
Console.WriteLine(arr[1]); //outputs 9

Which means the system starts counting the element index from 0. Moreover, accesses to
elements of arrays are done in constant time. That means accessing to the first element of the
array has the same cost (in time) of accessing the second element, the third element and so on.

You may also declare a bare reference to an array without instantiating an array.

int[] arr = null; // OK, declares a null reference to an array.


int first = arr[0]; // Throws System.NullReferenceException because there is no actual array.

An array can also be created and initialized with custom values using collection initialization
syntax:

https://riptutorial.com/ 49
int[] arr = new int[] { 24, 2, 13, 47, 45 };

The new int[] portion can be omitted when declaring an array variable. This is not a self-contained
expression, so using it as part of a different call does not work (for that, use the version with new):

int[] arr = { 24, 2, 13, 47, 45 }; // OK


int[] arr1;
arr1 = { 24, 2, 13, 47, 45 }; // Won't compile

Implicitly typed arrays

Alternatively, in combination with the var keyword, the specific type may be omitted so that the
type of the array is inferred:

// same as int[]
var arr = new [] { 1, 2, 3 };
// same as string[]
var arr = new [] { "one", "two", "three" };
// same as double[]
var arr = new [] { 1.0, 2.0, 3.0 };

Iterate over an array

int[] arr = new int[] {1, 6, 3, 3, 9};

for (int i = 0; i < arr.Length; i++)


{
Console.WriteLine(arr[i]);
}

using foreach:

foreach (int element in arr)


{
Console.WriteLine(element);
}

using unsafe access with pointers https://msdn.microsoft.com/en-ca/library/y31yhkeb.aspx

unsafe
{
int length = arr.Length;
fixed (int* p = arr)
{
int* pInt = p;
while (length-- > 0)
{
Console.WriteLine(*pInt);
pInt++;// move pointer to next element
}
}
}

https://riptutorial.com/ 50
Output:

1
6
3
3
9

Multi-dimensional arrays

Arrays can have more than one dimension. The following example creates a two-dimensional
array of ten rows and ten columns:

int[,] arr = new int[10, 10];

An array of three dimensions:

int[,,] arr = new int[10, 10, 10];

You can also initialize the array upon declaration:

int[,] arr = new int[4, 2] { {1, 1}, {2, 2}, {3, 3}, {4, 4} };

// Access a member of the multi-dimensional array:


Console.Out.WriteLine(arr[3, 1]); // 4

Jagged arrays

Jagged arrays are arrays that instead of primitive types, contain arrays (or other collections). It's
like an array of arrays - each array element contains another array.

They are similar to multidimensional arrays, but have a slight difference - as multidimensional
arrays are limited to a fixed number of rows and columns, with jagged arrays, every row can have
a different number of columns.

Declaring a jagged array

For example, declaring a jagged array with 8 columns:

int[][] a = new int[8][];

The second [] is initialized without a number. To initialize the sub arrays, you would need to do
that separately:

for (int i = 0; i < a.length; i++)


{
a[i] = new int[10];
}

https://riptutorial.com/ 51
Getting/Setting values

Now, getting one of the subarrays is easy. Let's print all the numbers of the 3rd column of a:

for (int i = 0; i < a[2].length; i++)


{
Console.WriteLine(a[2][i]);
}

Getting a specific value:

a[<row_number>][<column_number>]

Setting a specific value:

a[<row_number>][<column_number>] = <value>

Remember: It's always recommended to use jagged arrays (arrays of arrays) rather than
multidimensional arrays (matrixes). It's faster and safer to use.

Note on the order of the brackets

Consider a three-dimensional array of five-dimensional arrays of one-dimensional arrays of int.


This is written in C# as:

int[,,][,,,,][] arr = new int[8, 10, 12][,,,,][];

In the CLR type system, the convention for the ordering of the brackets is reversed, so with the
above arr instance we have:

arr.GetType().ToString() == "System.Int32[][,,,,][,,]"

and likewise:

typeof(int[,,][,,,,][]).ToString() == "System.Int32[][,,,,][,,]"

Checking if one array contains another array

public static class ArrayHelpers


{
public static bool Contains<T>(this T[] array, T[] candidate)
{
if (IsEmptyLocate(array, candidate))
return false;

if (candidate.Length > array.Length)


return false;

for (int a = 0; a <= array.Length - candidate.Length; a++)

https://riptutorial.com/ 52
{
if (array[a].Equals(candidate[0]))
{
int i = 0;
for (; i < candidate.Length; i++)
{
if (false == array[a + i].Equals(candidate[i]))
break;
}
if (i == candidate.Length)
return true;
}
}
return false;
}

static bool IsEmptyLocate<T>(T[] array, T[] candidate)


{
return array == null
|| candidate == null
|| array.Length == 0
|| candidate.Length == 0
|| candidate.Length > array.Length;
}
}

/// Sample

byte[] EndOfStream = Encoding.ASCII.GetBytes("---3141592---");


byte[] FakeReceivedFromStream = Encoding.ASCII.GetBytes("Hello, world!!!---3141592---");
if (FakeReceivedFromStream.Contains(EndOfStream))
{
Console.WriteLine("Message received");
}

Initializing an array filled with a repeated non-default value

As we know we can declare an array with default values:

int[] arr = new int[10];

This will create an array of 10 integers with each element of the array having value 0 (the default
value of type int).

To create an array initialized with a non-default value, we can use Enumerable.Repeat from the
System.Linq Namespace:

1. To create a bool array of size 10 filled with "true"

bool[] booleanArray = Enumerable.Repeat(true, 10).ToArray();

2. To create an int array of size 5 filled with "100"

https://riptutorial.com/ 53
int[] intArray = Enumerable.Repeat(100, 5).ToArray();

3. To create a string array of size 5 filled with "C#"

string[] strArray = Enumerable.Repeat("C#", 5).ToArray();

Copying arrays

Copying a partial array with the static Array.Copy() method, beginning at index 0 in both, source
and destination:

var sourceArray = new int[] { 11, 12, 3, 5, 2, 9, 28, 17 };


var destinationArray= new int[3];
Array.Copy(sourceArray, destinationArray, 3);

// destinationArray will have 11,12 and 3

Copying the whole array with the CopyTo() instance method, beginning at index 0 of the source and
the specified index in the destination:

var sourceArray = new int[] { 11, 12, 7 };


var destinationArray = new int[6];
sourceArray.CopyTo(destinationArray, 2);

// destinationArray will have 0, 0, 11, 12, 7 and 0

Clone is used to create a copy of an array object.

var sourceArray = new int[] { 11, 12, 7 };


var destinationArray = (int)sourceArray.Clone();

//destinationArray will be created and will have 11,12,17.

Both CopyTo and Clone perform shallow copy which means the contents contains references to the
same object as the elements in the original array.

Creating an array of sequential numbers

LINQ provides a method that makes it easy to create a collection filled with sequential numbers.
For example, you can declare an array which contains the integers between 1 and 100.

The Enumerable.Range method allows us to create sequence of integer numbers from a specified
start position and a number of elements.

The method takes two arguments: the starting value and the number of elements to generate.

Enumerable.Range(int start, int count)

Note that count cannot be negative.

https://riptutorial.com/ 54
Usage:

int[] sequence = Enumerable.Range(1, 100).ToArray();

This will generate an array containing the numbers 1 through 100 ([1, 2, 3, ..., 98, 99, 100]).

Because the Range method returns an IEnumerable<int>, we can use other LINQ methods on it:

int[] squares = Enumerable.Range(2, 10).Select(x => x * x).ToArray();

This will generate an array that contains 10 integer squares starting at 4: [4, 9, 16, ..., 100, 121]
.

Comparing arrays for equality

LINQ provides a built-in function for checking the equality of two IEnumerables, and that function
can be used on arrays.

The SequenceEqual function will return true if the arrays have the same length and the values in
corresponding indices are equal, and false otherwise.

int[] arr1 = { 3, 5, 7 };
int[] arr2 = { 3, 5, 7 };
bool result = arr1.SequenceEqual(arr2);
Console.WriteLine("Arrays equal? {0}", result);

This will print:

Arrays equal? True

Arrays as IEnumerable<> instances

All arrays implement the non-generic IList interface (and hence non-generic ICollection and
IEnumerable base interfaces).

More importantly, one-dimensional arrays implement the IList<> and IReadOnlyList<> generic
interfaces (and their base interfaces) for the type of data that they contain. This means that they
can be treated as generic enumerable types and passed in to a variety of methods without
needing to first convert them to a non-array form.

int[] arr1 = { 3, 5, 7 };
IEnumerable<int> enumerableIntegers = arr1; //Allowed because arrays implement IEnumerable<T>
List<int> listOfIntegers = new List<int>();
listOfIntegers.AddRange(arr1); //You can pass in a reference to an array to populate a List.

After running this code, the list listOfIntegers will contain a List<int> containing the values 3, 5,
and 7.

https://riptutorial.com/ 55
The IEnumerable<> support means arrays can be queried with LINQ, for example arr1.Select(i =>
10 * i).

Read Arrays online: https://riptutorial.com/csharp/topic/1429/arrays

https://riptutorial.com/ 56
Chapter 11: ASP.NET Identity
Introduction
Tutorials concerning asp.net Identity such as user management, role management, creating
tokens and more.

Examples
How to implement password reset token in asp.net identity using user
manager.

1. Create a new folder called MyClasses and create and add the following class

public class GmailEmailService:SmtpClient


{
// Gmail user-name
public string UserName { get; set; }

public GmailEmailService() :
base(ConfigurationManager.AppSettings["GmailHost"],
Int32.Parse(ConfigurationManager.AppSettings["GmailPort"]))
{
//Get values from web.config file:
this.UserName = ConfigurationManager.AppSettings["GmailUserName"];
this.EnableSsl = Boolean.Parse(ConfigurationManager.AppSettings["GmailSsl"]);
this.UseDefaultCredentials = false;
this.Credentials = new System.Net.NetworkCredential(this.UserName,
ConfigurationManager.AppSettings["GmailPassword"]);
}
}

2. Configure your Identity Class

public async Task SendAsync(IdentityMessage message)


{
MailMessage email = new MailMessage(new MailAddress("[email protected]",
"(any subject here)"),
new MailAddress(message.Destination));
email.Subject = message.Subject;
email.Body = message.Body;

email.IsBodyHtml = true;

GmailEmailService mailClient = new GmailEmailService();


await mailClient.SendMailAsync(email);
}

3. Add your credentials to the web.config. I did not use gmail in this portion because the use of
gmail is blocked in my workplace and it still works perfectly.

https://riptutorial.com/ 57
<add key="GmailUserName" value="[email protected]"/>
<add key="GmailPassword" value="yourPassword"/>
<add key="GmailHost" value="yourServer"/>
<add key="GmailPort" value="yourPort"/>
<add key="GmailSsl" value="chooseTrueOrFalse"/>
<!--Smptp Server (confirmations emails)-->

4. Make necessary changes to your Account Controller. Add the following highlighted code.

https://riptutorial.com/ 58
https://riptutorial.com/ 59
Compile then run. Cheers!

Read ASP.NET Identity online: https://riptutorial.com/csharp/topic/9577/asp-net-identity

https://riptutorial.com/ 60
Chapter 12: AssemblyInfo.cs Examples
Remarks
The filename AssemblyInfo.cs is used by convention as the source file where developers place
metadata attributes that describe the entire assembly they are building.

Examples
[AssemblyTitle]

This attribute is used to give a name to this particular assembly.

[assembly: AssemblyTitle("MyProduct")]

[AssemblyProduct]

This attribute is used to describe the product that this particular assembly is for. Multiple
assemblies can be components of the same product, in which case they can all share the same
value for this attribute.

[assembly: AssemblyProduct("MyProduct")]

Global and local AssemblyInfo

Having a global allows for better DRYness, you need only put values that are different into
AssemblyInfo.cs for projects that have variance. This use assumes your product has more than
one visual studio project.

GlobalAssemblyInfo.cs

using System.Reflection;
using System.Runtime.InteropServices;
//using Stackoverflow domain as a made up example

// It is common, and mostly good, to use one GlobalAssemblyInfo.cs that is added


// as a link to many projects of the same product, details below
// Change these attribute values in local assembly info to modify the information.
[assembly: AssemblyProduct("Stackoverflow Q&A")]
[assembly: AssemblyCompany("Stackoverflow")]
[assembly: AssemblyCopyright("Copyright © Stackoverflow 2016")]

// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("4e4f2d33-aaab-48ea-a63d-1f0a8e3c935f")]
[assembly: ComVisible(false)] //not going to expose ;)

// Version information for an assembly consists of the following four values:


// roughly translated from I reckon it is for SO, note that they most likely

https://riptutorial.com/ 61
// dynamically generate this file
// Major Version - Year 6 being 2016
// Minor Version - The month
// Day Number - Day of month
// Revision - Build number
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: [assembly: AssemblyVersion("year.month.day.*")]
[assembly: AssemblyVersion("2016.7.00.00")]
[assembly: AssemblyFileVersion("2016.7.27.3839")]

AssemblyInfo.cs - one for each project

//then the following might be put into a separate Assembly file per project, e.g.
[assembly: AssemblyTitle("Stackoveflow.Redis")]

You can add the GlobalAssemblyInfo.cs to the local project using the following procedure:

1. Select Add/Existing Item... in the context menu of the project


2. Select GlobalAssemblyInfo.cs
3. Expand the Add-Button by clicking on that little down-arrow on the right hand
4. Select "Add As Link" in the buttons drop down list

[AssemblyVersion]

This attribute applies a version to the assembly.

[assembly: AssemblyVersion("1.0.*")]

The * character is used to auto-increment a portion of the version automatically every time you
compile (often used for the "build" number)

Reading Assembly Attributes

Using .NET's rich reflection APIs, you can gain access to an assembly's metadata. For example,
you can get this assembly's title attribute with the following code

using System.Linq;
using System.Reflection;

...

Assembly assembly = typeof(this).Assembly;


var titleAttribute = assembly.GetCustomAttributes<AssemblyTitleAttribute>().FirstOrDefault();

Console.WriteLine($"This assembly title is {titleAttribute?.Title}");

Automated versioning

Your code in source control has version numbers either by default (SVN ids or Git SHA1 hashes)
or explicitly (Git tags). Rather than manually updating versions in AssemblyInfo.cs you can use a
build time process to write the version from your source control system into your AssemblyInfo.cs

https://riptutorial.com/ 62
files and thus onto your assemblies.

The GitVersionTask or SemVer.Git.Fody NuGet packages are examples of the above. To use
GitVersionTask, for instance, after installing the package in your project remove the
Assembly*Version attributes from your AssemblyInfo.cs files. This puts GitVersionTask in charge of
versioning your assemblies.

Note that Semantic Versioning is increasingly the de facto standard so these methods recommend
using source control tags that follow SemVer.

Common fields

It's good practice to complete your AssemblyInfo's default fields. The information may be picked
up by installers and will then appear when using Programs and Features (Windows 10) to uninstall
or change a program.

The minimum should be:

• AssemblyTitle - usually the namespace, i.e. MyCompany.MySolution.MyProject


• AssemblyCompany - the legal entities full name
• AssemblyProduct - marketing may have a view here
• AssemblyCopyright - keep it up to date as it looks scruffy otherwise

'AssemblyTitle' becomes the 'File description' when examining the DLL's Properties Details tab.

[AssemblyConfiguration]

AssemblyConfiguration: The AssemblyConfiguration attribute must have the configuration that was
used to build the assembly. Use conditional compilation to properly include different assembly
configurations. Use the block similar to the example below. Add as many different configurations
as you commonly use.

#if (DEBUG)

[assembly: AssemblyConfiguration("Debug")]

#else

[assembly: AssemblyConfiguration("Release")]

#endif

[InternalsVisibleTo]

If you want to make internal classes or functions of an assembly accessable from another
assembly you declare this by InternalsVisibleTo and the assembly name that is allowed to access.

In this example code in the assembly MyAssembly.UnitTests is allowed to call internal elements
from MyAssembly.

https://riptutorial.com/ 63
[assembly: InternalsVisibleTo("MyAssembly.UnitTests")]

This is especially useful for unit testing to prevent unnecessary public declarations.

[AssemblyKeyFile]

Whenever we want our assembly to install in GAC then it is must to have a strong name. For
strong naming assembly we have to create a public key. To generate the .snk file.

To create a strong name key file

1. Developers command prompt for VS2015 (with administrator Access)


2. At the command prompt, type cd C:\Directory_Name and press ENTER.
3. At the command prompt, type sn -k KeyFileName.snk, and then press ENTER.

once the keyFileName.snk is created at specified directory then give refernce in your project . give
AssemblyKeyFileAttribute attribute the path to snk file to generate the key when we build our class
library.

Properties -> AssemblyInfo.cs

[assembly: AssemblyKeyFile(@"c:\Directory_Name\KeyFileName.snk")]

Thi will create a strong name assembly after build. After creating your strong name assembly you
can then install it in GAC

Happy Coding :)

Read AssemblyInfo.cs Examples online: https://riptutorial.com/csharp/topic/4264/assemblyinfo-cs-


examples

https://riptutorial.com/ 64
Chapter 13: Async/await, Backgroundworker,
Task and Thread Examples
Remarks
To run any of these examples just call them like that:

static void Main()


{
new Program().ProcessDataAsync();
Console.ReadLine();
}

Examples
ASP.NET Configure Await

When ASP.NET handles a request, a thread is assigned from the thread pool and a request
context is created. The request context contains information about the current request which can
be accessed through the static HttpContext.Current property. The request context for the request is
then assigned to the thread handling the request.

A given request context may only be active on one thread at a time.

When execution reaches await, the thread handling a request is returned to the thread pool while
the asynchronous method runs and the request context is free for another thread to use.

public async Task<ActionResult> Index()


{
// Execution on the initially assigned thread
var products = await dbContext.Products.ToListAsync();

// Execution resumes on a "random" thread from the pool


// Execution continues using the original request context.
return View(products);
}

When the task completes the thread pool assigns another thread to continue execution of the
request. The request context is then assigned to this thread. This may or may not be the original
thread.

Blocking

When the result of an async method call is waited for synchronously deadlocks can arise. For
example the following code will result in a deadlock when IndexSync() is called:

https://riptutorial.com/ 65
public async Task<ActionResult> Index()
{
// Execution on the initially assigned thread
List<Product> products = await dbContext.Products.ToListAsync();

// Execution resumes on a "random" thread from the pool


return View(products);
}

public ActionResult IndexSync()


{
Task<ActionResult> task = Index();

// Block waiting for the result synchronously


ActionResult result = Task.Result;

return result;
}

This is because, by default the awaited task, in this case db.Products.ToListAsync() will capture the
context (in the case of ASP.NET the request context) and try to use it once it has completed.

When the entire call stack is asynchronous there is no problem because, once await is reached
the original thread is release, freeing the request context.

When we block synchronously using Task.Result or Task.Wait() (or other blocking methods) the
original thread is still active and retains the request context. The awaited method still operates
asynchronously and once the callback tries to run, i.e. once the awaited task has returned, it
attempts to obtain the request context.

Therefore the deadlock arises because while the blocking thread with the request context is
waiting for the asynchronous operation to complete, the asynchronous operation is trying to obtain
the request context in order to complete.

ConfigureAwait

By default calls to an awaited task will capture the current context and attempt to resume
execution on the context once complete.

By using ConfigureAwait(false) this can be prevented and deadlocks can be avoided.

public async Task<ActionResult> Index()


{
// Execution on the initially assigned thread
List<Product> products = await dbContext.Products.ToListAsync().ConfigureAwait(false);

// Execution resumes on a "random" thread from the pool without the original request
context
return View(products);
}

public ActionResult IndexSync()


{
Task<ActionResult> task = Index();

https://riptutorial.com/ 66
// Block waiting for the result synchronously
ActionResult result = Task.Result;

return result;
}

This can avoid deadlocks when it is necessary to block on asynchronous code, however this
comes at the cost of losing the context in the continuation (code after the call to await).

In ASP.NET this means that if your code following a call to await someTask.ConfigureAwait(false);
attempts to access information from the context, for example HttpContext.Current.User then the
information has been lost. In this case the HttpContext.Current is null. For example:

public async Task<ActionResult> Index()


{
// Contains information about the user sending the request
var user = System.Web.HttpContext.Current.User;

using (var client = new HttpClient())


{
await client.GetAsync("http://google.com").ConfigureAwait(false);
}

// Null Reference Exception, Current is null


var user2 = System.Web.HttpContext.Current.User;

return View();
}

If ConfigureAwait(true) is used (equivalent to having no ConfigureAwait at all) then both user and
user2 are populated with the same data.

For this reason it is often recommended to use ConfigureAwait(false) in library code where the
context is no longer used.

Async/await

See below for a simple example of how to use async/await to do some time intensive stuff in a
background process while maintaining the option of doing some other stuff that do not need to wait
on the time intensive stuff to complete.

However, if you need to work with the result of the time intensive method later, you can do this by
awaiting the execution.

public async Task ProcessDataAsync()


{
// Start the time intensive method
Task<int> task = TimeintensiveMethod(@"PATH_TO_SOME_FILE");

// Control returns here before TimeintensiveMethod returns


Console.WriteLine("You can read this while TimeintensiveMethod is still running.");

// Wait for TimeintensiveMethod to complete and get its result


int x = await task;

https://riptutorial.com/ 67
Console.WriteLine("Count: " + x);
}

private async Task<int> TimeintensiveMethod(object file)


{
Console.WriteLine("Start TimeintensiveMethod.");

// Do some time intensive calculations...


using (StreamReader reader = new StreamReader(file.ToString()))
{
string s = await reader.ReadToEndAsync();

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


s.GetHashCode();
}
Console.WriteLine("End TimeintensiveMethod.");

// return something as a "result"


return new Random().Next(100);
}

BackgroundWorker

See below for a simple example of how to use a BackgroundWorker object to perform time-intensive
operations in a background thread.

You need to:

1. Define a worker method that does the time-intensive work and call it from an event handler
for the DoWork event of a BackgroundWorker.
2. Start the execution with RunWorkerAsync. Any argument required by the worker method
attached to DoWork can be passed in via the DoWorkEventArgs parameter to RunWorkerAsync.

In addition to the DoWork event the BackgroundWorker class also defines two events that should be
used for interacting with the user interface. These are optional.

• The RunWorkerCompleted event is triggered when the DoWork handlers have completed.
• The ProgressChanged event is triggered when the ReportProgress method is called.

public void ProcessDataAsync()


{
// Start the time intensive method
BackgroundWorker bw = new BackgroundWorker();
bw.DoWork += BwDoWork;
bw.RunWorkerCompleted += BwRunWorkerCompleted;
bw.RunWorkerAsync(@"PATH_TO_SOME_FILE");

// Control returns here before TimeintensiveMethod returns


Console.WriteLine("You can read this while TimeintensiveMethod is still running.");
}

// Method that will be called after BwDoWork exits


private void BwRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// we can access possible return values of our Method via the Parameter e
Console.WriteLine("Count: " + e.Result);

https://riptutorial.com/ 68
}

// execution of our time intensive Method


private void BwDoWork(object sender, DoWorkEventArgs e)
{
e.Result = TimeintensiveMethod(e.Argument);
}

private int TimeintensiveMethod(object file)


{
Console.WriteLine("Start TimeintensiveMethod.");

// Do some time intensive calculations...


using (StreamReader reader = new StreamReader(file.ToString()))
{
string s = reader.ReadToEnd();

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


s.GetHashCode();
}
Console.WriteLine("End TimeintensiveMethod.");

// return something as a "result"


return new Random().Next(100);
}

Task

See below for a simple example of how to use a Task to do some time intensive stuff in a
background process.

All you need to do is wrap your time intensive method in a Task.Run() call.

public void ProcessDataAsync()


{
// Start the time intensive method
Task<int> t = Task.Run(() => TimeintensiveMethod(@"PATH_TO_SOME_FILE"));

// Control returns here before TimeintensiveMethod returns


Console.WriteLine("You can read this while TimeintensiveMethod is still running.");

Console.WriteLine("Count: " + t.Result);


}

private int TimeintensiveMethod(object file)


{
Console.WriteLine("Start TimeintensiveMethod.");

// Do some time intensive calculations...


using (StreamReader reader = new StreamReader(file.ToString()))
{
string s = reader.ReadToEnd();

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


s.GetHashCode();
}
Console.WriteLine("End TimeintensiveMethod.");

https://riptutorial.com/ 69
// return something as a "result"
return new Random().Next(100);
}

Thread

See below for a simple example of how to use a Thread to do some time intensive stuff in a
background process.

public async void ProcessDataAsync()


{
// Start the time intensive method
Thread t = new Thread(TimeintensiveMethod);

// Control returns here before TimeintensiveMethod returns


Console.WriteLine("You can read this while TimeintensiveMethod is still running.");
}

private void TimeintensiveMethod()


{
Console.WriteLine("Start TimeintensiveMethod.");

// Do some time intensive calculations...


using (StreamReader reader = new StreamReader(@"PATH_TO_SOME_FILE"))
{
string v = reader.ReadToEnd();

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


v.GetHashCode();
}
Console.WriteLine("End TimeintensiveMethod.");
}

As you can see we can not return a value from our TimeIntensiveMethod because Thread expects a
void Method as its parameter.

To get a return value from a Thread use either an event or the following:

int ret;
Thread t= new Thread(() =>
{
Console.WriteLine("Start TimeintensiveMethod.");

// Do some time intensive calculations...


using (StreamReader reader = new StreamReader(file))
{
string s = reader.ReadToEnd();

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


s.GetHashCode();
}
Console.WriteLine("End TimeintensiveMethod.");

// return something to demonstrate the coolness of await-async


ret = new Random().Next(100);
});

https://riptutorial.com/ 70
t.Start();
t.Join(1000);
Console.Writeline("Count: " + ret);

Task "run and forget" extension

In certain cases (e.g. logging) it might be useful to run task and do not await for the result. The
following extension allows to run task and continue execution of the rest code:

public static class TaskExtensions


{
public static async void RunAndForget(
this Task task, Action<Exception> onException = null)
{
try
{
await task;
}
catch (Exception ex)
{
onException?.Invoke(ex);
}
}
}

The result is awaited only inside the extension method. Since async/await is used, it is possible to
catch an exception and call an optional method for handling it.

An example how to use the extension:

var task = Task.FromResult(0); // Or any other task from e.g. external lib.
task.RunAndForget(
e =>
{
// Something went wrong, handle it.
});

Read Async/await, Backgroundworker, Task and Thread Examples online:


https://riptutorial.com/csharp/topic/3824/async-await--backgroundworker--task-and-thread-
examples

https://riptutorial.com/ 71
Chapter 14: Async-Await
Introduction
In C#, a method declared async won't block within a synchronous process, in case of you're using
I/O based operations (e.g. web access, working with files, ...). The result of such async marked
methods may be awaited via the use of the awaitkeyword.

Remarks
An async method can return void, Task or Task<T>.

The return type Task will wait for the method to finish and the result will be void. Task<T> will return
a value from type T after the method completes.

async methods should return Task or Task<T>, as opposed to void, in almost all circumstances. async
void methods cannot be awaited, which leads to a variety of problems. The only scenario where an
async should return void is in the case of an event handler.

async/await works by transforming your async method into a state machine. It does this by creating
a structure behind the scenes which stores the current state and any context (like local variables),
and exposes a MoveNext() method to advance states (and run any associated code) whenever an
awaited awaitable completes.

Examples
Simple consecutive calls

public async Task<JobResult> GetDataFromWebAsync()


{
var nextJob = await _database.GetNextJobAsync();
var response = await _httpClient.GetAsync(nextJob.Uri);
var pageContents = await response.Content.ReadAsStringAsync();
return await _database.SaveJobResultAsync(pageContents);
}

The main thing to note here is that while every await-ed method is called asynchronously - and for
the time of that call the control is yielded back to the system - the flow inside the method is linear
and does not require any special treatment due to asynchrony. If any of the methods called fail,
the exception will be processed "as expected", which in this case means that the method
execution will be aborted and the exception will be going up the stack.

Try/Catch/Finally

6.0

https://riptutorial.com/ 72
As of C# 6.0, the await keyword can now be used within a catch and finally block.

try {
var client = new AsyncClient();
await client.DoSomething();
} catch (MyException ex) {
await client.LogExceptionAsync();
throw;
} finally {
await client.CloseAsync();
}

5.06.0

Prior to C# 6.0, you would need to do something along the lines of the following. Note that 6.0 also
cleaned up the null checks with the Null Propagating operator.

AsynClient client;
MyException caughtException;
try {
client = new AsyncClient();
await client.DoSomething();
} catch (MyException ex) {
caughtException = ex;
}

if (client != null) {
if (caughtException != null) {
await client.LogExceptionAsync();
}
await client.CloseAsync();
if (caughtException != null) throw caughtException;
}

Please note that if you await a task not created by async (e.g. a task created by Task.Run), some
debuggers may break on exceptions thrown by the task even when it is seemingly handled by the
surrounding try/catch. This happens because the debugger considers it to be unhandled with
respect to user code. In Visual Studio, there is an option called "Just My Code", which can be
disabled to prevent the debugger from breaking in such situations.

Web.config setup to target 4.5 for correct async behaviour.

The web.config system.web.httpRuntime must target 4.5 to ensure the thread will renter the
request context before resuming your async method.

<httpRuntime targetFramework="4.5" />

Async and await have undefined behavior on ASP.NET prior to 4.5. Async / await will resume on
an arbitrary thread that may not have the request context. Applications under load will randomly
fail with null reference exceptions accessing the HttpContext after the await. Using
HttpContext.Current in WebApi is dangerous because of async

https://riptutorial.com/ 73
Concurrent calls

It is possible to await multiple calls concurrently by first invoking the awaitable tasks and then
awaiting them.

public async Task RunConcurrentTasks()


{
var firstTask = DoSomethingAsync();
var secondTask = DoSomethingElseAsync();

await firstTask;
await secondTask;
}

Alternatively, Task.WhenAll can be used to group multiple tasks into a single Task, which completes
when all of its passed tasks are complete.

public async Task RunConcurrentTasks()


{
var firstTask = DoSomethingAsync();
var secondTask = DoSomethingElseAsync();

await Task.WhenAll(firstTask, secondTask);


}

You can also do this inside a loop, for example:

List<Task> tasks = new List<Task>();


while (something) {
// do stuff
Task someAsyncTask = someAsyncMethod();
tasks.Add(someAsyncTask);
}

await Task.WhenAll(tasks);

To get results from a task after awaiting multiple tasks with Task.WhenAll, simply await the task
again. Since the task is already completed it will just return the result back

var task1 = SomeOpAsync();


var task2 = SomeOtherOpAsync();

await Task.WhenAll(task1, task2);

var result = await task2;

Also, the Task.WhenAny can be used to execute multiple tasks in parallel, like the Task.WhenAll
above, with the difference that this method will complete when any of the supplied tasks will be
completed.

public async Task RunConcurrentTasksWhenAny()


{
var firstTask = TaskOperation("#firstTask executed");

https://riptutorial.com/ 74
var secondTask = TaskOperation("#secondTask executed");
var thirdTask = TaskOperation("#thirdTask executed");
await Task.WhenAny(firstTask, secondTask, thirdTask);
}

The Task returned by RunConcurrentTasksWhenAny will complete when any of firstTask, secondTask, or
thirdTask completes.

Await operator and async keyword

await operator and async keyword come together:

The asynchronous method in which await is used must be modified by the async
keyword.

The opposite is not always true: you can mark a method as async without using await in its body.

What await actually does is to suspend execution of the code until the awaited task completes; any
task can be awaited.

Note: you cannot await for async method which returns nothing (void).

Actually, the word 'suspends' is a bit misleading because not only the execution stops, but the
thread may become free for executing other operations. Under the hood, await is implemented by
a bit of compiler magic: it splits a method into two parts - before and after await. The latter part is
executed when the awaited task completes.

If we ignore some important details, the compiler roughly does this for you:

public async Task<TResult> DoIt()


{
// do something and acquire someTask of type Task<TSomeResult>
var awaitedResult = await someTask;
// ... do something more and produce result of type TResult
return result;
}

becomes:

public Task<TResult> DoIt()


{
// ...
return someTask.ContinueWith(task => {
var result = ((Task<TSomeResult>)task).Result;
return DoIt_Continuation(result);
});
}

private TResult DoIt_Continuation(TSomeResult awaitedResult)


{
// ...
}

https://riptutorial.com/ 75
Any usual method can be turned into async in the following way:

await Task.Run(() => YourSyncMethod());

This can be advantageous when you need to execute a long running method on the UI thread
without freezing the UI.

But there is a very important remark here: Asynchronous does not always mean concurrent
(parallel or even multi-threaded). Even on a single thread, async-await still allows for
asynchronous code. For example, see this custom task scheduler. Such a 'crazy' task scheduler
can simply turn tasks into functions which are called within message loop processing.

We need to ask ourselves: What thread will execute the continuation of our method
DoIt_Continuation?

By default the await operator schedules the execution of continuation with the current
Synchronization context. It means that by default for WinForms and WPF continuation runs in the
UI thread. If, for some reason, you need to change this behavior, use method
Task.ConfigureAwait():

await Task.Run(() => YourSyncMethod()).ConfigureAwait(continueOnCapturedContext: false);

Returning a Task without await

Methods that perform asynchronous operations don't need to use await if:

• There is only one asynchronous call inside the method


• The asynchronous call is at the end of the method
• Catching/handling exception that may happen within the Task is not necessary

Consider this method that returns a Task:

public async Task<User> GetUserAsync(int id)


{
var lookupKey = "Users" + id;

return await dataStore.GetByKeyAsync(lookupKey);


}

If GetByKeyAsync has the same signature as GetUserAsync (returning a Task<User>), the method can
be simplified:

public Task<User> GetUserAsync(int id)


{
var lookupKey = "Users" + id;

return dataStore.GetByKeyAsync(lookupKey);
}

In this case, the method doesn't need to be marked async, even though it's preforming an

https://riptutorial.com/ 76
asynchronous operation. The Task returned by GetByKeyAsync is passed directly to the calling
method, where it will be awaited.

Important: Returning the Task instead of awaiting it, changes the exception behavior of the
method, as it won't throw the exception inside the method which starts the task but in the method
which awaits it.

public Task SaveAsync()


{
try {
return dataStore.SaveChangesAsync();
}
catch(Exception ex)
{
// this will never be called
logger.LogException(ex);
}
}

// Some other code calling SaveAsync()

// If exception happens, it will be thrown here, not inside SaveAsync()


await SaveAsync();

This will improve performance as it will save the compiler the generation of an extra async state
machine.

Blocking on async code can cause deadlocks

It is a bad practice to block on async calls as it can cause deadlocks in environments that have a
synchronization context. The best practice is to use async/await "all the way down." For example,
the following Windows Forms code causes a deadlock:

private async Task<bool> TryThis()


{
Trace.TraceInformation("Starting TryThis");
await Task.Run(() =>
{
Trace.TraceInformation("In TryThis task");
for (int i = 0; i < 100; i++)
{
// This runs successfully - the loop runs to completion
Trace.TraceInformation("For loop " + i);
System.Threading.Thread.Sleep(10);
}
});

// This never happens due to the deadlock


Trace.TraceInformation("About to return");
return true;
}

// Button click event handler


private void button1_Click(object sender, EventArgs e)
{
// .Result causes this to block on the asynchronous call

https://riptutorial.com/ 77
bool result = TryThis().Result;
// Never actually gets here
Trace.TraceInformation("Done with result");
}

Essentially, once the async call completes, it waits for the synchronization context to become
available. However, the event handler "holds on" to the synchronization context while it's waiting
for the TryThis() method to complete, thus causing a circular wait.

To fix this, code should be modified to

private async void button1_Click(object sender, EventArgs e)


{
bool result = await TryThis();
Trace.TraceInformation("Done with result");
}

Note: event handlers are the only place where async void should be used (because you can't await
an async void method).

Async/await will only improve performance if it allows the machine to do


additional work

Consider the following code:

public async Task MethodA()


{
await MethodB();
// Do other work
}

public async Task MethodB()


{
await MethodC();
// Do other work
}

public async Task MethodC()


{
// Or await some other async work
await Task.Delay(100);
}

This will not perform any better than

public void MethodA()


{
MethodB();
// Do other work
}

public void MethodB()


{
MethodC();

https://riptutorial.com/ 78
// Do other work
}

public void MethodC()


{
Thread.Sleep(100);
}

The primary purpose of async/await is to allow the machine to do additional work - for example, to
allow the calling thread to do other work while it's waiting for a result from some I/O operation. In
this case, the calling thread is never allowed to do more work than it would have been able to do
otherwise, so there's no performance gain over simply calling MethodA(), MethodB(), and MethodC()
synchronously.

Read Async-Await online: https://riptutorial.com/csharp/topic/48/async-await

https://riptutorial.com/ 79
Chapter 15: Asynchronous Socket
Introduction
By using asynchronous sockets a server can listening for incoming connections and do some
other logic in the mean time in contrast to synchronous socket when they are listening they block
the main thread and the application is becoming unresponsive an will freeze until a client
connects.

Remarks
Socket and network

How to access a Server outside my own network? This is a common question and when it is
asked is mostly flagged as of topic.

Server Side

On the network of your server you need to port forward your router to your server.

For Example PC where server is running on:

local IP = 192.168.1.115

Server is listening to port 1234.

Forward incoming connections on Port 1234 router to 192.168.1.115

Client Side

The only thing you need to change is the IP. You don't want to connect to your loopback address
but to the public IP from the network your server is running on. This IP you can get here.

_connectingSocket.Connect(new IPEndPoint(IPAddress.Parse("10.10.10.10"), 1234));

So now you create a request on this endpoint : 10.10.10.10:1234 if you did property port forward
your router your server and client will connect without any problem.

If you want to connect to a local IP you won't have to portforwart just change the loopback address
to 192.168.1.178 or something like that.

Sending data:

Data is send in byte array. You need to pack you data into an byte array and unpack it on the
other side.

If you are familiar with socket you also can try to encrypt your byte array before sending. This will

https://riptutorial.com/ 80
prevent anyone from stealing your package.

Examples
Asynchronous Socket (Client / Server) example.

Server Side example

Create Listener for server

Start of with creating an server that will handle clients that connect, and requests that will be send.
So create an Listener Class that will handle this.

class Listener
{
public Socket ListenerSocket; //This is the socket that will listen to any incoming
connections
public short Port = 1234; // on this port we will listen

public Listener()
{
ListenerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream,
ProtocolType.Tcp);
}
}

First we need to initialize the Listener socket where we can listen on for any connections. We are
going to use an Tcp Socket that is why we use SocketType.Stream. Also we specify to witch port
the server should listen to

Then we start listening for any incoming connections.

The tree methods we use here are:

1. ListenerSocket.Bind();

This method binds the socket to an IPEndPoint. This class contains the host and local or
remote port information needed by an application to connect to a service on a host.

2. ListenerSocket.Listen(10);

The backlog parameter specifies the number of incoming connections that can be queued for
acceptance.

3. ListenerSocket.BeginAccept();

The server will start listening for incoming connections and will go on with other logic. When
there is an connection the server switches back to this method and will run the
AcceptCallBack methodt

public void StartListening()

https://riptutorial.com/ 81
{
try
{
MessageBox.Show($"Listening started port:{Port} protocol type:
{ProtocolType.Tcp}");
ListenerSocket.Bind(new IPEndPoint(IPAddress.Any, Port));
ListenerSocket.Listen(10);
ListenerSocket.BeginAccept(AcceptCallback, ListenerSocket);
}
catch(Exception ex)
{
throw new Exception("listening error" + ex);
}
}

So when a client connects we can accept them by this method:

Three methods wee use here are:

1. ListenerSocket.EndAccept()

We started the callback with Listener.BeginAccept() end now we have to end that call back.
The EndAccept() method accepts an IAsyncResult parameter, this will store the state of the
asynchronous method, From this state we can extract the socket where the incoming
connection was coming from.

2. ClientController.AddClient()

With the socket we got from EndAccept() we create an Client with an own made method
(code ClientController below server example).

3. ListenerSocket.BeginAccept()

We need to start listening again when the socket is done with handling the new connection.
Pass in the method who will catch this callback. And also pass int the Listener socket so we
can reuse this socket for upcoming connections.

public void AcceptCallback(IAsyncResult ar)


{
try
{
Console.WriteLine($"Accept CallBack port:{Port} protocol type:
{ProtocolType.Tcp}");
Socket acceptedSocket = ListenerSocket.EndAccept(ar);
ClientController.AddClient(acceptedSocket);

ListenerSocket.BeginAccept(AcceptCallback, ListenerSocket);
}
catch (Exception ex)
{
throw new Exception("Base Accept error"+ ex);
}
}

Now we have an Listening Socket but how do we receive data send by the client that is what the

https://riptutorial.com/ 82
next code is showing.

Create Server Receiver for each client

First of create a receive class with a constructor that takes in a Socket as parameter:

public class ReceivePacket


{
private byte[] _buffer;
private Socket _receiveSocket;

public ReceivePacket(Socket receiveSocket)


{
_receiveSocket = receiveSocket;
}
}

In the next method we first start off with giving the buffer a size of 4 bytes (Int32) or package
contains to parts {lenght, actual data}. So the first 4 bytes we reserve for the lenght of the data the
rest for the actual data.

Next we use BeginReceive() method. This method is used to start receiving from connected
clients and when it will receive data it will run the ReceiveCallback function.

public void StartReceiving()


{
try
{
_buffer = new byte[4];
_receiveSocket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None,
ReceiveCallback, null);
}
catch {}
}

private void ReceiveCallback(IAsyncResult AR)


{
try
{
// if bytes are less than 1 takes place when a client disconnect from the server.
// So we run the Disconnect function on the current client
if (_receiveSocket.EndReceive(AR) > 1)
{
// Convert the first 4 bytes (int 32) that we received and convert it to an
Int32 (this is the size for the coming data).
_buffer = new byte[BitConverter.ToInt32(_buffer, 0)];
// Next receive this data into the buffer with size that we did receive before
_receiveSocket.Receive(_buffer, _buffer.Length, SocketFlags.None);
// When we received everything its onto you to convert it into the data that
you've send.
// For example string, int etc... in this example I only use the
implementation for sending and receiving a string.

// Convert the bytes to string and output it in a message box


string data = Encoding.Default.GetString(_buffer);
MessageBox.Show(data);
// Now we have to start all over again with waiting for a data to come from

https://riptutorial.com/ 83
the socket.
StartReceiving();
}
else
{
Disconnect();
}
}
catch
{
// if exeption is throw check if socket is connected because than you can
startreive again else Dissconect
if (!_receiveSocket.Connected)
{
Disconnect();
}
else
{
StartReceiving();
}
}
}

private void Disconnect()


{
// Close connection
_receiveSocket.Disconnect(true);
// Next line only apply for the server side receive
ClientController.RemoveClient(_clientId);
// Next line only apply on the Client Side receive
Here you want to run the method TryToConnect()
}

So we've setup a server that can receive and listen for incoming connections. When a clients
connect it will be added to a list of clients and every client has his own receive class. To make the
server listen:

Listener listener = new Listener();


listener.StartListening();

Some Classes I use in this example

class Client
{
public Socket _socket { get; set; }
public ReceivePacket Receive { get; set; }
public int Id { get; set; }

public Client(Socket socket, int id)


{
Receive = new ReceivePacket(socket, id);
Receive.StartReceiving();
_socket = socket;
Id = id;
}
}

static class ClientController

https://riptutorial.com/ 84
{
public static List<Client> Clients = new List<Client>();

public static void AddClient(Socket socket)


{
Clients.Add(new Client(socket,Clients.Count));
}

public static void RemoveClient(int id)


{
Clients.RemoveAt(Clients.FindIndex(x => x.Id == id));
}
}

Client Side example

Connecting to server

First of all we want to create a class what connects to the server te name we give it is: Connector:

class Connector
{
private Socket _connectingSocket;
}

Next Method for this class is TryToConnect()

This method goth a few interestin things:

1. Create the socket;

2. Next I loop until the socket is connected

3. Every loop it is just holding the Thread for 1 second we don't want to DOS the server XD

4. With Connect() it will try to connect to the server. If it fails it will throw an exception but the
wile will keep the program connecting to the server. You can use a Connect CallBack
method for this, but I'll just go for calling a method when the Socket is connected.

5. Notice the Client is now trying to connect to your local pc on port 1234.

public void TryToConnect()


{
_connectingSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream,
ProtocolType.Tcp);

while (!_connectingSocket.Connected)
{
Thread.Sleep(1000);

try
{
_connectingSocket.Connect(new IPEndPoint(IPAddress.Parse("127.0.0.1"),
1234));
}

https://riptutorial.com/ 85
catch { }
}
SetupForReceiveing();
}
}

private void SetupForReceiveing()


{
// View Client Class bottom of Client Example
Client.SetClient(_connectingSocket);
Client.StartReceiving();
}

Sending a message to the server

So now we have an almost finish or Socket application. The only thing that we don't have jet is a
Class for sending a message to the server.

public class SendPacket


{
private Socket _sendSocked;

public SendPacket(Socket sendSocket)


{
_sendSocked = sendSocket;
}

public void Send(string data)


{
try
{
/* what hapends here:
1. Create a list of bytes
2. Add the length of the string to the list.
So if this message arrives at the server we can easily read the length of
the coming message.
3. Add the message(string) bytes
*/

var fullPacket = new List<byte>();


fullPacket.AddRange(BitConverter.GetBytes(data.Length));
fullPacket.AddRange(Encoding.Default.GetBytes(data));

/* Send the message to the server we are currently connected to.


Or package stucture is {length of data 4 bytes (int32), actual data}*/
_sendSocked.Send(fullPacket.ToArray());
}
catch (Exception ex)
{
throw new Exception();
}
}

Finaly crate two buttons one for connect and the other for sending a message:

private void ConnectClick(object sender, EventArgs e)


{
Connector tpp = new Connector();

https://riptutorial.com/ 86
tpp.TryToConnect();
}

private void SendClick(object sender, EventArgs e)


{
Client.SendString("Test data from client");
}

The client class I used in this example

public static void SetClient(Socket socket)


{
Id = 1;
Socket = socket;
Receive = new ReceivePacket(socket, Id);
SendPacket = new SendPacket(socket);
}

Notice

The Receive Class from the server is the same as the receive class from the client.

Conclusion

You now have a server and a client. You can work this basic example out. For example make it
that the server also can receive files or other tings. Or send a message to the client. In the server
you got a list of client so when you receive something you will know from with client it came from.

Final result:

https://riptutorial.com/ 87
Read Asynchronous Socket online: https://riptutorial.com/csharp/topic/9638/asynchronous-socket

https://riptutorial.com/ 88
Chapter 16: Attributes
Examples
Creating a custom attribute

//1) All attributes should be inherited from System.Attribute


//2) You can customize your attribute usage (e.g. place restrictions) by using
System.AttributeUsage Attribute
//3) You can use this attribute only via reflection in the way it is supposed to be used
//4) MethodMetadataAttribute is just a name. You can use it without "Attribute" postfix - e.g.
[MethodMetadata("This text could be retrieved via reflection")].
//5) You can overload an attribute constructors
[System.AttributeUsage(System.AttributeTargets.Method | System.AttributeTargets.Class)]
public class MethodMetadataAttribute : System.Attribute
{
//this is custom field given just for an example
//you can create attribute without any fields
//even an empty attribute can be used - as marker
public string Text { get; set; }

//this constructor could be used as [MethodMetadata]


public MethodMetadataAttribute ()
{
}

//This constructor could be used as [MethodMetadata("String")]


public MethodMetadataAttribute (string text)
{
Text = text;
}
}

Using an attribute

[StackDemo(Text = "Hello, World!")]


public class MyClass
{
[StackDemo("Hello, World!")]
static void MyMethod()
{
}
}

Reading an attribute

Method GetCustomAttributes returns an array of custom attributes applied to the member. After
retrieving this array you can search for one or more specific attributes.

var attribute = typeof(MyClass).GetCustomAttributes().OfType<MyCustomAttribute>().Single();

Or iterate through them

https://riptutorial.com/ 89
foreach(var attribute in typeof(MyClass).GetCustomAttributes()) {
Console.WriteLine(attribute.GetType());
}

GetCustomAttribute extension method from System.Reflection.CustomAttributeExtensions retrieves a


custom attribute of a specified type, it can be applied to any MemberInfo.

var attribute = (MyCustomAttribute)


typeof(MyClass).GetCustomAttribute(typeof(MyCustomAttribute));

GetCustomAttribute also has generic signature to specify type of attribute to search for.

var attribute = typeof(MyClass).GetCustomAttribute<MyCustomAttribute>();

Boolean argument inherit can be passed to both of those methods. If this value set to true the
ancestors of element would be also to inspected.

DebuggerDisplay Attribute

Adding the DebuggerDisplay Attribute will change the way the debugger displays the class when it is
hovered over.

Expressions that are wrapped in {} will be evaluated by the debugger. This can be a simple
property like in the following sample or more complex logic.

[DebuggerDisplay("{StringProperty} - {IntProperty}")]
public class AnObject
{
public int ObjectId { get; set; }
public string StringProperty { get; set; }
public int IntProperty { get; set; }
}

Adding ,nq before the closing bracket removes the quotes when outputting a string.

[DebuggerDisplay("{StringProperty,nq} - {IntProperty}")]

Even though general expressions are allowed in the {} they are not recommended. The
DebuggerDisplay attribute will be written into the assembly metadata as a string. Expressions in {}
are not checked for validity. So a DebuggerDisplay attribute containing more complex logic than i.e.
some simple arithmetic might work fine in C#, but the same expression evaluated in VB.NET will

https://riptutorial.com/ 90
probably not be syntactically valid and produce an error while debugging.

A way to make DebuggerDisplay more language agnostic is to write the expression in a method or
property and call it instead.

[DebuggerDisplay("{DebuggerDisplay(),nq}")]
public class AnObject
{
public int ObjectId { get; set; }
public string StringProperty { get; set; }
public int IntProperty { get; set; }

private string DebuggerDisplay()


{
return $"{StringProperty} - {IntProperty}"";
}
}

One might want DebuggerDisplayto output all or just some of the properties and when debugging
and inspecting also the type of the object.
The example below also surrounds the helper method with #if DEBUG as DebuggerDisplay is used in
debugging environments.

[DebuggerDisplay("{DebuggerDisplay(),nq}")]
public class AnObject
{
public int ObjectId { get; set; }
public string StringProperty { get; set; }
public int IntProperty { get; set; }

#if DEBUG
private string DebuggerDisplay()
{
return
$"ObjectId:{this.ObjectId}, StringProperty:{this.StringProperty},
Type:{this.GetType()}";
}
#endif
}

Caller info attributes

Caller info attributes can be used to pass down information about the invoker to the invoked
method. The declaration looks like this:

using System.Runtime.CompilerServices;

public void LogException(Exception ex,


[CallerMemberName]string callerMemberName = "",
[CallerLineNumber]int callerLineNumber = 0,
[CallerFilePath]string callerFilePath = "")
{
//perform logging
}

https://riptutorial.com/ 91
And the invocation looks like this:

public void Save(DBContext context)


{
try
{
context.SaveChanges();
}
catch (Exception ex)
{
LogException(ex);
}
}

Notice that only the first parameter is passed explicitly to the LogException method whereas the rest
of them will be provided at compile time with the relevant values.

The callerMemberName parameter will receive the value "Save" - the name of the calling method.

The callerLineNumber parameter will receive the number of whichever line the LogException method
call is written on.

And the 'callerFilePath' parameter will receive the full path of the file Save method is declared in.

Reading an attribute from interface

There is no simple way to obtain attributes from an interface, since classes does not inherit
attributes from an interface. Whenever implementing an interface or overriding members in a
derived class, you need to re-declare the attributes. So in the example below output would be True
in all three cases.

using System;
using System.Linq;
using System.Reflection;

namespace InterfaceAttributesDemo {

[AttributeUsage(AttributeTargets.Interface, Inherited = true)]


class MyCustomAttribute : Attribute {
public string Text { get; set; }
}

[MyCustomAttribute(Text = "Hello from interface attribute")]


interface IMyClass {
void MyMethod();
}

class MyClass : IMyClass {


public void MyMethod() { }
}

public class Program {


public static void Main(string[] args) {
GetInterfaceAttributeDemo();
}

https://riptutorial.com/ 92
private static void GetInterfaceAttributeDemo() {
var attribute1 = (MyCustomAttribute)
typeof(MyClass).GetCustomAttribute(typeof(MyCustomAttribute), true);
Console.WriteLine(attribute1 == null); // True

var attribute2 =
typeof(MyClass).GetCustomAttributes(true).OfType<MyCustomAttribute>().SingleOrDefault();
Console.WriteLine(attribute2 == null); // True

var attribute3 = typeof(MyClass).GetCustomAttribute<MyCustomAttribute>(true);


Console.WriteLine(attribute3 == null); // True
}
}
}

One way to retrieve interface attributes is to search for them through all the interfaces
implemented by a class.

var attribute = typeof(MyClass).GetInterfaces().SelectMany(x =>


x.GetCustomAttributes().OfType<MyCustomAttribute>()).SingleOrDefault();
Console.WriteLine(attribute == null); // False
Console.WriteLine(attribute.Text); // Hello from interface attribute

Obsolete Attribute

System.Obsolete is an attribute that is used to mark a type or a member that has a better version,
and thus should not be used.

[Obsolete("This class is obsolete. Use SomeOtherClass instead.")]


class SomeClass
{
//
}

In case the class above is used, the compiler will give the warning "This class is obsolete. Use
SomeOtherClass instead."

Read Attributes online: https://riptutorial.com/csharp/topic/1062/attributes

https://riptutorial.com/ 93
Chapter 17: BackgroundWorker
Syntax
• bgWorker.CancellationPending //returns whether the bgWorker was cancelled during its
operation

• bgWorker.IsBusy //returns true if the bgWorker is in the middle of an operation

• bgWorker.ReportProgress(int x) //Reports a change in progress. Raises the "ProgressChanged"


event

• bgWorker.RunWorkerAsync() //Starts the BackgroundWorker by raising the "DoWork" event

• bgWorker.CancelAsync() //instructs the BackgroundWorker to stop after the completion of a


task.

Remarks
Performing long-running operations within the UI thread can cause your application to become
unresponsive, appearing to the user that it has stopped working. It is preferred that these tasks be
run on a background thread. Once complete, the UI can be updated.

Making changes to the UI during the BackgroundWorker's operation requires invoking the
changes to the UI thread, typically by using the Control.Invoke method on the control you are
updating. Neglecting to do so will cause your program to throw an exception.

The BackgroundWorker is typically only used in Windows Forms applications. In WPF


applications, Tasks are used to offload work onto background threads (possibly in combination
with async/await). Marshalling updates onto the UI thread is typically done automatically, when the
property being updated implements INotifyPropertyChanged, or manually by using the UI thread's
Dispatcher.

Examples
Assigning Event Handlers to a BackgroundWorker

Once the instance of the BackgroundWorker has been declared, it must be given properties and
event handlers for the tasks it performs.

/* This is the backgroundworker's "DoWork" event handler. This


method is what will contain all the work you
wish to have your program perform without blocking the UI. */

bgWorker.DoWork += bgWorker_DoWork;

/*This is how the DoWork event method signature looks like:*/


private void bgWorker_DoWork(object sender, DoWorkEventArgs e)
{

https://riptutorial.com/ 94
// Work to be done here
// ...
// To get a reference to the current Backgroundworker:
BackgroundWorker worker = sender as BackgroundWorker;
// The reference to the BackgroundWorker is often used to report progress
worker.ReportProgress(...);
}

/*This is the method that will be run once the BackgroundWorker has completed its tasks */

bgWorker.RunWorkerCompleted += bgWorker_CompletedWork;

/*This is how the RunWorkerCompletedEvent event method signature looks like:*/


private void bgWorker_CompletedWork(object sender, RunWorkerCompletedEventArgs e)
{
// Things to be done after the backgroundworker has finished
}

/* When you wish to have something occur when a change in progress


occurs, (like the completion of a specific task) the "ProgressChanged"
event handler is used. Note that ProgressChanged events may be invoked
by calls to bgWorker.ReportProgress(...) only if bgWorker.WorkerReportsProgress
is set to true. */

bgWorker.ProgressChanged += bgWorker_ProgressChanged;

/*This is how the ProgressChanged event method signature looks like:*/


private void bgWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
// Things to be done when a progress change has been reported

/* The ProgressChangedEventArgs gives access to a percentage,


allowing for easy reporting of how far along a process is*/
int progress = e.ProgressPercentage;
}

Assigning Properties to a BackgroundWorker

This allows the BackgroundWorker to be cancelled in between tasks

bgWorker.WorkerSupportsCancellation = true;

This allows the worker to report progress between completion of tasks...

bgWorker.WorkerReportsProgress = true;

//this must also be used in conjunction with the ProgressChanged event

Creating a new BackgroundWorker instance

A BackgroundWorker is commonly used to perform tasks, sometimes time consuming, without


blocking the UI thread.

// BackgroundWorker is part of the ComponentModel namespace.


using System.ComponentModel;

https://riptutorial.com/ 95
namespace BGWorkerExample
{
public partial class ExampleForm : Form
{

// the following creates an instance of the BackgroundWorker named "bgWorker"


BackgroundWorker bgWorker = new BackgroundWorker();

public ExampleForm() { ...

Using a BackgroundWorker to complete a task.

The following example demonstrates the use of a BackgroundWorker to update a WinForms


ProgressBar. The backgroundWorker will update the value of the progress bar without blocking
the UI thread, thus showing a reactive UI while work is done in the background.

namespace BgWorkerExample
{
public partial class Form1 : Form
{

//a new instance of a backgroundWorker is created.


BackgroundWorker bgWorker = new BackgroundWorker();

public Form1()
{
InitializeComponent();

prgProgressBar.Step = 1;

//this assigns event handlers for the backgroundWorker


bgWorker.DoWork += bgWorker_DoWork;
bgWorker.RunWorkerCompleted += bgWorker_WorkComplete;

//tell the backgroundWorker to raise the "DoWork" event, thus starting it.
//Check to make sure the background worker is not already running.
if(!bgWorker.IsBusy)
bgWorker.RunWorkerAsync();

private void bgWorker_DoWork(object sender, DoWorkEventArgs e)


{
//this is the method that the backgroundworker will perform on in the background
thread.
/* One thing to note! A try catch is not necessary as any exceptions will terminate
the backgroundWorker and report
the error to the "RunWorkerCompleted" event */
CountToY();
}

private void bgWorker_WorkComplete(object sender, RunWorkerCompletedEventArgs e)


{
//e.Error will contain any exceptions caught by the backgroundWorker
if (e.Error != null)
{
MessageBox.Show(e.Error.Message);

https://riptutorial.com/ 96
}
else
{
MessageBox.Show("Task Complete!");
prgProgressBar.Value = 0;
}
}

// example method to perform a "long" running task.


private void CountToY()
{
int x = 0;

int maxProgress = 100;


prgProgressBar.Maximum = maxProgress;

while (x < maxProgress)


{
System.Threading.Thread.Sleep(50);
Invoke(new Action(() => { prgProgressBar.PerformStep(); }));
x += 1;
}
}

The result is the following...

Read BackgroundWorker online: https://riptutorial.com/csharp/topic/1588/backgroundworker

https://riptutorial.com/ 97
Chapter 18: BigInteger
Remarks

When To Use
objects are by their very nature very heavy on RAM. Consequently, they should only be
BigInteger
used when absolutely necessary, ie for numbers on a truly astronomical scale.

Further to this, all arithmetic operations on these objects are an order of magnitude slower than
their primitive counterparts, this problem gets further compounded as the number grows as they
are not of a fixed size. It is therefore feasibly possible for a rogue BigInteger to cause a crash by
consuming all of the available RAM.

Alternatives
If speed is imperative to your solution it may be more efficient to implement this functionality
yourself using a class wrapping a Byte[] and overloading the necessary operators yourself.
However, this does require a significant amount of extra effort.

Examples
Calculate the First 1,000-Digit Fibonacci Number

Include using System.Numerics and add a reference to System.Numerics to the project.

using System;
using System.Numerics;

namespace Euler_25
{
class Program
{
static void Main(string[] args)
{
BigInteger l1 = 1;
BigInteger l2 = 1;
BigInteger current = l1 + l2;
while (current.ToString().Length < 1000)
{
l2 = l1;
l1 = current;
current = l1 + l2;
}
Console.WriteLine(current);
}
}
}

https://riptutorial.com/ 98
This simple algorithm iterates through Fibonacci numbers until it reaches one at least 1000
decimal digits in length, then prints it out. This value is significantly larger than even a ulong could
hold.

Theoretically, the only limit on the BigInteger class is the amount of RAM your application can
consume.

Note: BigInteger is only available in .NET 4.0 and higher.

Read BigInteger online: https://riptutorial.com/csharp/topic/5654/biginteger

https://riptutorial.com/ 99
Chapter 19: Binary Serialization
Remarks
The binary serialization engine is part of the .NET framework, but the examples given here are
specific to C#. As compared to other serialization engines built into the .NET framework, the binary
serializer is fast and efficient and usually requires very little extra code to get it to work. However, it
is also less tolerant to code changes; that is, if you serialize an object and then make a slight
change to the object's definition, it likely will not deserialize correctly.

Examples
Making an object serializable

Add the [Serializable] attribute to mark an entire object for binary serialization:

[Serializable]
public class Vector
{
public int X;
public int Y;
public int Z;

[NonSerialized]
public decimal DontSerializeThis;

[OptionalField]
public string Name;
}

All members will be serialized unless we explicitly opt-out using the [NonSerialized] attribute. In
our example, X, Y, Z, and Name are all serialized.

All members are required to be present on deserialization unless marked with [NonSerialized] or
[OptionalField]. In our example, X, Y, and Z are all required and deserialization will fail if they are
not present in the stream. DontSerializeThis will always be set to default(decimal) (which is 0). If
Name is present in the stream, then it will be set to that value, otherwise it will be set to
default(string) (which is null). The purpose of [OptionalField] is to provide a bit of version
tolerance.

Controlling serialization behavior with attributes

If you use the [NonSerialized] attribute, then that member will always have its default value after
deserialization (ex. 0 for an int, null for string, false for a bool, etc.), regardless of any initialization
done in the object itself (constructors, declarations, etc.). To compensate, the attributes
[OnDeserializing] (called just BEFORE deserializing) and [OnDeserialized] (called just AFTER
deserializing) together with their counterparts, [OnSerializing] and [OnSerialized] are provided.

https://riptutorial.com/ 100
Assume we want to add a "Rating" to our Vector and we want to make sure the value always
starts at 1. The way it is written below, it will be 0 after being deserialized:

[Serializable]
public class Vector
{
public int X;
public int Y;
public int Z;

[NonSerialized]
public decimal Rating = 1M;

public Vector()
{
Rating = 1M;
}

public Vector(decimal initialRating)


{
Rating = initialRating;
}
}

To fix this problem, we can simply add the following method inside of the class to set it to 1:

[OnDeserializing]
void OnDeserializing(StreamingContext context)
{
Rating = 1M;
}

Or, if we want to set it to a calculated value, we can wait for it to be finished deserializing and then
set it:

[OnDeserialized]
void OnDeserialized(StreamingContext context)
{
Rating = 1 + ((X+Y+Z)/3);
}

Similarly, we can control how things are written out by using [OnSerializing] and [OnSerialized].

Adding more control by implementing ISerializable

That would get more control over serialization, how to save and load types

Implement ISerializable interface and create an empty constructor to compile

[Serializable]
public class Item : ISerializable
{
private string _name;

https://riptutorial.com/ 101
public string Name
{
get { return _name; }
set { _name = value; }
}

public Item ()
{

protected Item (SerializationInfo info, StreamingContext context)


{
_name = (string)info.GetValue("_name", typeof(string));
}

public void GetObjectData(SerializationInfo info, StreamingContext context)


{
info.AddValue("_name", _name, typeof(string));
}
}

For data serialization, you can specify the desired name and the desired type

info.AddValue("_name", _name, typeof(string));

When the data is deserialized, you will be able to read the desired type

_name = (string)info.GetValue("_name", typeof(string));

Serialization surrogates (Implementing ISerializationSurrogate)

Implements a serialization surrogate selector that allows one object to perform serialization and
deserialization of another

As well allows to properly serialize or deserialize a class that is not itself serializable

Implement ISerializationSurrogate interface

public class ItemSurrogate : ISerializationSurrogate


{
public void GetObjectData(object obj, SerializationInfo info, StreamingContext context)
{
var item = (Item)obj;
info.AddValue("_name", item.Name);
}

public object SetObjectData(object obj, SerializationInfo info, StreamingContext context,


ISurrogateSelector selector)
{
var item = (Item)obj;
item.Name = (string)info.GetValue("_name", typeof(string));
return item;
}
}

https://riptutorial.com/ 102
Then you need to let your IFormatter know about the surrogates by defining and initializing a
SurrogateSelector and assigning it to your IFormatter

var surrogateSelector = new SurrogateSelector();


surrogateSelector.AddSurrogate(typeof(Item), new StreamingContext(StreamingContextStates.All),
new ItemSurrogate());
var binaryFormatter = new BinaryFormatter
{
SurrogateSelector = surrogateSelector
};

Even if the class is not marked serializable.

//this class is not serializable


public class Item
{
private string _name;

public string Name


{
get { return _name; }
set { _name = value; }
}
}

The complete solution

using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

namespace BinarySerializationExample
{
class Item
{
private string _name;

public string Name


{
get { return _name; }
set { _name = value; }
}
}

class ItemSurrogate : ISerializationSurrogate


{
public void GetObjectData(object obj, SerializationInfo info, StreamingContext
context)
{
var item = (Item)obj;
info.AddValue("_name", item.Name);
}

public object SetObjectData(object obj, SerializationInfo info, StreamingContext


context, ISurrogateSelector selector)
{
var item = (Item)obj;

https://riptutorial.com/ 103
item.Name = (string)info.GetValue("_name", typeof(string));
return item;
}
}

class Program
{
static void Main(string[] args)
{
var item = new Item
{
Name = "Orange"
};

var bytes = SerializeData(item);


var deserializedData = (Item)DeserializeData(bytes);
}

private static byte[] SerializeData(object obj)


{
var surrogateSelector = new SurrogateSelector();
surrogateSelector.AddSurrogate(typeof(Item), new
StreamingContext(StreamingContextStates.All), new ItemSurrogate());

var binaryFormatter = new BinaryFormatter


{
SurrogateSelector = surrogateSelector
};

using (var memoryStream = new MemoryStream())


{
binaryFormatter.Serialize(memoryStream, obj);
return memoryStream.ToArray();
}
}

private static object DeserializeData(byte[] bytes)


{
var surrogateSelector = new SurrogateSelector();
surrogateSelector.AddSurrogate(typeof(Item), new
StreamingContext(StreamingContextStates.All), new ItemSurrogate());

var binaryFormatter = new BinaryFormatter


{
SurrogateSelector = surrogateSelector
};

using (var memoryStream = new MemoryStream(bytes))


return binaryFormatter.Deserialize(memoryStream);
}
}
}

Serialization Binder

The binder gives you an opportunity to inspect what types are being loaded in your application
domain

Create a class inherited from SerializationBinder

https://riptutorial.com/ 104
class MyBinder : SerializationBinder
{
public override Type BindToType(string assemblyName, string typeName)
{
if (typeName.Equals("BinarySerializationExample.Item"))
return typeof(Item);
return null;
}
}

Now we can check what types are loading and on this basis to decide what we really want to
receive

For using a binder, you must add it to the BinaryFormatter.

object DeserializeData(byte[] bytes)


{
var binaryFormatter = new BinaryFormatter();
binaryFormatter.Binder = new MyBinder();

using (var memoryStream = new MemoryStream(bytes))


return binaryFormatter.Deserialize(memoryStream);
}

The complete solution

using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

namespace BinarySerializationExample
{
class MyBinder : SerializationBinder
{
public override Type BindToType(string assemblyName, string typeName)
{
if (typeName.Equals("BinarySerializationExample.Item"))
return typeof(Item);
return null;
}
}

[Serializable]
public class Item
{
private string _name;

public string Name


{
get { return _name; }
set { _name = value; }
}
}

class Program
{
static void Main(string[] args)

https://riptutorial.com/ 105
{
var item = new Item
{
Name = "Orange"
};

var bytes = SerializeData(item);


var deserializedData = (Item)DeserializeData(bytes);
}

private static byte[] SerializeData(object obj)


{
var binaryFormatter = new BinaryFormatter();
using (var memoryStream = new MemoryStream())
{
binaryFormatter.Serialize(memoryStream, obj);
return memoryStream.ToArray();
}
}

private static object DeserializeData(byte[] bytes)


{
var binaryFormatter = new BinaryFormatter
{
Binder = new MyBinder()
};

using (var memoryStream = new MemoryStream(bytes))


return binaryFormatter.Deserialize(memoryStream);
}
}
}

Some gotchas in backward compatibility

This small example shows how you can lose backward compatibility in your programs if you do not
take care in advance about this. And ways to get more control of serialization process

At first, we will write an example of the first version of the program:

Version 1

[Serializable]
class Data
{
[OptionalField]
private int _version;

public int Version


{
get { return _version; }
set { _version = value; }
}
}

And now, let us assume that in the second version of the program added a new class. And we
need to store it in an array.

https://riptutorial.com/ 106
Now code will look like this:

Version 2

[Serializable]
class NewItem
{
[OptionalField]
private string _name;

public string Name


{
get { return _name; }
set { _name = value; }
}
}

[Serializable]
class Data
{
[OptionalField]
private int _version;

public int Version


{
get { return _version; }
set { _version = value; }
}

[OptionalField]
private List<NewItem> _newItems;

public List<NewItem> NewItems


{
get { return _newItems; }
set { _newItems = value; }
}
}

And code for serialize and deserialize

private static byte[] SerializeData(object obj)


{
var binaryFormatter = new BinaryFormatter();
using (var memoryStream = new MemoryStream())
{
binaryFormatter.Serialize(memoryStream, obj);
return memoryStream.ToArray();
}
}

private static object DeserializeData(byte[] bytes)


{
var binaryFormatter = new BinaryFormatter();
using (var memoryStream = new MemoryStream(bytes))
return binaryFormatter.Deserialize(memoryStream);
}

https://riptutorial.com/ 107
And so, what would happen when you serialize the data in the program of v2 and will try to
deserialize them in the program of v1?

You get an exception:

System.Runtime.Serialization.SerializationException was unhandled


Message=The ObjectManager found an invalid number of fixups. This usually indicates a problem
in the Formatter.Source=mscorlib
StackTrace:
at System.Runtime.Serialization.ObjectManager.DoFixups()
at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler
handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain,
IMethodCallMessage methodCallMessage)
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream
serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain,
IMethodCallMessage methodCallMessage)
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream
serializationStream)
at Microsoft.Samples.TestV1.Main(String[] args) in c:\Users\andrew\Documents\Visual Studio
2013\Projects\vts\CS\V1 Application\TestV1Part2\TestV1Part2.cs:line 29
at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback
callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()

Why?

The ObjectManager has a different logic to resolve dependencies for arrays and for reference and
value types. We added an array of new the reference type which is absent in our assembly.

When ObjectManager attempts to resolve dependencies it builds the graph. When it sees the
array, it can not fix it immediately, so that it creates a dummy reference and then fixes the array
later.

And since this type is not in the assembly and dependencies can’t be fixed. For some reason, it
does not remove the array from the list of elements for the fixes and at the end, it throws an
exception “IncorrectNumberOfFixups”.

It is some ‘gotchas’ in the process of serialization. For some reason, it does not work correctly only
for arrays of new reference types.

A Note:
Similar code will work correctly if you do not use arrays with new classes

And the first way to fix it and maintain compatibility?

• Use a collection of new structures rather than classes or use a dictionary(possible classes),
because a dictionary it’s a collection of keyvaluepair(it’s structure)
• Use ISerializable, if you can't change the old code

Read Binary Serialization online: https://riptutorial.com/csharp/topic/4120/binary-serialization

https://riptutorial.com/ 108
Chapter 20: BindingList
Examples
Avoiding N*2 iteration

This is placed in a Windows Forms event handler

var nameList = new BindingList<string>();


ComboBox1.DataSource = nameList;
for(long i = 0; i < 10000; i++ ) {
nameList.AddRange(new [] {"Alice", "Bob", "Carol" });
}

This takes a long time to execute, to fix, do the below:

var nameList = new BindingList<string>();


ComboBox1.DataSource = nameList;
nameList.RaiseListChangedEvents = false;
for(long i = 0; i < 10000; i++ ) {
nameList.AddRange(new [] {"Alice", "Bob", "Carol" });
}
nameList.RaiseListChangedEvents = true;
nameList.ResetBindings();

Add item to list

BindingList<string> listOfUIItems = new BindingList<string>();


listOfUIItems.Add("Alice");
listOfUIItems.Add("Bob");

Read BindingList online: https://riptutorial.com/csharp/topic/182/bindinglist-t-

https://riptutorial.com/ 109
Chapter 21: Built-in Types
Examples
Immutable reference type - string

// assign string from a string literal


string s = "hello";

// assign string from an array of characters


char[] chars = new char[] { 'h', 'e', 'l', 'l', 'o' };
string s = new string(chars, 0, chars.Length);

// assign string from a char pointer, derived from a string


string s;
unsafe
{
fixed (char* charPointer = "hello")
{
s = new string(charPointer);
}
}

Value type - char

// single character s
char c = 's';

// character s: casted from integer value


char c = (char)115;

// unicode character: single character s


char c = '\u0073';

// unicode character: smiley face


char c = '\u263a';

Value type - short, int, long (signed 16 bit, 32 bit, 64 bit integers)

// assigning a signed short to its minimum value


short s = -32768;

// assigning a signed short to its maximum value


short s = 32767;

// assigning a signed int to its minimum value


int i = -2147483648;

// assigning a signed int to its maximum value


int i = 2147483647;

// assigning a signed long to its minimum value (note the long postfix)
long l = -9223372036854775808L;

https://riptutorial.com/ 110
// assigning a signed long to its maximum value (note the long postfix)
long l = 9223372036854775807L;

It is also possible to make these types nullable, meaning that additionally to the usual values, null
can be assigned, too. If a variable of a nullable type is not initialized, it will be null instead of 0.
Nullable types are marked by adding a question mark (?) after the type.

int a; //This is now 0.


int? b; //This is now null.

Value type - ushort, uint, ulong (unsigned 16 bit, 32 bit, 64 bit integers)

// assigning an unsigned short to its minimum value


ushort s = 0;

// assigning an unsigned short to its maximum value


ushort s = 65535;

// assigning an unsigned int to its minimum value


uint i = 0;

// assigning an unsigned int to its maximum value


uint i = 4294967295;

// assigning an unsigned long to its minimum value (note the unsigned long postfix)
ulong l = 0UL;

// assigning an unsigned long to its maximum value (note the unsigned long postfix)
ulong l = 18446744073709551615UL;

It is also possible to make these types nullable, meaning that additionally to the usual values, null
can be assigned, too. If a variable of a nullable type is not initialized, it will be null instead of 0.
Nullable types are marked by adding a question mark (?) after the type.

uint a; //This is now 0.


uint? b; //This is now null.

Value type - bool

// default value of boolean is false


bool b;
//default value of nullable boolean is null
bool? z;
b = true;
if(b) {
Console.WriteLine("Boolean has true value");
}

The bool keyword is an alias of System.Boolean. It is used to declare variables to store the
Boolean values, true and false.

https://riptutorial.com/ 111
Comparisons with boxed value types

If value types are assigned to variables of type object they are boxed - the value is stored in an
instance of a System.Object. This can lead to unintended consequences when comparing values
with ==, e.g.:

object left = (int)1; // int in an object box


object right = (int)1; // int in an object box

var comparison1 = left == right; // false

This can be avoided by using the overloaded Equals method, which will give the expected result.

var comparison2 = left.Equals(right); // true

Alternatively, the same could be done by unboxing the left and right variables so that the int
values are compared:

var comparison3 = (int)left == (int)right; // true

Conversion of boxed value types

Boxed value types can only be unboxed into their original Type, even if a conversion of the two Type
s is valid, e.g.:

object boxedInt = (int)1; // int boxed in an object

long unboxedInt1 = (long)boxedInt; // invalid cast

This can be avoided by first unboxing into the original Type, e.g.:

long unboxedInt2 = (long)(int)boxedInt; // valid

Read Built-in Types online: https://riptutorial.com/csharp/topic/42/built-in-types

https://riptutorial.com/ 112
Chapter 22: C# 3.0 Features
Remarks
C# version 3.0 was released as part of .Net version 3.5. Many of the features added with this
version were in support of LINQ (Language INtegrated Queries).

List of added features:

• LINQ
• Lambda expressions
• Extension methods
• Anonymous types
• Implicitly typed variables
• Object and Collection Initializers
• Automatically implemented properties
• Expression trees

Examples
Implicitly typed variables (var)

The var keyword allows a programmer to implicitly type a variable at compile time. var declarations
have the same type as explicitly declared variables.

var squaredNumber = 10 * 10;


var squaredNumberDouble = 10.0 * 10.0;
var builder = new StringBuilder();
var anonymousObject = new
{
One = SquaredNumber,
Two = SquaredNumberDouble,
Three = Builder
}

The types of the above variables are int, double, StringBuilder, and an anonymous type
respectively.

It is important to note that a var variable is not dynamically typed. SquaredNumber = Builder is not
valid since you are trying to set an int to an instance of StringBuilder

Language Integrated Queries (LINQ)

//Example 1
int[] array = { 1, 5, 2, 10, 7 };

// Select squares of all odd numbers in the array sorted in descending order
IEnumerable<int> query = from x in array

https://riptutorial.com/ 113
where x % 2 == 1
orderby x descending
select x * x;
// Result: 49, 25, 1

Example from wikipedia article on C# 3.0, LINQ sub-section

Example 1 uses query syntax which was designed to look similar to SQL queries.

//Example 2
IEnumerable<int> query = array.Where(x => x % 2 == 1)
.OrderByDescending(x => x)
.Select(x => x * x);
// Result: 49, 25, 1 using 'array' as defined in previous example

Example from wikipedia article on C# 3.0, LINQ sub-section

Example 2 uses method syntax to achieve the same outcome as example 1.

It is important to note that, in C#, LINQ query syntax is syntactic sugar for LINQ method syntax.
The compiler translates the queries into method calls at compile time. Some queries have to be
expressed in method syntax. From MSDN - "For example, you must use a method call to express
a query that retrieves the number of elements that match a specified condition."

Lambda expresions

Lambda Expresions are an extension of anonymous methods that allow for implicitly typed
parameters and return values. Their syntax is less verbose than anonymous methods and follows
a functional programming style.

using System;
using System.Collections.Generic;
using System.Linq;

public class Program


{
public static void Main()
{
var numberList = new List<int> {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
var sumOfSquares = numberList.Select( number => number * number )
.Aggregate( (int first, int second) => { return first + second; } );
Console.WriteLine( sumOfSquares );
}
}

The above code will output the sum of the squares of the numbers 1 through 10 to the console.

The first lambda expression squares the numbers in the list. Since there is only 1 parameter
parenthesis may be omitted. You can include parenthesis if you wish:

.Select( (number) => number * number);

https://riptutorial.com/ 114
or explicitly type the parameter but then parenthesis are required:

.Select( (int number) => number * number);

The lambda body is an expression and has an implicit return. You can use a statement body if you
want as well. This is useful for more complex lambdas.

.Select( number => { return number * number; } );

The select method returns a new IEnumerable with the computed values.

The second lambda expression sums the numbers in list returned from the select method.
Parentheses are required as there are multiple parameters. The types of the parameters are
explicitly typed but this is not necessary. The below method is equivalent.

.Aggregate( (first, second) => { return first + second; } );

As is this one:

.Aggregate( (int first, int second) => first + second );

Anonymous types

Anonymous types provide a convenient way to encapsulate a set of read-only properties into a
single object without having to explicitly define a type first. The type name is generated by the
compiler and is not available at the source code level. The type of each property is inferred by the
compiler.

You can make anonymous types by using the new keyword followed by a curly brace ({). Inside the
curly braces, you could define properties like on code below.

var v = new { Amount = 108, Message = "Hello" };

It's also possible to create an array of anonymous types. See code below:

var a = new[] {
new {
Fruit = "Apple",
Color = "Red"
},
new {
Fruit = "Banana",
Color = "Yellow"
}
};

Or use it with LINQ queries:

var productQuery = from prod in products

https://riptutorial.com/ 115
select new { prod.Color, prod.Price };

Read C# 3.0 Features online: https://riptutorial.com/csharp/topic/3820/csharp-3-0-features

https://riptutorial.com/ 116
Chapter 23: C# 4.0 Features
Examples
Optional parameters and named arguments

We can omit the argument in the call if that argument is an Optional Argument Every Optional
Argument has its own default value It will take default value if we do not supply the value A default
value of a Optional Argument must be a

1. Constant expression.
2. Must be a value type such as enum or struct.
3. Must be an expression of the form default(valueType)

It must be set at the end of parameter list

Method parameters with default values:

public void ExampleMethod(int required, string optValue = "test", int optNum = 42)
{
//...
}

As said by MSDN, A named argument ,

Enables you to pass the argument to the function by associating the parameter’s name No needs
for remembering the parameters position that we are not aware of always. No need to look the
order of the parameters in the parameters list of called function. We can specify parameter for
each arguments by its name.

Named arguments:

// required = 3, optValue = "test", optNum = 4


ExampleMethod(3, optNum: 4);
// required = 2, optValue = "foo", optNum = 42
ExampleMethod(2, optValue: "foo");
// required = 6, optValue = "bar", optNum = 1
ExampleMethod(optNum: 1, optValue: "bar", required: 6);

Limitation of using a Named Argument

Named argument specification must appear after all fixed arguments have been specified.

If you use a named argument before a fixed argument you will get a compile time error as follows.

https://riptutorial.com/ 117
Named argument specification must appear after all fixed arguments have been specified

Variance

Generic interfaces and delegates can have their type parameters marked as covariant or
contravariant using the out and in keywords respectively. These declarations are then respected
for type conversions, both implicit and explicit, and both compile time and run time.

For example, the existing interface IEnumerable<T> has been redefined as being covariant:

interface IEnumerable<out T>


{
IEnumerator<T> GetEnumerator();
}

The existing interface IComparer has been redefined as being contravariant:

public interface IComparer<in T>


{
int Compare(T x, T y);
}

Optional ref keyword when using COM

The ref keyword for callers of methods is now optional when calling into methods supplied by
COM interfaces. Given a COM method with the signature

void Increment(ref int x);

the invocation can now be written as either

Increment(0); // no need for "ref" or a place holder variable any more

Dynamic member lookup

A new pseudo-type dynamic is introduced into the C# type system. It is treated as System.Object, but
in addition, any member access (method call, field, property, or indexer access, or a delegate
invocation) or application of an operator on a value of such type is permitted without any type
checking, and its resolution is postponed until run-time. This is known as duck typing or late

https://riptutorial.com/ 118
binding. For example:

// Returns the value of Length property or field of any object


int GetLength(dynamic obj)
{
return obj.Length;
}

GetLength("Hello, world"); // a string has a Length property,


GetLength(new int[] { 1, 2, 3 }); // and so does an array,
GetLength(42); // but not an integer - an exception will be thrown
// in GetLength method at run-time

In this case, dynamic type is used to avoid more verbose Reflection. It still uses Reflection under
the hood, but it's usually faster thanks to caching.

This feature is primarily targeted at interoperability with dynamic languages.

// Initialize the engine and execute a file


var runtime = ScriptRuntime.CreateFromConfiguration();
dynamic globals = runtime.Globals;
runtime.ExecuteFile("Calc.rb");

// Use Calc type from Ruby


dynamic calc = globals.Calc.@new();
calc.valueA = 1337;
calc.valueB = 666;
dynamic answer = calc.Calculate();

Dynamic type has applications even in mostly statically typed code, for example it makes double
dispatch posible without implementing Visitor pattern.

Read C# 4.0 Features online: https://riptutorial.com/csharp/topic/3093/csharp-4-0-features

https://riptutorial.com/ 119
Chapter 24: C# 5.0 Features
Syntax
• Async & Await

• public Task MyTaskAsync(){ doSomething(); }

await MyTaskAsync();

• public Task<string> MyStringTaskAsync(){ return getSomeString(); }

string MyString = await MyStringTaskAsync();

• Caller Information Attributes

• public void MyCallerAttributes(string MyMessage,

[CallerMemberName] string MemberName = "",

[CallerFilePath] string SourceFilePath = "",

[CallerLineNumber] int LineNumber = 0)

• Trace.WriteLine("My Message: " + MyMessage);

Trace.WriteLine("Member: " + MemberName);

Trace.WriteLine("Source File Path: " + SourceFilePath);

Trace.WriteLine("Line Number: " + LineNumber);

Parameters

Method/Modifier with Parameter Details

Type<T> T is the return type

Remarks
C# 5.0 is coupled with Visual Studio .NET 2012

Examples
Async & Await

https://riptutorial.com/ 120
asyncand await are two operators that are intended to improve performance by freeing up Threads
and waiting for operations to complete before moving forward.

Here's an example of getting a string before returning it's length:

//This method is async because:


//1. It has async and Task or Task<T> as modifiers
//2. It ends in "Async"
async Task<int> GetStringLengthAsync(string URL){
HttpClient client = new HttpClient();
//Sends a GET request and returns the response body as a string
Task<string> getString = client.GetStringAsync(URL);
//Waits for getString to complete before returning its length
string contents = await getString;
return contents.Length;
}

private async void doProcess(){


int length = await GetStringLengthAsync("http://example.com/");
//Waits for all the above to finish before printing the number
Console.WriteLine(length);
}

Here's another example of downloading a file and handling what happens when it's progress has
changed and when the download completes (there are two ways to do this):

Method 1:

//This one using async event handlers, but not async coupled with await
private void DownloadAndUpdateAsync(string uri, string DownloadLocation){
WebClient web = new WebClient();
//Assign the event handler
web.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressChanged);
web.DownloadFileCompleted += new AsyncCompletedEventHandler(FileCompleted);
//Download the file asynchronously
web.DownloadFileAsync(new Uri(uri), DownloadLocation);
}

//event called for when download progress has changed


private void ProgressChanged(object sender, DownloadProgressChangedEventArgs e){
//example code
int i = 0;
i++;
doSomething();
}

//event called for when download has finished


private void FileCompleted(object sender, AsyncCompletedEventArgs e){
Console.WriteLine("Completed!")
}

Method 2:

//however, this one does


//Refer to first example on why this method is async
private void DownloadAndUpdateAsync(string uri, string DownloadLocation){
WebClient web = new WebClient();

https://riptutorial.com/ 121
//Assign the event handler
web.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressChanged);
//Download the file async
web.DownloadFileAsync(new Uri(uri), DownloadLocation);
//Notice how there is no complete event, instead we're using techniques from the first
example
}
private void ProgressChanged(object sender, DownloadProgressChangedEventArgs e){
int i = 0;
i++;
doSomething();
}
private void doProcess(){
//Wait for the download to finish
await DownloadAndUpdateAsync(new Uri("http://example.com/file"))
doSomething();
}

Caller Information Attributes

C.I.A.s are intended as a simple way of getting attributes from whatever is calling the targeted
method. There is really only 1 way to use them and there are only 3 attributes.

Example:

//This is the "calling method": the method that is calling the target method
public void doProcess()
{
GetMessageCallerAttributes("Show my attributes.");
}
//This is the target method
//There are only 3 caller attributes
public void GetMessageCallerAttributes(string message,
//gets the name of what is calling this method
[System.Runtime.CompilerServices.CallerMemberName] string memberName = "",
//gets the path of the file in which the "calling method" is in
[System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "",
//gets the line number of the "calling method"
[System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0)
{
//Writes lines of all the attributes
System.Diagnostics.Trace.WriteLine("Message: " + message);
System.Diagnostics.Trace.WriteLine("Member: " + memberName);
System.Diagnostics.Trace.WriteLine("Source File Path: " + sourceFilePath);
System.Diagnostics.Trace.WriteLine("Line Number: " + sourceLineNumber);
}

Example Output:

//Message: Show my attributes.


//Member: doProcess
//Source File Path: c:\Path\To\The\File
//Line Number: 13

Read C# 5.0 Features online: https://riptutorial.com/csharp/topic/4584/csharp-5-0-features

https://riptutorial.com/ 122
Chapter 25: C# 6.0 Features
Introduction
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.

Remarks
The sixth version of C# was released July 2015 alongside Visual Studio 2015 and .NET 4.6.

As well as adding some new language features it includes a complete rewrite of the compiler.
Previously csc.exe was a native Win32 application written in C++, with C# 6 it is now a .NET
managed application written in C#. This rewrite was known as project "Roslyn" and the code is
now open source and available on GitHub.

Examples
Operator nameof

The nameof operator returns the name of a code element as a string. This is useful when throwing
exceptions related to method arguments and also when implementing INotifyPropertyChanged.

public string SayHello(string greeted)


{
if (greeted == null)
throw new ArgumentNullException(nameof(greeted));

Console.WriteLine("Hello, " + greeted);


}

The nameof operator is evaluated at compile time and changes the expression into a string literal.
This is also useful for strings that are named after their member that exposes them. Consider the
following:

public static class Strings


{
public const string Foo = nameof(Foo); // Rather than Foo = "Foo"
public const string Bar = nameof(Bar); // Rather than Bar = "Bar"
}

Since nameof expressions are compile-time constants, they can be used in attributes, case labels,
switch statements, and so on.

https://riptutorial.com/ 123
It is convenient to use nameof with Enums. Instead of:

Console.WriteLine(Enum.One.ToString());

it is possible to use:

Console.WriteLine(nameof(Enum.One))

The output will be One in both cases.

The nameof operator can access non-static members using static-like syntax. Instead of doing:

string foo = "Foo";


string lengthName = nameof(foo.Length);

Can be replaced with:

string lengthName = nameof(string.Length);

The output will be Length in both examples. However, the latter prevents the creation of
unnecessary instances.

Although the nameof operator works with most language constructs, there are some limitations. For
example, you cannot use the nameof operator on open generic types or method return values:

public static int Main()


{
Console.WriteLine(nameof(List<>)); // Compile-time error
Console.WriteLine(nameof(Main())); // Compile-time error
}

Furthermore, if you apply it to a generic type, the generic type parameter will be ignored:

Console.WriteLine(nameof(List<int>)); // "List"
Console.WriteLine(nameof(List<bool>)); // "List"

For more examples, see this topic dedicated to nameof.

Workaround for previous versions (more


detail)
Although the nameof operator does not exist in C# for versions prior to 6.0, similar functionality can
be had by using MemberExpression as in the following:

6.0
https://riptutorial.com/ 124
Expression:

public static string NameOf<T>(Expression<Func<T>> propExp)


{
var memberExpression = propExp.Body as MemberExpression;
return memberExpression != null ? memberExpression.Member.Name : null;
}

public static string NameOf<TObj, T>(Expression<Func<TObj, T>> propExp)


{
var memberExpression = propExp.Body as MemberExpression;
return memberExpression != null ? memberExpression.Member.Name : null;
}

Usage:

string variableName = NameOf(() => variable);


string propertyName = NameOf((Foo o) => o.Bar);

Note that this approach causes an expression tree to be created on every call, so the performance
is much worse compared to nameof operator which is evaluated at compile time and has zero
overhead at runtime.

Expression-bodied function members

Expression-bodied function members allow the use of lambda expressions as member bodies. For
simple members, it can result in cleaner and more readable code.

Expression-bodied functions can be used for properties, indexers, methods, and operators.

Properties
public decimal TotalPrice => BasePrice + Taxes;

Is equivalent to:

public decimal TotalPrice


{
get
{
return BasePrice + Taxes;
}
}

When an expression-bodied function is used with a property, the property is implemented as a


getter-only property.

View Demo

https://riptutorial.com/ 125
Indexers
public object this[string key] => dictionary[key];

Is equivalent to:

public object this[string key]


{
get
{
return dictionary[key];
}
}

Methods
static int Multiply(int a, int b) => a * b;

Is equivalent to:

static int Multiply(int a, int b)


{
return a * b;
}

Which can also be used with void methods:

public void Dispose() => resource?.Dispose();

An override of ToString could be added to the Pair<T> class:

public override string ToString() => $"{First}, {Second}";

Additionally, this simplistic approach works with the override keyword:

public class Foo


{
public int Bar { get; }

public string override ToString() => $"Bar: {Bar}";


}

Operators

https://riptutorial.com/ 126
This also can be used by operators:

public class Land


{
public double Area { get; set; }

public static Land operator +(Land first, Land second) =>


new Land { Area = first.Area + second.Area };
}

Limitations
Expression-bodied function members have some limitations. They can't contain block statements
and any other statements that contain blocks: if, switch, for, foreach, while, do, try, etc.

Some if statements can be replaced with ternary operators. Some for and foreach statements can
be converted to LINQ queries, for example:

IEnumerable<string> Digits
{
get
{
for (int i = 0; i < 10; i++)
yield return i.ToString();
}
}

IEnumerable<string> Digits => Enumerable.Range(0, 10).Select(i => i.ToString());

In all other cases, the old syntax for function members can be used.

Expression-bodied function members can contain async/await, but it's often redundant:

async Task<int> Foo() => await Bar();

Can be replaced with:

Task<int> Foo() => Bar();

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

https://riptutorial.com/ 127
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 VB.NET 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 (ex.Number != 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
{ ... }
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:

https://riptutorial.com/ 128
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.
Type.GetType(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:

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

https://riptutorial.com/ 129
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) when (Log(ex, "An error occurred"))
{
// This catch block will never be reached
}

// ...

static bool Log(Exception ex, string message, params object[] args)


{
Debug.Print(message, args);
return false;
}

View Demo

The common approach in previous versions of C# was to log and re-throw the exception.

6.0

try
{
DoSomethingThatMightFail(s);
}
catch (Exception ex)
{
Log(ex, "An error occurred");
throw;
}

// ...

static void Log(Exception ex, string message, params object[] args)


{
Debug.Print(message, args);
}

https://riptutorial.com/ 130
View Demo

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)


{
Console.WriteLine("Start");
try
{
SomeOperation();
}
catch (Exception) when (EvaluatesTo())
{
Console.WriteLine("Catch");
}
finally
{
Console.WriteLine("Outer Finally");
}
}

private static bool EvaluatesTo()


{
Console.WriteLine($"EvaluatesTo: {Flag}");
return true;
}

private static void SomeOperation()


{
try
{
Flag = true;
throw new Exception("Boom");
}
finally
{
Flag = false;
Console.WriteLine("Inner Finally");
}
}

Produced Output:

Start

https://riptutorial.com/ 131
EvaluatesTo: True
Inner Finally
Catch
Outer Finally

View Demo

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;
Console.WriteLine("Inner Finally");
}
}

It is also common to see IDisposable helper classes leveraging the semantics of using blocks to
achieve the same goal, as IDisposable.Dispose will always be called before an exception called
within a using block starts bubbling up the stack.

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:

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

https://riptutorial.com/ 132
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.

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,

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

https://riptutorial.com/ 133
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 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; } = DateTime.UtcNow;

public string User { get; } =


System.Security.Principal.WindowsPrincipal.Current.Identity.Name;

public string Process { get; } =


System.Diagnostics.Process.GetCurrentProcess().ProcessName;
}

View Demo

Cautionary notes

https://riptutorial.com/ 134
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>();

// 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>(); } }
}

Index initializers

Index initializers make it possible to create and initialize objects with indexes at the same time.

This makes initializing Dictionaries very easy:

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


{

https://riptutorial.com/ 135
["foo"] = 34,
["bar"] = 42
};

Any object that has an indexed getter or setter can be used with this syntax:

class Program
{
public class MyClassWithIndexer
{
public int this[string index]
{
set
{
Console.WriteLine($"Index: {index}, value: {value}");
}
}
}

public static void Main()


{
var x = new MyClassWithIndexer()
{
["foo"] = 34,
["bar"] = 42
};

Console.ReadKey();
}
}

Output:

Index: foo, value: 34


Index: bar, value: 42

View Demo

If the class has multiple indexers it is possible to assign them all in a single group of statements:

class Program
{
public class MyClassWithIndexer
{
public int this[string index]
{
set
{
Console.WriteLine($"Index: {index}, value: {value}");
}
}
public string this[int index]
{
set
{
Console.WriteLine($"Index: {index}, value: {value}");
}

https://riptutorial.com/ 136
}
}

public static void Main()


{
var x = new MyClassWithIndexer()
{
["foo"] = 34,
["bar"] = 42,
[10] = "Ten",
[42] = "Meaning of life"
};
}
}

Output:

Index: foo, value: 34


Index: bar, value: 42
Index: 10, value: Ten
Index: 42, value: Meaning of life

It should be noted that the indexer set accessor might behave differently compared to an Add
method (used in collection initializers).

For example:

var d = new Dictionary<string, int>


{
["foo"] = 34,
["foo"] = 42,
}; // does not throw, second value overwrites the first one

versus:

var d = new Dictionary<string, int>


{
{ "foo", 34 },
{ "foo", 42 },
}; // run-time ArgumentException: An item with the same key has already been added.

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;

https://riptutorial.com/ 137
int bar = 42;

string resultString = $"The foo is {foo}, and the bar is {bar}.";

Console.WriteLine(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)


Console.WriteLine($"The foo is {{foo}}, and the bar is {{bar}}.");

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:

Console.WriteLine($@"In case it wasn't clear:


\u00B9
The foo
is {foo},
and the bar
is {bar}.");

Output:

In case it wasn't clear:


\u00B9
The foo
is 34,
and the bar
is 42.

View Demo

https://riptutorial.com/ 138
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 Math.Max within the curly braces:

Console.WriteLine($"And the greater one is: { Math.Max(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:

Console.WriteLine($"Foo formatted as a currency to 4 decimal places: {foo:c4}");

Output:

Foo formatted as a currency to 4 decimal places: $34.0000

View Demo

Or they can be formatted as dates:

Console.WriteLine($"Today is: {DateTime.Today: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:

Console.WriteLine($"{(foo > bar ? "Foo is larger than bar!" : "Bar is larger than foo!")}");

Output:

Bar is larger than foo!

View Demo

https://riptutorial.com/ 139
Conditional expressions and format specifiers can be mixed:

Console.WriteLine($"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:

Console.WriteLine($"Foo is: {foo}. In a non-verbatim string, we need to escape \" and \\ with
backslashes.");
Console.WriteLine($@"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: {foo}"

Output:

{foo} is: 34

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, {name}";


System.FormattableString s = $"Hello, {name}";
System.IFormattable 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.

https://riptutorial.com/ 140
A new type, System.FormattableString, 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 formattableString.GetArguments())
{
// do something to interpolation argument 'arg'
}

// use the standard interpolation and the current culture info


// to get an ordinary String:
var formatted = formattableString.ToString();

// ...
}

Call the above method with:

AddLogItem($"The foo is {foo}, 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: {foo}";


System.IFormattable s = $"Foo: {foo}";

You can also produce an IFormattable variable that allows you to convert the string with invariant
context:

var s = $"Bar: {bar}";


System.FormattableString 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(CultureInfo.CurrentCulture);

https://riptutorial.com/ 141
}
public static string Invariant(FormattableString formattableString)
{
return formattableString?.ToString(CultureInfo.InvariantCulture);
}
}

Then, to produce a correct string for the current culture, just use the expression:

Culture.Current($"interpolated {typeof(string).Name} string.")


Culture.Invariant($"interpolated {typeof(string).Name} string.")

Note: Current and 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 System.FormattableString;

string invariant = Invariant($"Now = {DateTime.Now}");


string current = $"Now = {DateTime.Now}";

Behind the scenes


Interpolated strings are just a syntactic sugar for String.Format(). The compiler (Roslyn) will turn it
into a String.Format behind the scenes:

var text = $"Hello {name + lastName}";

The above will be converted to something like this:

string text = string.Format("Hello {0}", new object[] {


name + lastName
});

String Interpolation and Linq


It's possible to use interpolated strings in Linq statements to increase readability further.

https://riptutorial.com/ 142
var fooBar = (from DataRow x in fooBarTable.Rows
select string.Format("{0}{1}", x["foo"], x["bar"])).ToList();

Can be re-written as:

var fooBar = (from DataRow x in fooBarTable.Rows


select $"{x["foo"]}{x["bar"]}").ToList();

Reusable Interpolated Strings


With string.Format, you can create reusable format strings:

public const string ErrorFormat = "Exception caught:\r\n{0}";

// ...

Logger.Log(string.Format(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}";

// ...

Logger.Log(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 {name} {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 string.Format

https://riptutorial.com/ 143
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 ("strings.fr.resx"), German ("strings.de.resx"),
// and English ("strings.en.resx")
void ShowMyNameLocalized(string name, string middlename = "", string surname = "")
{
// get localized string
var localizedMyNameIs = Properties.strings.Hello;
// insert spaces where necessary
name = (string.IsNullOrWhiteSpace(name) ? "" : name + " ");
middlename = (string.IsNullOrWhiteSpace(middlename) ? "" : middlename + " ");
surname = (string.IsNullOrWhiteSpace(surname) ? "" : surname + " ");
// display it
Console.WriteLine($"{localizedMyNameIs} {name}{middlename}{surname}".Trim());
}

// switch to French and greet John


Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("fr-FR");
ShowMyNameLocalized(FirstName);

// switch to German and greet John


Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("de-DE");
ShowMyNameLocalized(FirstName);

// switch to US English and greet John


Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("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#.

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:

https://riptutorial.com/ 144
Console.WriteLine($"String has {$"My class is called {nameof(MyClass)}.".Length} chars:");
Console.WriteLine($"My class is called {nameof(MyClass)}.");

Output:

String has 27 chars:

My class is called MyClass.

Await in catch and finally

It is possible to use await expression to apply await operator to Tasks or Task(OfTResult) in the
catch and finally blocks in C#6.

It was not possible to use the await expression in the catch and finally blocks in earlier versions
due to compiler limitations. C#6 makes awaiting async tasks a lot easier by allowing the await
expression.

try
{
//since C#5
await service.InitializeAsync();
}
catch (Exception e)
{
//since C#6
await logger.LogAsync(e);
}
finally
{
//since C#6
await service.CloseAsync();
}

It was required in C# 5 to use a bool or declare an Exception outside the try catch to perform async
operations. This method is shown in the following example:

bool error = false;


Exception ex = null;

try
{
// Since C#5
await service.InitializeAsync();
}
catch (Exception e)
{
// Declare bool or place exception inside variable
error = true;
ex = e;
}

// If you don't use the exception


if (error)
{

https://riptutorial.com/ 145
// Handle async task
}

// If want to use information from the exception


if (ex != null)
{
await logger.LogAsync(e);
}

// Close the service, since this isn't possible in the finally


await service.CloseAsync();

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 = classroom.GetTeacher().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 = classroom.GetTeacher()?.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-

https://riptutorial.com/ 146
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 = classroom.GetTeacher().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

bool hasCertification = classroom?.GetTeacher()?.HasCertification.GetValueOrDefault();


// 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 IndexOutOfRangeException.

Use with void Functions


Null-conditional operator can also be used with void functions. However in this case, the statement

https://riptutorial.com/ 147
will not evaluate to null. It will just prevent a NullReferenceException.

List<string> list = null;


list?.Add("hi"); // Does not evaluate to null

Use with Event Invocation


Assuming the following event definition:

private event EventArgs OnCompleted;

When invoking an event, traditionally, it is best practice to check if the event is null in case no
subscribers are present:

var handler = OnCompleted;


if (handler != null)
{
handler(EventArgs.Empty);
}

Since the null-conditional operator has been introduced, the invocation can be reduced to a single
line:

OnCompleted?.Invoke(EventArgs.Empty);

Limitations
Null-conditional operator produces rvalue, not lvalue, that is, it cannot be used for property
assignment, event subscription etc. For example, the following code will not work:

// Error: The left-hand side of an assignment must be a variable, property or indexer


Process.GetProcessById(1337)?.EnableRaisingEvents = true;
// Error: The event can only appear on the left hand side of += or -=
Process.GetProcessById(1337)?.Exited += OnProcessExited;

Gotchas
Note that:

int? nameLength = person?.Name.Length; // safe if 'person' is null

is not the same as:

https://riptutorial.com/ 148
int? nameLength = (person?.Name).Length; // avoid this

because the former corresponds to:

int? nameLength = person != null ? (int?)person.Name.Length : null;

and the latter corresponds to:

int? nameLength = (person != null ? person.Name : null).Length;

Despite ternary operator ?: is used here for explaining the difference between two cases, these
operators are not equivalent. This can be easily demonstrated with the following example:

void Main()
{
var foo = new Foo();
Console.WriteLine("Null propagation");
Console.WriteLine(foo.Bar?.Length);

Console.WriteLine("Ternary");
Console.WriteLine(foo.Bar != null ? foo.Bar.Length : (int?)null);
}

class Foo
{
public string Bar
{
get
{
Console.WriteLine("I was read");
return string.Empty;
}
}
}

Which outputs:

Null propagation
I was read
0
Ternary
I was read
I was read
0

View Demo

To avoid multiple invocations equivalent would be:

var interimResult = foo.Bar;


Console.WriteLine(interimResult != null ? interimResult.Length : (int?)null);

https://riptutorial.com/ 149
And this difference somewhat explains why null propagation operator is not yet supported in
expression trees.

Using static type

The using static [Namespace.Type] directive allows the importing of static members of types and
enumeration values. Extension methods are imported as extension methods (from just one type),
not into top-level scope.

6.0

using static System.Console;


using static System.ConsoleColor;
using static System.Math;

class Program
{
static void Main()
{
BackgroundColor = DarkBlue;
WriteLine(Sqrt(2));
}
}

Live Demo Fiddle

6.0

using System;

class Program
{
static void Main()
{
Console.BackgroundColor = ConsoleColor.DarkBlue;
Console.WriteLine(Math.Sqrt(2));
}
}

Improved overload resolution

Following snippet shows an example of passing a method group (as opposed to a lambda) when a
delegate is expected. Overload resolution will now resolve this instead of raising an ambiguous
overload error due to the ability of C# 6 to check the return type of the method that was passed.

using System;
public class Program
{
public static void Main()
{
Overloaded(DoSomething);
}

static void Overloaded(Action action)

https://riptutorial.com/ 150
{
Console.WriteLine("overload with action called");
}

static void Overloaded(Func<int> function)


{
Console.WriteLine("overload with Func<int> called");
}

static int DoSomething()


{
Console.WriteLine(0);
return 0;
}
}

Results:

6.0

Output

overload with Func<int> called

View Demo

5.0

Error

error CS0121: The call is ambiguous between the following methods or properties:
'Program.Overloaded(System.Action)' and 'Program.Overloaded(System.Func)'

C# 6 can also handle well the following case of exact matching for lambda expressions which
would have resulted in an error in C# 5.

using System;

class Program
{
static void Foo(Func<Func<long>> func) {}
static void Foo(Func<Func<int>> func) {}

static void Main()


{
Foo(() => () => 7);
}
}

Minor changes and bugfixes

Parentheses are now forbidden around named parameters. The following compiles in C#5, but not
C#6

5.0

https://riptutorial.com/ 151
Console.WriteLine((value: 23));

Operands of is and as are no longer allowed to be method groups. The following compiles in C#5,
but not C#6

5.0

var result = "".Any is byte;

The native compiler allowed this (although it did show a warning), and in fact didn’t
even check extension method compatibility, allowing crazy things like 1.Any is string
or IDisposable.Dispose is object.

See this reference for updates on changes.

Using an extension method for collection initialization

Collection initialization syntax can be used when instantiating any class which implements
IEnumerable and has a method named Add which takes a single parameter.

In previous versions, this Add method had to be an instance method on the class being initialized.
In C#6, it can also be an extension method.

public class CollectionWithAdd : IEnumerable


{
public void Add<T>(T item)
{
Console.WriteLine("Item added with instance add method: " + item);
}

public IEnumerator GetEnumerator()


{
// Some implementation here
}
}

public class CollectionWithoutAdd : IEnumerable


{
public IEnumerator GetEnumerator()
{
// Some implementation here
}
}

public static class Extensions


{
public static void Add<T>(this CollectionWithoutAdd collection, T item)
{
Console.WriteLine("Item added with extension add method: " + item);
}
}

public class Program


{
public static void Main()

https://riptutorial.com/ 152
{
var collection1 = new CollectionWithAdd{1,2,3}; // Valid in all C# versions
var collection2 = new CollectionWithoutAdd{4,5,6}; // Valid only since C# 6
}
}

This will output:

Item added with instance add method: 1


Item added with instance add method: 2
Item added with instance add method: 3
Item added with extension add method: 4
Item added with extension add method: 5
Item added with extension add method: 6

Disable Warnings Enhancements

In C# 5.0 and earlier the developer could only suppress warnings by number. With the introduction
of Roslyn Analyzers, C# needs a way to disable warnings issued from specific libraries. With C#
6.0 the pragma directive can suppress warnings by name.

Before:

#pragma warning disable 0501

C# 6.0:

#pragma warning disable CS0501

Read C# 6.0 Features online: https://riptutorial.com/csharp/topic/24/csharp-6-0-features

https://riptutorial.com/ 153
Chapter 26: C# 7.0 Features
Introduction
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

Examples
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:

7.0

int value;
if (int.TryParse(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:

7.0

https://riptutorial.com/ 154
if (int.TryParse(input, out var value))
{
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 _.

p.GetCoordinates(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.

7.0

var a = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
var groupedByMod2 = a.Select(x => new
{
Source = x,
Mod2 = x % 2
})
.GroupBy(x => x.Mod2)
.ToDictionary(g => g.Key, g => g.ToArray());
if (groupedByMod2.TryGetValue(1, out var oddElements))
{
Console.WriteLine(oddElements.Length);
}

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 = int.TryParse(item, out var tmp)

https://riptutorial.com/ 155
select success ? tmp : 0; // Error: The name 'tmp' does not exist in the current context

References
• Original out var declaration proposal on GitHub

Binary literals

The 0b prefix can be used to represent Binary literals.

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:

https://riptutorial.com/ 156
[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
}

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)

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.

https://riptutorial.com/ 157
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 System.ValueTuple 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();


// > result.sum
// 1
// > result.count
// 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;
(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:

https://riptutorial.com/ 158
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 = person.FirstName;
lastName = person.LastName;
}
}

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 = person.Name.First; // "Jane"


var lastName = person.Name.Last; // "Smith"

Tuple Initialization

https://riptutorial.com/ 159
You can also arbitrarily create tuples in code:

var name = ("John", "Smith");


Console.WriteLine(name.Item1);
// Outputs John

Console.WriteLine(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");


Console.WriteLine(name.first);
// 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);
stats.sum = items.Sum();
stats.average = items.Average();
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".

https://riptutorial.com/ 160
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


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)


{

https://riptutorial.com/ 161
var result = labels
.Where(w => w.firstThingy == firstElement && w.secondThingyLabel == secondElement)
.FirstOrDefault();

if (result == null)
throw new ArgumentException("combo not found");

return result.foundValue;
}

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)

References
• Original Tuples language feature proposal on GitHub
• A runnable VS 15 solution for C# 7.0 features
• NuGet Tuple Package

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()

https://riptutorial.com/ 162
{
// You can declare inner-local functions in a local function
double GetCircleArea(double r) => Math.PI * 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("input1.txt");
IEnumerable<string> emails2 = await getEmailsFromFileAsync("input2.txt");
await writeLinesToFileAsync(emails1.Concat(emails2), "output.txt");

async Task<IEnumerable<string>> getEmailsFromFileAsync(string fileName)


{
string text;

using (StreamReader reader = File.OpenText(fileName))


{
text = await reader.ReadToEndAsync();
}

return from Match emailMatch in emailRegex.Matches(text) select emailMatch.Value;

https://riptutorial.com/ 163
}

async Task writeLinesToFileAsync(IEnumerable<string> lines, string fileName)


{
using (StreamWriter writer = File.CreateText(fileName))
{
foreach (string line in lines)
{
await writer.WriteLineAsync(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.

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

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)
{

https://riptutorial.com/ 164
case Triangle t:
Console.WriteLine($"{t.Width} {t.Height} {t.Base}");
break;
case Rectangle sq when sq.Width == sq.Height:
Console.WriteLine($"Square rectangle: {sq.Width} {sq.Height}");
break;
case Rectangle r:
Console.WriteLine($"{r.Width} {r.Height}");
break;
case Square s:
Console.WriteLine($"{s.Width}");
break;
default:
Console.WriteLine("<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
7.0

string s = o as string;
if(s != null)
{
// do something with s
}

can be rewritten as:

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
{

https://riptutorial.com/ 165
// s is unassigned here, but accessible
}

// s is unassigned here, but accessible


}
// s is not accessible here

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;
Debug.Assert(a == 1); // true
Debug.Assert(b == 2); // true
Debug.Assert(c == 4); // true

Unsafe Ref Operations


In System.Runtime.CompilerServices.Unsafe 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:

https://riptutorial.com/ 166
byte[] b = new byte[4] { 0x42, 0x42, 0x42, 0x42 };

ref int r = ref Unsafe.As<byte, int>(ref b[0]);


Assert.Equal(0x42424242, r);

0x0EF00EF0;
Assert.Equal(0xFE, b[0] | b[1] | b[2] | b[3]);

Beware of endianness when doing this, though, e.g. check BitConverter.IsLittleEndian 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 Unsafe.Add(ref a[0], 1);


Assert.Equal(0x234, r1);

ref int r2 = ref Unsafe.Add(ref r1, 2);


Assert.Equal(0x456, r2);

ref int r3 = ref Unsafe.Add(ref r2, -3);


Assert.Equal(0x123, r3);

Or the similar Subtract:

string[] a = new string[] { "abc", "def", "ghi", "jkl" };

ref string r1 = ref Unsafe.Subtract(ref a[0], -2);


Assert.Equal("ghi", r1);

ref string r2 = ref Unsafe.Subtract(ref r1, -1);


Assert.Equal("jkl", r2);

ref string r3 = ref Unsafe.Subtract(ref r2, 3);


Assert.Equal("abc", r3);

Additionally, one can check if two ref values are the same i.e. same address:

long[] a = new long[2];

Assert.True(Unsafe.AreSame(ref a[0], ref a[0]));


Assert.False(Unsafe.AreSame(ref a[0], ref a[1]));

Links
Roslyn Github Issue

System.Runtime.CompilerServices.Unsafe on github

throw expressions

https://riptutorial.com/ 167
C# 7.0 allows throwing as an expression in certain places:

class Person
{
public string Name { get; }

public Person(string name) => Name = name ?? throw new


ArgumentNullException(nameof(name));

public string GetFirstName()


{
var parts = Name.Split(' ');
return (parts.Length > 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 = spoons.Length > 0 ? spoons : null;

if (spoonsArray == null)
{
throw new Exception("There are no spoons");
}

Or

var spoonsArray = spoons.Length > 0


? spoons
: new Func<string[]>(() =>
{
throw new Exception("There are no spoons");
})();

In C# 7.0 the above is now simplified to:

var spoonsArray = spoons.Length > 0 ? spoons : throw new Exception("There are no spoons");

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();

https://riptutorial.com/ 168
public Person(string name) => names.TryAdd(id, name); // constructors

~Person() => names.TryRemove(id, out _); // finalizers

public string Name


{
get => names[id]; // getters
set => names[id] = value; // setters
}
}

Also see the out var declaration section for the discard operator.

ValueTask

is a class and causes the unnecessary overhead of its allocation when the result is
Task<T>
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 Task.Delay(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 Task.Delay, but often is in many real-world async/await scenarios)
• Takes 65ns with JIT

async ValueTask<int> TestValueTask(int d)


{
await Task.Delay(d);
return 10;
}

https://riptutorial.com/ 169
2. Increased implementation flexibility
Implementations of an async interface wishing to be synchronous would otherwise be forced to
use either Task.Run or Task.FromResult (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 thing.BarAsync();

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 Task.Delay(1);
return value;
}
}

https://riptutorial.com/ 170
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> System.Threading.Tasks.Extensions package can be
downloaded from Nuget Gallery

Read C# 7.0 Features online: https://riptutorial.com/csharp/topic/1936/csharp-7-0-features

https://riptutorial.com/ 171
Chapter 27: C# Authentication handler
Examples
Authentication handler

public class AuthenticationHandler : DelegatingHandler


{
/// <summary>
/// Holds request's header name which will contains token.
/// </summary>
private const string securityToken = "__RequestAuthToken";

/// <summary>
/// Default overridden method which performs authentication.
/// </summary>
/// <param name="request">Http request message.</param>
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns>Returns http response message of type <see cref="HttpResponseMessage"/>
class asynchronously.</returns>
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
CancellationToken cancellationToken)
{
if (request.Headers.Contains(securityToken))
{
bool authorized = Authorize(request);
if (!authorized)
{
return ApiHttpUtility.FromResult(request, false,
HttpStatusCode.Unauthorized, MessageTypes.Error, Resource.UnAuthenticatedUser);
}
}
else
{
return ApiHttpUtility.FromResult(request, false, HttpStatusCode.BadRequest,
MessageTypes.Error, Resource.UnAuthenticatedUser);
}

return base.SendAsync(request, cancellationToken);


}

/// <summary>
/// Authorize user by validating token.
/// </summary>
/// <param name="requestMessage">Authorization context.</param>
/// <returns>Returns a value indicating whether current request is authenticated or
not.</returns>
private bool Authorize(HttpRequestMessage requestMessage)
{
try
{
HttpRequest request = HttpContext.Current.Request;
string token = request.Headers[securityToken];
return SecurityUtility.IsTokenValid(token, request.UserAgent,
HttpContext.Current.Server.MapPath("~/Content/"), requestMessage);
}
catch (Exception)

https://riptutorial.com/ 172
{
return false;
}
}
}

Read C# Authentication handler online: https://riptutorial.com/csharp/topic/5430/csharp-


authentication-handler

https://riptutorial.com/ 173
Chapter 28: C# Script
Examples
Simple code evaluation

You can evaluate any valid C# code:

int value = await CSharpScript.EvaluateAsync<int>("15 * 89 + 95");


var span = await CSharpScript.EvaluateAsync<TimeSpan>("new DateTime(2016,1,1) -
DateTime.Now");

If type is not specified, the result is object:

object value = await CSharpScript.EvaluateAsync("15 * 89 + 95");

Read C# Script online: https://riptutorial.com/csharp/topic/3780/csharp-script

https://riptutorial.com/ 174
Chapter 29: Caching
Examples
MemoryCache

//Get instance of cache


using System.Runtime.Caching;

var cache = MemoryCache.Default;

//Check if cache contains an item with


cache.Contains("CacheKey");

//get item from cache


var item = cache.Get("CacheKey");

//get item from cache or add item if not existing


object list = MemoryCache.Default.AddOrGetExisting("CacheKey", "object to be stored",
DateTime.Now.AddHours(12));

//note if item not existing the item is added by this method


//but the method returns null

Read Caching online: https://riptutorial.com/csharp/topic/4383/caching

https://riptutorial.com/ 175
Chapter 30: Casting
Remarks
Casting is not the same as Converting. It is possible to convert the string value "-1" to an integer
value (-1), but this must be done through library methods like Convert.ToInt32() or Int32.Parse(). It
cannot be done using casting syntax directly.

Examples
Cast an object to a base type

Given the following definitions :

public interface IMyInterface1


{
string GetName();
}

public interface IMyInterface2


{
string GetName();
}

public class MyClass : IMyInterface1, IMyInterface2


{
string IMyInterface1.GetName()
{
return "IMyInterface1";
}

string IMyInterface2.GetName()
{
return "IMyInterface2";
}
}

Casting an object to a base type example :

MyClass obj = new MyClass();

IMyInterface1 myClass1 = (IMyInterface1)obj;


IMyInterface2 myClass2 = (IMyInterface2)obj;

Console.WriteLine("I am : {0}", myClass1.GetName());


Console.WriteLine("I am : {0}", myClass2.GetName());

// Outputs :
// I am : IMyInterface1
// I am : IMyInterface2

https://riptutorial.com/ 176
Explicit Casting

If you know that a value is of a specific type, you can explicitly cast it to that type in order to use it
in a context where that type is needed.

object value = -1;


int number = (int) value;
Console.WriteLine(Math.Abs(number));

If we tried passing value directly to Math.Abs(), we would get a compile-time exception because
Math.Abs() doesn't have an overload that takes an object as a parameter.

If value could not be cast to an int, then the second line in this example would throw an
InvalidCastException

Safe Explicit Casting (`as` operator)

If you aren't sure whether a value is of the type you think it is, you can safely cast it using the as
operator. If the value is not of that type, the resulting value will be null.

object value = "-1";


int? number = value as int?;
if(number != null)
{
Console.WriteLine(Math.Abs(number.Value));
}

Note that null values have no type, so the as keyword will safely yield null when casting any null
value.

Implicit Casting

A value will automatically be cast to the appropriate type if the compiler knows that it can always
be converted to that type.

int number = -1;


object value = number;
Console.WriteLine(value);

In this example, we didn't need to use the typical explicit casting syntax because the compiler
knows all ints can be cast to objects. In fact, we could avoid creating variables and pass -1
directly as the argument of Console.WriteLine() that expects an object.

Console.WriteLine(-1);

Checking compatibility without casting

If you need to know whether a value's type extends or implements a given type, but you don't want
to actually cast it as that type, you can use the is operator.

https://riptutorial.com/ 177
if(value is int)
{
Console.WriteLine(value + "is an int");
}

Explicit Numeric Conversions

Explicit casting operators can be used to perform conversions of numeric types, even though they
don't extend or implement one another.

double value = -1.1;


int number = (int) value;

Note that in cases where the destination type has less precision than the original type, precision
will be lost. For example, -1.1 as a double value in the above example becomes -1 as an integer
value.

Also, numeric conversions rely on compile-time types, so they won't work if the numeric types
have been "boxed" into objects.

object value = -1.1;


int number = (int) value; // throws InvalidCastException

Conversion Operators

In C#, types can define custom Conversion Operators, which allow values to be converted to and
from other types using either explicit or implicit casts. For example, consider a class that is meant
to represent a JavaScript expression:

public class JsExpression


{
private readonly string expression;
public JsExpression(string rawExpression)
{
this.expression = rawExpression;
}
public override string ToString()
{
return this.expression;
}
public JsExpression IsEqualTo(JsExpression other)
{
return new JsExpression("(" + this + " == " + other + ")");
}
}

If we wanted to create a JsExpression representing a comparison of two JavaScript values, we


could do something like this:

JsExpression intExpression = new JsExpression("-1");


JsExpression doubleExpression = new JsExpression("-1.0");
Console.WriteLine(intExpression.IsEqualTo(doubleExpression)); // (-1 == -1.0)

https://riptutorial.com/ 178
But we can add some explicit conversion operators to JsExpression, to allow a simple conversion
when using explicit casting.

public static explicit operator JsExpression(int value)


{
return new JsExpression(value.ToString());
}
public static explicit operator JsExpression(double value)
{
return new JsExpression(value.ToString());
}

// Usage:
JsExpression intExpression = (JsExpression)(-1);
JsExpression doubleExpression = (JsExpression)(-1.0);
Console.WriteLine(intExpression.IsEqualTo(doubleExpression)); // (-1 == -1.0)

Or, we could change these operators to implicit to make the syntax much simpler.

public static implicit operator JsExpression(int value)


{
return new JsExpression(value.ToString());
}
public static implicit operator JsExpression(double value)
{
return new JsExpression(value.ToString());
}

// Usage:
JsExpression intExpression = -1;
Console.WriteLine(intExpression.IsEqualTo(-1.0)); // (-1 == -1.0)

LINQ Casting operations

Suppose you have types like the following:

interface IThing { }
class Thing : IThing { }

LINQ allows you to create a projection that changes the compile-time generic type of an
IEnumerable<> via the Enumerable.Cast<>() and Enumerable.OfType<>() extension methods.

IEnumerable<IThing> things = new IThing[] {new Thing()};


IEnumerable<Thing> things2 = things.Cast<Thing>();
IEnumerable<Thing> things3 = things.OfType<Thing>();

When things2 is evaluated, the Cast<>() method will try to cast all of the values in things into Thing
s. If it encounters a value that cannot be cast, an InvalidCastException will be thrown.

When things3 is evaluated, the OfType<>() method will do the same, except that if it encounters a
value that cannot be cast, it will simply omit that value rather than throw an exception.

Due to the generic type of these methods, they cannot invoke Conversion Operators or perform

https://riptutorial.com/ 179
numeric conversions.

double[] doubles = new[]{1,2,3}.Cast<double>().ToArray(); // Throws InvalidCastException

You can simply perform a cast inside a .Select() as a workaround:

double[] doubles = new[]{1,2,3}.Select(i => (double)i).ToArray();

Read Casting online: https://riptutorial.com/csharp/topic/2690/casting

https://riptutorial.com/ 180
Chapter 31: Checked and Unchecked
Syntax
• checked(a + b) // checked expression
• unchecked(a + b) // unchecked expression
• checked { c = a + b; c += 5; } // checked block
• unchecked { c = a + b; c += 5; } // unchecked block

Examples
Checked and Unchecked

C# statements executes in either checked or unchecked context. In a checked context, arithmetic


overflow raises an exception. In an unchecked context, arithmetic overflow is ignored and the
result is truncated.

short m = 32767;
short n = 32767;
int result1 = checked((short)(m + n)); //will throw an OverflowException
int result2 = unchecked((short)(m + n)); // will return -2

If neither of these are specified then the default context will rely on other factors, such as compiler
options.

Checked and Unchecked as a scope

The keywords can also create scopes in order to (un)check multiple operations.

short m = 32767;
short n = 32767;
checked
{
int result1 = (short)(m + n); //will throw an OverflowException
}
unchecked
{
int result2 = (short)(m + n); // will return -2
}

Read Checked and Unchecked online: https://riptutorial.com/csharp/topic/2394/checked-and-


unchecked

https://riptutorial.com/ 181
Chapter 32: CLSCompliantAttribute
Syntax
1. [assembly:CLSCompliant(true)]
2. [CLSCompliant(true)]

Parameters

Constructor Parameter

Initializes an instance of the CLSCompliantAttribute class


CLSCompliantAttribute(Boolean) with a Boolean value indicating whether the indicated
program element is CLS-compliant.

Remarks
The Common Language Specification (CLS) is a set of base rules to which any language targeting
the CLI(language which confirms the Common Language Infrastructure specifications) should
confirm in order to interoperate with other CLS-compliant languages.

List of CLI languages

You should mark your assembly as CLSCompliant in most cases when you are distributing
libraries. This attribute will guarantee you that your code will be usable by all CLS-compliant
languages. This means that your code can be consumed by any language that can be compiled
and run on CLR(Common Language Runtime)

When your assembly is marked with CLSCompliantAttribute, the compiler will check if your code
violates any of CLS rules and return warning if it is needed.

Examples
Access Modifier to which CLS rules apply

using System;

[assembly:CLSCompliant(true)]
namespace CLSDoc
{

public class Cat


{
internal UInt16 _age = 0;
private UInt16 _daysTillVacination = 0;

https://riptutorial.com/ 182
//Warning CS3003 Type of 'Cat.DaysTillVacination' is not CLS-compliant
protected UInt16 DaysTillVacination
{
get { return _daysTillVacination; }
}

//Warning CS3003 Type of 'Cat.Age' is not CLS-compliant


public UInt16 Age
{ get { return _age; } }

//valid behaviour by CLS-compliant rules


public int IncreaseAge()
{
int increasedAge = (int)_age + 1;

return increasedAge;
}

}
}

The rules for CLS compliance apply only to a public/protected components.

Violation of CLS rule: Unsigned types / sbyte

using System;

[assembly:CLSCompliant(true)]
namespace CLSDoc
{

public class Car


{
internal UInt16 _yearOfCreation = 0;

//Warning CS3008 Identifier '_numberOfDoors' is not CLS-compliant


//Warning CS3003 Type of 'Car._numberOfDoors' is not CLS-compliant
public UInt32 _numberOfDoors = 0;

//Warning CS3003 Type of 'Car.YearOfCreation' is not CLS-compliant


public UInt16 YearOfCreation
{
get { return _yearOfCreation; }
}

//Warning CS3002 Return type of 'Car.CalculateDistance()' is not CLS-compliant


public UInt64 CalculateDistance()
{
return 0;
}

//Warning CS3002 Return type of 'Car.TestDummyUnsignedPointerMethod()' is not CLS-


compliant
public UIntPtr TestDummyUnsignedPointerMethod()
{
int[] arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
UIntPtr ptr = (UIntPtr)arr[0];

https://riptutorial.com/ 183
return ptr;
}

//Warning CS3003 Type of 'Car.age' is not CLS-compliant


public sbyte age = 120;

}
}

Violation of CLS rule: Same naming

using System;

[assembly:CLSCompliant(true)]
namespace CLSDoc
{

public class Car


{
//Warning CS3005 Identifier 'Car.CALCULATEAge()' differing only in case is not
CLS-compliant
public int CalculateAge()
{
return 0;
}

public int CALCULATEAge()


{
return 0;
}

}
}

Visual Basic is not case sensitive

Violation of CLS rule: Identifier _

using System;

[assembly:CLSCompliant(true)]
namespace CLSDoc
{

public class Car


{
//Warning CS3008 Identifier '_age' is not CLS-complian
public int _age = 0;
}

You can not start variable with _

https://riptutorial.com/ 184
Violation of CLS rule: Inherit from non CLSComplaint class

using System;

[assembly:CLSCompliant(true)]
namespace CLSDoc
{

[CLSCompliant(false)]
public class Animal
{
public int age = 0;
}

//Warning CS3009 'Dog': base type 'Animal' is not CLS-compliant


public class Dog : Animal
{
}

Read CLSCompliantAttribute online: https://riptutorial.com/csharp/topic/7214/clscompliantattribute

https://riptutorial.com/ 185
Chapter 33: Code Contracts
Syntax
1. Contract.Requires(Condition,userMessage)

Contract.Requires(Condition,userMessage)

Contract.Result<T>

Contract.Ensures()

Contract.Invariants()

Remarks
.NET supports the Design by Contract idea via its Contracts class found in the System.Diagnostics
namespace and introduced in .NET 4.0. Code Contracts API includes classes for static and
runtime checks of code and allows you to define preconditions, postconditions, and invariants
within a method. The preconditions specify the conditions the parameters must fulfill before a
method can execute, postconditions that are verified upon completion of a method, and the
invariants define the conditions that do not change during the execution of a method.

Why are Code Contracts needed?

Tracking issues of an application when your application is running, is one the foremost concerns of
all the developers and administrators. Tracking can be performed in many ways. For example -

• You can apply tracing on our application and get the details of an application when the
application is running

• You can use event logging mechanism when you are running the application. The messages
can be seen using Event Viewer

• You can apply Performance Monitoring after a specific time interval and write live data from
your application.

Code Contracts uses a different approach for tracking and managing issues within an application.
Instead of validating everything that is returned from a method call, Code Contracts with the help
of preconditions, postconditions, and invariants on methods, ensure that everything entering and
leaving your methods are correct.

Examples
Preconditions

https://riptutorial.com/ 186
namespace CodeContractsDemo
{
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;

public class PaymentProcessor


{
private List<Payment> _payments = new List<Payment>();

public void Add(Payment payment)


{
Contract.Requires(payment != null);
Contract.Requires(!string.IsNullOrEmpty(payment.Name));
Contract.Requires(payment.Date <= DateTime.Now);
Contract.Requires(payment.Amount > 0);

this._payments.Add(payment);
}
}
}

Postconditions

public double GetPaymentsTotal(string name)


{
Contract.Ensures(Contract.Result<double>() >= 0);

double total = 0.0;

foreach (var payment in this._payments) {


if (string.Equals(payment.Name, name)) {
total += payment.Amount;
}
}

return total;
}

Invariants

namespace CodeContractsDemo
{
using System;
using System.Diagnostics.Contracts;

public class Point


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

public Point()
{
}

public Point(int x, int y)


{

https://riptutorial.com/ 187
this.X = x;
this.Y = y;
}

public void Set(int x, int y)


{
this.X = x;
this.Y = y;
}

public void Test(int x, int y)


{
for (int dx = -x; dx <= x; dx++) {
this.X = dx;
Console.WriteLine("Current X = {0}", this.X);
}

for (int dy = -y; dy <= y; dy++) {


this.Y = dy;
Console.WriteLine("Current Y = {0}", this.Y);
}

Console.WriteLine("X = {0}", this.X);


Console.WriteLine("Y = {0}", this.Y);
}

[ContractInvariantMethod]
private void ValidateCoordinates()
{
Contract.Invariant(this.X >= 0);
Contract.Invariant(this.Y >= 0);
}
}
}

Defining Contracts on Interface

[ContractClass(typeof(ValidationContract))]
interface IValidation
{
string CustomerID{get;set;}
string Password{get;set;}
}

[ContractClassFor(typeof(IValidation))]
sealed class ValidationContract:IValidation
{
string IValidation.CustomerID
{
[Pure]
get
{
return Contract.Result<string>();
}
set
{
Contract.Requires<ArgumentNullException>(!string.IsNullOrEmpty(value), "Customer
ID cannot be null!!");
}

https://riptutorial.com/ 188
}

string IValidation.Password
{
[Pure]
get
{
return Contract.Result<string>();
}
set
{
Contract.Requires<ArgumentNullException>(!string.IsNullOrEmpty(value), "Password
cannot be null!!");
}
}
}

class Validation:IValidation
{
public string GetCustomerPassword(string customerID)
{
Contract.Requires(!string.IsNullOrEmpty(customerID),"Customer ID cannot be Null");
Contract.Requires<ArgumentNullException>(!string.IsNullOrEmpty(customerID),
"Exception!!");
Contract.Ensures(Contract.Result<string>() != null);
string password="AAA@1234";
if (customerID!=null)
{
return password;
}
else
{
return null;
}

private string m_custID, m_PWD;

public string CustomerID


{
get
{
return m_custID;
}
set
{
m_custID = value;
}
}

public string Password


{
get
{
return m_PWD;
}
set
{
m_PWD = value;
}

https://riptutorial.com/ 189
}
}

In the above code, we have defined an interface called IValidation with an attribute
[ContractClass]. This attribute takes an address of a class where we have implemented a contract
for an Interface. The class ValidationContract makes use of properties defined in the interface and
checks for the null values using Contract.Requires<T>. T is an exception class.

We have also marked the get accessor with an attribute [Pure]. The pure attribute ensures that the
method or a property does not change the instance state of a class in which IValidation interface
is implemented.

Read Code Contracts online: https://riptutorial.com/csharp/topic/4241/code-contracts

https://riptutorial.com/ 190
Chapter 34: Code Contracts and Assertions
Examples
Assertions to check logic should always be true

Assertions are used not to perform testing of input parameters, but to verify that program flow is
corect -- i.e., that you can make certain assumptions about your code at a certain point in time. In
other words: a test done with Debug.Assert should always assume that the value tested is true.

Debug.Assert only executes in DEBUG builds; it is filtered out of RELEASE builds. It must be
considered a debugging tool in addition to unit testing and not as a replacement of code contracts
or input validation methods.

For instance, this is a good assertion:

var systemData = RetrieveSystemConfiguration();


Debug.Assert(systemData != null);

Here assert is a good choice because we can assume that RetrieveSystemConfiguration() will
return a valid value and will never return null.

Here is another good example:

UserData user = RetrieveUserData();


Debug.Assert(user != null);
Debug.Assert(user.Age > 0);
int year = DateTime.Today.Year - user.Age;

First, we may assume that RetrieveUserData() will return a valid value. Then, before using the Age
property, we verify the assumption (which should always be true) that the age of the user is strictly
positive.

This is a bad example of assert:

string input = Console.ReadLine();


int age = Convert.ToInt32(input);
Debug.Assert(age > 16);
Console.WriteLine("Great, you are over 16");

Assert is not for input validation because it is incorrect to assume that this assertion will always be
true. You must use input validation methods for that. In the case above, you should also verify that
the input value is a number in the first place.

Read Code Contracts and Assertions online: https://riptutorial.com/csharp/topic/4349/code-


contracts-and-assertions

https://riptutorial.com/ 191
Chapter 35: Collection Initializers
Remarks
The only requirement for an object to be initialized using this syntactic sugar is that the type
implements System.Collections.IEnumerable and the Add method. Although we call it a collection
initializer, the object does not have to be an collection.

Examples
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>();


temp.Add("foo");
temp.Add("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>();


temp.Add(1, "One");
temp.Add(2, "Two");
var numberDictionarynumberDictionary = temp;

C# 6 Index Initializers

Starting with C# 6, collections with indexers can be initialized by specifying the index to assign in

https://riptutorial.com/ 192
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>();


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>();


dict.Add("key1", 1);
dict.Add("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
{
Console.WriteLine("{0} was assigned to index {1}", value, index);
}
}
}

var foo = new IndexableClass


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

https://riptutorial.com/ 193
This would output:

10 was assigned to index 0


20 was assigned to index 1

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 },
"baz",
123.45d,
};
}
}

class MyCollection : IEnumerable


{
private IList list = new ArrayList();

public void Add(string item)


{
list.Add(item)
}

public void Add(string item, int count)


{
for(int i=0;i< count;i++) {
list.Add(item);
}
}

public IEnumerator GetEnumerator()


{
return list.GetEnumerator();
}
}

static class MyCollectionExtensions


{
public static void Add(this MyCollection @this, double value) =>
@this.Add(value.ToString());
}

Collection Initializers with Parameter Arrays

You can mix normal parameters and parameter arrays:

https://riptutorial.com/ 194
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}
}

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>();
}

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


}

A new Tag object can be created like this:

Tag t = new Tag


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

https://riptutorial.com/ 195
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.

Read Collection Initializers online: https://riptutorial.com/csharp/topic/21/collection-initializers

https://riptutorial.com/ 196
Chapter 36: Comments and regions
Examples
Comments

Using comments in your projects is a handy way of leaving explanations of your design choices,
and should aim to make your (or someone else's) life easier when maintaining or adding to the
code.

There are a two ways of adding a comment to your code.

Single line comments


Any text placed after // will be treated as a comment.

public class Program


{
// This is the entry point of my program.
public static void Main()
{
// Prints a message to the console. - This is a comment!
System.Console.WriteLine("Hello, World!");

// System.Console.WriteLine("Hello, World again!"); // You can even comment out code.


System.Console.ReadLine();
}
}

Multi line or delimited comments


Any text between /* and */ will be treated as a comment.

public class Program


{
public static void Main()
{
/*
This is a multi line comment
it will be ignored by the compiler.
*/
System.Console.WriteLine("Hello, World!");

// It's also possible to make an inline comment with /* */


// although it's rarely used in practice
System.Console.WriteLine(/* Inline comment */ "Hello, World!");

System.Console.ReadLine();
}

https://riptutorial.com/ 197
}

Regions

A region is a collapsible block of code, that can help with the readability and organisation of your
code.

NOTE: StyleCop's rule SA1124 DoNotUseRegions discourages use of regions. They are usually a
sign of badly organized code, as C# includes partial classes and other features which make
regions obsolete.

You can use regions in the following way:

class Program
{
#region Application entry point
static void Main(string[] args)
{
PrintHelloWorld();
System.Console.ReadLine();
}
#endregion

#region My method
private static void PrintHelloWorld()
{
System.Console.WriteLine("Hello, World!");
}
#endregion
}

When the above code is view in an IDE, you will be able to collapse and expand the code using
the + and - symbols.

Expanded

https://riptutorial.com/ 198
Collapsed

Documentation comments

XML documentation comments can be used to provide API documentation that can be easily
processed by tools:

/// <summary>
/// A helper class for validating method arguments.
/// </summary>
public static class Precondition
{
/// <summary>
/// Throws an <see cref="ArgumentOutOfRangeException"/> with the parameter
/// name set to <c>paramName</c> if <c>value</c> does not satisfy the
/// <c>predicate</c> specified.
/// </summary>
/// <typeparam name="T">
/// The type of the argument checked
/// </typeparam>
/// <param name="value">
/// The argument to be checked
/// </param>
/// <param name="predicate">
/// The predicate the value is required to satisfy
/// </param>
/// <param name="paramName">
/// The parameter name to be passed to the
/// <see cref="ArgumentOutOfRangeException"/>.
/// </param>
/// <returns>The value specified</returns>
public static T Satisfies<T>(T value, Func<T, bool> predicate, string paramName)
{
if (!predicate(value))
throw new ArgumentOutOfRangeException(paramName);

return value;
}
}

Documentation is instantly picked up by IntelliSense:

https://riptutorial.com/ 199
Read Comments and regions online: https://riptutorial.com/csharp/topic/5346/comments-and-
regions

https://riptutorial.com/ 200
Chapter 37: Common String Operations
Examples
Splitting a String by specific character

string helloWorld = "hello world, how is it going?";


string[] parts1 = helloWorld.Split(',');

//parts1: ["hello world", " how is it going?"]

string[] parts2 = helloWorld.Split(' ');

//parts2: ["hello", "world,", "how", "is", "it", "going?"]

Getting Substrings of a given string

string helloWorld = "Hello World!";


string world = helloWorld.Substring(6); //world = "World!"
string hello = helloWorld.Substring(0,5); // hello = "Hello"

Substring returns the string up from a given index, or between two indexes (both inclusive).

Determine whether a string begins with a given sequence

string HelloWorld = "Hello World";


HelloWorld.StartsWith("Hello"); // true
HelloWorld.StartsWith("Foo"); // false

Finding a string within a string

Using the System.String.Contains you can find out if a particular string exists within a string. The
method returns a boolean, true if the string exists else false.

string s = "Hello World";


bool stringExists = s.Contains("ello"); //stringExists =true as the string contains the
substring

Trimming Unwanted Characters Off the Start and/or End of Strings.

String.Trim()

string x = " Hello World! ";


string y = x.Trim(); // "Hello World!"

string q = "{(Hi!*";
string r = q.Trim( '(', '*', '{' ); // "Hi!"

https://riptutorial.com/ 201
String.TrimStart() and String.TrimEnd()

string q = "{(Hi*";
string r = q.TrimStart( '{' ); // "(Hi*"
string s = q.TrimEnd( '*' ); // "{(Hi"

Formatting a string

Use the String.Format() method to replace one or more items in the string with the string
representation of a specified object:

String.Format("Hello {0} Foo {1}", "World", "Bar") //Hello World Foo Bar

Joining an array of strings into a new one

var parts = new[] { "Foo", "Bar", "Fizz", "Buzz"};


var joined = string.Join(", ", parts);

//joined = "Foo, Bar, Fizz, Buzz"

Padding a string to a fixed length

string s = "Foo";
string paddedLeft = s.PadLeft(5); // paddedLeft = " Foo" (pads with spaces by default)
string paddedRight = s.PadRight(6, '+'); // paddedRight = "Foo+++"
string noPadded = s.PadLeft(2); // noPadded = "Foo" (original string is never
shortened)

Construct a string from Array

The String.Join method will help us to construct a string From array/list of characters or string.
This method accepts two parameters. The first one is the delimiter or the separator which will help
you to separate each element in the array. And the second parameter is the Array itself.

String from char array:

string delimiter=",";
char[] charArray = new[] { 'a', 'b', 'c' };
string inputString = String.Join(delimiter, charArray);

Output : a,b,c if we change the delimiter as "" then the output will become abc.

String from List of char:

string delimiter = "|";


List<char> charList = new List<char>() { 'a', 'b', 'c' };
string inputString = String.Join(delimiter, charList);

https://riptutorial.com/ 202
Output : a|b|c

String from List of Strings:

string delimiter = " ";


List<string> stringList = new List<string>() { "Ram", "is", "a","boy" };
string inputString = String.Join(delimiter, stringList);

Output : Ram is a boy

String from array of strings:

string delimiter = "_";


string[] stringArray = new [] { "Ram", "is", "a","boy" };
string inputString = String.Join(delimiter, stringArray);

Output : Ram_is_a_boy

Formatting using ToString

Usually we are using String.Format method for formatting purpose, the.ToString is usually used for
converting other types to string. We can specify the format along with the ToString method while
conversion is taking place, So we can avoid an additional Formatting. Let Me Explain how it works
with different types;

Integer to formatted string:

int intValue = 10;


string zeroPaddedInteger = intValue.ToString("000"); // Output will be "010"
string customFormat = intValue.ToString("Input value is 0"); // output will be "Input value
is 10"

double to formatted string:

double doubleValue = 10.456;


string roundedDouble = doubleValue.ToString("0.00"); // output 10.46
string integerPart = doubleValue.ToString("00"); // output 10
string customFormat = doubleValue.ToString("Input value is 0.0"); // Input value is 10.5

Formatting DateTime using ToString

DateTime currentDate = DateTime.Now; // {7/21/2016 7:23:15 PM}


string dateTimeString = currentDate.ToString("dd-MM-yyyy HH:mm:ss"); // "21-07-2016 19:23:15"
string dateOnlyString = currentDate.ToString("dd-MM-yyyy"); // "21-07-2016"
string dateWithMonthInWords = currentDate.ToString("dd-MMMM-yyyy HH:mm:ss"); // "21-July-2016
19:23:15"

Getting x characters from the right side of a string

Visual Basic has Left, Right, and Mid functions that returns characters from the Left, Right, and

https://riptutorial.com/ 203
Middle of a string. These methods does not exist in C#, but can be implemented with Substring().
They can be implemented as an extension methods like the following:

public static class StringExtensions


{
/// <summary>
/// VB Left function
/// </summary>
/// <param name="stringparam"></param>
/// <param name="numchars"></param>
/// <returns>Left-most numchars characters</returns>
public static string Left( this string stringparam, int numchars )
{
// Handle possible Null or numeric stringparam being passed
stringparam += string.Empty;

// Handle possible negative numchars being passed


numchars = Math.Abs( numchars );

// Validate numchars parameter


if (numchars > stringparam.Length)
numchars = stringparam.Length;

return stringparam.Substring( 0, numchars );


}

/// <summary>
/// VB Right function
/// </summary>
/// <param name="stringparam"></param>
/// <param name="numchars"></param>
/// <returns>Right-most numchars characters</returns>
public static string Right( this string stringparam, int numchars )
{
// Handle possible Null or numeric stringparam being passed
stringparam += string.Empty;

// Handle possible negative numchars being passed


numchars = Math.Abs( numchars );

// Validate numchars parameter


if (numchars > stringparam.Length)
numchars = stringparam.Length;

return stringparam.Substring( stringparam.Length - numchars );


}

/// <summary>
/// VB Mid function - to end of string
/// </summary>
/// <param name="stringparam"></param>
/// <param name="startIndex">VB-Style startindex, 1st char startindex = 1</param>
/// <returns>Balance of string beginning at startindex character</returns>
public static string Mid( this string stringparam, int startindex )
{
// Handle possible Null or numeric stringparam being passed
stringparam += string.Empty;

// Handle possible negative startindex being passed


startindex = Math.Abs( startindex );

https://riptutorial.com/ 204
// Validate numchars parameter
if (startindex > stringparam.Length)
startindex = stringparam.Length;

// C# strings are zero-based, convert passed startindex


return stringparam.Substring( startindex - 1 );
}

/// <summary>
/// VB Mid function - for number of characters
/// </summary>
/// <param name="stringparam"></param>
/// <param name="startIndex">VB-Style startindex, 1st char startindex = 1</param>
/// <param name="numchars">number of characters to return</param>
/// <returns>Balance of string beginning at startindex character</returns>
public static string Mid( this string stringparam, int startindex, int numchars)
{
// Handle possible Null or numeric stringparam being passed
stringparam += string.Empty;

// Handle possible negative startindex being passed


startindex = Math.Abs( startindex );

// Handle possible negative numchars being passed


numchars = Math.Abs( numchars );

// Validate numchars parameter


if (startindex > stringparam.Length)
startindex = stringparam.Length;

// C# strings are zero-based, convert passed startindex


return stringparam.Substring( startindex - 1, numchars );

}
}

This extension method can be used as follows:

string myLongString = "Hello World!";


string myShortString = myLongString.Right(6); // "World!"
string myLeftString = myLongString.Left(5); // "Hello"
string myMidString1 = myLongString.Left(4); // "lo World"
string myMidString2 = myLongString.Left(2,3); // "ell"

Checking for empty String using String.IsNullOrEmpty() and


String.IsNullOrWhiteSpace()

string nullString = null;


string emptyString = "";
string whitespaceString = " ";
string tabString = "\t";
string newlineString = "\n";
string nonEmptyString = "abc123";

bool result;

https://riptutorial.com/ 205
result = String.IsNullOrEmpty(nullString); // true
result = String.IsNullOrEmpty(emptyString); // true
result = String.IsNullOrEmpty(whitespaceString); // false
result = String.IsNullOrEmpty(tabString); // false
result = String.IsNullOrEmpty(newlineString); // false
result = String.IsNullOrEmpty(nonEmptyString); // false

result = String.IsNullOrWhiteSpace(nullString); // true


result = String.IsNullOrWhiteSpace(emptyString); // true
result = String.IsNullOrWhiteSpace(tabString); // true
result = String.IsNullOrWhiteSpace(newlineString); // true
result = String.IsNullOrWhiteSpace(whitespaceString); // true
result = String.IsNullOrWhiteSpace(nonEmptyString); // false

Getting a char at specific index and enumerating the string

You can use the Substring method to get any number of characters from a string at any given
location. However, if you only want a single character, you can use the string indexer to get a
single character at any given index like you do with an array:

string s = "hello";
char c = s[1]; //Returns 'e'

Notice that the return type is char, unlike the Substring method which returns a string type.

You can also use the indexer to iterate through the characters of the string:

string s = "hello";
foreach (char c in s)
Console.WriteLine(c);
/********* This will print each character on a new line:
h
e
l
l
o
**********/

Convert Decimal Number to Binary,Octal and Hexadecimal Format

1. To convert decimal number to binary format use base 2

Int32 Number = 15;


Console.WriteLine(Convert.ToString(Number, 2)); //OUTPUT : 1111

2. To convert decimal number to octal format use base 8

int Number = 15;


Console.WriteLine(Convert.ToString(Number, 8)); //OUTPUT : 17

3. To convert decimal number to hexadecimal format use base 16

https://riptutorial.com/ 206
var Number = 15;
Console.WriteLine(Convert.ToString(Number, 16)); //OUTPUT : f

Splitting a String by another string

string str = "this--is--a--complete--sentence";


string[] tokens = str.Split(new[] { "--" }, StringSplitOptions.None);

Result:

[ "this", "is", "a", "complete", "sentence" ]

Correctly reversing a string

Most times when people have to reverse a string, they do it more or less like this:

char[] a = s.ToCharArray();
System.Array.Reverse(a);
string r = new string(a);

However, what these people don't realize is that this is actually wrong.
And I don't mean because of the missing NULL check.

It is actually wrong because a Glyph/GraphemeCluster can consist out of several codepoints (aka.
characters).

To see why this is so, we first have to be aware of the fact what the term "character" actually
means.

Reference:

Character is an overloaded term than can mean many things.

A code point is the atomic unit of information. Text is a sequence of code points. Each
code point is a number which is given meaning by the Unicode standard.

A grapheme is a sequence of one or more code points that are displayed as a single,
graphical unit that a reader recognizes as a single element of the writing system. For
example, both a and ä are graphemes, but they may consist of multiple code points
(e.g. ä may be two code points, one for the base character a followed by one for the
diaresis; but there's also an alternative, legacy, single code point representing this
grapheme). Some code points are never part of any grapheme (e.g. the zero-width
non-joiner, or directional overrides).

A glyph is an image, usually stored in a font (which is a collection of glyphs), used to


represent graphemes or parts thereof. Fonts may compose multiple glyphs into a
single representation, for example, if the above ä is a single code point, a font may
chose to render that as two separate, spatially overlaid glyphs. For OTF, the font's
GSUB and GPOS tables contain substitution and positioning information to make this

https://riptutorial.com/ 207
work. A font may contain multiple alternative glyphs for the same grapheme, too.

So in C#, a character is actually a CodePoint.

Which means, if you just reverse a valid string like Les Misérables, which can look like this

string s = "Les Mise\u0301rables";

as a sequence of characters, you will get:

selbaŕesiM seL

As you can see, the accent is on the R character, instead of the e character.
Although string.reverse.reverse will yield the original string if you both times reverse the char
array, this kind of reversal is definitely NOT the reverse of the original string.

You'll need to reverse each GraphemeCluster only.


So, if done correctly, you reverse a string like this:

private static System.Collections.Generic.List<string> GraphemeClusters(string s)


{
System.Collections.Generic.List<string> ls = new
System.Collections.Generic.List<string>();

System.Globalization.TextElementEnumerator enumerator =
System.Globalization.StringInfo.GetTextElementEnumerator(s);
while (enumerator.MoveNext())
{
ls.Add((string)enumerator.Current);
}

return ls;
}

// this
private static string ReverseGraphemeClusters(string s)
{
if(string.IsNullOrEmpty(s) || s.Length == 1)
return s;

System.Collections.Generic.List<string> ls = GraphemeClusters(s);
ls.Reverse();

return string.Join("", ls.ToArray());


}

public static void TestMe()


{
string s = "Les Mise\u0301rables";
// s = "noël";
string r = ReverseGraphemeClusters(s);

// This would be wrong:


// char[] a = s.ToCharArray();
// System.Array.Reverse(a);
// string r = new string(a);

https://riptutorial.com/ 208
System.Console.WriteLine(r);
}

And - oh joy - you'll realize if you do it correctly like this, it will also work for Asian/South-
Asian/East-Asian languages (and French/Swedish/Norwegian, etc.)...

Replacing a string within a string

Using the System.String.Replace method, you can replace part of a string with another string.

string s = "Hello World";


s = s.Replace("World", "Universe"); // s = "Hello Universe"

All the occurrences of the search string are replaced.

This method can also be used to remove part of a string, using the String.Empty field:

string s = "Hello World";


s = s.Replace("ell", String.Empty); // s = "Ho World"

Changing the case of characters within a String

The System.String class supports a number of methods to convert between uppercase and
lowercase characters in a string.

• System.String.ToLowerInvariant is used to return a String object converted to lowercase.

• System.String.ToUpperInvariant is used to return a String object converted to uppercase.

Note: The reason to use the invariant versions of these methods is to prevent producing
unexpected culture-specific letters. This is explained here in detail.

Example:

string s = "My String";


s = s.ToLowerInvariant(); // "my string"
s = s.ToUpperInvariant(); // "MY STRING"

Note that you can choose to specify a specific Culture when converting to lowercase and
uppercase by using the String.ToLower(CultureInfo) and String.ToUpper(CultureInfo) methods
accordingly.

Concatenate an array of strings into a single string

The System.String.Join method allows to concatenate all elements in a string array, using a
specified separator between each element:

string[] words = {"One", "Two", "Three", "Four"};

https://riptutorial.com/ 209
string singleString = String.Join(",", words); // singleString = "One,Two,Three,Four"

String Concatenation

String Concatenation can be done by using the System.String.Concat method, or (much easier)
using the + operator:

string first = "Hello ";


string second = "World";

string concat = first + second; // concat = "Hello World"


concat = String.Concat(first, second); // concat = "Hello World"

In C# 6 this can be done as follows:

string concat = $"{first},{second}";

Read Common String Operations online: https://riptutorial.com/csharp/topic/73/common-string-


operations

https://riptutorial.com/ 210
Chapter 38: Conditional Statements
Examples
If-Else Statement

Programming in general often requires a decision or a branch within the code to account for how
the code operates under different inputs or conditions. Within the C# programming language (and
most programming languages for this matter), the simplest and sometimes the most useful way of
creating a branch within your program is through an If-Else statement.

Lets assume we have method (a.k.a. a function) which takes an int parameter which will represent
a score up to 100, and the method will print out a message saying whether we pass or fail.

static void PrintPassOrFail(int score)


{
if (score >= 50) // If score is greater or equal to 50
{
Console.WriteLine("Pass!");
}
else // If score is not greater or equal to 50
{
Console.WriteLine("Fail!");
}
}

When looking at this method, you may notice this line of code (score >= 50) inside the If
statement. This can be seen as a boolean condition, where if the condition is evaluated to equal
true, then the code that is in between the if { } is ran.

For example, if this method was called like this: PrintPassOrFail(60);, the output of the method
would be a Console Print saying Pass! since the parameter value of 60 is greater or equal to 50.

However, if the method was called like: PrintPassOrFail(30);, the output of the method would print
out saying Fail!. This is because the value 30 is not greater or equal to 50, thus the code in
between the else { } is ran instead of the If statement.

In this example, we've said that score should go up to 100, which hasn't been accounted for at all.
To account for score not going past 100 or possibly dropping below 0, see the If-Else If-Else
Statement example.

If-Else If-Else Statement

Following on from the If-Else Statement example, it is now time to introduce the Else If
statement. The Else If statement follows directly after the If statement in the If-Else If-Else
structure, but intrinsically has has a similar syntax as the If statement. It is used to add more
branches to the code than what a simple If-Else statement can.

https://riptutorial.com/ 211
In the example from If-Else Statement, the example specified that the score goes up to 100;
however there were never any checks against this. To fix this, lets modify the method from If-Else
Statement to look like this:

static void PrintPassOrFail(int score)


{
if (score > 100) // If score is greater than 100
{
Console.WriteLine("Error: score is greater than 100!");
}
else if (score < 0) // Else If score is less than 0
{
Console.WriteLine("Error: score is less than 0!");
}
else if (score >= 50) // Else if score is greater or equal to 50
{
Console.WriteLine("Pass!");
}
else // If none above, then score must be between 0 and 49
{
Console.WriteLine("Fail!");
}
}

All these statements will run in order from the top all the way to the bottom until a condition has
been met. In this new update of the method, we've added two new branches to now accommodate
for the score going out of bounds.

For example, if we now called the method in our code as PrintPassOFail(110);, the output would be
a Console Print saying Error: score is greater than 100!; and if we called the method in our code
like PrintPassOrFail(-20);, the output would say Error: score is less than 0!.

Switch statements

A switch statement allows a variable to be tested for equality against a list of values. Each value is
called a case, and the variable being switched on is checked for each switch case.

A switch statement is often more concise and understandable than if...else if... else..
statements when testing multiple possible values for a single variable.

Syntax is as follows

switch(expression) {
case constant-expression:
statement(s);
break;
case constant-expression:
statement(s);
break;

// you can have any number of case statements


default : // Optional
statement(s);
break;

https://riptutorial.com/ 212
}

there are sevaral things that have to consider while using the switch statement

• The expression used in a switch statement must have an integral or enumerated type, or be
of a class type in which the class has a single conversion function to an integral or
enumerated type.
• You can have any number of case statements within a switch. Each case is followed by the
value to be compared to and a colon. The values to compare to have to be unique within
each switch statement.
• A switch statement can have an optional default case. The default case can be used for
performing a task when none of the cases is true.
• Each case has to end with a break statement unless it is an empty statement. In that case
execution will continue at the case below it. The break statement can also be omitted when a
return, throw or goto case statement is used.

Example can be given with the grades wise

char grade = 'B';

switch (grade)
{
case 'A':
Console.WriteLine("Excellent!");
break;
case 'B':
case 'C':
Console.WriteLine("Well done");
break;
case 'D':
Console.WriteLine("You passed");
break;
case 'F':
Console.WriteLine("Better try again");
break;
default:
Console.WriteLine("Invalid grade");
break;
}

If statement conditions are standard boolean expressions and values

The following statement

if (conditionA && conditionB && conditionC) //...

is exactly equivalent to

bool conditions = conditionA && conditionB && conditionC;


if (conditions) // ...

in other words, the conditions inside the "if" statement just form an ordinary Boolean expression.

https://riptutorial.com/ 213
A common mistake when writing conditional statements is to explicitly compare to true and false:

if (conditionA == true && conditionB == false && conditionC == true) // ...

This can be rewritten as

if (conditionA && !conditionB && conditionC)

Read Conditional Statements online: https://riptutorial.com/csharp/topic/3144/conditional-


statements

https://riptutorial.com/ 214
Chapter 39: Constructors and Finalizers
Introduction
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.

Remarks
C# does not actually have destructors, but rather Finalizers which use C++ style destructor syntax.
Specifying a destructor overrides the Object.Finalize() method which cannot be called directly.

Unlike other languages with similar syntax, these methods are not called when objects go out of
scope, but are called when the Garbage Collector runs, which occurs under certain conditions. As
such, they are not guaranteed to run in any particular order.

Finalizers should be responsible for cleaning up unmanaged resources only (pointers acquired via
the Marshal class, received through p/Invoke (system calls) or raw pointers used within unsafe
blocks). To clean up managed resources, please review IDisposable, the Dispose pattern and the
using statement.

(Further reading: When should I create a destructor?)

Examples
Default Constructor

When a type is defined without a constructor:

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:

https://riptutorial.com/ 215
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.

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(); // dog.Name will be set to "Dog" by default.


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

https://riptutorial.com/ 216
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()
{
Console.WriteLine("Animal initialized");
}

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


public Animal()
{
Console.WriteLine("Animal created");
}

public static void Yawn()


{
Console.WriteLine("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.

Animal.Yawn();

This will output:

Animal initialized

https://riptutorial.com/ 217
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();
}
}

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() { Console.WriteLine("An unknown animal gets born."); }
public Animal(string name) { Console.WriteLine(name + " gets born"); }
}

public class Mammal : Animal


{
public Mammal(string name)
{
Console.WriteLine(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.

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)
{

https://riptutorial.com/ 218
Console.WriteLine(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

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()
{
Console.WriteLine("Base class finalized!");
}
}

class TheDerivedClass : TheBaseClass


{
~TheDerivedClass()
{
Console.WriteLine("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!
GC.Collect();

//Derived class finalized!


//Base class finalized!

Singleton constructor pattern

public class SingletonClass


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

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

https://riptutorial.com/ 219
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
SingletonClass.Instance.

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.

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:

using System.Runtime.CompilerServices;
// ...
RuntimeHelpers.RunClassConstructor(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.

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();
}

protected virtual AnotherBase CreateAnother()


{
return new AnotherBase();
}

https://riptutorial.com/ 220
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.

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()
{
Console.WriteLine(typeof(T).FullName);
}

public static void Yawn() { }


}

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

This will output:

System.Object
System.String

See also How do static constructors for generic types work ?

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 exception.

https://riptutorial.com/ 221
public class Animal
{
static Animal()
{
Console.WriteLine("Static ctor");
throw new Exception();
}

public static void Yawn() {}


}

try
{
Animal.Yawn();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}

try
{
Animal.Yawn();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}

This will output:

Static ctor

System.TypeInitializationException: The type initializer for 'Animal' threw an exception.


---> System.Exception: Exception of type 'System.Exception' was thrown.

[...]

System.TypeInitializationException: The type initializer for 'Animal' threw an exception.


---> System.Exception: Exception of type 'System.Exception' was thrown.

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

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)
{
Console.WriteLine("Shall this be executed?");

https://riptutorial.com/ 222
}

if (TestProperty == 2)
{
Console.WriteLine("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)
{
Console.WriteLine("Shall this be executed?");
}

if (TestProperty == 2)
{
Console.WriteLine("Or shall this be executed");
}
}
}

static void Main(string[] args)


{

https://riptutorial.com/ 223
var testInstance = new TestClass() { TestProperty = 1 };
Console.WriteLine(testInstance.TestProperty); //resulting in 1
}

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 Console.WriteLine(testInstance.TestProperty)
to be

"1"

Read Constructors and Finalizers online: https://riptutorial.com/csharp/topic/25/constructors-and-


finalizers

https://riptutorial.com/ 224
Chapter 40: Creating a Console Application
using a Plain-Text Editor and the C# Compiler
(csc.exe)
Examples
Creating a Console application using a Plain-Text Editor and the C# Compiler

In order to use a plain-text editor to create a Console application that is written in C#, you'll need
the C# Compiler. The C# Compiler (csc.exe), can be found at the following location:
%WINDIR%\Microsoft.NET\Framework64\v4.0.30319\csc.exe

N.B. Depending upon which version of the .NET Framework that is installed on your system, you
may need to change the path above, accordingly.

Saving the Code


The purpose of this topic is not to teach you how to write a Console application, but to teach you
how to compile one [to produce a single executable file], with nothing other than the C# Compiler
and any Plain-Text Editor (such as Notepad).

1. Open the Run dialog, by using the keyboard shortcut Windows Key + R
2. Type notepad, then hit Enter
3. Paste the example code below, into Notepad
4. Save the file as ConsoleApp.cs, by going to File → Save As..., then entering ConsoleApp.cs in
the 'File Name' text field, then selecting All Files as the file-type.
5. Click Save

Compiling the Source Code


1. Open the Run dialog, using Windows Key +R
2. Enter:

%WINDIR%\Microsoft.NET\Framework64\v4.0.30319\csc.exe /t:exe
/out:"C:\Users\yourUserName\Documents\ConsoleApp.exe"
"C:\Users\yourUserName\Documents\ConsoleApp.cs"

Now, go back to where you originally saved your ConsoleApp.cs file. You should now see an
executable file (ConsoleApp.exe). Double-click ConsoleApp.exe to open it.

https://riptutorial.com/ 225
That's it! Your console application has been compiled. An executable file has been created and
you now have a working Console app.

using System;

namespace ConsoleApp
{
class Program
{
private static string input = String.Empty;

static void Main(string[] args)


{
goto DisplayGreeting;

DisplayGreeting:
{
Console.WriteLine("Hello! What is your name?");

input = Console.ReadLine();

if (input.Length >= 1)
{
Console.WriteLine(
"Hello, " +
input +
", enter 'Exit' at any time to exit this app.");

goto AwaitFurtherInstruction;
}
else
{
goto DisplayGreeting;
}
}

AwaitFurtherInstruction:
{
input = Console.ReadLine();

if(input.ToLower() == "exit")
{
input = String.Empty;

Environment.Exit(0);
}
else
{
goto AwaitFurtherInstruction;
}
}
}
}
}

Read Creating a Console Application using a Plain-Text Editor and the C# Compiler (csc.exe)
online: https://riptutorial.com/csharp/topic/6676/creating-a-console-application-using-a-plain-text-
editor-and-the-csharp-compiler--csc-exe-

https://riptutorial.com/ 226
Chapter 41: Creating Own MessageBox in
Windows Form Application
Introduction
First we need to know what a MessageBox is...

The MessageBox control displays a message with specified text, and can be customised by
specifying a custom image, title and button sets (These button sets allow the user to choose more
than a basic yes/no answer).

By creating our own MessageBox we can re-use that MessageBox Control in any new applications
just by using the generated dll, or copying the file containing the class.

Syntax
• 'static DialogResult result = DialogResult.No; //DialogResult is returned by dialogs after
dismissal.'

Examples
Creating Own MessageBox Control.

To create our own MessageBox control simply follow the guide below...

1. Open up your instance of Visual Studio (VS 2008/2010/2012/2015/2017)

2. Go to the toolbar at the top and click File -> New Project --> Windows Forms Application -->
Give the project a name and then click ok.

3. Once loaded, drag and drop a button control from the Toolbox (found on the left) onto the
form (as shown below).

https://riptutorial.com/ 227
4. Double click the button and the Integrated Development Environment will automatically
generate the click event handler for you.

5. Edit the code for the form so that it looks like the following (You can right-click the form and
click Edit Code):

namespace MsgBoxExample {
public partial class MsgBoxExampleForm : Form {
//Constructor, called when the class is initialised.
public MsgBoxExampleForm() {
InitializeComponent();
}

//Called whenever the button is clicked.


private void btnShowMessageBox_Click(object sender, EventArgs e) {
CustomMsgBox.Show($"I'm a {nameof(CustomMsgBox)}!", "MSG", "OK");
}
}
}

6. Solution Explorer -> Right Click on your project --> Add --> Windows Form and set the name
as "CustomMsgBox.cs"

7. Drag in a button & label control from the Toolbox to the form (It'll look something like the
form below after doing it):

https://riptutorial.com/ 228
8. Now write out the code below into the newly created form:

private DialogResult result = DialogResult.No;


public static DialogResult Show(string text, string caption, string btnOkText) {
var msgBox = new CustomMsgBox();
msgBox.lblText.Text = text; //The text for the label...
msgBox.Text = caption; //Title of form
msgBox.btnOk.Text = btnOkText; //Text on the button
//This method is blocking, and will only return once the user
//clicks ok or closes the form.
msgBox.ShowDialog();
return result;
}

private void btnOk_Click(object sender, EventArgs e) {


result = DialogResult.Yes;
MsgBox.Close();
}

9. Now run the program by just pressing F5 Key. Congratulations, you've made a reusable
control.

How to use own created MessageBox control in another Windows Form


application.

To find your existing .cs files, right click on the project in your instance of Visual Studio, and click
Open Folder in File Explorer.

1. Visual Studio --> Your current project (Windows Form) --> Solution Explorer --> Project
Name --> Right Click --> Add --> Existing Item --> Then locate your existing .cs file.

2. Now there's one last thing to do in order to use the control. Add a using statement to your
code, so that your assembly knows about its dependencies.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
.
.
.
using CustomMsgBox; //Here's the using statement for our dependency.

https://riptutorial.com/ 229
3. To display the messagebox, simply use the following...

CustomMsgBox.Show("Your Message for Message Box...","MSG","OK");

Read Creating Own MessageBox in Windows Form Application online:


https://riptutorial.com/csharp/topic/9788/creating-own-messagebox-in-windows-form-application

https://riptutorial.com/ 230
Chapter 42: Creational Design Patterns
Remarks
The creational patterns aim to separate a system from how its objects are created, composed, and
represented. They increase the system's flexibility in terms of the what, who, how, and when of
object creation. Creational patterns encapsulate the knowledge about which classes a system
uses, but they hide the details of how the instances of these classes are created and put together.
Programmers have come to realize that composing systems with inheritance makes those
systems too rigid. The creational patterns are designed to break this close coupling.

Examples
Singleton Pattern

The Singleton pattern is designed to restrict creation of a class to exactly one single instance.

This pattern is used in a scenario where it makes sense to have only one of something, such as:

• a single class that orchestrates other objects' interactions, ex. Manager class
• or one class that represents a unique, single resource, ex. Logging component

One of the most common ways to implement the Singleton pattern is via a static factory method
such as a CreateInstance() or GetInstance() (or a static property in C#, Instance), which is then
designed to always return the same instance.

The first call to the method or property creates and returns the Singleton instance. Thereafter, the
method always returns the same instance. This way, there is only ever one instance of the
singleton object.

Preventing creation of instances via new can be accomplished by making the class constructor(s)
private.

Here is a typical code example for implementing a Singleton pattern in C#:

class Singleton
{
// Because the _instance member is made private, the only way to get the single
// instance is via the static Instance property below. This can also be similarly
// achieved with a GetInstance() method instead of the property.
private static Singleton _instance = null;

// Making the constructor private prevents other instances from being


// created via something like Singleton s = new Singleton(), protecting
// against unintentional misuse.
private Singleton()
{
}

https://riptutorial.com/ 231
public static Singleton Instance
{
get
{
// The first call will create the one and only instance.
if (_instance == null)
{
_instance = new Singleton();
}

// Every call afterwards will return the single instance created above.
return _instance;
}
}
}

To illustrate this pattern further, the code below checks whether an identical instance of the
Singleton is returned when the Instance property is called more than once.

class Program
{
static void Main(string[] args)
{
Singleton s1 = Singleton.Instance;
Singleton s2 = Singleton.Instance;

// Both Singleton objects above should now reference the same Singleton instance.
if (Object.ReferenceEquals(s1, s2))
{
Console.WriteLine("Singleton is working");
}
else
{
// Otherwise, the Singleton Instance property is returning something
// other than the unique, single instance when called.
Console.WriteLine("Singleton is broken");
}
}
}

Note: this implementation is not thread safe.

To see more examples, including how to make this thread-safe, visit: Singleton Implementation

Singletons are conceptually similar to a global value, and cause similar design flaws and
concerns. Because of this, the Singleton pattern is widely regarded as an anti-pattern.

Visit "What is so bad about Singletons?" for more information on the problems that arise with their
use.

In C#, you have the ability to make a class static, which makes all members static, and the class
cannot be instantiated. Given this, it is common to see static classes used in place of the Singleton
pattern.

For key differences between the two, visit C# Singleton Pattern Versus Static Class.

https://riptutorial.com/ 232
Factory Method pattern

Factory Method is one of creational design patterns. It is used to deal with the problem of creating
objects without specifying exact result type. This document will teach you how to use Factory
Method DP properly.

Let me explain the idea of it to you on a simple example. Imagine you're working in a factory that
produces three types of devices - Ammeter, Voltmeter and resistance meter. You are writing a
program for a central computer that will create selected device, but you don't know final decision
of your boss on what to produce.

Let's create an interface IDevice with some common functions that all devices have:

public interface IDevice


{
int Measure();
void TurnOff();
void TurnOn();
}

Now, we can create classes that represent our devices. Those classes must implement IDevice
interface:

public class AmMeter : IDevice


{
private Random r = null;
public AmMeter()
{
r = new Random();
}
public int Measure() { return r.Next(-25, 60); }
public void TurnOff() { Console.WriteLine("AmMeter flashes lights saying good bye!"); }
public void TurnOn() { Console.WriteLine("AmMeter turns on..."); }
}
public class OhmMeter : IDevice
{
private Random r = null;
public OhmMeter()
{
r = new Random();
}
public int Measure() { return r.Next(0, 1000000); }
public void TurnOff() { Console.WriteLine("OhmMeter flashes lights saying good bye!"); }
public void TurnOn() { Console.WriteLine("OhmMeter turns on..."); }
}
public class VoltMeter : IDevice
{
private Random r = null;
public VoltMeter()
{
r = new Random();
}
public int Measure() { return r.Next(-230, 230); }
public void TurnOff() { Console.WriteLine("VoltMeter flashes lights saying good bye!"); }
public void TurnOn() { Console.WriteLine("VoltMeter turns on..."); }
}

https://riptutorial.com/ 233
Now we have to define factory method. Let's create DeviceFactory class with static method inside:

public enum Device


{
AM,
VOLT,
OHM
}
public class DeviceFactory
{
public static IDevice CreateDevice(Device d)
{
switch(d)
{
case Device.AM: return new AmMeter();
case Device.VOLT: return new VoltMeter();
case Device.OHM: return new OhmMeter();
default: return new AmMeter();
}
}
}

Great! Let's test our code:

public class Program


{
static void Main(string[] args)
{
IDevice device = DeviceFactory.CreateDevice(Device.AM);
device.TurnOn();
Console.WriteLine(device.Measure());
Console.WriteLine(device.Measure());
Console.WriteLine(device.Measure());
Console.WriteLine(device.Measure());
Console.WriteLine(device.Measure());
device.TurnOff();
Console.WriteLine();

device = DeviceFactory.CreateDevice(Device.VOLT);
device.TurnOn();
Console.WriteLine(device.Measure());
Console.WriteLine(device.Measure());
Console.WriteLine(device.Measure());
Console.WriteLine(device.Measure());
Console.WriteLine(device.Measure());
device.TurnOff();
Console.WriteLine();

device = DeviceFactory.CreateDevice(Device.OHM);
device.TurnOn();
Console.WriteLine(device.Measure());
Console.WriteLine(device.Measure());
Console.WriteLine(device.Measure());
Console.WriteLine(device.Measure());
Console.WriteLine(device.Measure());
device.TurnOff();
Console.WriteLine();
}
}

https://riptutorial.com/ 234
This is the example output you might see after running this code:

AmMeter turns on...

36

33

43

24

AmMeter flashes lights saying good bye!

VoltMeter turns on...

102

-61

85

138

36

VoltMeter flashes lights saying good bye!

OhmMeter turns on...

723828

368536

685412

800266

578595

OhmMeter flashes lights saying good bye!

Builder Pattern

Separate the construction of a complex object from its representation so that the same
construction process can create different representations and and provides a high level of control
over the assembly of the objects.

In this example demonstrates the Builder pattern in which different vehicles are assembled in a
step-by-step fashion. The Shop uses VehicleBuilders to construct a variety of Vehicles in a series

https://riptutorial.com/ 235
of sequential steps.

using System;
using System.Collections.Generic;

namespace GangOfFour.Builder
{
/// <summary>
/// MainApp startup class for Real-World
/// Builder Design Pattern.
/// </summary>
public class MainApp
{
/// <summary>
/// Entry point into console application.
/// </summary>
public static void Main()
{
VehicleBuilder builder;

// Create shop with vehicle builders


Shop shop = new Shop();

// Construct and display vehicles


builder = new ScooterBuilder();
shop.Construct(builder);
builder.Vehicle.Show();

builder = new CarBuilder();


shop.Construct(builder);
builder.Vehicle.Show();

builder = new MotorCycleBuilder();


shop.Construct(builder);
builder.Vehicle.Show();

// Wait for user


Console.ReadKey();
}
}

/// <summary>
/// The 'Director' class
/// </summary>
class Shop
{
// Builder uses a complex series of steps
public void Construct(VehicleBuilder vehicleBuilder)
{
vehicleBuilder.BuildFrame();
vehicleBuilder.BuildEngine();
vehicleBuilder.BuildWheels();
vehicleBuilder.BuildDoors();
}
}

/// <summary>
/// The 'Builder' abstract class
/// </summary>
abstract class VehicleBuilder
{

https://riptutorial.com/ 236
protected Vehicle vehicle;

// Gets vehicle instance


public Vehicle Vehicle
{
get { return vehicle; }
}

// Abstract build methods


public abstract void BuildFrame();
public abstract void BuildEngine();
public abstract void BuildWheels();
public abstract void BuildDoors();
}

/// <summary>
/// The 'ConcreteBuilder1' class
/// </summary>
class MotorCycleBuilder : VehicleBuilder
{
public MotorCycleBuilder()
{
vehicle = new Vehicle("MotorCycle");
}

public override void BuildFrame()


{
vehicle["frame"] = "MotorCycle Frame";
}

public override void BuildEngine()


{
vehicle["engine"] = "500 cc";
}

public override void BuildWheels()


{
vehicle["wheels"] = "2";
}

public override void BuildDoors()


{
vehicle["doors"] = "0";
}
}

/// <summary>
/// The 'ConcreteBuilder2' class
/// </summary>
class CarBuilder : VehicleBuilder
{
public CarBuilder()
{
vehicle = new Vehicle("Car");
}

public override void BuildFrame()


{
vehicle["frame"] = "Car Frame";
}

https://riptutorial.com/ 237
public override void BuildEngine()
{
vehicle["engine"] = "2500 cc";
}

public override void BuildWheels()


{
vehicle["wheels"] = "4";
}

public override void BuildDoors()


{
vehicle["doors"] = "4";
}
}

/// <summary>
/// The 'ConcreteBuilder3' class
/// </summary>
class ScooterBuilder : VehicleBuilder
{
public ScooterBuilder()
{
vehicle = new Vehicle("Scooter");
}

public override void BuildFrame()


{
vehicle["frame"] = "Scooter Frame";
}

public override void BuildEngine()


{
vehicle["engine"] = "50 cc";
}

public override void BuildWheels()


{
vehicle["wheels"] = "2";
}

public override void BuildDoors()


{
vehicle["doors"] = "0";
}
}

/// <summary>
/// The 'Product' class
/// </summary>
class Vehicle
{
private string _vehicleType;
private Dictionary<string,string> _parts =
new Dictionary<string,string>();

// Constructor
public Vehicle(string vehicleType)
{
this._vehicleType = vehicleType;

https://riptutorial.com/ 238
}

// Indexer
public string this[string key]
{
get { return _parts[key]; }
set { _parts[key] = value; }
}

public void Show()


{
Console.WriteLine("\n---------------------------");
Console.WriteLine("Vehicle Type: {0}", _vehicleType);
Console.WriteLine(" Frame : {0}", _parts["frame"]);
Console.WriteLine(" Engine : {0}", _parts["engine"]);
Console.WriteLine(" #Wheels: {0}", _parts["wheels"]);
Console.WriteLine(" #Doors : {0}", _parts["doors"]);
}
}
}

Output

Vehicle Type: Scooter Frame : Scooter Frame


Engine : none
#Wheels: 2
#Doors : 0

Vehicle Type: Car


Frame : Car Frame
Engine : 2500 cc
#Wheels: 4
#Doors : 4

Vehicle Type: MotorCycle


Frame : MotorCycle Frame
Engine : 500 cc
#Wheels: 2
#Doors : 0

Prototype Pattern

Specify the kind of objects to create using a prototypical instance, and create new objects by
copying this prototype.

In this example demonstrates the Prototype pattern in which new Color objects are created by
copying pre-existing, user-defined Colors of the same type.

using System;
using System.Collections.Generic;

https://riptutorial.com/ 239
namespace GangOfFour.Prototype
{
/// <summary>
/// MainApp startup class for Real-World
/// Prototype Design Pattern.
/// </summary>
class MainApp
{
/// <summary>
/// Entry point into console application.
/// </summary>
static void Main()
{
ColorManager colormanager = new ColorManager();

// Initialize with standard colors


colormanager["red"] = new Color(255, 0, 0);
colormanager["green"] = new Color(0, 255, 0);
colormanager["blue"] = new Color(0, 0, 255);

// User adds personalized colors


colormanager["angry"] = new Color(255, 54, 0);
colormanager["peace"] = new Color(128, 211, 128);
colormanager["flame"] = new Color(211, 34, 20);

// User clones selected colors


Color color1 = colormanager["red"].Clone() as Color;
Color color2 = colormanager["peace"].Clone() as Color;
Color color3 = colormanager["flame"].Clone() as Color;

// Wait for user


Console.ReadKey();
}
}

/// <summary>
/// The 'Prototype' abstract class
/// </summary>
abstract class ColorPrototype
{
public abstract ColorPrototype Clone();
}

/// <summary>
/// The 'ConcretePrototype' class
/// </summary>
class Color : ColorPrototype
{
private int _red;
private int _green;
private int _blue;

// Constructor
public Color(int red, int green, int blue)
{
this._red = red;
this._green = green;
this._blue = blue;
}

https://riptutorial.com/ 240
// Create a shallow copy
public override ColorPrototype Clone()
{
Console.WriteLine(
"Cloning color RGB: {0,3},{1,3},{2,3}",
_red, _green, _blue);

return this.MemberwiseClone() as ColorPrototype;


}
}

/// <summary>
/// Prototype manager
/// </summary>
class ColorManager
{
private Dictionary<string, ColorPrototype> _colors =
new Dictionary<string, ColorPrototype>();

// Indexer
public ColorPrototype this[string key]
{
get { return _colors[key]; }
set { _colors.Add(key, value); }
}
}
}

Output:

Cloning color RGB: 255, 0, 0

Cloning color RGB: 128,211,128

Cloning color RGB: 211, 34, 20

Abstract Factory Pattern

Provide an interface for creating families of related or dependent objects without specifying their
concrete classes.

In this example demonstrates the creation of different animal worlds for a computer game using
different factories. Although the animals created by the Continent factories are different, the
interactions among the animals remain the same.

using System;

namespace GangOfFour.AbstractFactory
{
/// <summary>
/// MainApp startup class for Real-World
/// Abstract Factory Design Pattern.
/// </summary>
class MainApp
{
/// <summary>

https://riptutorial.com/ 241
/// Entry point into console application.
/// </summary>
public static void Main()
{
// Create and run the African animal world
ContinentFactory africa = new AfricaFactory();
AnimalWorld world = new AnimalWorld(africa);
world.RunFoodChain();

// Create and run the American animal world


ContinentFactory america = new AmericaFactory();
world = new AnimalWorld(america);
world.RunFoodChain();

// Wait for user input


Console.ReadKey();
}
}

/// <summary>
/// The 'AbstractFactory' abstract class
/// </summary>
abstract class ContinentFactory
{
public abstract Herbivore CreateHerbivore();
public abstract Carnivore CreateCarnivore();
}

/// <summary>
/// The 'ConcreteFactory1' class
/// </summary>
class AfricaFactory : ContinentFactory
{
public override Herbivore CreateHerbivore()
{
return new Wildebeest();
}
public override Carnivore CreateCarnivore()
{
return new Lion();
}
}

/// <summary>
/// The 'ConcreteFactory2' class
/// </summary>
class AmericaFactory : ContinentFactory
{
public override Herbivore CreateHerbivore()
{
return new Bison();
}
public override Carnivore CreateCarnivore()
{
return new Wolf();
}
}

/// <summary>
/// The 'AbstractProductA' abstract class

https://riptutorial.com/ 242
/// </summary>
abstract class Herbivore
{
}

/// <summary>
/// The 'AbstractProductB' abstract class
/// </summary>
abstract class Carnivore
{
public abstract void Eat(Herbivore h);
}

/// <summary>
/// The 'ProductA1' class
/// </summary>
class Wildebeest : Herbivore
{
}

/// <summary>
/// The 'ProductB1' class
/// </summary>
class Lion : Carnivore
{
public override void Eat(Herbivore h)
{
// Eat Wildebeest
Console.WriteLine(this.GetType().Name +
" eats " + h.GetType().Name);
}
}

/// <summary>
/// The 'ProductA2' class
/// </summary>
class Bison : Herbivore
{
}

/// <summary>
/// The 'ProductB2' class
/// </summary>
class Wolf : Carnivore
{
public override void Eat(Herbivore h)
{
// Eat Bison
Console.WriteLine(this.GetType().Name +
" eats " + h.GetType().Name);
}
}

/// <summary>
/// The 'Client' class
/// </summary>
class AnimalWorld
{
private Herbivore _herbivore;
private Carnivore _carnivore;

https://riptutorial.com/ 243
// Constructor
public AnimalWorld(ContinentFactory factory)
{
_carnivore = factory.CreateCarnivore();
_herbivore = factory.CreateHerbivore();
}

public void RunFoodChain()


{
_carnivore.Eat(_herbivore);
}
}
}

Output:

Lion eats Wildebeest

Wolf eats Bison

Read Creational Design Patterns online: https://riptutorial.com/csharp/topic/6654/creational-


design-patterns

https://riptutorial.com/ 244
Chapter 43: Cryptography
(System.Security.Cryptography)
Examples
Modern Examples of Symmetric Authenticated Encryption of a string

Cryptography is something very hard and after spending a lot of time reading different examples
and seeing how easy it is to introduce some form of vulnerability I found an answer originally
written by @jbtule that I think is very good. Enjoy reading:

"The general best practice for symmetric encryption is to use Authenticated Encryption with
Associated Data (AEAD), however this isn't a part of the standard .net crypto libraries. So the first
example uses AES256 and then HMAC256, a two step Encrypt then MAC, which requires more
overhead and more keys.

The second example uses the simpler practice of AES256-GCM using the open source Bouncy
Castle (via nuget).

Both examples have a main function that takes secret message string, key(s) and an optional non-
secret payload and return and authenticated encrypted string optionally prepended with the non-
secret data. Ideally you would use these with 256bit key(s) randomly generated see NewKey().

Both examples also have a helper methods that use a string password to generate the keys.
These helper methods are provided as a convenience to match up with other examples, however
they are far less secure because the strength of the password is going to be far weaker than a 256
bit key.

Update: Added byte[] overloads, and only the Gist has the full formatting with 4 spaces indent
and api docs due to StackOverflow answer limits."

.NET Built-in Encrypt(AES)-Then-MAC(HMAC) [Gist]

/*
* This work (Modern Encryption of a String C#, by James Tuley),
* identified by James Tuley, is free of known copyright restrictions.
* https://gist.github.com/4336842
* http://creativecommons.org/publicdomain/mark/1.0/
*/

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace Encryption
{
public static class AESThenHMAC

https://riptutorial.com/ 245
{
private static readonly RandomNumberGenerator Random = RandomNumberGenerator.Create();

//Preconfigured Encryption Parameters


public static readonly int BlockBitSize = 128;
public static readonly int KeyBitSize = 256;

//Preconfigured Password Key Derivation Parameters


public static readonly int SaltBitSize = 64;
public static readonly int Iterations = 10000;
public static readonly int MinPasswordLength = 12;

/// <summary>
/// Helper that generates a random key on each call.
/// </summary>
/// <returns></returns>
public static byte[] NewKey()
{
var key = new byte[KeyBitSize / 8];
Random.GetBytes(key);
return key;
}

/// <summary>
/// Simple Encryption (AES) then Authentication (HMAC) for a UTF8 Message.
/// </summary>
/// <param name="secretMessage">The secret message.</param>
/// <param name="cryptKey">The crypt key.</param>
/// <param name="authKey">The auth key.</param>
/// <param name="nonSecretPayload">(Optional) Non-Secret Payload.</param>
/// <returns>
/// Encrypted Message
/// </returns>
/// <exception cref="System.ArgumentException">Secret Message
Required!;secretMessage</exception>
/// <remarks>
/// Adds overhead of (Optional-Payload + BlockSize(16) + Message-Padded-To-Blocksize +
HMac-Tag(32)) * 1.33 Base64
/// </remarks>
public static string SimpleEncrypt(string secretMessage, byte[] cryptKey, byte[] authKey,
byte[] nonSecretPayload = null)
{
if (string.IsNullOrEmpty(secretMessage))
throw new ArgumentException("Secret Message Required!", "secretMessage");

var plainText = Encoding.UTF8.GetBytes(secretMessage);


var cipherText = SimpleEncrypt(plainText, cryptKey, authKey, nonSecretPayload);
return Convert.ToBase64String(cipherText);
}

/// <summary>
/// Simple Authentication (HMAC) then Decryption (AES) for a secrets UTF8 Message.
/// </summary>
/// <param name="encryptedMessage">The encrypted message.</param>
/// <param name="cryptKey">The crypt key.</param>
/// <param name="authKey">The auth key.</param>
/// <param name="nonSecretPayloadLength">Length of the non secret payload.</param>
/// <returns>
/// Decrypted Message
/// </returns>
/// <exception cref="System.ArgumentException">Encrypted Message

https://riptutorial.com/ 246
Required!;encryptedMessage</exception>
public static string SimpleDecrypt(string encryptedMessage, byte[] cryptKey, byte[]
authKey,
int nonSecretPayloadLength = 0)
{
if (string.IsNullOrWhiteSpace(encryptedMessage))
throw new ArgumentException("Encrypted Message Required!", "encryptedMessage");

var cipherText = Convert.FromBase64String(encryptedMessage);


var plainText = SimpleDecrypt(cipherText, cryptKey, authKey, nonSecretPayloadLength);
return plainText == null ? null : Encoding.UTF8.GetString(plainText);
}

/// <summary>
/// Simple Encryption (AES) then Authentication (HMAC) of a UTF8 message
/// using Keys derived from a Password (PBKDF2).
/// </summary>
/// <param name="secretMessage">The secret message.</param>
/// <param name="password">The password.</param>
/// <param name="nonSecretPayload">The non secret payload.</param>
/// <returns>
/// Encrypted Message
/// </returns>
/// <exception cref="System.ArgumentException">password</exception>
/// <remarks>
/// Significantly less secure than using random binary keys.
/// Adds additional non secret payload for key generation parameters.
/// </remarks>
public static string SimpleEncryptWithPassword(string secretMessage, string password,
byte[] nonSecretPayload = null)
{
if (string.IsNullOrEmpty(secretMessage))
throw new ArgumentException("Secret Message Required!", "secretMessage");

var plainText = Encoding.UTF8.GetBytes(secretMessage);


var cipherText = SimpleEncryptWithPassword(plainText, password, nonSecretPayload);
return Convert.ToBase64String(cipherText);
}

/// <summary>
/// Simple Authentication (HMAC) and then Descryption (AES) of a UTF8 Message
/// using keys derived from a password (PBKDF2).
/// </summary>
/// <param name="encryptedMessage">The encrypted message.</param>
/// <param name="password">The password.</param>
/// <param name="nonSecretPayloadLength">Length of the non secret payload.</param>
/// <returns>
/// Decrypted Message
/// </returns>
/// <exception cref="System.ArgumentException">Encrypted Message
Required!;encryptedMessage</exception>
/// <remarks>
/// Significantly less secure than using random binary keys.
/// </remarks>
public static string SimpleDecryptWithPassword(string encryptedMessage, string password,
int nonSecretPayloadLength = 0)
{
if (string.IsNullOrWhiteSpace(encryptedMessage))
throw new ArgumentException("Encrypted Message Required!", "encryptedMessage");

var cipherText = Convert.FromBase64String(encryptedMessage);

https://riptutorial.com/ 247
var plainText = SimpleDecryptWithPassword(cipherText, password, nonSecretPayloadLength);
return plainText == null ? null : Encoding.UTF8.GetString(plainText);
}

public static byte[] SimpleEncrypt(byte[] secretMessage, byte[] cryptKey, byte[] authKey,


byte[] nonSecretPayload = null)
{
//User Error Checks
if (cryptKey == null || cryptKey.Length != KeyBitSize / 8)
throw new ArgumentException(String.Format("Key needs to be {0} bit!", KeyBitSize),
"cryptKey");

if (authKey == null || authKey.Length != KeyBitSize / 8)


throw new ArgumentException(String.Format("Key needs to be {0} bit!", KeyBitSize),
"authKey");

if (secretMessage == null || secretMessage.Length < 1)


throw new ArgumentException("Secret Message Required!", "secretMessage");

//non-secret payload optional


nonSecretPayload = nonSecretPayload ?? new byte[] { };

byte[] cipherText;
byte[] iv;

using (var aes = new AesManaged


{
KeySize = KeyBitSize,
BlockSize = BlockBitSize,
Mode = CipherMode.CBC,
Padding = PaddingMode.PKCS7
})
{

//Use random IV
aes.GenerateIV();
iv = aes.IV;

using (var encrypter = aes.CreateEncryptor(cryptKey, iv))


using (var cipherStream = new MemoryStream())
{
using (var cryptoStream = new CryptoStream(cipherStream, encrypter,
CryptoStreamMode.Write))
using (var binaryWriter = new BinaryWriter(cryptoStream))
{
//Encrypt Data
binaryWriter.Write(secretMessage);
}

cipherText = cipherStream.ToArray();
}

//Assemble encrypted message and add authentication


using (var hmac = new HMACSHA256(authKey))
using (var encryptedStream = new MemoryStream())
{
using (var binaryWriter = new BinaryWriter(encryptedStream))
{
//Prepend non-secret payload if any

https://riptutorial.com/ 248
binaryWriter.Write(nonSecretPayload);
//Prepend IV
binaryWriter.Write(iv);
//Write Ciphertext
binaryWriter.Write(cipherText);
binaryWriter.Flush();

//Authenticate all data


var tag = hmac.ComputeHash(encryptedStream.ToArray());
//Postpend tag
binaryWriter.Write(tag);
}
return encryptedStream.ToArray();
}

public static byte[] SimpleDecrypt(byte[] encryptedMessage, byte[] cryptKey, byte[]


authKey, int nonSecretPayloadLength = 0)
{

//Basic Usage Error Checks


if (cryptKey == null || cryptKey.Length != KeyBitSize / 8)
throw new ArgumentException(String.Format("CryptKey needs to be {0} bit!",
KeyBitSize), "cryptKey");

if (authKey == null || authKey.Length != KeyBitSize / 8)


throw new ArgumentException(String.Format("AuthKey needs to be {0} bit!", KeyBitSize),
"authKey");

if (encryptedMessage == null || encryptedMessage.Length == 0)


throw new ArgumentException("Encrypted Message Required!", "encryptedMessage");

using (var hmac = new HMACSHA256(authKey))


{
var sentTag = new byte[hmac.HashSize / 8];
//Calculate Tag
var calcTag = hmac.ComputeHash(encryptedMessage, 0, encryptedMessage.Length -
sentTag.Length);
var ivLength = (BlockBitSize / 8);

//if message length is to small just return null


if (encryptedMessage.Length < sentTag.Length + nonSecretPayloadLength + ivLength)
return null;

//Grab Sent Tag


Array.Copy(encryptedMessage, encryptedMessage.Length - sentTag.Length, sentTag, 0,
sentTag.Length);

//Compare Tag with constant time comparison


var compare = 0;
for (var i = 0; i < sentTag.Length; i++)
compare |= sentTag[i] ^ calcTag[i];

//if message doesn't authenticate return null


if (compare != 0)
return null;

using (var aes = new AesManaged


{
KeySize = KeyBitSize,

https://riptutorial.com/ 249
BlockSize = BlockBitSize,
Mode = CipherMode.CBC,
Padding = PaddingMode.PKCS7
})
{

//Grab IV from message


var iv = new byte[ivLength];
Array.Copy(encryptedMessage, nonSecretPayloadLength, iv, 0, iv.Length);

using (var decrypter = aes.CreateDecryptor(cryptKey, iv))


using (var plainTextStream = new MemoryStream())
{
using (var decrypterStream = new CryptoStream(plainTextStream, decrypter,
CryptoStreamMode.Write))
using (var binaryWriter = new BinaryWriter(decrypterStream))
{
//Decrypt Cipher Text from Message
binaryWriter.Write(
encryptedMessage,
nonSecretPayloadLength + iv.Length,
encryptedMessage.Length - nonSecretPayloadLength - iv.Length - sentTag.Length
);
}
//Return Plain Text
return plainTextStream.ToArray();
}
}
}
}

public static byte[] SimpleEncryptWithPassword(byte[] secretMessage, string password,


byte[] nonSecretPayload = null)
{
nonSecretPayload = nonSecretPayload ?? new byte[] {};

//User Error Checks


if (string.IsNullOrWhiteSpace(password) || password.Length < MinPasswordLength)
throw new ArgumentException(String.Format("Must have a password of at least {0}
characters!", MinPasswordLength), "password");

if (secretMessage == null || secretMessage.Length ==0)


throw new ArgumentException("Secret Message Required!", "secretMessage");

var payload = new byte[((SaltBitSize / 8) * 2) + nonSecretPayload.Length];

Array.Copy(nonSecretPayload, payload, nonSecretPayload.Length);


int payloadIndex = nonSecretPayload.Length;

byte[] cryptKey;
byte[] authKey;
//Use Random Salt to prevent pre-generated weak password attacks.
using (var generator = new Rfc2898DeriveBytes(password, SaltBitSize / 8, Iterations))
{
var salt = generator.Salt;

//Generate Keys
cryptKey = generator.GetBytes(KeyBitSize / 8);

//Create Non Secret Payload


Array.Copy(salt, 0, payload, payloadIndex, salt.Length);

https://riptutorial.com/ 250
payloadIndex += salt.Length;
}

//Deriving separate key, might be less efficient than using HKDF,


//but now compatible with RNEncryptor which had a very similar wireformat and requires
less code than HKDF.
using (var generator = new Rfc2898DeriveBytes(password, SaltBitSize / 8, Iterations))
{
var salt = generator.Salt;

//Generate Keys
authKey = generator.GetBytes(KeyBitSize / 8);

//Create Rest of Non Secret Payload


Array.Copy(salt, 0, payload, payloadIndex, salt.Length);
}

return SimpleEncrypt(secretMessage, cryptKey, authKey, payload);


}

public static byte[] SimpleDecryptWithPassword(byte[] encryptedMessage, string password,


int nonSecretPayloadLength = 0)
{
//User Error Checks
if (string.IsNullOrWhiteSpace(password) || password.Length < MinPasswordLength)
throw new ArgumentException(String.Format("Must have a password of at least {0}
characters!", MinPasswordLength), "password");

if (encryptedMessage == null || encryptedMessage.Length == 0)


throw new ArgumentException("Encrypted Message Required!", "encryptedMessage");

var cryptSalt = new byte[SaltBitSize / 8];


var authSalt = new byte[SaltBitSize / 8];

//Grab Salt from Non-Secret Payload


Array.Copy(encryptedMessage, nonSecretPayloadLength, cryptSalt, 0, cryptSalt.Length);
Array.Copy(encryptedMessage, nonSecretPayloadLength + cryptSalt.Length, authSalt, 0,
authSalt.Length);

byte[] cryptKey;
byte[] authKey;

//Generate crypt key


using (var generator = new Rfc2898DeriveBytes(password, cryptSalt, Iterations))
{
cryptKey = generator.GetBytes(KeyBitSize / 8);
}
//Generate auth key
using (var generator = new Rfc2898DeriveBytes(password, authSalt, Iterations))
{
authKey = generator.GetBytes(KeyBitSize / 8);
}

return SimpleDecrypt(encryptedMessage, cryptKey, authKey, cryptSalt.Length +


authSalt.Length + nonSecretPayloadLength);
}
}
}

Bouncy Castle AES-GCM [Gist]

https://riptutorial.com/ 251
/*
* This work (Modern Encryption of a String C#, by James Tuley),
* identified by James Tuley, is free of known copyright restrictions.
* https://gist.github.com/4336842
* http://creativecommons.org/publicdomain/mark/1.0/
*/

using System;
using System.IO;
using System.Text;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Modes;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
namespace Encryption
{

public static class AESGCM


{
private static readonly SecureRandom Random = new SecureRandom();

//Preconfigured Encryption Parameters


public static readonly int NonceBitSize = 128;
public static readonly int MacBitSize = 128;
public static readonly int KeyBitSize = 256;

//Preconfigured Password Key Derivation Parameters


public static readonly int SaltBitSize = 128;
public static readonly int Iterations = 10000;
public static readonly int MinPasswordLength = 12;

/// <summary>
/// Helper that generates a random new key on each call.
/// </summary>
/// <returns></returns>
public static byte[] NewKey()
{
var key = new byte[KeyBitSize / 8];
Random.NextBytes(key);
return key;
}

/// <summary>
/// Simple Encryption And Authentication (AES-GCM) of a UTF8 string.
/// </summary>
/// <param name="secretMessage">The secret message.</param>
/// <param name="key">The key.</param>
/// <param name="nonSecretPayload">Optional non-secret payload.</param>
/// <returns>
/// Encrypted Message
/// </returns>
/// <exception cref="System.ArgumentException">Secret Message
Required!;secretMessage</exception>
/// <remarks>
/// Adds overhead of (Optional-Payload + BlockSize(16) + Message + HMac-Tag(16)) * 1.33
Base64
/// </remarks>
public static string SimpleEncrypt(string secretMessage, byte[] key, byte[]

https://riptutorial.com/ 252
nonSecretPayload = null)
{
if (string.IsNullOrEmpty(secretMessage))
throw new ArgumentException("Secret Message Required!", "secretMessage");

var plainText = Encoding.UTF8.GetBytes(secretMessage);


var cipherText = SimpleEncrypt(plainText, key, nonSecretPayload);
return Convert.ToBase64String(cipherText);
}

/// <summary>
/// Simple Decryption & Authentication (AES-GCM) of a UTF8 Message
/// </summary>
/// <param name="encryptedMessage">The encrypted message.</param>
/// <param name="key">The key.</param>
/// <param name="nonSecretPayloadLength">Length of the optional non-secret
payload.</param>
/// <returns>Decrypted Message</returns>
public static string SimpleDecrypt(string encryptedMessage, byte[] key, int
nonSecretPayloadLength = 0)
{
if (string.IsNullOrEmpty(encryptedMessage))
throw new ArgumentException("Encrypted Message Required!", "encryptedMessage");

var cipherText = Convert.FromBase64String(encryptedMessage);


var plainText = SimpleDecrypt(cipherText, key, nonSecretPayloadLength);
return plainText == null ? null : Encoding.UTF8.GetString(plainText);
}

/// <summary>
/// Simple Encryption And Authentication (AES-GCM) of a UTF8 String
/// using key derived from a password (PBKDF2).
/// </summary>
/// <param name="secretMessage">The secret message.</param>
/// <param name="password">The password.</param>
/// <param name="nonSecretPayload">The non secret payload.</param>
/// <returns>
/// Encrypted Message
/// </returns>
/// <remarks>
/// Significantly less secure than using random binary keys.
/// Adds additional non secret payload for key generation parameters.
/// </remarks>
public static string SimpleEncryptWithPassword(string secretMessage, string password,
byte[] nonSecretPayload = null)
{
if (string.IsNullOrEmpty(secretMessage))
throw new ArgumentException("Secret Message Required!", "secretMessage");

var plainText = Encoding.UTF8.GetBytes(secretMessage);


var cipherText = SimpleEncryptWithPassword(plainText, password, nonSecretPayload);
return Convert.ToBase64String(cipherText);
}

/// <summary>
/// Simple Decryption and Authentication (AES-GCM) of a UTF8 message
/// using a key derived from a password (PBKDF2)
/// </summary>
/// <param name="encryptedMessage">The encrypted message.</param>

https://riptutorial.com/ 253
/// <param name="password">The password.</param>
/// <param name="nonSecretPayloadLength">Length of the non secret payload.</param>
/// <returns>
/// Decrypted Message
/// </returns>
/// <exception cref="System.ArgumentException">Encrypted Message
Required!;encryptedMessage</exception>
/// <remarks>
/// Significantly less secure than using random binary keys.
/// </remarks>
public static string SimpleDecryptWithPassword(string encryptedMessage, string password,
int nonSecretPayloadLength = 0)
{
if (string.IsNullOrWhiteSpace(encryptedMessage))
throw new ArgumentException("Encrypted Message Required!", "encryptedMessage");

var cipherText = Convert.FromBase64String(encryptedMessage);


var plainText = SimpleDecryptWithPassword(cipherText, password, nonSecretPayloadLength);
return plainText == null ? null : Encoding.UTF8.GetString(plainText);
}

public static byte[] SimpleEncrypt(byte[] secretMessage, byte[] key, byte[]


nonSecretPayload = null)
{
//User Error Checks
if (key == null || key.Length != KeyBitSize / 8)
throw new ArgumentException(String.Format("Key needs to be {0} bit!", KeyBitSize),
"key");

if (secretMessage == null || secretMessage.Length == 0)


throw new ArgumentException("Secret Message Required!", "secretMessage");

//Non-secret Payload Optional


nonSecretPayload = nonSecretPayload ?? new byte[] { };

//Using random nonce large enough not to repeat


var nonce = new byte[NonceBitSize / 8];
Random.NextBytes(nonce, 0, nonce.Length);

var cipher = new GcmBlockCipher(new AesFastEngine());


var parameters = new AeadParameters(new KeyParameter(key), MacBitSize, nonce,
nonSecretPayload);
cipher.Init(true, parameters);

//Generate Cipher Text With Auth Tag


var cipherText = new byte[cipher.GetOutputSize(secretMessage.Length)];
var len = cipher.ProcessBytes(secretMessage, 0, secretMessage.Length, cipherText, 0);
cipher.DoFinal(cipherText, len);

//Assemble Message
using (var combinedStream = new MemoryStream())
{
using (var binaryWriter = new BinaryWriter(combinedStream))
{
//Prepend Authenticated Payload
binaryWriter.Write(nonSecretPayload);
//Prepend Nonce
binaryWriter.Write(nonce);
//Write Cipher Text
binaryWriter.Write(cipherText);
}

https://riptutorial.com/ 254
return combinedStream.ToArray();
}
}

public static byte[] SimpleDecrypt(byte[] encryptedMessage, byte[] key, int


nonSecretPayloadLength = 0)
{
//User Error Checks
if (key == null || key.Length != KeyBitSize / 8)
throw new ArgumentException(String.Format("Key needs to be {0} bit!", KeyBitSize),
"key");

if (encryptedMessage == null || encryptedMessage.Length == 0)


throw new ArgumentException("Encrypted Message Required!", "encryptedMessage");

using (var cipherStream = new MemoryStream(encryptedMessage))


using (var cipherReader = new BinaryReader(cipherStream))
{
//Grab Payload
var nonSecretPayload = cipherReader.ReadBytes(nonSecretPayloadLength);

//Grab Nonce
var nonce = cipherReader.ReadBytes(NonceBitSize / 8);

var cipher = new GcmBlockCipher(new AesFastEngine());


var parameters = new AeadParameters(new KeyParameter(key), MacBitSize, nonce,
nonSecretPayload);
cipher.Init(false, parameters);

//Decrypt Cipher Text


var cipherText = cipherReader.ReadBytes(encryptedMessage.Length -
nonSecretPayloadLength - nonce.Length);
var plainText = new byte[cipher.GetOutputSize(cipherText.Length)];

try
{
var len = cipher.ProcessBytes(cipherText, 0, cipherText.Length, plainText, 0);
cipher.DoFinal(plainText, len);

}
catch (InvalidCipherTextException)
{
//Return null if it doesn't authenticate
return null;
}

return plainText;
}

public static byte[] SimpleEncryptWithPassword(byte[] secretMessage, string password,


byte[] nonSecretPayload = null)
{
nonSecretPayload = nonSecretPayload ?? new byte[] {};

//User Error Checks


if (string.IsNullOrWhiteSpace(password) || password.Length < MinPasswordLength)
throw new ArgumentException(String.Format("Must have a password of at least {0}
characters!", MinPasswordLength), "password");

https://riptutorial.com/ 255
if (secretMessage == null || secretMessage.Length == 0)
throw new ArgumentException("Secret Message Required!", "secretMessage");

var generator = new Pkcs5S2ParametersGenerator();

//Use Random Salt to minimize pre-generated weak password attacks.


var salt = new byte[SaltBitSize / 8];
Random.NextBytes(salt);

generator.Init(
PbeParametersGenerator.Pkcs5PasswordToBytes(password.ToCharArray()),
salt,
Iterations);

//Generate Key
var key = (KeyParameter)generator.GenerateDerivedMacParameters(KeyBitSize);

//Create Full Non Secret Payload


var payload = new byte[salt.Length + nonSecretPayload.Length];
Array.Copy(nonSecretPayload, payload, nonSecretPayload.Length);
Array.Copy(salt,0, payload,nonSecretPayload.Length, salt.Length);

return SimpleEncrypt(secretMessage, key.GetKey(), payload);


}

public static byte[] SimpleDecryptWithPassword(byte[] encryptedMessage, string password,


int nonSecretPayloadLength = 0)
{
//User Error Checks
if (string.IsNullOrWhiteSpace(password) || password.Length < MinPasswordLength)
throw new ArgumentException(String.Format("Must have a password of at least {0}
characters!", MinPasswordLength), "password");

if (encryptedMessage == null || encryptedMessage.Length == 0)


throw new ArgumentException("Encrypted Message Required!", "encryptedMessage");

var generator = new Pkcs5S2ParametersGenerator();

//Grab Salt from Payload


var salt = new byte[SaltBitSize / 8];
Array.Copy(encryptedMessage, nonSecretPayloadLength, salt, 0, salt.Length);

generator.Init(
PbeParametersGenerator.Pkcs5PasswordToBytes(password.ToCharArray()),
salt,
Iterations);

//Generate Key
var key = (KeyParameter)generator.GenerateDerivedMacParameters(KeyBitSize);

return SimpleDecrypt(encryptedMessage, key.GetKey(), salt.Length +


nonSecretPayloadLength);
}
}
}

Introduction to Symmetric and Asymmetric Encryption

You can improve the security for data transit or storing by implementing encrypting techniques.

https://riptutorial.com/ 256
Basically there are two approaches when using System.Security.Cryptography: symmetric and
asymmetric.

Symmetric Encryption
This method uses a private key in order to perform the data transformation.

Pros:

• Symmetric algorithms consume less resources and are faster than asymmetric ones.
• The amount of data you can encrypt is unlimited.

Cons:

• Encryption and decryption use the same key. Someone will be able to decrypt your data if
the key is compromised.
• You could end up with many different secret keys to manage if you choose to use a different
secret key for different data.

Under System.Security.Cryptography you have different classes that perform symmetric


encryption, they are known as block ciphers:

• AesManaged (AES algorithm).


• AesCryptoServiceProvider (AES algorithm FIPS 140-2 complaint).
• DESCryptoServiceProvider (DES algorithm).
• RC2CryptoServiceProvider (Rivest Cipher 2 algorithm).
• RijndaelManaged (AES algorithm). Note: RijndaelManaged is not FIPS-197 complaint.
• TripleDES (TripleDES algorithm).

Asymmetric Encryption
This method uses a combination of public and private keys in order to perform the data
transformation.

Pros:

• It uses larger keys than symmetric algorithms, thus they are less susceptible to being
cracked by using brute force.
• It is easier to guarantee who is able to encrypt and decrypt the data because it relies on two
keys (public and private).

Cons:

• There is a limit on the amount of data that you can encrypt. The limit is different for each
algorithm and is typically proportional with the key size of the algorithm. For example, an
RSACryptoServiceProvider object with a key length of 1,024 bits can only encrypt a

https://riptutorial.com/ 257
message that is smaller than 128 bytes.
• Asymmetric algorithms are very slow in comparison to symmetric algorithms.

Under System.Security.Cryptography you have access to different classes that perform


asymmetric encryption:

• DSACryptoServiceProvider (Digital Signature Algorithm algorithm)


• RSACryptoServiceProvider (RSA Algorithm algorithm)

Password Hashing

Passwords should never be stored as plain text! They should be hashed with a randomly
generated salt (to defend against rainbow table attacks) using a slow password hashing algorithm.
A high number of iterations (> 10k) can be used to slow down brute force attacks. A delay of
~100ms is acceptable to a user logging in, but makes breaking a long password difficult. When
choosing a number of iterations you should use the maximum tolerable value for your application
and increase it as computer performance improves. You will also need to consider stopping
repeated requests which could be used as a DoS attack.

When hashing for the first time a salt can be generated for you, the resulting hash and salt can
then be stored to a file.

private void firstHash(string userName, string userPassword, int numberOfItterations)


{
Rfc2898DeriveBytes PBKDF2 = new Rfc2898DeriveBytes(userPassword, 8, numberOfItterations);
//Hash the password with a 8 byte salt
byte[] hashedPassword = PBKDF2.GetBytes(20); //Returns a 20 byte hash
byte[] salt = PBKDF2.Salt;
writeHashToFile(userName, hashedPassword, salt, numberOfItterations); //Store the hashed
password with the salt and number of itterations to check against future password entries
}

Checking an existing users password, read their hash and salt from a file and compare to the hash
of the entered password

private bool checkPassword(string userName, string userPassword, int numberOfItterations)


{
byte[] usersHash = getUserHashFromFile(userName);
byte[] userSalt = getUserSaltFromFile(userName);
Rfc2898DeriveBytes PBKDF2 = new Rfc2898DeriveBytes(userPassword, userSalt,
numberOfItterations); //Hash the password with the users salt
byte[] hashedPassword = PBKDF2.GetBytes(20); //Returns a 20 byte hash
bool passwordsMach = comparePasswords(usersHash, hashedPassword); //Compares byte
arrays
return passwordsMach;
}

Simple Symmetric File Encryption

The following code sample demonstrates a quick and easy means of encrypting and decrypting
files using the AES symmetric encryption algorithm.

https://riptutorial.com/ 258
The code randomly generates the Salt and Initialization Vectors each time a file is encrypted,
meaning that encrypting the same file with the same password will always lead to different output.
The salt and IV are written to the output file so that only the password is required to decrypt it.

public static void ProcessFile(string inputPath, string password, bool encryptMode, string
outputPath)
{
using (var cypher = new AesManaged())
using (var fsIn = new FileStream(inputPath, FileMode.Open))
using (var fsOut = new FileStream(outputPath, FileMode.Create))
{
const int saltLength = 256;
var salt = new byte[saltLength];
var iv = new byte[cypher.BlockSize / 8];

if (encryptMode)
{
// Generate random salt and IV, then write them to file
using (var rng = new RNGCryptoServiceProvider())
{
rng.GetBytes(salt);
rng.GetBytes(iv);
}
fsOut.Write(salt, 0, salt.Length);
fsOut.Write(iv, 0, iv.Length);
}
else
{
// Read the salt and IV from the file
fsIn.Read(salt, 0, saltLength);
fsIn.Read(iv, 0, iv.Length);
}

// Generate a secure password, based on the password and salt provided


var pdb = new Rfc2898DeriveBytes(password, salt);
var key = pdb.GetBytes(cypher.KeySize / 8);

// Encrypt or decrypt the file


using (var cryptoTransform = encryptMode
? cypher.CreateEncryptor(key, iv)
: cypher.CreateDecryptor(key, iv))
using (var cs = new CryptoStream(fsOut, cryptoTransform, CryptoStreamMode.Write))
{
fsIn.CopyTo(cs);
}
}
}

Cryptographically Secure Random Data

There are times when the framework's Random() class may not be considered random enough,
given that it is based on a psuedo-random number generator. The framework's Crypto classes do,
however, provide something more robust in the form of RNGCryptoServiceProvider.

The following code samples demonstrate how to generate Cryptographically Secure byte arrays,
strings and numbers.

https://riptutorial.com/ 259
Random Byte Array

public static byte[] GenerateRandomData(int length)


{
var rnd = new byte[length];
using (var rng = new RNGCryptoServiceProvider())
rng.GetBytes(rnd);
return rnd;
}

Random Integer (with even distribution)

public static int GenerateRandomInt(int minVal=0, int maxVal=100)


{
var rnd = new byte[4];
using (var rng = new RNGCryptoServiceProvider())
rng.GetBytes(rnd);
var i = Math.Abs(BitConverter.ToInt32(rnd, 0));
return Convert.ToInt32(i % (maxVal - minVal + 1) + minVal);
}

Random String

public static string GenerateRandomString(int length, string allowableChars=null)


{
if (string.IsNullOrEmpty(allowableChars))
allowableChars = @"ABCDEFGHIJKLMNOPQRSTUVWXYZ";

// Generate random data


var rnd = new byte[length];
using (var rng = new RNGCryptoServiceProvider())
rng.GetBytes(rnd);

// Generate the output string


var allowable = allowableChars.ToCharArray();
var l = allowable.Length;
var chars = new char[length];
for (var i = 0; i < length; i++)
chars[i] = allowable[rnd[i] % l];

return new string(chars);


}

Fast Asymmetric File Encryption

Asymmetric encryption is often regarded as preferable to Symmetric encryption for transferring


messages to other parties. This is mainly because it negates many of the risks related to the
exchange of a shared key and ensures that whilst anyone with the public key can encrypt a
message for the intended recipient, only that recipient can decrypt it. Unfortunately the major
down-side of asymmetric encryption algorithms is that they are significantly slower than their
symmetric cousins. As such the asymmetric encryption of files, especially large ones, can often be
a very computationally intensive process.

In order to provide both security AND performance, a hybrid approach can be taken. This entails

https://riptutorial.com/ 260
the cryptographically random generation of a key and initialization vector for Symmetric
encryption. These values are then encrypted using an Asymmetric algorithm and written to the
output file, before being used to encrypt the source data Symmetrically and appending it to the
output.

This approach provides a high degree of both performance and security, in that the data is
encrypted using a symmetric algorithm (fast) and the key and iv, both randomly generated
(secure) are encrypted by an asymmetric algorithm (secure). It also has the added advantage that
the same payload encrypted on different occasions will have very different cyphertext, because
the symmetric keys are randomly generated each time.

The following class demonstrates asymmetric encryption of strings and byte arrays, as well as
hybrid file encryption.

public static class AsymmetricProvider


{
#region Key Generation
public class KeyPair
{
public string PublicKey { get; set; }
public string PrivateKey { get; set; }
}

public static KeyPair GenerateNewKeyPair(int keySize = 4096)


{
// KeySize is measured in bits. 1024 is the default, 2048 is better, 4096 is more
robust but takes a fair bit longer to generate.
using (var rsa = new RSACryptoServiceProvider(keySize))
{
return new KeyPair {PublicKey = rsa.ToXmlString(false), PrivateKey =
rsa.ToXmlString(true)};
}
}

#endregion

#region Asymmetric Data Encryption and Decryption

public static byte[] EncryptData(byte[] data, string publicKey)


{
using (var asymmetricProvider = new RSACryptoServiceProvider())
{
asymmetricProvider.FromXmlString(publicKey);
return asymmetricProvider.Encrypt(data, true);
}
}

public static byte[] DecryptData(byte[] data, string publicKey)


{
using (var asymmetricProvider = new RSACryptoServiceProvider())
{
asymmetricProvider.FromXmlString(publicKey);
if (asymmetricProvider.PublicOnly)
throw new Exception("The key provided is a public key and does not contain the
private key elements required for decryption");
return asymmetricProvider.Decrypt(data, true);
}

https://riptutorial.com/ 261
}

public static string EncryptString(string value, string publicKey)


{
return Convert.ToBase64String(EncryptData(Encoding.UTF8.GetBytes(value), publicKey));
}

public static string DecryptString(string value, string privateKey)


{
return Encoding.UTF8.GetString(EncryptData(Convert.FromBase64String(value),
privateKey));
}

#endregion

#region Hybrid File Encryption and Decription

public static void EncryptFile(string inputFilePath, string outputFilePath, string


publicKey)
{
using (var symmetricCypher = new AesManaged())
{
// Generate random key and IV for symmetric encryption
var key = new byte[symmetricCypher.KeySize / 8];
var iv = new byte[symmetricCypher.BlockSize / 8];
using (var rng = new RNGCryptoServiceProvider())
{
rng.GetBytes(key);
rng.GetBytes(iv);
}

// Encrypt the symmetric key and IV


var buf = new byte[key.Length + iv.Length];
Array.Copy(key, buf, key.Length);
Array.Copy(iv, 0, buf, key.Length, iv.Length);
buf = EncryptData(buf, publicKey);

var bufLen = BitConverter.GetBytes(buf.Length);

// Symmetrically encrypt the data and write it to the file, along with the
encrypted key and iv
using (var cypherKey = symmetricCypher.CreateEncryptor(key, iv))
using (var fsIn = new FileStream(inputFilePath, FileMode.Open))
using (var fsOut = new FileStream(outputFilePath, FileMode.Create))
using (var cs = new CryptoStream(fsOut, cypherKey, CryptoStreamMode.Write))
{
fsOut.Write(bufLen,0, bufLen.Length);
fsOut.Write(buf, 0, buf.Length);
fsIn.CopyTo(cs);
}
}
}

public static void DecryptFile(string inputFilePath, string outputFilePath, string


privateKey)
{
using (var symmetricCypher = new AesManaged())
using (var fsIn = new FileStream(inputFilePath, FileMode.Open))
{
// Determine the length of the encrypted key and IV
var buf = new byte[sizeof(int)];

https://riptutorial.com/ 262
fsIn.Read(buf, 0, buf.Length);
var bufLen = BitConverter.ToInt32(buf, 0);

// Read the encrypted key and IV data from the file and decrypt using the
asymmetric algorithm
buf = new byte[bufLen];
fsIn.Read(buf, 0, buf.Length);
buf = DecryptData(buf, privateKey);

var key = new byte[symmetricCypher.KeySize / 8];


var iv = new byte[symmetricCypher.BlockSize / 8];
Array.Copy(buf, key, key.Length);
Array.Copy(buf, key.Length, iv, 0, iv.Length);

// Decript the file data using the symmetric algorithm


using (var cypherKey = symmetricCypher.CreateDecryptor(key, iv))
using (var fsOut = new FileStream(outputFilePath, FileMode.Create))
using (var cs = new CryptoStream(fsOut, cypherKey, CryptoStreamMode.Write))
{
fsIn.CopyTo(cs);
}
}
}

#endregion

#region Key Storage

public static void WritePublicKey(string publicKeyFilePath, string publicKey)


{
File.WriteAllText(publicKeyFilePath, publicKey);
}
public static string ReadPublicKey(string publicKeyFilePath)
{
return File.ReadAllText(publicKeyFilePath);
}

private const string SymmetricSalt = "Stack_Overflow!"; // Change me!

public static string ReadPrivateKey(string privateKeyFilePath, string password)


{
var salt = Encoding.UTF8.GetBytes(SymmetricSalt);
var cypherText = File.ReadAllBytes(privateKeyFilePath);

using (var cypher = new AesManaged())


{
var pdb = new Rfc2898DeriveBytes(password, salt);
var key = pdb.GetBytes(cypher.KeySize / 8);
var iv = pdb.GetBytes(cypher.BlockSize / 8);

using (var decryptor = cypher.CreateDecryptor(key, iv))


using (var msDecrypt = new MemoryStream(cypherText))
using (var csDecrypt = new CryptoStream(msDecrypt, decryptor,
CryptoStreamMode.Read))
using (var srDecrypt = new StreamReader(csDecrypt))
{
return srDecrypt.ReadToEnd();
}
}
}

https://riptutorial.com/ 263
public static void WritePrivateKey(string privateKeyFilePath, string privateKey, string
password)
{
var salt = Encoding.UTF8.GetBytes(SymmetricSalt);
using (var cypher = new AesManaged())
{
var pdb = new Rfc2898DeriveBytes(password, salt);
var key = pdb.GetBytes(cypher.KeySize / 8);
var iv = pdb.GetBytes(cypher.BlockSize / 8);

using (var encryptor = cypher.CreateEncryptor(key, iv))


using (var fsEncrypt = new FileStream(privateKeyFilePath, FileMode.Create))
using (var csEncrypt = new CryptoStream(fsEncrypt, encryptor,
CryptoStreamMode.Write))
using (var swEncrypt = new StreamWriter(csEncrypt))
{
swEncrypt.Write(privateKey);
}
}
}

#endregion
}

Example of use:

private static void HybridCryptoTest(string privateKeyPath, string privateKeyPassword, string


inputPath)
{
// Setup the test
var publicKeyPath = Path.ChangeExtension(privateKeyPath, ".public");
var outputPath = Path.Combine(Path.ChangeExtension(inputPath, ".enc"));
var testPath = Path.Combine(Path.ChangeExtension(inputPath, ".test"));

if (!File.Exists(privateKeyPath))
{
var keys = AsymmetricProvider.GenerateNewKeyPair(2048);
AsymmetricProvider.WritePublicKey(publicKeyPath, keys.PublicKey);
AsymmetricProvider.WritePrivateKey(privateKeyPath, keys.PrivateKey,
privateKeyPassword);
}

// Encrypt the file


var publicKey = AsymmetricProvider.ReadPublicKey(publicKeyPath);
AsymmetricProvider.EncryptFile(inputPath, outputPath, publicKey);

// Decrypt it again to compare against the source file


var privateKey = AsymmetricProvider.ReadPrivateKey(privateKeyPath, privateKeyPassword);
AsymmetricProvider.DecryptFile(outputPath, testPath, privateKey);

// Check that the two files match


var source = File.ReadAllBytes(inputPath);
var dest = File.ReadAllBytes(testPath);

if (source.Length != dest.Length)
throw new Exception("Length does not match");

if (source.Where((t, i) => t != dest[i]).Any())


throw new Exception("Data mismatch");
}

https://riptutorial.com/ 264
Read Cryptography (System.Security.Cryptography) online:
https://riptutorial.com/csharp/topic/2988/cryptography--system-security-cryptography-

https://riptutorial.com/ 265
Chapter 44: Data Annotation
Examples
DisplayNameAttribute (display attribute)

DisplayName sets display name for a property, event or public void method having zero (0)
arguments.

public class Employee


{
[DisplayName(@"Employee first name")]
public string FirstName { get; set; }
}

Simple usage example in XAML application

<Window x:Class="WpfApplication.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wpfApplication="clr-namespace:WpfApplication"
Height="100" Width="360" Title="Display name example">

<Window.Resources>
<wpfApplication:DisplayNameConverter x:Key="DisplayNameConverter"/>
</Window.Resources>

<StackPanel Margin="5">
<!-- Label (DisplayName attribute) -->
<Label Content="{Binding Employee, Converter={StaticResource DisplayNameConverter},
ConverterParameter=FirstName}" />
<!-- TextBox (FirstName property value) -->
<TextBox Text="{Binding Employee.FirstName, Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}" />
</StackPanel>

</Window>

namespace WpfApplication
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private Employee _employee = new Employee();

public MainWindow()
{
InitializeComponent();
DataContext = this;
}

https://riptutorial.com/ 266
public Employee Employee
{
get { return _employee; }
set { _employee = value; }
}
}
}

namespace WpfApplication
{
public class DisplayNameConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo
culture)
{
// Get display name for given instance type and property name
var attribute = value.GetType()
.GetProperty(parameter.ToString())
.GetCustomAttributes(false)
.OfType<DisplayNameAttribute>()
.FirstOrDefault();

return attribute != null ? attribute.DisplayName : string.Empty;


}

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo


culture)
{
throw new NotImplementedException();
}
}
}

EditableAttribute (data modeling attribute)

EditableAttribute sets whether users should be able to change the value of the class property.

public class Employee


{
[Editable(false)]
public string FirstName { get; set; }
}

Simple usage example in XAML application

<Window x:Class="WpfApplication.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

https://riptutorial.com/ 267
xmlns:wpfApplication="clr-namespace:WpfApplication"
Height="70" Width="360" Title="Display name example">

<Window.Resources>
<wpfApplication:EditableConverter x:Key="EditableConverter"/>
</Window.Resources>

<StackPanel Margin="5">
<!-- TextBox Text (FirstName property value) -->
<!-- TextBox IsEnabled (Editable attribute) -->
<TextBox Text="{Binding Employee.FirstName, Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}"
IsEnabled="{Binding Employee, Converter={StaticResource EditableConverter},
ConverterParameter=FirstName}"/>
</StackPanel>

</Window>

namespace WpfApplication
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private Employee _employee = new Employee() { FirstName = "This is not editable"};

public MainWindow()
{
InitializeComponent();
DataContext = this;
}

public Employee Employee


{
get { return _employee; }
set { _employee = value; }
}
}
}

namespace WpfApplication
{
public class EditableConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo
culture)
{
// return editable attribute's value for given instance property,
// defaults to true if not found
var attribute = value.GetType()
.GetProperty(parameter.ToString())
.GetCustomAttributes(false)
.OfType<EditableAttribute>()
.FirstOrDefault();

return attribute != null ? attribute.AllowEdit : true;


}

https://riptutorial.com/ 268
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo
culture)
{
throw new NotImplementedException();
}
}
}

Validation Attributes

Validation attributes are used to enforce various validation rules in a declarative fashion on
classes or class members. All validation attributes derive from the ValidationAttribute base class.

Example: RequiredAttribute
When validated through the ValidationAttribute.Validate method, this attribute will return an error
if the Name property is null or contains only whitespace.

public class ContactModel


{
[Required(ErrorMessage = "Please provide a name.")]
public string Name { get; set; }
}

Example: StringLengthAttribute
The StringLengthAttribute validates if a string is less than the maximum length of a string. It can
optionally specify a minimum length. Both values are inclusive.

public class ContactModel


{
[StringLength(20, MinimumLength = 5, ErrorMessage = "A name must be between five and
twenty characters.")]
public string Name { get; set; }
}

Example: RangeAttribute
The RangeAttribute gives the maximum and minimum value for a numeric field.

public class Model

https://riptutorial.com/ 269
{
[Range(0.01, 100.00,ErrorMessage = "Price must be between 0.01 and 100.00")]
public decimal Price { get; set; }
}

Example: CustomValidationAttribute
The CustomValidationAttribute class allows a custom static method to be invoked for validation.
The custom method must be static ValidationResult [MethodName] (object input).

public class Model


{
[CustomValidation(typeof(MyCustomValidation), "IsNotAnApple")]
public string FavoriteFruit { get; set; }
}

Method declaration:

public static class MyCustomValidation


{
public static ValidationResult IsNotAnApple(object input)
{
var result = ValidationResult.Success;

if (input?.ToString()?.ToUpperInvariant() == "APPLE")
{
result = new ValidationResult("Apples are not allowed.");
}

return result;
}
}

Creating a custom validation attribute

Custom validation attributes can be created by deriving from the ValidationAttribute base class,
then overriding virtual methods as needed.

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)]


public class NotABananaAttribute : ValidationAttribute
{
public override bool IsValid(object value)
{
var inputValue = value as string;
var isValid = true;

if (!string.IsNullOrEmpty(inputValue))
{
isValid = inputValue.ToUpperInvariant() != "BANANA";
}

return isValid;
}

https://riptutorial.com/ 270
}

This attribute can then be used like this:

public class Model


{
[NotABanana(ErrorMessage = "Bananas are not allowed.")]
public string FavoriteFruit { get; set; }
}

Data Annotation Basics

Data annotations are a way of adding more contextual information to classes or members of a
class. There are three main categories of annotations:

• Validation Attributes: add validation criteria to data


• Display Attributes: specify how the data should be displayed to the user
• Modelling Attributes: add information on usage and relationship with other classes

Usage
Here is an example where two ValidationAttribute and one DisplayAttribute are used:

class Kid
{
[Range(0, 18)] // The age cannot be over 18 and cannot be negative
public int Age { get; set; }
[StringLength(MaximumLength = 50, MinimumLength = 3)] // The name cannot be under 3 chars
or more than 50 chars
public string Name { get; set; }
[DataType(DataType.Date)] // The birthday will be displayed as a date only (without the
time)
public DateTime Birthday { get; set; }
}

Data annotations are mostly used in frameworks such as ASP.NET. For example, in ASP.NET MVC,
when a model is received by a controller method, ModelState.IsValid() can be used to tell if the
received model respects all its ValidationAttribute. DisplayAttribute is also used in ASP.NET MVC to
determine how to display values on a web page.

Manually Execute Validation Attributes

Most of the times, validation attributes are use inside frameworks (such as ASP.NET). Those
frameworks take care of executing the validation attributes. But what if you want to execute
validation attributes manually? Just use the Validator class (no reflection needed).

Validation Context
Any validation needs a context to give some information about what is being validated. This can

https://riptutorial.com/ 271
include various information such as the object to be validated, some properties, the name to
display in the error message, etc.

ValidationContext vc = new ValidationContext(objectToValidate); // The simplest form of


validation context. It contains only a reference to the object being validated.

Once the context is created, there are multiple ways of doing validation.

Validate an Object and All of its Properties

ICollection<ValidationResult> results = new List<ValidationResult>(); // Will contain the


results of the validation
bool isValid = Validator.TryValidateObject(objectToValidate, vc, results, true); // Validates
the object and its properties using the previously created context.
// The variable isValid will be true if everything is valid
// The results variable contains the results of the validation

Validate a Property of an Object

ICollection<ValidationResult> results = new List<ValidationResult>(); // Will contain the


results of the validation
bool isValid = Validator.TryValidatePropery(objectToValidate.PropertyToValidate, vc, results,
true); // Validates the property using the previously created context.
// The variable isValid will be true if everything is valid
// The results variable contains the results of the validation

And More
To learn more about manual validation see:

• ValidationContext Class Documentation


• Validator Class Documentation

Read Data Annotation online: https://riptutorial.com/csharp/topic/4942/data-annotation

https://riptutorial.com/ 272
Chapter 45: DateTime Methods
Examples
DateTime.Add(TimeSpan)

// Calculate what day of the week is 36 days from this instant.


System.DateTime today = System.DateTime.Now;
System.TimeSpan duration = new System.TimeSpan(36, 0, 0, 0);
System.DateTime answer = today.Add(duration);
System.Console.WriteLine("{0:dddd}", answer);

DateTime.AddDays(Double)

Add days into a dateTime object.

DateTime today = DateTime.Now;


DateTime answer = today.AddDays(36);
Console.WriteLine("Today: {0:dddd}", today);
Console.WriteLine("36 days from today: {0:dddd}", answer);

You also can subtract days passing a negative value:

DateTime today = DateTime.Now;


DateTime answer = today.AddDays(-3);
Console.WriteLine("Today: {0:dddd}", today);
Console.WriteLine("-3 days from today: {0:dddd}", answer);

DateTime.AddHours(Double)

double[] hours = {.08333, .16667, .25, .33333, .5, .66667, 1, 2,


29, 30, 31, 90, 365};
DateTime dateValue = new DateTime(2009, 3, 1, 12, 0, 0);

foreach (double hour in hours)


Console.WriteLine("{0} + {1} hour(s) = {2}", dateValue, hour,
dateValue.AddHours(hour));

DateTime.AddMilliseconds(Double)

string dateFormat = "MM/dd/yyyy hh:mm:ss.fffffff";


DateTime date1 = new DateTime(2010, 9, 8, 16, 0, 0);
Console.WriteLine("Original date: {0} ({1:N0} ticks)\n",
date1.ToString(dateFormat), date1.Ticks);

DateTime date2 = date1.AddMilliseconds(1);


Console.WriteLine("Second date: {0} ({1:N0} ticks)",
date2.ToString(dateFormat), date2.Ticks);
Console.WriteLine("Difference between dates: {0} ({1:N0} ticks)\n",

https://riptutorial.com/ 273
date2 - date1, date2.Ticks - date1.Ticks);

DateTime date3 = date1.AddMilliseconds(1.5);


Console.WriteLine("Third date: {0} ({1:N0} ticks)",
date3.ToString(dateFormat), date3.Ticks);
Console.WriteLine("Difference between dates: {0} ({1:N0} ticks)",
date3 - date1, date3.Ticks - date1.Ticks);

DateTime.Compare(DateTime t1, DateTime t2 )

DateTime date1 = new DateTime(2009, 8, 1, 0, 0, 0);


DateTime date2 = new DateTime(2009, 8, 1, 12, 0, 0);
int result = DateTime.Compare(date1, date2);
string relationship;

if (result < 0)
relationship = "is earlier than";
else if (result == 0)
relationship = "is the same time as";
else relationship = "is later than";

Console.WriteLine("{0} {1} {2}", date1, relationship, date2);

DateTime.DaysInMonth(Int32,Int32)

const int July = 7;


const int Feb = 2;

int daysInJuly = System.DateTime.DaysInMonth(2001, July);


Console.WriteLine(daysInJuly);

// daysInFeb gets 28 because the year 1998 was not a leap year.
int daysInFeb = System.DateTime.DaysInMonth(1998, Feb);
Console.WriteLine(daysInFeb);

// daysInFebLeap gets 29 because the year 1996 was a leap year.


int daysInFebLeap = System.DateTime.DaysInMonth(1996, Feb);
Console.WriteLine(daysInFebLeap);

DateTime.AddYears(Int32)

Add years on the dateTime object:

DateTime baseDate = new DateTime(2000, 2, 29);


Console.WriteLine("Base Date: {0:d}\n", baseDate);

// Show dates of previous fifteen years.


for (int ctr = -1; ctr >= -15; ctr--)
Console.WriteLine("{0,2} year(s) ago:{1:d}",
Math.Abs(ctr), baseDate.AddYears(ctr));

Console.WriteLine();

// Show dates of next fifteen years.


for (int ctr = 1; ctr <= 15; ctr++)

https://riptutorial.com/ 274
Console.WriteLine("{0,2} year(s) from now: {1:d}",
ctr, baseDate.AddYears(ctr));

Pure functions warning when dealing with DateTime

Wikipedia currently defines a pure function as follows:

1. The function always evaluates the same result value given the same argument value(s). The
function result value cannot depend on any hidden information or state that may change
while program execution proceeds or between different executions of the program, nor can it
depend on any external input from I/O devices .
2. Evaluation of the result does not cause any semantically observable side effect or output,
such as mutation of mutable objects or output to I/O devices

As a developer you need to be aware of pure methods and you will stumble upon these a lot in
many areas. One I have seen that bites many junior developers is working with DateTime class
methods. A lot of these are pure and if you are unaware of these you can be in for a suprise. An
example:

DateTime sample = new DateTime(2016, 12, 25);


sample.AddDays(1);
Console.WriteLine(sample.ToShortDateString());

Given the example above one may expect the result printed to console to be '26/12/2016' but in
reality you end up with the same date. This is because AddDays is a pure method and does not
affect the original date. To get the expected output you would have to modify the AddDays call to
the following:

sample = sample.AddDays(1);

DateTime.Parse(String)

// Converts the string representation of a date and time to its DateTime equivalent

var dateTime = DateTime.Parse("14:23 22 Jul 2016");

Console.WriteLine(dateTime.ToString());

DateTime.TryParse(String, DateTime)

// Converts the specified string representation of a date and time to its DateTime equivalent
and returns a value that indicates whether the conversion succeeded

string[] dateTimeStrings = new []{


"14:23 22 Jul 2016",
"99:23 2x Jul 2016",
"22/7/2016 14:23:00"
};

foreach(var dateTimeString in dateTimeStrings){

https://riptutorial.com/ 275
DateTime dateTime;

bool wasParsed = DateTime.TryParse(dateTimeString, out dateTime);

string result = dateTimeString +


(wasParsed
? $"was parsed to {dateTime}"
: "can't be parsed to DateTime");

Console.WriteLine(result);
}

Parse and TryParse with culture info

You might want to use it when parsing DateTimes from different cultures (languages), following
example parses Dutch date.

DateTime dateResult;
var dutchDateString = "31 oktober 1999 04:20";
var dutchCulture = CultureInfo.CreateSpecificCulture("nl-NL");
DateTime.TryParse(dutchDateString, dutchCulture, styles, out dateResult);
// output {31/10/1999 04:20:00}

Example of Parse:

DateTime.Parse(dutchDateString, dutchCulture)
// output {31/10/1999 04:20:00}

DateTime as initializer in for-loop

// This iterates through a range between two DateTimes


// with the given iterator (any of the Add methods)

DateTime start = new DateTime(2016, 01, 01);


DateTime until = new DateTime(2016, 02, 01);

// NOTICE: As the add methods return a new DateTime you have


// to overwrite dt in the iterator like dt = dt.Add()
for (DateTime dt = start; dt < until; dt = dt.AddDays(1))
{
Console.WriteLine("Added {0} days. Resulting DateTime: {1}",
(dt - start).Days, dt.ToString());
}

Iterating on a TimeSpan works the same way.

DateTime ToString, ToShortDateString, ToLongDateString and ToString


formatted

using System;

public class Program

https://riptutorial.com/ 276
{
public static void Main()
{
var date = new DateTime(2016,12,31);

Console.WriteLine(date.ToString()); //Outputs: 12/31/2016 12:00:00 AM


Console.WriteLine(date.ToShortDateString()); //Outputs: 12/31/2016
Console.WriteLine(date.ToLongDateString()); //Outputs: Saturday, December 31, 2016
Console.WriteLine(date.ToString("dd/MM/yyyy")); //Outputs: 31/12/2016
}
}

Current Date

To get the current date you use the DateTime.Today property. This returns a DateTime object with
today's date. When this is then converted .ToString() it is done so in your system's locality by
default.

For example:

Console.WriteLine(DateTime.Today);

Writes today's date, in your local format to the console.

DateTime Formating

Standard DateTime Formatting

DateTimeFormatInfo specifies a set of specifiers for simple date and time formating. Every
specifier correspond to a particular DateTimeFormatInfo format pattern.

//Create datetime
DateTime dt = new DateTime(2016,08,01,18,50,23,230);

var t = String.Format("{0:t}", dt); // "6:50 PM" ShortTime


var d = String.Format("{0:d}", dt); // "8/1/2016" ShortDate
var T = String.Format("{0:T}", dt); // "6:50:23 PM" LongTime
var D = String.Format("{0:D}", dt); // "Monday, August 1, 2016" LongDate
var f = String.Format("{0:f}", dt); // "Monday, August 1, 2016 6:50 PM"
LongDate+ShortTime
var F = String.Format("{0:F}", dt); // "Monday, August 1, 2016 6:50:23 PM" FullDateTime
var g = String.Format("{0:g}", dt); // "8/1/2016 6:50 PM"
ShortDate+ShortTime
var G = String.Format("{0:G}", dt); // "8/1/2016 6:50:23 PM"
ShortDate+LongTime
var m = String.Format("{0:m}", dt); // "August 1" MonthDay
var y = String.Format("{0:y}", dt); // "August 2016" YearMonth
var r = String.Format("{0:r}", dt); // "SMon, 01 Aug 2016 18:50:23 GMT" RFC1123
var s = String.Format("{0:s}", dt); // "2016-08-01T18:50:23" SortableDateTime
var u = String.Format("{0:u}", dt); // "2016-08-01 18:50:23Z"
UniversalSortableDateTime

Custom DateTime Formatting

https://riptutorial.com/ 277
There are following custom format specifiers:

• y (year)
• M (month)
• d (day)
• h (hour 12)
• H (hour 24)
• m (minute)
• s (second)
• f (second fraction)
• F (second fraction, trailing zeroes are trimmed)
• t (P.M or A.M)
• z (time zone).

var year = String.Format("{0:y yy yyy yyyy}", dt); // "16 16 2016 2016" year
var month = String.Format("{0:M MM MMM MMMM}", dt); // "8 08 Aug August" month
var day = String.Format("{0:d dd ddd dddd}", dt); // "1 01 Mon Monday" day
var hour = String.Format("{0:h hh H HH}", dt); // "6 06 18 18" hour 12/24
var minute = String.Format("{0:m mm}", dt); // "50 50" minute
var secound = String.Format("{0:s ss}", dt); // "23 23" second
var fraction = String.Format("{0:f ff fff ffff}", dt); // "2 23 230 2300" sec.fraction
var fraction2 = String.Format("{0:F FF FFF FFFF}", dt); // "2 23 23 23" without zeroes
var period = String.Format("{0:t tt}", dt); // "P PM" A.M. or P.M.
var zone = String.Format("{0:z zz zzz}", dt); // "+0 +00 +00:00" time zone

You can use also date separator / (slash) and time sepatator : (colon).

For code example

For more information MSDN.

DateTime.ParseExact(String,String,IFormatProvider)

Converts the specified string representation of a date and time to its DateTime equivalent using
the specified format and culture-specific format information. The format of the string representation
must match the specified format exactly.

Convert a specific format string to equivalent DateTime

Let's say we have a culture-specific DateTime string 08-07-2016 11:30:12 PM as MM-dd-yyyy hh:mm:ss
tt format and we want it to convert to equivalent DateTime object

string str = "08-07-2016 11:30:12 PM";


DateTime date = DateTime.ParseExact(str, "MM-dd-yyyy hh:mm:ss tt",
CultureInfo.CurrentCulture);

Convert a date time string to equivalent DateTime object without any specific culture format

Let's say we have a DateTime string in dd-MM-yy hh:mm:ss tt format and we want it to convert to
equivalent DateTime object, without any specific culture information

https://riptutorial.com/ 278
string str = "17-06-16 11:30:12 PM";
DateTime date = DateTime.ParseExact(str, "dd-MM-yy hh:mm:ss tt",
CultureInfo.InvariantCulture);

Convert a date time string to equivalent DateTime object without any specific culture
format with different format

Let's say we have a Date string , example like '23-12-2016' or '12/23/2016' and we want it to
convert to equivalent DateTime object, without any specific culture information

string date = '23-12-2016' or date = 12/23/2016';


string[] formats = new string[] {"dd-MM-yyyy","MM/dd/yyyy"}; // even can add more possible
formats.
DateTime date = DateTime.ParseExact(date,formats,
CultureInfo.InvariantCulture,DateTimeStyles.None);

NOTE : System.Globalization needs to be added for CultureInfo Class

DateTime.TryParseExact(String,String,IFormatProvider,DateTimeStyles,DateTime)

Converts the specified string representation of a date and time to its DateTime equivalent using
the specified format, culture-specific format information, and style. The format of the string
representation must match the specified format exactly. The method returns a value that indicates
whether the conversion succeeded.

For Example

CultureInfo enUS = new CultureInfo("en-US");


string dateString;
System.DateTime dateValue;

Parse date with no style flags.

dateString = " 5/01/2009 8:30 AM";


if (DateTime.TryParseExact(dateString, "g", enUS, DateTimeStyles.None, out dateValue))
{
Console.WriteLine("Converted '{0}' to {1} ({2}).", dateString, dateValue, dateValue.Kind);
}
else
{
Console.WriteLine("'{0}' is not in an acceptable format.", dateString);
}

// Allow a leading space in the date string.


if(DateTime.TryParseExact(dateString, "g", enUS, DateTimeStyles.AllowLeadingWhite, out
dateValue))
{
Console.WriteLine("Converted '{0}' to {1} ({2}).", dateString, dateValue, dateValue.Kind);
else
{
Console.WriteLine("'{0}' is not in an acceptable format.", dateString);
}

https://riptutorial.com/ 279
Use custom formats with M and MM.

dateString = "5/01/2009 09:00";


if(DateTime.TryParseExact(dateString, "M/dd/yyyy hh:mm", enUS, DateTimeStyles.None, out
dateValue))
{
Console.WriteLine("Converted '{0}' to {1} ({2}).", dateString, dateValue, dateValue.Kind);
}
else
{
Console.WriteLine("'{0}' is not in an acceptable format.", dateString);
}

// Allow a leading space in the date string.


if(DateTime.TryParseExact(dateString, "MM/dd/yyyy hh:mm", enUS, DateTimeStyles.None, out
dateValue))
{
Console.WriteLine("Converted '{0}' to {1} ({2}).", dateString, dateValue, dateValue.Kind);
}
else
{
Console.WriteLine("'{0}' is not in an acceptable format.", dateString);
}

Parse a string with time zone information.

dateString = "05/01/2009 01:30:42 PM -05:00";


if (DateTime.TryParseExact(dateString, "MM/dd/yyyy hh:mm:ss tt zzz", enUS,
DateTimeStyles.None, out dateValue))
{
Console.WriteLine("Converted '{0}' to {1} ({2}).", dateString, dateValue, dateValue.Kind);
}
else
{
Console.WriteLine("'{0}' is not in an acceptable format.", dateString);
}

// Allow a leading space in the date string.


if (DateTime.TryParseExact(dateString, "MM/dd/yyyy hh:mm:ss tt zzz", enUS,
DateTimeStyles.AdjustToUniversal, out dateValue))
{
Console.WriteLine("Converted '{0}' to {1} ({2}).", dateString, dateValue, dateValue.Kind);
}
else
{
Console.WriteLine("'{0}' is not in an acceptable format.", dateString);
}

Parse a string represengting UTC.

dateString = "2008-06-11T16:11:20.0904778Z";
if(DateTime.TryParseExact(dateString, "o", CultureInfo.InvariantCulture, DateTimeStyles.None,
out dateValue))
{
Console.WriteLine("Converted '{0}' to {1} ({2}).", dateString, dateValue, dateValue.Kind);
}
else

https://riptutorial.com/ 280
{
Console.WriteLine("'{0}' is not in an acceptable format.", dateString);
}

if (DateTime.TryParseExact(dateString, "o", CultureInfo.InvariantCulture,


DateTimeStyles.RoundtripKind, out dateValue))
{
Console.WriteLine("Converted '{0}' to {1} ({2}).", dateString, dateValue, dateValue.Kind);
}
else
{
Console.WriteLine("'{0}' is not in an acceptable format.", dateString);
}

Outputs

' 5/01/2009 8:30 AM' is not in an acceptable format.


Converted ' 5/01/2009 8:30 AM' to 5/1/2009 8:30:00 AM (Unspecified).
Converted '5/01/2009 09:00' to 5/1/2009 9:00:00 AM (Unspecified).
'5/01/2009 09:00' is not in an acceptable format.
Converted '05/01/2009 01:30:42 PM -05:00' to 5/1/2009 11:30:42 AM (Local).
Converted '05/01/2009 01:30:42 PM -05:00' to 5/1/2009 6:30:42 PM (Utc).
Converted '2008-06-11T16:11:20.0904778Z' to 6/11/2008 9:11:20 AM (Local).
Converted '2008-06-11T16:11:20.0904778Z' to 6/11/2008 4:11:20 PM (Utc).

Read DateTime Methods online: https://riptutorial.com/csharp/topic/1587/datetime-methods

https://riptutorial.com/ 281
Chapter 46: Delegates
Remarks

Summary
A delegate type is a type representing a particular method signature. An instance of this type
refers to a particular method with a matching signature. Method parameters may have delegate
types, and so this one method to be passed a reference to another method, which may then be
invoked

In-built delegate types: Action<...> , Predicate<T> and


Func<...,TResult>

The System namespace contains Action<...>,Predicate<T> and Func<...,TResult> delegates, where


the "..." represents between 0 and 16 generic type parameters (for 0 parameters, Action is non-
generic).

Func represents methods with a return type matching TResult, and Action represents methods
without a return value (void). In both cases, the additional generic type parameters match, in
order, the method parameters.

Predicate represents method with boolean return type, T is input parameter.

Custom delegate types


Named delegate types can be declared using the delegate keyword.

Invoking delegates
Delegates can be invoked using the same syntax as methods: the name of the delegate instance,
followed by parentheses containing any parameters.

Assigning to delegates
Delegates can be assigned to in the following ways:

• Assigning a named method


• Assigning an anonymous method using a lambda
• Assigning a named method using the delegate keyword.

https://riptutorial.com/ 282
Combining delegates
Multiple delegate objects can be assigned to one delegate instance by using the + operator. The -
operator can be used to remove a component delegate from another delegate.

Examples
Underlying references of named method delegates

When assigning named methods to delegates, they will refer to the same underlying object if:

• They are the same instance method, on the same instance of a class

• They are the same static method on a class

public class Greeter


{
public void WriteInstance()
{
Console.WriteLine("Instance");
}

public static void WriteStatic()


{
Console.WriteLine("Static");
}
}

// ...

Greeter greeter1 = new Greeter();


Greeter greeter2 = new Greeter();

Action instance1 = greeter1.WriteInstance;


Action instance2 = greeter2.WriteInstance;
Action instance1Again = greeter1.WriteInstance;

Console.WriteLine(instance1.Equals(instance2)); // False
Console.WriteLine(instance1.Equals(instance1Again)); // True

Action @static = Greeter.WriteStatic;


Action staticAgain = Greeter.WriteStatic;

Console.WriteLine(@static.Equals(staticAgain)); // True

Declaring a delegate type

The following syntax creates a delegate type with name NumberInOutDelegate, representing a
method which takes an int and returns an int.

public delegate int NumberInOutDelegate(int input);

https://riptutorial.com/ 283
This can be used as follows:

public static class Program


{
static void Main()
{
NumberInOutDelegate square = MathDelegates.Square;
int answer1 = square(4);
Console.WriteLine(answer1); // Will output 16

NumberInOutDelegate cube = MathDelegates.Cube;


int answer2 = cube(4);
Console.WriteLine(answer2); // Will output 64
}
}

public static class MathDelegates


{
static int Square (int x)
{
return x*x;
}

static int Cube (int x)


{
return x*x*x;
}
}

The example delegate instance is executed in the same way as the Square method. A delegate
instance literally acts as a delegate for the caller: the caller invokes the delegate, and then the
delegate calls the target method. This indirection decouples the caller from the target method.

You can declare a generic delegate type, and in that case you may specify that the type is
covariant (out) or contravariant (in) in some of the type arguments. For example:

public delegate TTo Converter<in TFrom, out TTo>(TFrom input);

Like other generic types, generic delegate types can have constraints, such as where TFrom :
struct, IConvertible where TTo : new().

Avoid co- and contravariance for delegate types that are meant to be used for multicast delegates,
such as event handler types. This is because concatenation (+) can fail if the run-time type is
different from the compile-time type because of the variance. For example, avoid:

public delegate void EventHandler<in TEventArgs>(object sender, TEventArgs e);

Instead, use an invariant generic type:

public delegate void EventHandler<TEventArgs>(object sender, TEventArgs e);

https://riptutorial.com/ 284
Also supported are delegates where some parameters are modified by ref or out, as in:

public delegate bool TryParser<T>(string input, out T result);

(sample use TryParser<decimal> example = decimal.TryParse;), or delegates where the last


parameter has the params modifier. Delegate types can have optional parameters (supply default
values). Delegate types can use pointer types like int* or char* in their signatures or return types
(use unsafe keyword). A delegate type and its parameters can carry custom attributes.

The Func, Action and Predicate delegate types

The System namespace contains Func<..., TResult> delegate types with between 0 and 15
generic parameters, returning type TResult.

private void UseFunc(Func<string> func)


{
string output = func(); // Func with a single generic type parameter returns that type
Console.WriteLine(output);
}

private void UseFunc(Func<int, int, string> func)


{
string output = func(4, 2); // Func with multiple generic type parameters takes all but
the first as parameters of that type
Console.WriteLine(output);
}

The System namespace also contains Action<...> delegate types with different number of generic
parameters (from 0 to 16). It is similar to Func<T1, .., Tn>, but it always returns void.

private void UseAction(Action action)


{
action(); // The non-generic Action has no parameters
}

private void UseAction(Action<int, string> action)


{
action(4, "two"); // The generic action is invoked with parameters matching its type
arguments
}

Predicate<T> is also a form of Func but it will always return bool. A predicate is a way of specifying a
custom criteria. Depending on the value of the input and the logic defined within the predicate, it
will return either true or false. Predicate<T> therefore behaves in the same way as Func<T, bool>
and both can be initialized and used in the same way.

Predicate<string> predicate = s => s.StartsWith("a");


Func<string, bool> func = s => s.StartsWith("a");

// Both of these return true


var predicateReturnsTrue = predicate("abc");
var funcReturnsTrue = func("abc");

https://riptutorial.com/ 285
// Both of these return false
var predicateReturnsFalse = predicate("xyz");
var funcReturnsFalse = func("xyz");

The choice of whether to use Predicate<T> or Func<T, bool> is really a matter of opinion.
Predicate<T> is arguably more expressive of the author's intent, while Func<T, bool> is likely to be
familiar to a greater proportion of C# developers.

In addition to that, there are some cases where only one of the options is available, especially
when interacting with another API. For example List<T> and Array<T> generally take Predicate<T>
for their methods, while most LINQ extensions only accept Func<T, bool>.

Assigning a named method to a delegate

Named methods can be assigned to delegates with matching signatures:

public static class Example


{
public static int AddOne(int input)
{
return input + 1;
}
}

Func<int,int> addOne = Example.AddOne

Example.AddOne takes an int and returns an int, its signature matches the delegate Func<int,int>.
Example.AddOne can be directly assigned to addOne because they have matching signatures.

Delegate Equality

Calling .Equals() on a delegate compares by reference equality:

Action action1 = () => Console.WriteLine("Hello delegates");


Action action2 = () => Console.WriteLine("Hello delegates");
Action action1Again = action1;

Console.WriteLine(action1.Equals(action1)) // True
Console.WriteLine(action1.Equals(action2)) // False
Console.WriteLine(action1Again.Equals(action1)) // True

These rules also apply when doing += or -= on a multicast delegate, for example when subscribing
and unsubscribing from events.

Assigning to a delegate by lambda

Lambdas can be used to create anonymous methods to assign to a delegate:

Func<int,int> addOne = x => x+1;

https://riptutorial.com/ 286
Note that the explicit declaration of type is required when creating a variable this way:

var addOne = x => x+1; // Does not work

Passing delegates as parameters

Delegates can be used as typed function pointers:

class FuncAsParameters
{
public void Run()
{
DoSomething(ErrorHandler1);
DoSomething(ErrorHandler2);
}

public bool ErrorHandler1(string message)


{
Console.WriteLine(message);
var shouldWeContinue = ...
return shouldWeContinue;
}

public bool ErrorHandler2(string message)


{
// ...Write message to file...
var shouldWeContinue = ...
return shouldWeContinue;
}

public void DoSomething(Func<string, bool> errorHandler)


{
// In here, we don't care what handler we got passed!
...
if (...error...)
{
if (!errorHandler("Some error occurred!"))
{
// The handler decided we can't continue
return;
}
}
}
}

Combine Delegates (Multicast Delegates)

Addition + and subtraction - operations can be used to combine delegate instances. The delegate
contains a list of the assigned delegates.

using System;
using System.Reflection;
using System.Reflection.Emit;

namespace DelegatesExample {
class MainClass {

https://riptutorial.com/ 287
private delegate void MyDelegate(int a);

private static void PrintInt(int a) {


Console.WriteLine(a);
}

private static void PrintType<T>(T a) {


Console.WriteLine(a.GetType());
}

public static void Main (string[] args)


{
MyDelegate d1 = PrintInt;
MyDelegate d2 = PrintType;

// Output:
// 1
d1(1);

// Output:
// System.Int32
d2(1);

MyDelegate d3 = d1 + d2;
// Output:
// 1
// System.Int32
d3(1);

MyDelegate d4 = d3 - d2;
// Output:
// 1
d4(1);

// Output:
// True
Console.WriteLine(d1 == d4);
}
}
}

In this example d3 is a combination of d1 and d2 delegates, so when called the program outputs
both 1 and System.Int32 strings.

Combining delegates with non void return types:

If a multicast delegate has a nonvoid return type, the caller receives the return value from the last
method to be invoked. The preceding methods are still called, but their return values are
discarded.

class Program
{
public delegate int Transformer(int x);

static void Main(string[] args)


{
Transformer t = Square;

https://riptutorial.com/ 288
t += Cube;
Console.WriteLine(t(2)); // O/P 8
}

static int Square(int x) { return x * x; }

static int Cube(int x) { return x*x*x; }


}

t(2) will call first Square and then Cube. The return value of Square is discarded and return value of
the last method i.e. Cube is retained.

Safe invoke multicast delegate

Ever wanted to call a multicast delegate but you want the entire invokation list to be called even if
an exception occurs in any in the chain. Then you are in luck, I have created an extension method
that does just that, throwing an AggregateException only after execution of the entire list completes:

public static class DelegateExtensions


{
public static void SafeInvoke(this Delegate del,params object[] args)
{
var exceptions = new List<Exception>();

foreach (var handler in del.GetInvocationList())


{
try
{
handler.Method.Invoke(handler.Target, args);
}
catch (Exception ex)
{
exceptions.Add(ex);
}
}

if(exceptions.Any())
{
throw new AggregateException(exceptions);
}
}
}

public class Test


{
public delegate void SampleDelegate();

public void Run()


{
SampleDelegate delegateInstance = this.Target2;
delegateInstance += this.Target1;

try
{
delegateInstance.SafeInvoke();
}
catch(AggregateException ex)
{

https://riptutorial.com/ 289
// Do any exception handling here
}
}

private void Target1()


{
Console.WriteLine("Target 1 executed");
}

private void Target2()


{
Console.WriteLine("Target 2 executed");
throw new Exception();
}
}

This outputs:

Target 2 executed
Target 1 executed

Invoking directly, without SaveInvoke, would only execute Target 2.

Closure inside a delegate

Closures are inline anonymous methods that have the ability to use Parent method variables and
other anonymous methods which are defined in the parent's scope.

In essence, a closure is a block of code which can be executed at a later time, but
which maintains the environment in which it was first created - i.e. it can still use the
local variables etc of the method which created it, even after that method has finished
executing. -- Jon Skeet

delegate int testDel();


static void Main(string[] args)
{
int foo = 4;
testDel myClosure = delegate()
{
return foo;
};
int bar = myClosure();

Example taken from Closures in .NET.

Encapsulating transformations in funcs

public class MyObject{


public DateTime? TestDate { get; set; }

public Func<MyObject, bool> DateIsValid = myObject => myObject.TestDate.HasValue &&

https://riptutorial.com/ 290
myObject.TestDate > DateTime.Now;

public void DoSomething(){


//We can do this:
if(this.TestDate.HasValue && this.TestDate > DateTime.Now){
CallAnotherMethod();
}

//or this:
if(DateIsValid(this)){
CallAnotherMethod();
}
}
}

In the spirit of clean coding, encapsulating checks and transformations like the one above as a
Func can make your code easier to read and understand. While the above example is very simple,
what if there were multiple DateTime properties each with their own differing validation rules and
we wanted to check different combinations? Simple, one-line Funcs that each have established
return logic can be both readable and reduce the apparent complexity of your code. Consider the
below Func calls and imagine how much more code would be cluttering up the method:

public void CheckForIntegrity(){


if(ShipDateIsValid(this) && TestResultsHaveBeenIssued(this) && !TestResultsFail(this)){
SendPassingTestNotification();
}
}

Read Delegates online: https://riptutorial.com/csharp/topic/1194/delegates

https://riptutorial.com/ 291
Chapter 47: Dependency Injection
Remarks
Wikipedia definition of dependency injection is:

In software engineering, dependency injection is a software design pattern that implements


inversion of control for resolving dependencies. A dependency is an object that can be used (a
service). An injection is the passing of a dependency to a dependent object (a client) that would
use it.

**This site features an answer to the question How to explain Dependency Injection to a 5-
year old. The most highly rated answer, provided by John Munsch provides a surprisingly
accurate analogy targeted at the (imaginary) five-year-old inquisitor: When you go and get
things out of the refrigerator for yourself, you can cause problems. You might leave the
door open, you might get something Mommy or Daddy doesn’t want you to have. You
might even be looking for something we don’t even have or which has expired. What you
should be doing is stating a need, “I need something to drink with lunch,” and then we will
make sure you have something when you sit down to eat. What this means in terms of
object-oriented software development is this: collaborating classes (the five-year-olds)
should rely on the infrastructure (the parents) to provide

** This code uses MEF to dynamically load the dll and resolve the dependencies. ILogger
dependency is resolved by MEF and injectd into the user class. User class never receives
Concrete implementation of ILogger and it has no idea of what or which type of logger its using.**

Examples
Dependency injection using MEF

public interface ILogger


{
void Log(string message);
}

[Export(typeof(ILogger))]
[ExportMetadata("Name", "Console")]
public class ConsoleLogger:ILogger
{
public void Log(string message)
{
Console.WriteLine(message);
}
}

[Export(typeof(ILogger))]
[ExportMetadata("Name", "File")]
public class FileLogger:ILogger
{

https://riptutorial.com/ 292
public void Log(string message)
{
//Write the message to file
}
}

public class User


{
private readonly ILogger logger;
public User(ILogger logger)
{
this.logger = logger;
}
public void LogUser(string message)
{
logger.Log(message) ;
}
}

public interface ILoggerMetaData


{
string Name { get; }
}

internal class Program


{
private CompositionContainer _container;

[ImportMany]
private IEnumerable<Lazy<ILogger, ILoggerMetaData>> _loggers;

private static void Main()


{
ComposeLoggers();
Lazy<ILogger, ILoggerMetaData> loggerNameAndLoggerMapping = _ loggers.First((n) =>
((n.Metadata.Name.ToUpper() =="Console"));
ILogger logger= loggerNameAndLoggerMapping.Value
var user = new User(logger);
user.LogUser("user name");
}

private void ComposeLoggers()


{
//An aggregate catalog that combines multiple catalogs
var catalog = new AggregateCatalog();
string loggersDllDirectory =Path.Combine(Utilities.GetApplicationDirectory(),
"Loggers");
if (!Directory.Exists(loggersDllDirectory ))
{
Directory.CreateDirectory(loggersDllDirectory );
}
//Adds all the parts found in the same assem