You are on page 1of 618

Tabla de contenido

ASP.NET Core Tutorial.................................................................................................................20


Prerequisites...........................................................................................................................20
ASP.NET Core...................................................................................................................................20
ASP.NET Core Version History......................................................................................................22
.NET Core......................................................................................................................................22
Why ASP.NET Core?.....................................................................................................................23
ASP.NET Core - Development Environment Setup...........................................................................23
Install .NET Core SDK....................................................................................................................24
IDE................................................................................................................................................27
Visual Studio 2017:...................................................................................................................27
Command-line Interface (CLI):.................................................................................................28
First ASP.NET Core Application...................................................................................................28
ASP.NET Core Project Structure.......................................................................................................34
.csproj...........................................................................................................................................36
Dependencies...............................................................................................................................38
Properties.....................................................................................................................................39
ASP.NET Core - wwwroot.................................................................................................................41
ASP.NET Core - Program.cs..............................................................................................................43
Setup Host in ASP.NET Core 1.x....................................................................................................43
Setup Host in ASP.NET Core 2.x....................................................................................................45
ASP.NET Core - Startup Class............................................................................................................47
ConfigureServices()......................................................................................................................48
Configure()...................................................................................................................................49
.NET Core Command-Line Interface.................................................................................................49
Command Structure.....................................................................................................................50
Create a New Project...................................................................................................................52
Add Package Reference................................................................................................................52
Restore Packages.........................................................................................................................52
Build Project.................................................................................................................................52
Run project...................................................................................................................................53
Getting Help.................................................................................................................................53
ASP.NET Core - Dependency Injection..............................................................................................54
Built-in IoC Container...................................................................................................................54
Registering Application Service....................................................................................................55
Understanding Service Lifetime...................................................................................................56
Extension Methods for Registration.............................................................................................56
Constructor Injection...................................................................................................................57
Action Method Injection..............................................................................................................57
Property Injection........................................................................................................................58
Get Services Manually..................................................................................................................58
ASP.NET Core - Middleware.............................................................................................................58
Configure Middleware..................................................................................................................59
Understand Run Method..............................................................................................................60
Configure Multiple Middleware...................................................................................................61
Add Built-in Middleware Via NuGet.............................................................................................62
Diagnostics Middleware...............................................................................................................63
ASP.NET Core - Logging....................................................................................................................64
ILoggerFactory..............................................................................................................................65
ILoggerProvider............................................................................................................................66
ILogger..........................................................................................................................................66
Built-in Logging Providers.............................................................................................................66
Console Logger.............................................................................................................................66
Step 1 - Install NuGet Package..................................................................................................67
Step 2 - Use Provider................................................................................................................68
Step 3 - Create Logs..................................................................................................................69
Log Levels.....................................................................................................................................70
Third-party Logging Providers......................................................................................................71
ASP.NET Core - Environment Variable..............................................................................................71
Access Environment Variable at Runtime.....................................................................................74
ASP.NET Core - Exception Handling..................................................................................................75
Install Microsoft.AspNetCore.Diagnostics Package......................................................................76
UseDeveloperExceptionPage...................................................................................................76
UseExceptionHandler...............................................................................................................77
ASP.NET Core - Serving Static Files...................................................................................................79
Install StaticFiles Middleware.......................................................................................................80
Using StaticFiles Middleware.......................................................................................................81
Set Default File.............................................................................................................................87
FileServer.....................................................................................................................................88
.NET Core Application Types............................................................................................................89
Portable Application.....................................................................................................................89
Self-contained Application...........................................................................................................89
Configure Application Type..........................................................................................................89
Code Sharing in .NET Core...........................................................................................................90
Target Multiple Frameworks in .NET Core 2.x App...........................................................................91
Framework Specific References...................................................................................................98
ASP.NET MVC Tutorials....................................................................................................................99
Prerequisites............................................................................................................................99
MVC Architecture..........................................................................................................................99
ASP.NET MVC Version History.................................................................................................101
Create First ASP.NET MVC Application...........................................................................................102
Setup Development Environment..............................................................................................102
Create first simple MVC application...........................................................................................102
ASP.NET MVC Folder Structure......................................................................................................110
App_Data...............................................................................................................................111
App_Start...............................................................................................................................111
Content..................................................................................................................................112
Controllers..............................................................................................................................112
fonts.......................................................................................................................................113
Models...................................................................................................................................114
Scripts.....................................................................................................................................114
Views......................................................................................................................................114
Global.asax.............................................................................................................................115
Packages.config......................................................................................................................116
Web.config.............................................................................................................................116
Routing in MVC..............................................................................................................................116
Route..........................................................................................................................................116
Configure a Route......................................................................................................................117
URL Pattern............................................................................................................................118
Multiple Routes..........................................................................................................................119
Route Constraints.......................................................................................................................120
Register Routes..........................................................................................................................120
Controller.......................................................................................................................................121
Adding a New Controller............................................................................................................122
Action method...............................................................................................................................126
Default Action Method...............................................................................................................127
ActionResult...............................................................................................................................128
Action Method Parameters........................................................................................................129
Action Selectors.............................................................................................................................130
ActionName...............................................................................................................................130
NonAction..................................................................................................................................131
ActionVerbs..................................................................................................................................132
Model in ASP.NET MVC..................................................................................................................134
Adding a Model..........................................................................................................................134
View in ASP.NET MVC....................................................................................................................135
Razor View Engine......................................................................................................................136
Create New View........................................................................................................................137
Integrate Controller, View and Model............................................................................................142
Razor Syntax...................................................................................................................................145
Inline expression........................................................................................................................146
Multi-statement Code block.......................................................................................................146
Display Text from Code Block.....................................................................................................146
if-else condition..........................................................................................................................147
for loop.......................................................................................................................................147
Model.........................................................................................................................................148
Declare Variables.......................................................................................................................148
HTML Helpers.................................................................................................................................149
HtmlHelper - TextBox.....................................................................................................................150
TextBox()....................................................................................................................................151
TextBox() method signature...................................................................................................151
TextBoxFor.................................................................................................................................152
TextBoxFor() method Signature.............................................................................................152
Difference between TextBox and TextBoxFor............................................................................153
HtmlHelper - TextArea...................................................................................................................153
TextArea()..................................................................................................................................153
TextArea() method Signature.................................................................................................153
TextAreaFor................................................................................................................................155
TextBoxFor() method Signature.............................................................................................155
HtmlHelper - CheckBox..................................................................................................................155
CheckBox().................................................................................................................................156
CheckBox() method Signature................................................................................................156
CheckBoxFor...............................................................................................................................156
CheckBoxFor() method Signature...........................................................................................156
HtmlHelper - RadioButton..............................................................................................................157
RadioButton().............................................................................................................................158
RadioButton() method Signature...........................................................................................158
RadioButtonFor..........................................................................................................................158
RadioButtonFor() method Signature......................................................................................158
HtmlHelper - DropDownList...........................................................................................................159
DropDownList()..........................................................................................................................160
DropDownList() method signature.........................................................................................160
DropDownListFor.......................................................................................................................161
DropDownListFor() method signature....................................................................................161
HtmlHelper - Hidden field..............................................................................................................162
Hidden().....................................................................................................................................162
Hidden() method signature....................................................................................................162
HiddenFor..................................................................................................................................163
HiddenFor() method signature...............................................................................................163
HtmlHelper - Password..................................................................................................................163
Password()..................................................................................................................................164
Password() method signature................................................................................................164
PasswordFor()............................................................................................................................164
PasswordFor() method signature...........................................................................................165
HtmlHelper - Display HTML String..................................................................................................165
Display().....................................................................................................................................166
DisplayFor...................................................................................................................................166
HtmlHelper - Label.........................................................................................................................166
Label()........................................................................................................................................167
LabelFor......................................................................................................................................167
HtmlHelper - Editor........................................................................................................................168
Editor().......................................................................................................................................169
EditorFor....................................................................................................................................169
Model Binding................................................................................................................................170
Binding to Primitive type............................................................................................................171
Binding to Complex type............................................................................................................172
FormCollection.......................................................................................................................173
Bind Attribute.............................................................................................................................174
Inside Model Binding..................................................................................................................175
Create Edit View in ASP.NET MVC..................................................................................................175
Implement Data Validation in MVC................................................................................................185
DataAnnotations........................................................................................................................186
ASP.NET MVC: ValidationMessage.................................................................................................192
ValidationMessage() Signature...................................................................................................192
Custom Error Message...............................................................................................................194
ASP.NET MVC: ValidationMessageFor............................................................................................194
ValidationMessageFor() Signature.............................................................................................194
Custom Error Message...............................................................................................................196
ASP.NET MVC: ValidationSummary................................................................................................196
ValidationSummary() Signature.................................................................................................197
Display Field Level Error Messages using ValidationSummary...................................................197
Display Custom Error Messages.................................................................................................198
Layout View....................................................................................................................................199
Use Layout View.........................................................................................................................203
_ViewStart.cshtml..................................................................................................................203
Setting Layout property in individual view.............................................................................204
Specify Layout Page in ActionResult Method.........................................................................205
Rendering Methods....................................................................................................................206
Create Layout View........................................................................................................................208
Partial View....................................................................................................................................212
Create a New Partial View..........................................................................................................214
Render Partial View....................................................................................................................216
Html.Partial()..........................................................................................................................216
Html.RenderPartial()..............................................................................................................216
Html.RenderAction()..............................................................................................................217
ASP.NET MVC - ViewBag...........................................................................................................220
ASP.NET MVC - ViewData.........................................................................................................222
ASP.NET MVC - TempData........................................................................................................223
ASP.NET MVC- Filters.....................................................................................................................226
Register Filters............................................................................................................................229
1. Global Level........................................................................................................................229
2. Controller level...................................................................................................................229
3. Action method level...........................................................................................................230
Filter Order.................................................................................................................................230
Create Custom Filter..................................................................................................................230
ASP.NET MVC - Action Filters.........................................................................................................232
Custom Action Filter...................................................................................................................232
Bundling.........................................................................................................................................235
Minification................................................................................................................................236
Bundle Types..............................................................................................................................236
ScriptBundle in ASP.NET MVC........................................................................................................237
Using Wildcards..........................................................................................................................238
Using CDN..................................................................................................................................239
Include ScriptBundle in Razor View............................................................................................239
StyleBundle....................................................................................................................................241
Include Style Bundle in Razor View............................................................................................241
Area................................................................................................................................................242
Create Area................................................................................................................................243
Inversion of Control Tutorial..........................................................................................................246
Prerequisites..........................................................................................................................246
IoC Test...................................................................................................................................246
IoC Introduction.............................................................................................................................246
Inversion of Control................................................................................................................247
Dependency Inversion Principle.............................................................................................248
Dependency Injection.............................................................................................................248
IoC Container..........................................................................................................................248
Inversion of Control.....................................................................................................................249
Control Over the Flow of a Program..................................................................................249
Control Over the Dependent Object Creation...................................................................251
Dependency Inversion Principle.....................................................................................................255
DIP Definition.............................................................................................................................256
What is Abstraction?..............................................................................................................257
Dependency Injection....................................................................................................................260
Types of Dependency Injection..................................................................................................261
Constructor Injection.................................................................................................................263
Property Injection......................................................................................................................264
Method Injection........................................................................................................................265
IoC Container...............................................................................................................................266
Unity Container..............................................................................................................................267
Unity Container Features:..........................................................................................................267
Install Unity Container in Visual Studio..........................................................................................268
Unity Container: Register and Resolve...........................................................................................271
Using UnityContainer.................................................................................................................273
Register......................................................................................................................................273
Resolve.......................................................................................................................................274
Multiple Registration..................................................................................................................275
Register Named Type.................................................................................................................275
Register Instance........................................................................................................................276
var container = new UUnity Container: Property Injection................................................276
[Dependency] Attribute..............................................................................................................277
Named Mapping.....................................................................................................................278
Run-time Configuration..............................................................................................................279
Unity Container: Constructor Injection..........................................................................................280
Multiple Parameters..................................................................................................................281
Multiple Constructors................................................................................................................282
Primitive Type Parameter...........................................................................................................283
Unity Container: Method Injection................................................................................................284
[InjectionMethod] Attribute.......................................................................................................286
Run-time Configuration..............................................................................................................286
Unity Container: Overrides.............................................................................................................287
ParameterOverride....................................................................................................................288
PropertyOverride.......................................................................................................................289
DependencyOverride.................................................................................................................290
Lifetime Managers in Unity Container...........................................................................................290
TransientLifetimeManager.........................................................................................................292
ContainerControlledLifetimeManager.......................................................................................293
HierarchicalLifetimeManager.....................................................................................................293
C# Tutorials....................................................................................................................................294
C# Version History.......................................................................................................................294
Setup Developement Environment for C#......................................................................................296
The .NET Framework..................................................................................................................296
Integrated Development Environment (IDE)..............................................................................296
Advantages of Visual Studio.......................................................................................................299
First C# Program.............................................................................................................................300
Compile and Run C# Program.....................................................................................................301
C# Class..........................................................................................................................................302
C# Access Modifiers...................................................................................................................303
C# Field.......................................................................................................................................303
C# Constructor...........................................................................................................................303
C# Method.................................................................................................................................304
Property.....................................................................................................................................304
Auto-implemented Property......................................................................................................305
Namespace.................................................................................................................................305
C# Variable...................................................................................................................................306
C# Data Types.................................................................................................................................308
Alias vs .Net Type.......................................................................................................................310
Value Type and Reference Type.....................................................................................................311
Value Type:.................................................................................................................................311
Passing by Value:....................................................................................................................312
Reference Type..........................................................................................................................313
Pass by Reference..................................................................................................................314
Null.............................................................................................................................................314
C# Keywords...................................................................................................................................316
Modifier Keywords.....................................................................................................................316
Access Modifier Keywords:........................................................................................................317
Statement Keywords..................................................................................................................317
Method Parameter Keywords....................................................................................................318
Namespace Keywords................................................................................................................318
Operator Keywords....................................................................................................................319
Access Keywords........................................................................................................................319
Literal Keywords.........................................................................................................................319
Type Keywords...........................................................................................................................320
Contextual Keywords.................................................................................................................321
Query Keywords.........................................................................................................................321
C# Interface:...................................................................................................................................323
Explicit Implementation:............................................................................................................324
C# Operators..................................................................................................................................324
if Statement...................................................................................................................................326
if-else Statement........................................................................................................................327
else if Statement........................................................................................................................328
Nested if Statements..................................................................................................................329
C# - Ternary operator ?:.................................................................................................................330
Nested Ternary operator:...........................................................................................................331
C# - switch......................................................................................................................................332
Goto in switch:...........................................................................................................................333
Nested switch:............................................................................................................................334
C# - for loop....................................................................................................................................335
Infinite for Loop..........................................................................................................................337
break in for loop.........................................................................................................................338
Nested for Loop..........................................................................................................................338
C# - while loop:..............................................................................................................................339
Nested while loop:.....................................................................................................................340
C# - do while..................................................................................................................................341
Nested do-while.........................................................................................................................343
C# - struct.......................................................................................................................................343
Characteristics of Structure:.......................................................................................................346
Difference between Struct and Class:........................................................................................346
C# - enum.......................................................................................................................................347
Enum methods:..........................................................................................................................348
C# - StringBuilder...........................................................................................................................350
StringBuilder Initialization..........................................................................................................351
Important Methods of StringBuilder..........................................................................................352
Append()/AppendLine().........................................................................................................352
AppendFormat().....................................................................................................................353
Insert()....................................................................................................................................353
Remove()................................................................................................................................353
Replace()................................................................................................................................353
Indexer...................................................................................................................................354
ToString()................................................................................................................................354
C# - Array.......................................................................................................................................355
Array Declaration.......................................................................................................................355
Initialization................................................................................................................................355
Late initialization........................................................................................................................356
Accessing Array Elements...........................................................................................................357
Array properties and methods...................................................................................................358
Array Helper Class......................................................................................................................358
C# - Multi-dimensional Array.........................................................................................................359
C# - Jagged Array............................................................................................................................360
C# Collection:.................................................................................................................................361
C# - ArrayList..................................................................................................................................362
Important Properties and Methods of ArrayList........................................................................362
Add Elements into ArrayList.......................................................................................................364
Access ArrayList Elements..........................................................................................................364
Insert Elements into ArrayList....................................................................................................365
Remove Elements from ArrayList...............................................................................................366
ArrayList Sorting.........................................................................................................................367
Check for an Existing Elements in ArrayList................................................................................368
C# - SortedList................................................................................................................................369
Important Properties and Methods of SortedList......................................................................369
Add elements in SortedList........................................................................................................370
Access SortedList........................................................................................................................372
Access SortedList using foreach Loop.........................................................................................373
Remove elements from SortedList.............................................................................................373
Check for an existing key in SortedList.......................................................................................374
C# - Stack........................................................................................................................................375
Important Properties and Methods of Stack:.............................................................................375
Add Values into Stack.................................................................................................................375
Accessing Stack Elements...........................................................................................................376
Peek().........................................................................................................................................376
Pop()...........................................................................................................................................377
Contains()...................................................................................................................................377
Clear().........................................................................................................................................378
C# - Queue.....................................................................................................................................378
Important Properties and Methods of Queue:...........................................................................379
Add elements in Queue..............................................................................................................379
Access Queue.............................................................................................................................380
Peek().........................................................................................................................................380
Contains()...................................................................................................................................381
Clear().........................................................................................................................................382
C# - Hashtable................................................................................................................................382
Important Propertis and Methods of Hashtable........................................................................383
Add key-value into Hashtable....................................................................................................383
Access Hashtable........................................................................................................................384
Remove elements in Hashtable..................................................................................................386
Check for Existing Elements.......................................................................................................386
Clear().........................................................................................................................................387
C# - Indexer....................................................................................................................................388
Override Indexer........................................................................................................................389
Insert Indexer Code snippet in VisualStudio...............................................................................391
C# - Stream.....................................................................................................................................391
Stream Readers and Writers......................................................................................................392
Working with Files & Directories in C#...........................................................................................393
File..............................................................................................................................................394
Important Methods of Static File Class.......................................................................................394
Append Text Lines......................................................................................................................395
Append String.............................................................................................................................396
Overwrite Text...........................................................................................................................396
C# - FileInfo....................................................................................................................................397
Important Properties and Methods of FileInfo:.........................................................................397
Exception in C#...............................................................................................................................401
Important Exception Classes:.....................................................................................................403
Exception Handling in C#................................................................................................................404
Catch block:................................................................................................................................406
Invalid catch Block..................................................................................................................407
Finally Block................................................................................................................................408
Nested try-catch.........................................................................................................................409
C# - throw keyword........................................................................................................................411
Create Custom Exception Class in C#.............................................................................................411
C# - Delegate..................................................................................................................................413
Invoking Delegate.......................................................................................................................415
Pass Delegate as a Parameter....................................................................................................415
Multicast Delegate.....................................................................................................................416
C# - Event.......................................................................................................................................417
Event Arguments........................................................................................................................421
Generics in C#................................................................................................................................423
Generic Class as Base Class........................................................................................................426
Generic Delegates......................................................................................................................427
Advantages of Generics..............................................................................................................428
C#: Constraints in Generics............................................................................................................428
Multiple constraints:..................................................................................................................430
Constraint on Generic Methods.................................................................................................431
C# - Generic Collection...................................................................................................................431
C# - Generic List<T>........................................................................................................................432
Add Elements into List................................................................................................................434
AddRange().............................................................................................................................435
Accessing List..............................................................................................................................435
Insert Elements into List.............................................................................................................437
Remove Elements from List........................................................................................................437
TrueForAll()............................................................................................................................438
C# - Generic SortedList...................................................................................................................439
Initialize Generic SortedList:.......................................................................................................439
Important Properties and Methods of Generic SortedList.........................................................439
Add Elements into SortedList.....................................................................................................440
Accessing Generic SortedList......................................................................................................441
Accessing Elements using foreach loop..................................................................................442
Accessing key.............................................................................................................................443
Remove Elements from Generic SortedList................................................................................443
ContainsKey() and ContainsValue()........................................................................................444
Accessing SortedList using LINQ.................................................................................................444
C# - Dictionary................................................................................................................................445
Dictionary Initialization..............................................................................................................446
Important Properties and Methods of IDictionary.....................................................................446
Add Elements into Dictionary.....................................................................................................447
Accessing Dictionary Elements...................................................................................................448
Check for an Existing Elements...................................................................................................450
Remove Elements in Dictionary.................................................................................................452
C# - Partial Class.............................................................................................................................452
Partial Class Requirements:....................................................................................................453
Advantages of Partial Class.....................................................................................................454
Partial Methods..........................................................................................................................454
Requirements for Partial Method..........................................................................................455
C# - Static.......................................................................................................................................456
C# Static Constructor..................................................................................................................458
Memory Allocation for Static Items............................................................................................460
C# - Anonymous Method...............................................................................................................461
Anonymous Method Limitations................................................................................................462
Nullable Type in C#.........................................................................................................................463
Shorthand Syntax for Nullable Types.........................................................................................464
?? Operator............................................................................................................................465
Assignment Rules...................................................................................................................465
Nullable Helper Class..................................................................................................................466
Characteristics of Nullable Types...............................................................................................467
Covariance and Contravariance in C#.............................................................................................467
Covariance in C#.........................................................................................................................468
Covariance with Delegate..........................................................................................................468
C# Contravariance......................................................................................................................469
Covariance and Contravariance in C#.............................................................................................471
Covariance in C#.........................................................................................................................472
Covariance with Delegate..........................................................................................................472
C# Contravariance......................................................................................................................473
C# LINQ..........................................................................................................................................474
Lamda Expression.......................................................................................................................475
C# - Func.........................................................................................................................................475
C# Func with an Anonymous Method........................................................................................477
Func with Lambda Expression....................................................................................................477
C# - Action Delegate.......................................................................................................................478
Advantages of Action and Func Delegates.................................................................................479
C# - Predicate Delegate................................................................................................................479
C# - Extension Method................................................................................................................481
C# - Anonymous Type....................................................................................................................483
Nested Anonymous Type...........................................................................................................485
Scope of Anonymous Type.........................................................................................................486
Anonymous Types with a LINQ Query........................................................................................486
C# - Dynamic Type..........................................................................................................................487
Methods and Properties of Dynamic Type.................................................................................489
Dynamic Type as a Method Parameter......................................................................................490
C# - Object Initializer Syntax...........................................................................................................491
Collection Initializer Syntax........................................................................................................492
Advantages of Initializers...........................................................................................................492
C# - Tuple.......................................................................................................................................493
Accessing Tuple Elements..........................................................................................................493
Nested Tuples.............................................................................................................................494
Tuple as a Method Parameter....................................................................................................494
Tuple as a Return Type...............................................................................................................495
Usage of Tuple............................................................................................................................495
Tuple Limitations:.......................................................................................................................495
C# - ValueTuple..............................................................................................................................495
ValueTuple Initialization.............................................................................................................496
Named Members:......................................................................................................................497
ValueTuple as Return Type:........................................................................................................498
Deconstruction...........................................................................................................................498
LINQ Tutorial..................................................................................................................................499
Prerequisites..........................................................................................................................499
LINQ Test................................................................................................................................499
What is LINQ?.................................................................................................................................500
Why LINQ?.....................................................................................................................................501
Advantages of LINQ....................................................................................................................504
LINQ API.........................................................................................................................................504
Enumerable................................................................................................................................505
Queryable...................................................................................................................................505
LINQ Query Syntax.........................................................................................................................506
Query Syntax..............................................................................................................................506
LINQ Method Syntax..................................................................................................................509
Anatomy of the Lambda Expression...............................................................................................511
Lambda Expression with Multiple Parameters...........................................................................513
Lambd Expression without Parameter.......................................................................................513
Multiple Statements in Lambda Expression Body......................................................................513
Declare Local Variable in Lambda Expression Body....................................................................514
Assign Lambda Expression to Delegate......................................................................................514
Action Delegate..........................................................................................................................515
Lambda Expression in LINQ Query.............................................................................................516
Standard Query Operators.............................................................................................................517
Standard Query Operators in Query Syntax...............................................................................517
Standard Query Operators in Method Syntax............................................................................517
Filtering Operators - Where...........................................................................................................518
Where........................................................................................................................................519
Where clause in Query Syntax................................................................................................519
Where extension method in Method Syntax..........................................................................521
Multiple Where clause...........................................................................................................521
Filtering Operator - OfType........................................................................................................522
OfType in Query Syntax......................................................................................................522
OfType in Method Syntax....................................................................................................523
Sorting Operators: OrderBy & OrderByDescending.......................................................................523
OrderBy..........................................................................................................................................524
OrderBy in Method Syntax.........................................................................................................525
OrderByDescending.......................................................................................................................526
Multiple Sorting..........................................................................................................................526
Sorting Operators: ThenBy & ThenByDescending...................................................................527
Grouping Operators: GroupBy & ToLookup...................................................................................529
GroupBy.....................................................................................................................................529
GroupBy in Query Syntax.......................................................................................................530
GroupBy in Method Syntax....................................................................................................532
ToLookup....................................................................................................................................533
Joining Operator: Join....................................................................................................................533
Join.............................................................................................................................................534
Join in Method Syntax............................................................................................................534
Join in Query Syntax...............................................................................................................537
Joining Operator: GroupJoin..........................................................................................................538
GroupJoin in Query Syntax.........................................................................................................542
Projection Operators: Select, SelectMany......................................................................................544
Select......................................................................................................................................544
Select in Query Syntax............................................................................................................544
Select in Method Syntax.........................................................................................................545
Select Many................................................................................................................................546
Quantifier Operators......................................................................................................................546
All...............................................................................................................................................547
Any.............................................................................................................................................547
Quantifier Operator: Contains....................................................................................................548
Aggregation Operators: Aggregate.................................................................................................551
Aggregate...................................................................................................................................551
Aggregate Method with Seed Value...........................................................................................553
Aggregate Method with Result Selector.....................................................................................554
Aggregation Operator: Average.....................................................................................................555
Aggregation Operator: Count.........................................................................................................557
Count Operator in Query Syntax................................................................................................559
Aggregation Operator: Max...........................................................................................................559
Max Operator in Query Syntax...................................................................................................562
Aggregation Operator: Sum...........................................................................................................562
Sum operator in query syntax....................................................................................................564
Element Operators: ElementAt, ElementAtOrDefault....................................................................565
Element Operators: First & FirstOrDefault.....................................................................................567
Element Operators : Last & LastOrDefault.....................................................................................569
Element Operators: Single & SingleOrDefault..........................................................................572
Equality Operator: SequenceEqual............................................................................................574
Concatenation Operator: Concat...................................................................................................576
Generation Operator: DefaultIfEmpty............................................................................................577
Generation Operators: Empty, Range, Repeat...............................................................................579
Empty.........................................................................................................................................579
Range.........................................................................................................................................580
Repeat........................................................................................................................................580
Set Operator: Distinct.....................................................................................................................581
Distinct.......................................................................................................................................582
Distinct operator in Query Syntax..............................................................................................584
Set Operator: Except...................................................................................................................584
Set Operator: Intersect................................................................................................................586
Set Operator: Union.....................................................................................................................588
Query Syntax........................................................................................................................590
Partitioning Operators: Skip & SkipWhile.......................................................................................591
Skip.............................................................................................................................................592
Skip Operator in Query Syntax...................................................................................................592
SkipWhile...................................................................................................................................592
SkipWhile operator in Query Syntax..........................................................................................594
Partitioning Operators: Take & TakeWhile.....................................................................................594
TakeWhile..................................................................................................................................595
Conversion Operators....................................................................................................................596
AsEnumerable & AsQueryable...................................................................................................597
Cast............................................................................................................................................598
To Operators: ToArray(), ToList(), ToDictionary().......................................................................599
Expression in LINQ.........................................................................................................................600
Define an Expression..................................................................................................................601
Invoke an Expression..................................................................................................................602
Expression Tree..............................................................................................................................603
Why Expression Tree?................................................................................................................606
Deferred Execution of LINQ Query.................................................................................................609
Deferred Execution returns the Latest Data...........................................................................610
Implementing Deferred Execution.............................................................................................611
Immediate Execution of LINQ Query..............................................................................................612
Method Syntax.......................................................................................................................612
Query Syntax..........................................................................................................................613
let keyword...................................................................................................................................614
into keyword.................................................................................................................................614
Sample LINQ Queries.....................................................................................................................615
Multiple Select and where operator..........................................................................................615
Group By....................................................................................................................................616
Left outer join.............................................................................................................................617
Sorting........................................................................................................................................618
Inner Join....................................................................................................................................619
Nested Query.............................................................................................................................619
ASP.NET Core Tutorial
ASP.NET Core is a new version of ASP.NET by Microsoft. It is an open-source web
framework which can be run on Windows, Mac, or Linux.

These tutorials will help you understand ASP.NET Core web application step by step.
Tutorials are broken down into chapters, where each chapter contains a number of related
topics that are packed with easy to understand explanations and real-world examples.

These tutorials are designed for beginners and professionals who want learn how to build
ASP.NET Core web applications step by step.

Prerequisites

Basic knowledge of C#, HTML, Visual Studio, and Object Oriented Programming is
required.

ASP.NET Core
ASP.NET Core is a free, open-source and cloud optimized web framework which can run
on Windows, Linux, or Mac. You can say that it is the new version of ASP.NET. The
framework is a complete rewrite from scratch in order to make it open source, modular and
cross-platform. It was initially launched as ASP.NET 5 but then it was renamed to
ASP.NET Core.
ASP.NET Core is a modular framework distributed as NuGet packages. This allows us to
include packages that are required in our application.

ASP.NET Core applications run on both, .NET Core and traditional .NET framework
(.NET Framework 4.x).

ASP.NET Core is designed to be deployed on cloud as well as on-premises. Developers can


now build cloud-based web applications, IoT (Internet of Thing) and mobile backend
applications using ASP.NET Core framework which can run on Windows, Linux, and Mac
operating systems.

ASP.NET Core is an open source framework supported by Microsoft and the community,
so you can also contribute or download the source code from the respective repositories on
Github.

ASP.NET Core Version History


Version Release Date

ASP.NET Core 2.0 August 2017


Version Release Date

ASP.NET Core 1.1 November 2016

ASP.NET Core 1.0 June 2016

Learn more about ASP.NET Core releases on GitHub.

.NET Core

Many people are confused between ASP.NET Core and .NET Core. Please note that
ASP.NET Core and .NET Core are not the same. They are different, just like ASP.NET and
.NET Framework are different.

.NET Core is a fast, lightweight, modular and open source framework for creating web
applications and services that run on Windows, Linux and Mac. So, it is a platform on
which ASP.NET Core application runs.

.NET Core is named "Core" because it includes core features of the .NET framework. The
main objective of .NET Core is to make .NET framework open source, and cross-platform
compatible so that it can be used in resource-constrained environments. It includes
minimum features that are required to run a basic .NET Core app and other advanced
features that can be included as a package from NuGet.

The following figure illustrates the components of .NET Core.

.NET Core Components

As you can see above, .NET Core includes .NET Compiler platform Roslyn, .NET Core
runtime CoreCLR, .NET Core framework CoreFX and ASP.NET Core . ASP.NET Core is
a part of .NET Core SDK so you don't need to install ASP.NET Core separately. ASP.NET
Core and .NET Core is a part of .NET Foundation.
.NET Core comes under MIT or Apache 2 licenses. Visit .NET Core repository on Github
to contribute or download the source code.

Why ASP.NET Core?

 Supports Multiple Platforms: ASP.NET Core applications can run on Windows, Linux, and
Mac. So you don't need to build different apps for different platforms using different
frameworks.
 Fast: ASP.NET Core no longer depends on System.Web.dll for browser-server
communication. ASP.NET Core allows us to include packages which we need for our
application. This reduces the request pipeline and improves the performance and
scalability.
 IoC Container: It includes built-in IoC container for automatic dependency injection which
makes it maintainable and testable.
 Integration with Modern UI Frameworks: It allows you to use and manage modern UI
frameworks such as AngularJS, ReactJS, Umber, Bootstrap etc. using Bower (a package
manager for the web).
 Hosting: ASP.NET Core web application can be hosted on multiple platforms with any web
server such as IIS, Apache etc. It is not dependent only on IIS as a standard .NET
Framework.
 Code Sharing: It allows you to build a class library which can be used with other .NET
frameworks such as .NET Framework 4.x or Mono. Thus a single code based can be shared
across frameworks.
 Side-by-Side App Versioning: ASP.NET Core runs on .NET Core which supports
simultaneous running of multiple versions of applications.
 Smaller Deployment Footprint: ASP.NET Core application runs on .NET Core which is
smaller than full .NET Framework. So, the application which uses only a part of .NET
CoreFX will have smaller deployment size. This reduces the deployment foot print.

Learn to install ASP.NET Core in the next chapter.

ASP.NET Core - Development


Environment Setup
To develop ASP.NET Core application, the following must be installed in your system:

1. .NET Core SDK


2. Integrated Development Environment (IDE)

ASP.NET Core is a part of .NET Core SDK, so you don't need to install it separately. As of
this writing, the current release is .NET Core 1.1. Read .NET Core Release Notes to know
more about all the releases.
Install .NET Core SDK

.NET Core SDK can be installed on the platform you are using such as Windows, Linux or
Mac.

Note:

.NET Core Runtime and .NET Core SDK are different things. .NET Core Runtime is only used to
run .NET Core application whereas .NET Core SDK includes tools and libraries to develop .NET Core
applications. To setup a development environment, we need to install .NET Core SDK for the
platform we use for the development such as Windows, Linux or Mac.

Go to https://www.microsoft.com/net/core and select the platform you are using. Here, we


use Windows so select Windows as shown below.
Install .NET Core SDK for Windows

As you can see above, click on the Download .NET Core SDK button to download the
latest version of .NET Core SDK installer. It will download .NET Core 2.0 SDK as of this
writing.

Alternatively,

Download .NET Core SDK: Download .NET Core SDK for different platform from here.
Download .NET Core Runtime: Download .NET Core Runtime for different platform
from here. Remember, .NET Core runtime is used only to run .NET Core application but
not for the development.

After downloading installer, click on it to start the installation of .NET Core 2.0 SDK.

Click Run to go to the next step as shown below.


Click on Install button to install .NET Core 2.0 SDK.

IDE

You can develop, restore, build and run .NET Core application either with Visual Studio or
with command line interface for .NET Core. Here, we will use Visual Studio 2017 to
develop .NET Core 2.0 applications.

Visual Studio 2017:

You can download Visual Studio 2017 installer from the same page
https://www.microsoft.com/net/core. Click on the Download Visual Studio button to
download Visual Studio 2017 Community edition. Alternatively, you can go to
https://www.visualstudio.com/downloads/ and download installer for the specific Visual
Studio edition.

After installation, you can start to create .NET Core applications.


Command-line Interface (CLI):

If you do not use Visual Studio for .NET core application development for some reason and
want to use different IDE then you can use command-line interface to create, compile,
build, restore and run .NET Core application.

.NET Core SDK installation also installs command-line interface for the selected platform.
It installs the latest stable version of the tools and put them on your PATH so you can run
dotnet from the Console.

Once installed, you can verify it by opening command prompt and type dotnet and press
Enter. This will display installed version and usage information as shown below.

Visit Command-line Interface chapter for more information.

After installation, let's create our first ASP.NET Core application in the next chapter.

First ASP.NET Core Application


Here, we will learn how to create our first .NET core 2.0 application. We will use Visual
Studio 2017 to create ASP.NET Core 2.0 web application.

The first step is to open Visual Studio. Click on File->New, and click on Projects.

In the New Project dialog box, click on the Templates node. Expand the Templates node,
then expand Visual C#, and click on the Web template.
ASP.NET Project Templates

As shown above, the middle pane on the New Project dialog box includes the following
two templates for ASP.NET Web projects:

 ASP.NET Core Web Application - Select this template to create a new


crossplatform compatible ASP.NET Core web application project that runs on
the .NET Core framework.
 ASP.NET Web Application (.NET Framework) - Select this template to create a
new ASP.NET web application project that runs on standard .NET Framework.

Here, we want to create a cross-platform ASP.NET Core web application. So, select
ASP.NET Core Web Application template. Give the appropriate name, location, and the
solution name for the ASP.NET Core application. In this example, we will give the name
MyFirstCoreApp, and click on the OK button. This will open another popup as shown
below.

ASP.NET Core Templates

As you can see, we can select the version of the framework we want to use in our
application. We are going to use .NET Core 2.0 framework here. So select ASP.NET Core
2.0 in the dropdown as shown below.
ASP.NET Core Version

Now, select an Empty ASP.NET Core template in order to understand the basics of
ASP.NET core web application. We will not use Docker support or authentication here, so
click on OK to create an ASP.NET core web application as shown below.
ASP.NET Core Web Project in Visual Studio

Wait for some time till Visual Studio restores the packages in the project. Restoring process
means Visual Studio will automatically add, update or delete configured dependencies as
NuGet packages in the project. The entire project structure of the created project will look
like below.
ASP.NET Core Project Structure

We will understand the project structure in the next chapter. To run this web application, go
to Debug menu and click on Start without Debugging, or press Ctrl + F5. This will open the
browser and display the following result.
The above output "Hello World!" comes from the Configure method of Startup class in
the Startup.cs file in the project. Open Startup.cs file and see Configure method. Change
"Hello World!" string to something else and it will change the output accordingly. Learn
about Startup class in the Startup.cs chapter.

You can also see the IIS express icon on the system tray. Right click on it. You can see the
ASP.NET sites currently running in your development machine.

ASP.NET
Core app in System tray

This is how we can create a new cross-platform ASP.NET core application that runs
on .NET Core. Learn about the ASP.NET Core project structure in the next chapter.

ASP.NET Core Project Structure


In the previous chapter, we created our first ASP.NET Core 2.0 web application. Here, you
will learn about the project structure and significance of each file created by ASP.NET
Core application template in Visual Studio 2017.

The following is a default project structure when you create an empty ASP.NET Core
application in Visual Studio.

ASP.NET Core Project Structure

The above solution explorer displays project solution. We can change it to folder view by
clicking Solution and Folders icon and selecting Folder View option. This displays the
solution explorer with all project folders and files as shown below.
Solution Explorer - Folder View

Note:

ASP.NET Core project files and folders are synchronized with physical files and folders. If you add a
new file or folder in project folder then it will directly reflect in the solution explorer. You don't
need to add it in the project explicitly by right clicking on the project.

.csproj

ASP.NET Core 1.0 does not create .csproj file, instead, it uses .xproj and project.json files
to manage the project. This has changed in ASP.NET Core 2.0. Visual Studio now
uses .csproj file to manage projects. We can edit the .csproj settings by right clicking on the
project and selecting Edit <project-name>.csproj as shown below.
Edit .csproj

The .csproj for the above project looks like below.


Edit .csproj

The csproj file includes settings related to targeted .NET Frameworks, project folders,
NuGet package references etc.

Dependencies

The Dependencies in the ASP.NET Core 2.0 project contain all the installed server-side
NuGet packages as well as client-side frameworks such as jQuery, AngularJS, Bootstrap
etc. These client-side dependencies are managed using Bower in Visual Studio.
Dependencies

As you can see above, dependencies node in solution explorer displays installed NuGet
packages. This also includes bower folder which has all the client-side frameworks library
installed it using Bower.

Properties

The Properties node includes launchSettings.json file which includes Visual Studio profiles
of debug settings. The following is a default launchSettings.json file.
launchSettings.json

We can also edit settings from the debug tab of project properties. Right click on the project
-> select Properties -> click Debug tab.
Project Properties

In the debug tab, select a profile which you want to edit as shown above. You may change
environment variables, url etc.

Learn about wwwroot in the next chapter.

ASP.NET Core - wwwroot


By default, the wwwroot folder in the ASP.NET Core project is treated as a web root
folder. Static files can be stored in any folder under the web root and accessed with a
relative path to that root.

In the standard ASP.NET application, static files can be served from the root folder of an
application or any other folder under it. This has been changed in ASP.NET Core. Now,
only those files that are in the web root - wwwroot folder can be served over an http
request. All other files are blocked and cannot be served by default.

Generally, there should be separate folders for the different types of static files such as
JavaScript, CSS, Images, library scripts etc. in the wwwroot folder as shown below.

wwwroot

You can access static files with base URL and file name. For example, we can access above
site.css file in the css folder by http://localhost:<port>/css/app.css.

Remember, you need to include a middleware for serving static files in the Configure
method of Startup.cs. Learn more about it in Serving Static File section.
ASP.NET Core - Program.cs
ASP.NET Core web application is actually a console project which starts executing from
the entry point public static void Main() in Program class where we can create a host
for the web application.

The steps for creating a host in ASP.NET Core 1.x is slightly different in ASP.NET Core
2.x. Let's understand Program class in ASP.NET Core 1.x application so that it will be easy
to understand it in ASP.NET Core 2.x.

Setup Host in ASP.NET Core 1.x

The following is a typical Program.cs in ASP.NET Core 1.x.

Program.cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;

namespace MyFirstCoreApp
{
public class Program
{
public static void Main(string[] args)
{
var host = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.Build();

host.Run();
}
}
}

Every ASP.NET Core web application requires a host to be executed. In the above Main()
method, we configure a web hosting environment for the ASP.NET Core 1.x web
application. A host must implement IWebHost interface. Let's understand the above code
step by step.

First, var host = new WebHostBuilder()

The WebHostBuilder class is the helper class to create and configure a host for a web
application. So, first of all we will have to create an object of it.
Note:

WebHostBuilder class is included in .NET Core API. However, we can create our own helper class
by implementing IWebHostBuilder interface for custom hosting requirement.

.UseKestrel()

The UseKestrel() method is an extension method which specifies Kestrel as an internal


web server. The Kestrel is an open-source, cross-platform web server for ASP.NET Core. It
is designed to be used behind proxy because it has not yet matured to be exposed as a full-
fledge web server.

ASP.NET Core application can be a cross-platform application so it can be used with any
web server, and not only IIS. Hence, there will be an external web server such as IIS,
Apache, Nginx etc. which will dispatch http requests to the internal web server Kestrel.
Learn more about web servers in ASP.NET Core here.

.UseContentRoot(Directory.GetCurrentDirectory())

The UseContentRoot() method specifies the current directory as a root directory which
will be src folder in the default ASP.NET Core project. The content root directory
determines where the content files are located such as MVC view files, CSS, images etc.

.UseIISIntegration()

The UseIISIntegration() method specifies the IIS as the external web server or the
reverse proxy server.

.UseStartup<Startup>()

The UseStartup<startup>() method specifies the Startup class to be used by the web
host. Visual Studio creates Startup.cs by default with every new ASP.NET Core
application. This Startup class is like Global.asax of .NET framework where you can
configure request pipeline (middleware). We may give any other name to the Startup class
instead of Startup. We just need to specify it as a generic parameter in UseStartup<T>()
method. You will learn about it in the next chapter.

And lastly, the Build() method returns an instance of IWebHost using the configuration
specified above.

So now, we have built our hosting environment and it's time to start the web application.

host.Run();

The Run() method starts the web application and blocks the calling thread till the host is
shutdown. The command line application will become web application from this point
onwards.
Thus, ASP.NET Core application starts from the Main() method of the Program class
where you can build the hosting environment and start the web application.

Setup Host in ASP.NET Core 2.x

The following is the Program class in ASP.NET Core 2.x:

Program.cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;

namespace MyFirstCoreApp
{
public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}

public static IWebHost BuildWebHost(string[] args) =>


WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
}
}

As you can see above, the Main() method calls method expression BuildWebHost() to
build web host with pre-configured defaults. The BuildWebHost expression can also be
written as a method that returns IWebHost as shown below.

public static void Main(string[] args)


{
BuildWebHost(args).Run();
}

public static IWebHost BuildWebHost(string[] args)


{
return WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
}

Let's understand hosting steps.

The WebHost is a static class which can be used for creating an instance of IWebHost and
IWebHostBuilder with pre-configured defaults. The CreateDefaultBuilder() method
creates a new instance of WebHostBuilder with pre-configured defaults. Internally, it
configures Kestrel, IISIntegration and other configurations. The following is
CreateDefaultBuilder() method from the source code on GitHub.

CreateDefaultBuilder()
public static IWebHostBuilder CreateDefaultBuilder(string[] args)
{
var builder = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.ConfigureAppConfiguration((hostingContext, config) =>
{
var env = hostingContext.HostingEnvironment;

config.AddJsonFile("appsettings.json", optional: true,


reloadOnChange: true)
.AddJsonFile($"appsettings.
{env.EnvironmentName}.json", optional: true, reloadOnChange: true);

if (env.IsDevelopment())
{
var appAssembly = Assembly.Load(new
AssemblyName(env.ApplicationName));
if (appAssembly != null)
{
config.AddUserSecrets(appAssembly, optional: true);
}
}

config.AddEnvironmentVariables();

if (args != null)
{
config.AddCommandLine(args);
}
})
.ConfigureLogging((hostingContext, logging) =>
{

logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging
"));
logging.AddConsole();
logging.AddDebug();
})
.UseIISIntegration()
.UseDefaultServiceProvider((context, options) =>
{
options.ValidateScopes =
context.HostingEnvironment.IsDevelopment();
});

return builder;
}
As you can see above, the CreateDefaultBuilder method creates an instance of
WebHostBuilder and sets up Kestrel, content root directory, IIS integration which is same
as ASP.NET Core 1.x Main() method.

It also calls ConfigureAppConfiguration() to load configurations from appsettings.json


files, environment variables and user secrets. The ConfigureLogging() method setup
logging to console and debug window.

Thus, Program.cs in ASP.NET Core 2.x makes it easy for us to setup a web host.

Learn about Startup.cs in the next chapter.

ASP.NET Core - Startup Class


Here, we will have an overview of Startup class contained in Startup.cs in the root folder of
the project.

ASP.NET Core application must include Startup class. It is like Global.asax in the
traditional .NET application. As the name suggests, it is executed first when the application
starts.

The startup class can be configured using UseStartup<T>() method at the time of
configuring the host in the Main() method of Program class as shown below.

public class Program


{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}

public static IWebHost BuildWebHost(string[] args)


{
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
}
}

The name "Startup" is by ASP.NET Core convention. However, we can give any name to
the Startup class, just specify it as the generic parameter in the UseStartup<T>() method.
For example, to name the Startup class as MyStartup, specify it as
.UseStartup<MyStartup>().

Open Startup class in Visual Studio by clicking on the Startup.cs in the solution explorer.
The following is a default Startup class in ASP.NET Core 2.x.
startup.cs

As you can see, Startup class includes two public methods: ConfigureServices and
Configure.

The Startup class must include a Configure method and can optionally include
ConfigureService method.

ConfigureServices()

The Dependency Injection pattern is used heavely in ASP.NET Core architecture. It


includes built-in IoC container to provide dependent objects using constructors.

The ConfigureServices method is a place where you can register your dependent classes
with the built-in IoC container. After registering dependent class, it can be used anywhere
in the application. You just need to include it in the parameter of the constructor of a class
where you want to use it. The IoC container will inject it automatically.

ASP.NET Core refers dependent class as a Service. So, whenever you read "Service" then
understand it as a class which is going to be used in some other class.

ConfigureServices method includes IServiceCollection parameter to register services to the


IoC container. Learn more about it in the next chapter.
Configure()

The Configure method is a place where you can configure application request pipeline for
your application using IApplicationBuilder instance that is provided by the built-in IoC
container.

ASP.NET Core introduced the middleware components to define a request pipeline, which
will be executed on every request. You include only those middleware components which
are required by your application and thus increase the performance of your application.

The following is a default Configure method.

public void Configure(IApplicationBuilder app, IHostingEnvironment env)


{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}

app.Run(async (context) =>


{
await context.Response.WriteAsync("Hello World!");
});
}

As you can see, the Configure method includes three parameters IApplicationBuilder,
IHostingEnvironment, and ILoggerFactory by default. These services are framework
services injected by built-in IoC container.

At run time, the ConfigureServices method is called before the Configure method. This is
so that you can register your custom service with the IoC container which you may use in
the Configure method.

Learn more about the Configure method in the Middleware chapter.

.NET Core Command-Line Interface


The .NET Core command-line interface (CLI) is a new cross-platform tool for creating,
restoring packages, building, running and publishing .NET applications.

We created our first ASP.NET Core application using Visual Studio in the previous
chapter. Visual Studio internally uses this CLI to restore, build and publish an application.
Other higher level IDEs, editors and tools can use CLI to support .NET Core applications.

The .NET Core CLI is installed with .NET Core SDK for selected platforms. So we don't
need to install it separately on the development machine. We can verify whether the CLI is
installed properly by opening command prompt in Windows and writing dotnet and
pressing Enter. If it displays usage and help as shown below then it means it is installed
properly.

.NET Core Command-line Interface

Command Structure

The following is a command structure.

dotnet <command> <argument> <option>

All the commands start with driver named dotnet. The driver starts the execution of the
specified command. After dotnet, we can supply command (also known as verb) to perform
a specific action. Each command can be followed by arguments and options. The following
are .NET Core 2.x CLI commands.

Basic Commands Description

Creates a new project, configuration file, or solution based on the


new
specified template.

restore Restores the dependencies and tools of a project.

build Builds a project and all of its dependencies.

Run Runs source code without any explicit compile or launch commands.

Packs the application and its dependencies into a folder for


publish
deployment to a hosting system.
Basic Commands Description

test Executes unit tests.

vtest Runs tests from the specified files.

pack Packs the code into a NuGet package.

clean Cleans the output of a project.

sln Modifies a .NET Core solution file.

help Display help on the specified command

store Stores the specified assemblies in the runtime package store.

Project Modification
Description
Commands

add package Adds a package reference to a project.

add reference Adds project-to-project (P2P) references.

remove package Removes package reference from the project.

remove reference Removes project reference

list reference Lists all project-to-project references

Advanced Commands Description

nuget delete Deletes or unlists a package from the server.

nuget locals Clears or lists local NuGet resources.

nuget push Pushes a package to the server and publishes it.

msbuild Builds a project and all of its dependencies.

dotnet install script Script used to install the .NET Core CLI tools and the shared runtime.

Let's create, restore, build, and run .NET Core console application using command-line
interface without using Visual Studio.

Create a New Project

To create a new .NET Core project, we have to use new command followed by template
name argument. We can create console, class library, web, mvc, webapi, razor, angular,
react etc. projects using CLI. Use console template to create a new .NET Core console
application.
The following creates new console project in the current directory with the same name as
current directory.

dotnet new console

The following command creates a new console project named MyConsoleApp. The -n or --
name option species the name of a project.

dotnet new console -n MyConsoleApp

The following command creates a new console application named MyConsoleApp to


MyProjects directory. The -o or --output option is used to specify an output directory where
the project should be generated.

dotnet new console -n MyConsoleApp -o C:\MyProjects

After creating a project, navigate to the project directories in command prompt to apply
project specific commands which is C:\MyConsoleApp in our case.

Add Package Reference

We often need to add NuGet package reference for different purposes. For example, apply
the following command to add Newtonsoft.json package to our console project.

C:\MyConsoleApp>dotnet add package Newtonsoft.json

This will add Newtonsoft.json package to our project. We can verify it by opening .csproj
file.

Restore Packages

To restore packages or to update existing packages, we can use restore command as below.

C:\MyConsoleApp>dotnet restore

Build Project

To build a new or existing project, apply C:\MyConsoleApp>dotnet build command.

Run project

To run our console project, apply dotnet run command as shown below.
As you can see above, it displays an output "Hello World!".

Getting Help

We can get help on any .NET Core CLI commands by typing -h or -help at the end of the
command we want to get help on. For example, dotnet new -h will display help on the new
command, arguments and options we can use with it, as shown below.
Thus, we can use .NET Core command-line interface to create, restore packages, build, run,
and publish different types of .NET Core applications.

ASP.NET Core - Dependency Injection


ASP.NET Core is designed from scratch to support Dependency Injection. ASP.NET Core
injects objects of dependency classes through constructor or method by using built-in IoC
container.

Built-in IoC Container

ASP.NET Core framework contains simple out-of-the-box IoC container which does not
have as many features as other third party IoC containers. If you want more features such as
auto-registration, scanning, interceptors, or decorators then you may replace built-in IoC
container with a third party container.

The built-in container is represented by IServiceProvider implementation that supports


constructor injection by default. The types (classes) managed by built-in IoC container is
called services.

There are basically two types of services in ASP.NET Core:


1. Framework Services: Services which are a part of ASP.NET Core framework such as
IApplicationBuilder, IHostingEnvironment, ILoggerFactory etc.
2. Application Services: The services (custom types or classes) which you as a programmer
create for your application.

In order to let the IoC container automatically inject our application services, we first need
to register them with IoC container.

Registering Application Service

Consider the following example of simple ILog interface and its implementation class. We
will see how to register it with built-in IoC container and use it in our application.

public interface ILog


{
void info(string str);
}

class MyConsoleLogger : ILog


{
public void info(string str)
{
Console.WriteLine(str);
}
}

ASP.NET Core allows us to register our application services with IoC container, in the
ConfigureServices method of the Startup class. The ConfigureServices method
includes a parameter of IServiceCollection type which is used to register application
services.

Let's register above ILog with IoC container in ConfigureServices() method as shown
below.

Example: Register Service


public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.Add(new ServiceDescriptor(typeof(ILog), new
MyConsoleLogger()));
}

// other code removed for clarity..


}

As you can see above, Add() method of IServiceCollection instance is used to register a
service with an IoC container. The ServiceDescriptor is used to specify a service type and
its instance. We have specified ILog as service type and MyConsoleLogger as its instance.
This will register ILog service as a singleton by default. Now, an IoC container will create
a singleton object of MyConsoleLogger class and inject it in the constructor of classes
wherever we include ILog as a constructor or method parameter throughout the application.

Thus, we can register our custom application services with an IoC container in ASP.NET
Core application. There are other extension methods available for quick and easy
registration of services which we will see later in this chapter.

Understanding Service Lifetime

Built-in IoC container manages the lifetime of a registered service type. It automatically
disposes a service instance based on the specified lifetime.

The built-in IoC container supports three kinds of lifetimes:

1. Singleton: IoC container will create and share a single instance of a service throughout the
application's lifetime.
2. Transient: The IoC container will create a new instance of the specified service type every
time you ask for it.
3. Scoped: IoC container will create an instance of the specified service type once per
request and will be shared in a single request.

The following example shows how to register a service with different lifetimes.

Example: Register a Service with Lifetime


public void ConfigureServices(IServiceCollection services)
{
services.Add(new ServiceDescriptor(typeof(ILog), new
MyConsoleLogger())); // singleton

services.Add(new ServiceDescriptor(typeof(ILog),
typeof(MyConsoleLogger), ServiceLifetime.Transient)); // Transient

services.Add(new ServiceDescriptor(typeof(ILog),
typeof(MyConsoleLogger), ServiceLifetime.Scoped)); // Scoped
}
Extension Methods for Registration

ASP.NET Core framework includes extension methods for each types of lifetime;
AddSingleton(), AddTransient() and AddScoped() methods for singleton, transient and
scoped lifetime respectively.

The following example shows the ways of registering types (service) using extension
methods.

Example: Extension Methods


public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<ILog, MyConsoleLogger>();
services.AddSingleton(typeof(ILog), typeof(MyConsoleLogger));

services.AddTransient<ILog, MyConsoleLogger>();
services.AddTransient(typeof(ILog), typeof(MyConsoleLogger));

services.AddScoped<ILog, MyConsoleLogger>();
services.AddScoped(typeof(ILog), typeof(MyConsoleLogger));
}
Constructor Injection

Once we register a service, the IoC container automatically performs constructor injection
if a service type is included as a parameter in a constructor.

For example, we can use ILog service type in any MVC controller. Consider the following
example.

Example: Using Service


public class HomeController : Controller
{
ILog _log;

public HomeController(ILog log)


{
_log = log;
}
public IActionResult Index()
{
_log.info("Executing /home/index");

return View();
}
}

In the above example, an IoC container will automatically pass an instance of


MyConsoleLogger to the constructor of HomeController. We don't need to do anything
else. An IoC container will create and dispose an instance of ILog based on the registered
lifetime.

Action Method Injection

Sometimes we may only need dependency service type in a single action method. For this,
use [FromServices] attribute with the service type parameter in the method.

Example: Action Method Injection


using Microsoft.AspNetCore.Mvc;

public class HomeController : Controller


{
public HomeController()
{
}

public IActionResult Index([FromServices] ILog log)


{
log.info("Index method executing");

return View();
}
}
Property Injection

Built-in IoC container does not support property injection. You will have to use third party
IoC container.

Get Services Manually

It is not required to include dependency services in the constructor. We can access


dependent services configured with built-in IoC container manually using
RequestServices property of HttpContext as shown below.

Example: Get Service Instance Manually


public class HomeController : Controller
{
public HomeController()
{
}
public IActionResult Index()
{
var services = this.HttpContext.RequestServices;
var log = (ILog)services.GetService(typeof(ILog));

log.info("Index method executing");

return View();
}
}

It is recommended to use constructor injection instead of getting it using


RequestServices.

Learn about middleware in the next chapter.

ASP.NET Core - Middleware


ASP.NET Core introduced a new concept called Middleware. A middleware is nothing but
a component (class) which is executed on every request in ASP.NET Core application. In
the classic ASP.NET, HttpHandlers and HttpModules were part of request pipeline.
Middleware is similar to HttpHandlers and HttpModules where both needs to be configured
and executed in each request.

Typically, there will be multiple middleware in ASP.NET Core web application. It can be
either framework provided middleware, added via NuGet or your own custom middleware.
We can set the order of middleware execution in the request pipeline. Each middleware
adds or modifies http request and optionally passes control to the next middleware
component. The following figure illustrates the execution of middleware components.

ASP.NET Core Middleware

Middlewares build the request pipeline. The following figure illustrates the ASP.NET Core
request processing.

ASP.NET Core Request Processing

Configure Middleware

We can configure middleware in the Configure method of the Startup class using
IApplicationBuilder instance. The following example adds a single middleware using
Run method which returns a string "Hello World!" on each request.

public class Startup


{
public Startup()
{
}
public void Configure(IApplicationBuilder app, IHostingEnvironment
env, ILoggerFactory loggerFactory)
{
//configure middleware using IApplicationBuilder here..

app.Run(async (context) =>


{
await context.Response.WriteAsync("Hello World!");

});

// other code removed for clarity..


}
}

In the above example, Run() is an extension method on IApplicationBuilder instance


which adds a terminal middleware to the application's request pipeline. The above
configured middleware returns a response with a string "Hello World!" for each request.

Understand Run Method

We used Run extension method to add middleware. The following is the signature of the
Run method:

Method Signature:
public static void Run(this IApplicationBuilder app, RequestDelegate
handler)

The Run method is an extension method on IApplicationBuilder and accepts a


parameter of RequestDelegate. The RequestDelegate is a delegate method which
handles the request. The following is a RequestDelegate signature.

Method Signature:
public delegate Task RequestDelegate(HttpContext context);

As you can see above, the Run method accepts a method as a parameter whose signature
should match with RequestDelegate. Therefore, the method should accept the
HttpContext parameter and return Task. So, you can either specify a lambda expression or
specify a function in the Run method. The lambda expression specified in the Run method
above is similar to the one in the example shown below.

public class Startup


{
public Startup()
{
}

public void Configure(IApplicationBuilder app, IHostingEnvironment


env)
{
app.Run(MyMiddleware);
}

private Task MyMiddleware(HttpContext context)


{
return context.Response.WriteAsync("Hello World! ");
}
}

The above MyMiddleware function is not asynchronous and so will block the thread till the
time it completes the execution. So, make it asynchronous by using async and await to
improve performance and scalability.

// other code removed for clarity

public void Configure(IApplicationBuilder app, IHostingEnvironment env)


{
app.Run(MyMiddleware);
}

private async Task MyMiddleware(HttpContext context)


{
await context.Response.WriteAsync("Hello World! ");
}

Thus, the above code snippet is same as the one below.

app.Run(async context => await context.Response.WriteAsync("Hello


World!") );

//or

app.Run(async (context) =>


{
await context.Response.WriteAsync("Hello World!");
});

So, in this way, we can configure middleware using Run method.

Configure Multiple Middleware

Mostly there will be multiple middleware components in ASP.NET Core application which
will be executed sequentially. The Run method adds a terminal middleware so it cannot call
next middleware as it would be the last middleware in a sequence. The following will
always execute the first Run method and will never reach the second Run method.

public void Configure(IApplicationBuilder app, IHostingEnvironment env)


{
app.Run(async (context) =>
{
await context.Response.WriteAsync("Hello World From 1st
Middleware");
});

// the following will never be executed


app.Run(async (context) =>
{
await context.Response.WriteAsync("Hello World From 2nd
Middleware");
});
}

To configure multiple middleware, use Use() extension method. It is similar to Run()


method except that it includes next parameter to invoke next middleware in the sequence.
Consider the following example.

Example: Use()
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.Use(async (context, next) =>
{
await context.Response.WriteAsync("Hello World From 1st
Middleware!");

await next();
});

app.Run(async (context) =>


{
await context.Response.WriteAsync("Hello World From 2nd
Middleware");
});
}

The above example will display Hello World From 1st Middleware!Hello World
From 2nd Middleware! in the browser.

Thus, we can use Use() method to configure multiple middlewares in the order we like.

Add Built-in Middleware Via NuGet

ASP.NET Core is a modular framework. We can add server side features we need in our
application by installing different plug-ins via NuGet. There are many middleware plug-ins
available which can be used in our application.

The followings are some built-in middleware:

Middleware Description

Authentication Adds authentication support.

CORS Configures Cross-Origin Resource Sharing.


Middleware Description

Routing Adds routing capabilities for MVC or web form

Session Adds support for user session.

StaticFiles Adds support for serving static files and directory browsing.

Diagnostics Adds support for reporting and handling exceptions and errors.

Let's see how to use Diagnostics middleware.

Diagnostics Middleware

Let's install and use Diagnostics middleware. Diagnostics middleware is used for reporting
and handling exceptions and errors in ASP.NET Core, and diagnosing Entity Framework
Core migrations errors.

Open project.json and add Microsoft.AspNetCore.Diagnostics dependency if it is not


added. Wait for some time till Visual Studio restores the packages.

This package includes following middleware and extension methods for it.

Middleware Extension Method Description

Captures synchronous and


asynchronous exceptions
DeveloperExceptionPageMiddleware UseDeveloperExceptionPage() from the pipeline and
generates HTML error
responses.

Catch exceptions, log them


ExceptionHandlerMiddleware UseExceptionHandler() and re-execute in an
alternate pipeline.

Check for responses with


StatusCodePagesMiddleware UseStatusCodePages() status codes between 400
and 599.

Display Welcome page for


WelcomePageMiddleware UseWelcomePage()
the root path.

We can call respective Use* extension methods to use the above middleware in the
configure method of Startup class.

Let's add welcomePage middleware which will display welcome page for the root path.
Example: Add Diagnostics Middleware
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseWelcomePage();
//other code removed for clarity
}

The above example will display the following welcome page for each request.

This way we can use different Use* extension methods to include different middleware.

Next, learn how to implement logging functionality in the ASP.NET Core application.

ASP.NET Core - Logging


ASP.NET Core framework provides built-in supports for logging. However, we can also
use third party logging provider easily in ASP.NET Core application.

Before we see how to implement logging in ASP.NET Core application, let's understand
the important logging interfaces and classes available in ASP.NET Core framework. The
following are built-in interfaces and classes available for logging under
Microsoft.Extensions.Logging namespace .

1. ILoggingFactory
2. ILoggingProvider
3. ILogger
4. LoggingFactory

The following figure shows the relationship between logging classes.

Logging Infrastructure

Let's have an overview on each of them.

ILoggerFactory

The ILoggerFactory is the factory interface for creating an appropriate ILogger type
instance and also to add ILoggerProvider instance.

ILoggerFactory:
public interface ILoggerFactory : IDisposable
{
ILogger CreateLogger(string categoryName);
void AddProvider(ILoggerProvider provider);
}

ASP.NET Core framework includes built-in LoggerFactory class that implements


ILoggerFactory interface. We can use it to add an instance of type ILoggerProvider and
to retrieve ILogger instance for the specified category.

ASP.NET Core runtime creates an instance of LoggerFactory class and registers it for
ILoggerFactory with the built-in IoC container when the application starts. Thus, we can
use ILoggerFactory interface anywhere in your application. The IoC container will pass
an instance of LoggerFactory to your application wherever it encounters ILoggerFactory
type.

ILoggerProvider

The ILoggerProvider manages and creates appropriate logger specified by logging


category.

ILoggerProvider:
public interface ILoggerProvider : IDisposable
{
ILogger CreateLogger(string categoryName);
}

We can create our own logging provider by implementing ILoggerProvider interface.

ILogger

ILogger interface includes methods for logging to the underlying storage.

ILogger:
public interface ILogger
{
void Log<TState>(LogLevel logLevel, EventId eventId, TState state,
Exception exception, Func<TState, Exception, string> formatter);
bool IsEnabled(LogLevel logLevel);
IDisposable BeginScope<TState>(TState state);
}
Built-in Logging Providers

There are different logging providers available as NuGet packages which we can use to
send log output to the different medium such as console, debug window, EventSource etc.
ASP.NET Core ships with the following providers:

1. Console
2. Debug
3. EventSource
4. EventLog
5. TraceSource
6. Azure App Service

Let's have an overview of Console logger.

Console Logger

The Microsoft.Extensions.Logging.Console package includes logging classes which


sends log output to the console. The following are important classes for console logging.

1. ConsoleLoggingProvider
2. ConsoleLogger
3. ConsoleLoggerExtension
4. ConsoleLoggerSettings
5. ConsoleLoggerScope

The following figure illustrates the console logger classes.


Logging Infrastructure

As you can see in the above figure, the ConsoleLogger implements ILogger and
ConsoleLoggingProvider implements ILoggingProvider. The
ConsoleLoggerExtensions class includes extension method AddConsole() which adds
console logger to LoggerFactory.

Now, let's use console logger to display log output to the console in both ASP.NET Core
1.x and 2.x application.

Step 1 - Install NuGet Package

ASP.NET Core 1.x:

Include Microsoft.Extensions.Logging.Console dependencies in project.json if it is


not added already.

"dependencies": {
"Microsoft.NETCore.App": {
"version": "1.0.1",
"type": "platform"
},
"Microsoft.AspNetCore.Diagnostics": "1.0.0",
"Microsoft.AspNetCore.Server.IISIntegration": "1.0.0",
"Microsoft.AspNetCore.Server.Kestrel": "1.0.1",
"Microsoft.Extensions.Logging.Console": "1.0.0"
}

Visual Studio will restore the packages automatically as soon as project.json is saved.

ASP.NET Core 2.x:


By default, Microsoft.Extensions.Logging.Console is included in the meta package
Microsoft.AspNetCore.All, so we don't need to install it separately in ASP.NET Core
2.x application.

Step 2 - Use Provider

ASP.NET Core 1.x:

Now, in order to use console logger, we first need to configure it. First, we need to add
ConsoleLoggerProvider to the providers list using LoggerFactory. As you can see in the
LoggerFactory class above, it provides AddProvider() method which adds our custom
ILoggerProvider type instance to the list. The
Microsoft.Extensions.Logging.Console package includes all necessary classes. So, we
can add ConsoleLoggerProvider instance as shown below.

Example: Add ConsoleLoggerProvider


public class Startup
{
public Startup()
{
}

public void Configure(IApplicationBuilder app, IHostingEnvironment


env, ILoggerFactory loggerFactory)
{
loggerFactory.AddProvider(new ConsoleLoggerProvider((category,
logLevel) => logLevel >= LogLevel.Information, false));

//code removed for clarity


}
}

As you can see above, we add an instance of ConsoleLoggerProvider to the factory.


Now, we can start logging. The console will display all the logs whose LogLevel is
Information or above.

We can also use AddConsole() extension method instead of configuring console logger
manually as shown below.

Example: Add Console Logger


public class Startup
{
public Startup()
{
}

public void Configure(IApplicationBuilder app, IHostingEnvironment


env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole();

//code removed for clarity


}
}

ASP.NET Core 2.x:

The CreateDefaultBuilder() already includes console and debug logging providers. So


there is no need to add it again in the Configure() method in ASP.NET Core 2.x
application.

Step 3 - Create Logs

This step is applicable for both ASP.NET Core 1.x and 2.x application.

Now, we can create logs and see it on the console by getting an instance of ILogger using
LoggerFactory and start logging as shown below.

Example: Add Console Logger


public class Startup
{
public Startup()
{
}

public void Configure(IApplicationBuilder app, IHostingEnvironment


env, ILoggerFactory loggerFactory)
{

loggerFactory.AddConsole();

//start logging to the console


var logger = loggerFactory.CreateLogger<ConsoleLogger>();
logger.LogInformation("Executing Configure()");

//code removed for clarity


}
}

We can also use ILogger anywhere in our application. IoC container will inject
ConsoleLogger instance wherever it sees ILogger. For example, we can use ILogger in
the MVC-controller as shown below.

Example: Logging in MVC Controller


public class HomeController : Controller
{
ILogger _logger;

public HomeController(ILogger<HomeController> logger)


{
_logger = logger;
}
public IActionResult Index()
{
_logger.LogInformation("Executing Home/Index");

return View();
}
}

You will see the above log on the console when you browse
http://localhost:5000/home/index.

We can use any of the above mentioned built-in logging providers by following the same
process.

Log Levels

Log levels indicate the importance or severity of the log messages. Built-in log providers
include extension methods to indicate log levels.

ASP.NET Core defines following log levels.

Extension
Log Level Severity Description
Method

Trace 0 LogTrace() Log messages only for tracing purpose for the developers

Debug 1 LogDebug() Log messages for short-term debugging purpose

Information 2 LogInformation() Log messages for the flow of the application.

Log messages for abnormal or unexpected events in the


Warning 3 LogWarning()
application flow.

Error 4 LogError() Log error messages.

Log messages for the failures that require immediate


Critical 5 LogCritical()
attention

We can use extension method to indicate level of the log messages as shown below.

Example: Log Level


public class HomeController : Controller
{
ILogger _logger;

public HomeController(ILogger<HomeController> logger)


{
_logger = logger;
}

public IActionResult Index(string id)


{
_logger.LogInformation("Home/Index Executing..");

if (String. IsNullOrEmpty(id))
{
_logger.LogWarning(LoggingEvents.GET_ITEM_NOTFOUND,
"Index({ID}) NOT FOUND", id);

return NotFound();
}

return View();
}
}
Third-party Logging Providers

The following are some logging providers that work with ASP.NET Core:

Logging Provider Description

elmah.io Provider for the Elmah.Io service

Loggr Provider for the Logger service

NLog Provider for the NLog library

Serilog Provider for the Serilog library

Learn about ASP.NET Core environment variables in the next chapter.

ASP.NET Core - Environment Variable


Typically, in professional application development, there are multiple phases where an
application is tested before publishing it to the real users. These phases by convention are
development, staging, and production. We as developers might like to control the behavior
of an application based on the phases the application is in. Environment variable indicates
the runtime environment in which an application is currently running.

ASP.NET Core uses an environment variable called ASPNETCORE_ENVIRONMENT to indicate


the runtime environment. The value of this variable can be anything as per your need but
typically it can be Development, Staging, or Production. The value is case insensitive in
Windows and Mac OS but it is case sensitive on Linux.
In Visual Studio, we can set ASPNETCORE_ENVIRONMENT in the debug tab of project
properties. Open project properties by right clicking on the project in the solution explorer
and select Properties.

Ope
n Project Properties

This will open properties page. Click on Debug tab and you will see Environment Variables
as shown below.
Environment Variable

You may change the value as per your need. This value will be saved in the
launchSettings.json file as shown below.
launchsettings.json

You may also change the environment variable directly in launchSettings.json.

Access Environment Variable at Runtime

We can get the value of an environment variable in our code to execute some additional
code based on its value. The IHostingEnvironment service includes EnvironmentName
property which contains the value of ASPNETCORE_ENVIRONMENT variable. ASP.NET Core
also includes extension methods to check the environment such as IsDevelopment(),
IsStating(), IsEnvironment() and IsProduction().

The IHostingEnvironment service is provided by ASP.NET hosting layer and can be used
anywhere in your application via Dependency Injection. The following example shows how
we can check the environment variable in the Configure method of Startup class.
Example: Access Environment Variable
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsEnvironment("Development"))
{
// code to be executed in development environment

if (env.IsDevelopment())
{
// code to be executed in development environment

if (env.IsStaging())
{
// code to be executed in staging environment

if (env.IsProduction())
{
// code to be executed in production environment

}
}

Learn all about exception handling in ASP.NET Core application and how this environment
variable can be used there, in the next chapter.

ASP.NET Core - Exception Handling


Exception handling is one of the most important features of any application. Fortunately,
ASP.NET Core includes a middleware that makes exception handling easy. In this chapter,
we will learn about exception handling in ASP.NET Core application.

By default, ASP.NET Core returns a simple status code for any exception that occurs in an
application. Consider the following example of Configure method which throws an error.

public class Startup


{
public void Configure(IApplicationBuilder app, IHostingEnvironment
env)
{
app.Run(context => { throw new Exception("error"); });
}
}

The above code will display the following result.


Install Microsoft.AspNetCore.Diagnostics Package

To handle exceptions and display user friendly messages, we need to install


Microsoft.AspNetCore.Diagnostics NuGet package and add middleware in the
Configure() method. If you are using Visual Studio templates to create ASP.NET Core
application then this package might be already installed. If not then you can add
Microsoft.AspNetCore.Diagnostics package via NuGet manager.

The Microsoft.AspNetCore.Diagnostics package includes following extension methods


to handle exceptions in different scenario:

1. UseDeveloperExceptionPage
2. UseExceptionHandler

UseDeveloperExceptionPage

The UseDeveloperExceptionPage extension method adds middleware into the request


pipeline which displays developer friendly exception detail page. This helps developers in
tracing errors that occur during development phase.

As this middleware displays sensitive information, it is advisable to add it only in


development environment.

public class Startup


{
public void Configure(IApplicationBuilder app, IHostingEnvironment
env)
{
if (env.IsDevelopment() || env.IsStaging())
{
app.UseDeveloperExceptionPage();
}

app.Run(context => { throw new Exception("error"); });


}
}

The above code will display the following result.

Exception Handling

As you can see above, the developer exception page includes 4 tabs: Stack, Query, Cookies,
and Headers. Stack tab displays information of stack trace, which indicates where exactly
an error occurred. Query tab displays information about query string. Cookies tab displays
information about cookies set by the request and Headers tab displays information about
headers.

UseExceptionHandler

In MVC Core application, we might want some other controller to handle all exceptions
and display custom user friendly error messages. The UseExceptionHandler extension
method allows us to configure custom error handling route. This is useful when an
application runs under production environment.
Example: Exception Handler in MVC
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{

if (env.IsDevelopment() || env.IsStaging())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
}

//code removed for clarity


}

In the above example, the UseExceptionHandler("/Home/Error") sets the error handler


path. If an error occurred in the MVC application then it will redirect the request to
/home/error, which will execute the Error action method of HomeController.

Create a simple Error action method in HomeController class as shown below.

HomeController:
public class HomeController : Controller
{
public HomeController()
{
}

public IActionResult Error()


{
return View();
}

// other code removed for the clarity

The following is the content of Error.cshtml.

Error.cshtml
@{
ViewData["Title"] = "Error";
}

<h1 class="text-danger">Error.</h1>
<h2 class="text-danger">An error occurred while processing your
request.</h2>

<h3>Development Mode</h3>
<p>
Swapping to <strong>Development</strong> environment will display
more detailed information about the error that occurred.
</p>
<p>
<strong>Development environment should not be enabled in deployed
applications</strong>, as it can result in sensitive information from
exceptions being displayed to end users. For local debugging, development
environment can be enabled by setting the
<strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to
<strong>Development</strong>, and restarting the application.
</p>

Now, when an error occurs, it displays the page shown below.

Exception Handling

Thus, we can configure middleware to handle exceptions in ASP.NET Core application.

Note:

Visual Studio automatically creates Error.cshtml under Home folder when you create ASP.NET
Core project with MVC template.

ASP.NET Core - Serving Static Files


Here, we will learn how to serve static files such as html, JavaScript, CSS, or image files on
HTTP request without any server-side processing.
ASP.NET Core application cannot serve static files by default. We must include
Microsoft.AspNetCore.StaticFiles middleware in the request pipeline.

Install StaticFiles Middleware

The Microsoft.AspNetCore.StaticFiles middleware package is already included in the


meta package Microsoft.AspNetCore.All, so we don't need to install it separately in
ASP.NET Core 2.x application.

To install StaticFiles middleware in ASP.NET Core 1.x application, open NuGet package
manager by right clicking on project in the solution explorer and select Manage NuGet
Packages... Search for staticfiles in the search box in the browse tab. This will display
Microsoft.AspNetCore.StaticFiles middleware as shown below.

Install StaticFiles Middleware

Click on the Install button on the right pane to install it. Once installed, the
Microsoft.AspNetCore.StaticFiles is automatically included in the dependencies
section of the project.json.
StaticFiles
Dependency in project.json

Using StaticFiles Middleware

By default, all the static files of a web application should be located in the web root folder
wwwroot. To understand this, let's create a simple default.html in the wwwroot folder with
the following content.

Default.html
Now, to serve the above Default.html static file, we must add StaticFiles middleware in the
Configure() method of Startup file as shown below.

public class Startup


{
public Startup()
{
}

public void Configure(IApplicationBuilder app, IHostingEnvironment


env)
{
app.UseStaticFiles();

app.Run(async (context) =>


{
await context.Response.WriteAsync("Hello World");
});
}
}

As you can see above, the app.UseStaticFiles() method adds StaticFiles middleware
into the request pipeline. The UseStaticFiles is an extension method included in the
StaticFiles middleware so that we can easily configure it.

Now, open the browser and send http request http://localhost:<port>/default.html which
will display default.html as a response as shown below.
Serving HTML File

This way we can serve any other file stored in wwwroot folder or sub-folder. For example,
consider the following test.js file in the wwwroot folder.
test.js

Now, we can access this file by sending http://localhost:<port>/test.js request.


Serving JS File

Suppose, you want to serve files from the outside of web root folder (wwwroot). For
example, you include images in the following Images folder as shown below.
Serving Static Files

Now, specify StaticFileOptions parameter in the UseStaticFiles method to serve


images from the Images folder as shown below.

public void Configure(IApplicationBuilder app, IHostingEnvironment env)


{
app.UseStaticFiles(); // For the wwwroot folder

app.UseStaticFiles(new StaticFileOptions()
{
FileProvider = new PhysicalFileProvider(
Path.Combine(Directory.GetCurrentDirectory(),
@"Images")),
RequestPath = new PathString("/app-images")
});
}

As you can see, we used FileProvider option to specify Images folder from which static
files will be served. The RequestPath option specifies the relative path in the URL which
maps to the static folder.

Now, a request to http://localhost/app-images/MyImage.png will serve the MyImage.png


file.
Set Default File

As we have seen above, default.html or test.js was served on the specific request for it.
However, what if we want to serve default html file on the root request?

Currently, when you send http://localhost:<port> request, it will be handled by run method
and display the following result.

To serve default.html on the root request http://localhost:<port>, call UseDefaultFiles()


method before UseStaticFiles() in the Configure method as shown below.

public void Configure(IApplicationBuilder app, IHostingEnvironment env)


{
app.UseDefaultFiles();
app.UseStaticFiles();

app.Run(async (context) =>


{
await context.Response.WriteAsync("Hello World");
});
}

The UseDefaultFiles configures the DefaultFiles middleware which is a part of


StaticFiles middleware. This will automatically serve html file named default.html,
default.htm, index.html or index.htm on the http request http://localhost:<port>. The above
example will display default.html file on http://localhost:<port> as shown below.
Serving Static Files

Note:

Order of middleware is very important. app.UseDefaultFiles() should be added before


app.UseStaticFiles() in the request pipeline.

FileServer

The FileServer middleware combines the functionalities of UseDefaultFiles and


UseStaticFiles middlware. So, instead of using both the middlware, just use UseFileServer
in the Configure method.

UseFileServer = UseDefaultFiles + UseStaticFiles

Example: UseFileServer
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseFileServer();

app.Run(async (context) =>


{
await context.Response.WriteAsync("Hello World");
});
}

Thus, we can serve static files on http requests.


.NET Core Application Types
We can create two types of applications in .NET Core.

1. Portable Application
2. Self-contained application

Portable Application

Portable applications are applications which expect .NET Core runtime on the deployment
machines. It cannot be run on a machine which does not have .NET Core runtime installed.

.NET
Core Portable Application

Self-contained Application

Self-contained applications are applications which include .NET Core runtime when we
publish it. It can run on a machine which does not have .NET Core runtime installed.

.NET Core Self-contained Application

Configure Application Type

We can configure ASP.NET Core application as portable or self-contained application


using type property of Microsoft.NETCore.App dependency in project.json. The
"type":"platform" indicates that this application expects .NET Core on the machine. This
makes it a portable application.
For the self-contained application, remove type-platform from the dependency. This makes
it a self-contained application which means .NET Core will be included when you build
and publish an application.

Code Sharing in .NET Core


With .NET Core, we can currently develop applications with three different .NET
frameworks for different platforms. The traditional or standard .NET Framework is for
Windows, Mono framework for iOS, OSx and Android and .NET Core for Windows, Mac
and Linux.

.NET Frameworks

These frameworks use different framework class libraries. It means code written in one
framework cannot be used with other frameworks. For example, a console application
developed with .NET Framework cannot run on .NET Core or vice-versa. Thus, code-
sharing is not allowed.

It would be nice to write code once and share with other applications with different .NET
frameworks. Isn't it?

Code Sharing

To solve this problem of code sharing, we can use the following three approaches:

1. Create Portable Class Library


2. Target Multiple Frameworks ASP.NET Core app
3. Target .NET Standard

Creating portable class library to share code with other .NET frameworks is not a new thing
in .NET. Learn about it here.

Learn about how to target multiple frameworks in ASP.NET Core application for code
sharing in the next chapter.

Target Multiple Frameworks in .NET Core


2.x App
As mentioned in the previous chapter, creating a .NET Core application which targets
multiple frameworks is one of the approaches for code sharing.

We can create .NET Core application and configure multiple target frameworks for it so
that it can run with all the configured target frameworks. To demonstrate this, let's
create .NET Core 2.0 console application which can run with .NET Core as well as
traditional .NET framework in Visual Studio 2017.

The first step is to create a new project in Visual Studio 2017 by clicking on File -> New
Project.. This will open New Project popup as shown below.
Create .NET Core 2.x Console Application

In the New Project popup, select Console Application (.NET Core), provide the appropriate
name and click OK. This will create new console project as shown below.
Console Application

Now, we can configure multiple frameworks by editing .csproj file. So, right click on the
project in solution explorer and select Edit <project-name>.csproj as shown below.
Edit .csproj

The .csproj will look like below.

.csproj:
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>

</Project>

As you can see above, <TargetFramework> is netcoreapp2.0. It means currently this


application can run on .NET Core 2.0 framework. We can include multiple monikers for
multiple frameworks here, in order to target multiple frameworks.
To target multiple frameworks, change <TargetFramework> to plural
<TargetFrameworks> and include monikers for different frameworks you want to target
separated by ;.

Here, we will support two more frameworks .NET Framework 4.0 & 4.6. So include net40
and net46 monikers respectively as shown below. Look at TFMs for all supported target
frameworks here.

.csproj:
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>netcoreapp2.0;net45;net46</TargetFrameworks>
</PropertyGroup>

</Project>

As soon as you save the above .csproj file, Visual Studio will load and include the
references for .NET 4.5 and .NET 4.6 into Dependencies section as shown below.
Multi Frameworks Dependencies

Now, open program.cs and let's add framework specific code using preprocessor conditions
#if and #elif as shown below.

Program.cs
using System;

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

#if NET40
Console.WriteLine("Target framework: .NET Framework 4.0");
#elif NET45
Console.WriteLine("Target framework: .NET Framework 4.5");
#else
Console.WriteLine("Target framework: .NET Core 2.0");
#endif
Console.ReadKey();
}
}
}

As you can see above, to write framework specific code, use symbol with condition
for .NET framework moniker and replace the dot with an underscore and change lowercase
letters to uppercase.

To run the application for specific framework, click on the run dropdown and select a
targeted framework as shown below.

Multi
Frameworks Dependencies

Now, run the application and you will see the following output.
Framework Specific References

Sometimes you may need to include specific references for a particular framework. For
example, .NET Core 2.0 meta package already includes System.Net reference which is not
included in .NET 4.0 and 4.5. So, we need to include it in .csproj file using conditional
reference as shown below.

.csproj:
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>netcoreapp2.0;net45;net46</TargetFrameworks>
</PropertyGroup>

<ItemGroup Condition=" '$(TargetFramework)' == 'net40' ">


<Reference Include="System.Net" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'net45' ">
<Reference Include="System.Net" />
</ItemGroup>

</Project>

Now, System.Net reference will be added to .NET 4.0 & 4.5 and System.Net specific code
will be executed for all frameworks.
ASP.NET MVC Tutorials
ASP.NET MVC tutorials cover all the features of ASP.NET MVC. You will learn basic to
advance level features of ASP.Net MVC. Basic tutorials have used MVC 5, but it is
applicable to all the previous versions and upcoming versions of MVC as well.

These tutorials are designed for beginners and professionals who want to learn ASP.NET
MVC 5 step by step.

Prerequisites

Basic knowledge of .Net Framework3.5/4.5, C#, Visual Studio is required.

Click Next to get started.

MVC Architecture
In this section, you will get an overview of MVC architecture. The MVC architectural
pattern has existed for a long time in software engineering. All most all the languages use
MVC with slight variation, but conceptually it remains the same.

Let's understand the MVC architecture in ASP.NET.

MVC stands for Model, View and Controller. MVC separates application into three
components - Model, View and Controller.

Model: Model represents shape of the data and business logic. It maintains the data of the
application. Model objects retrieve and store model state in a database.

Model is a data and business logic.

View: View is a user interface. View display data using model to the user and also enables
them to modify the data.

View is a User Interface.

Controller: Controller handles the user request. Typically, user interact with View, which
in-tern raises appropriate URL request, this request will be handled by a controller. The
controller renders the appropriate view with the model data as a response.

Controller is a request handler.

The following figure illustrates the interaction between Model, View and Controller.
MVC Architecture

The following figure illustrates the flow of the user's request in ASP.NET MVC.

Reque
st/Response in MVC Architecture

As per the above figure, when the user enters a URL in the browser, it goes to the server
and calls appropriate controller. Then, the Controller uses the appropriate View and Model
and creates the response and sends it back to the user. We will see the details of the
interaction in the next few sections.

Visit MSDN to learn MVC in detail.

Points to Remember :

1. MVC stands for Model, View and Controller.


2. Model is responsible for maintaining application data and business logic.
3. View is a user interface of the application, which displays the data.
4. Controller handles user's requests and renders appropriate View with Model data.
ASP.NET MVC Version History
Microsoft had introduced ASP.NET MVC in .Net 3.5, since then lots of new features have
been added.

The following table list brief history of ASP.NET MVC.

Visual .Net Release


MVC Version Features
Studio Version date
 MVC architecture with webform
engine
 Routing
13-Mar-
MVC 1.0 VS2008 .Net 3.5  HTML Helpers
2009
 Ajax Helpers
 Auto binding

 Area
 Asynchronous controller
 Html helper methods with
lambda expression
.Net 10-Mar-
MVC 2.0 VS 2008,  DataAnnotations attributes
3.5/4.0 2010
 Client side validation
 Custom template
 Scaffolding

 Unobtrusive javascript
validation
 Razor view engine
13-Jan-  Global filters
MVC 3.0 VS 2010 .Net 4.0
2011  Remote validation
 Dependency resolver for IoC
 ViewBag

 Mobile project template


VS 2010  Bundling and minification
.NET 15-Aug-
MVC 4.0 SP1,  Support for Windows Azure
4.0/4.5 2012
VS 2012 SDK

MVC 5.0 VS 2013 .NET 4.5 17-oct-  Authentication filters


Visual .Net Release
MVC Version Features
Studio Version date
 Bootstrap support
 New scaffolding items
2013
 ASP.Net Identity

 Attribute based routing


MVC 5.2 - 28-Aug-  bug fixes and minor features
VS 2013 .NET 4.5
Current 2014 upate

Let's create first simple MVC application in the next section.

Create First ASP.NET MVC Application


In this section, we will create a new MVC 5 application with Visual Studio 2013 for Web
and understand the basic building blocks of a MVC Application.

First of all, setup a development environment to develop an ASP.NET MVC 5 application.

Setup Development Environment

You can develop ASP.NET MVC application with appropriate version of Visual Studio and
.NET framework, as you have seen in the previous section of version history.

Here, we will use MVC v5.2, Visual Studio 2017 Community edition and .NET framework
4.6 to create our first MVC application.

Download the latest version of Visual Studio from


https://visualstudio.microsoft.com/downloads.

Create first simple MVC application

First of all, open a Visual Studio 2017 Community edition and select File menu -> New ->
Project as shown below.
Create a New Project in Visual Studio

From the New Project dialog as shown below, expand Visual C# node and select Web in
the left pane, and then select ASP.NET Web Application (.NET Framework) in the
middle pane. Enter the name of your project MyMVCApplication. (You can give any
appropriate name for your application). Also, you can change the location of the MVC
application by clicking on Browse.. button. Finally, click OK.
Create MVC Project in Visual Studio

From the New ASP.NET Web Application dialog, select MVC (if not selected already) as
shown below.
Create MVC Application

You can also change the authentication by clicking on Change Authentication button.
You can select appropriate authentication mode for your application as shown below.
Select Authenctication Type

Here, we are keeping the default authentication for our application which is No
Authentication. Click OK to continue.

Wait for some time till Visual Studio creates a simple MVC project using default template
as shown below.
First MVC Application

Now, press F5 to run the project in debug mode or Ctrl + F5 to run the project without
debugging. It will open home page in the browser as shown below.
Run MVC Application

MVC 5 project includes JavaScript and CSS files of bootstrap 3.0 by default. So you can
create responsive web pages. This responsive UI will change its look and feel based on the
screen size of the different devices. For example, top menu bar will be changed in the
mobile devices as shown below.
Responsive MVC Application
So in this way, you can create your first MVC 5 application using Visual Studio 2013 for
Web.

Learn about ASP.NET MVC folder structure in the next section.

ASP.NET MVC Folder Structure


We have created our first MVC 5 application in the previous section. Visual Studio creates
the following folder structure for MVC application by default.

MVC Folder Structure

Let's see significance of each folder.

App_Data

App_Data folder can contain application data files like LocalDB, .mdf files, xml files and
other data related files. IIS will never serve files from App_Data folder.

App_Start
App_Start folder can contain class files which will be executed when the application starts.
Typically, these would be config files like AuthConfig.cs, BundleConfig.cs,
FilterConfig.cs, RouteConfig.cs etc. MVC 5 includes BundleConfig.cs, FilterConfig.cs and
RouteConfig.cs by default. We will see significance of these files later.

App_Start Folder

Content

Content folder contains static files like css files, images and icons files. MVC 5 application
includes bootstrap.css, bootstrap.min.css and Site.css by default.
Content Folder

Controllers

Controllers folder contains class files for the controllers. Controllers handles users' request
and returns a response. MVC requires the name of all controller files to end with
"Controller". You will learn about the controller in the next section.

Controller Folder
fonts

Fonts folder contains custom font files for your application.

Fonts folder

Models

Models folder contains model class files. Typically model class includes public properties,
which will be used by application to hold and manipulate application data.

Scripts

Scripts folder contains JavaScript or VBScript files for the application. MVC 5 includes
javascript files for bootstrap, jquery 1.10 and modernizer by default.
Scripts Folder

Views

Views folder contains html files for the application. Typically view file is a .cshtml file
where you write html and C# or VB.NET code.

Views folder includes separate folder for each controllers. For example, all the .cshtml
files, which will be rendered by HomeController will be in View > Home folder.

Shared folder under View folder contains all the views which will be shared among
different controllers e.g. layout files.
View Folder

Additionally, MVC project also includes following configuration files:

Global.asax

Global.asax allows you to write code that runs in response to application level events, such
as Application_BeginRequest, application_start, application_error, session_start,
session_end etc.

Packages.config

Packages.config file is managed by NuGet to keep track of what packages and versions you
have installed in the application.

Web.config
Web.config file contains application level configurations.

Learn how MVC framework handles request using routing in the next section.

Routing in MVC
In the ASP.NET Web Forms application, every URL must match with a specific .aspx file.
For example, a URL http://domain/studentsinfo.aspx must match with the file
studentsinfo.aspx that contains code and markup for rendering a response to the browser.

Routing is not specific to MVC framework. It can be used with ASP.NET Webform
application or MVC application.

ASP.NET introduced Routing to eliminate needs of mapping each URL with a physical
file. Routing enable us to define URL pattern that maps to the request handler. This request
handler can be a file or class. In ASP.NET Webform application, request handler is .aspx
file and in MVC, it is Controller class and Action method. For example,
http://domain/students can be mapped to http://domain/studentsinfo.aspx in ASP.NET
Webforms and the same URL can be mapped to Student Controller and Index action
method in MVC.

Route

Route defines the URL pattern and handler information. All the configured routes of an
application stored in RouteTable and will be used by Routing engine to determine
appropriate handler class or file for an incoming request.

The following figure illustrates the Routing process.


Routing in
MVC

Configure a Route

Every MVC application must configure (register) at least one route, which is configured by
MVC framework by default. You can register a route in RouteConfig class, which is in
RouteConfig.cs under App_Start folder. The following figure illustrates how to configure
a Route in the RouteConfig class .

Configure Route in MVC


As you can see in the above figure, the route is configured using the MapRoute() extension
method of RouteCollection, where name is "Default", url pattern is
"{controller}/{action}/{id}" and defaults parameter for controller, action method and id
parameter. Defaults specifies which controller, action method or value of id parameter
should be used if they do not exist in the incoming request URL.

The same way, you can configure other routes using MapRoute method of RouteCollection.
This RouteCollection is actually a property of RouteTable class.

URL Pattern

The URL pattern is considered only after domain name part in the URL. For example, the
URL pattern "{controller}/{action}/{id}" would look like
localhost:1234/{controller}/{action}/{id}. Anything after "localhost:1234/" would be
considered as controller name. The same way, anything after controller name would be
considered as action name and then value of id parameter.

Routing in MVC

If the URL doesn't contain anything after domain name then the default controller and
action method will handle the request. For example, http://lcoalhost:1234 would be handled
by HomeController and Index method as configured in the defaults parameter.

The following table shows which Controller, Action method and Id parameter would
handle different URLs considering above default route.

URL Controller Action Id

http://localhost/home HomeController Index null

http://localhost/home/index/123 HomeController Index 123

http://localhost/home/about HomeController About null

http://localhost/home/contact HomeController Contact null

http://localhost/student StudentController Index null

http://localhost/student/edit/123 StudentController Edit 123


Multiple Routes

You can also configure a custom route using MapRoute extension method. You need to
provide at least two parameters in MapRoute, route name and url pattern. The Defaults
parameter is optional.

You can register multiple custom routes with different names. Consider the following
example where we register "Student" route.

Example: Custom Routes


public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

routes.MapRoute(
name: "Student",
url: "students/{id}",
defaults: new { controller = "Student", action = "Index"}
);

routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id =
UrlParameter.Optional }
);
}
}

As shown in the above code, URL pattern for the Student route is students/{id}, which
specifies that any URL that starts with domainName/students, must be handled by
StudentController. Notice that we haven't specified {action} in the URL pattern because we
want every URL that starts with student should always use Index action of
StudentController. We have specified default controller and action to handle any URL
request which starts from domainname/students.

MVC framework evaluates each route in sequence. It starts with first configured route and
if incoming url doesn't satisfy the URL pattern of the route then it will evaluate second
route and so on. In the above example, routing engine will evaluate Student route first and
if incoming url doesn't starts with /students then only it will consider second route which is
default route.

The following table shows how different URLs will be mapped to Student route:

URL Controller Action Id

http://localhost/student/123 StudentController Index 123


URL Controller Action Id

http://localhost/student/index/123 StudentController Index 123

http://localhost/student?Id=123 StudentController Index 123

Route Constraints

You can also apply restrictions on the value of parameter by configuring route constraints.
For example, the following route applies a restriction on id parameter that the value of an id
must be numeric.

Example: Route Constraints


routes.MapRoute(
name: "Student",
url: "student/{id}/{name}/{standardId}",
defaults: new { controller = "Student", action = "Index", id =
UrlParameter.Optional, name = UrlParameter.Optional, standardId =
UrlParameter.Optional },
constraints: new { id = @"\d+" }
);

So if you give non-numeric value for id parameter then that request will be handled by
another route or, if there are no matching routes then "The resource could not be found"
error will be thrown.

Register Routes

Now, after configuring all the routes in RouteConfig class, you need to register it in the
Application_Start() event in the Global.asax. So that it includes all your routes into
RouteTable.

Example: Route Registration


public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
RouteConfig.RegisterRoutes(RouteTable.Routes);
}
}

The following figure illustrate Route registration process.


Register Route

Thus, routing plays important role in MVC framework.

Points to Remember :

1. Routing plays important role in MVC framework. Routing maps URL to physical file or class
(controller class in MVC).
2. Route contains URL pattern and handler information. URL pattern starts after domain
name.
3. Routes can be configured in RouteConfig class. Multiple custom routes can also be
configured.
4. Route constraints applies restrictions on the value of parameters.
5. Route must be registered in Application_Start event in Global.ascx.cs file.

Controller
In this section, you will learn about the Controller in ASP.NET MVC.

The Controller in MVC architecture handles any incoming URL request. Controller is a
class, derived from the base class System.Web.Mvc.Controller. Controller class contains
public methods called Action methods. Controller and its action method handles incoming
browser requests, retrieves necessary model data and returns appropriate responses.

In ASP.NET MVC, every controller class name must end with a word "Controller". For
example, controller for home page must be HomeController and controller for student must
be StudentController. Also, every controller class must be located in Controller folder of
MVC folder structure.

Adding a New Controller

Now, let's add a new empty controller in our MVC application in Visual Studio.

MVC will throw "The resource cannot be found" error when you do not append
"Controller" to the controller class name.

In the previous section we learned how to create our first MVC application, which in turn
created a default HomeController. Here, we will create a new StudentController.

In the Visual Studio, right click on the Controller folder -> select Add -> click on
Controller..
Add New Controller

This opens Add Scaffold dialog as shown below.

Note:

Scaffolding is an automatic code generation framework for ASP.NET web applications. Scaffolding
reduces the time taken to develop a controller, view etc. in MVC framework. You can develop a
customized scaffolding template using T4 templates as per your architecture and coding standard.
Adding Controller

Add Scaffold dialog contains different templates to create a new controller. We will learn
about other templates later. For now, select "MVC 5 Controller - Empty" and click Add.
It will open Add Controller dialog as shown below

Adding Controller

In the Add Controller dialog, enter the name of the controller. Remember, controller name
must end with Controller. Let's enter StudentController and click Add.
Adding Controller

This will create StudentController class with Index method in StudentController.cs file
under Controllers folder, as shown below.

Example: Controller
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MVC_BasicTutorials.Controllers
{
public class StudentController : Controller
{
// GET: Student
public ActionResult Index()
{
return View();
}
}
}

As you can see above, the StudentController class is derived from Controller class. Every
controller in MVC must derived from this abstract Controller class. This base Controller
class contains helper methods that can be used for various purposes.

Now, we will return a dummy string from Index action method of above StudentController.
Changing the return type of Index method from ActionResult to string and returning
dummy string is shown below. You will learn about ActionResult in the next section.

Example: Controller
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MVC_BasicTutorials.Controllers
{
public class StudentController : Controller
{
// GET: Student
public string Index()
{
return "This is Index action method of
StudentController";
}
}
}

We have already seen in the routing section that the URL request http://localhost/student or
http://localhost/student/index is handled by the Index() method of StudentController class,
shown above. So let's invoke it from the browser and you will see the following page in the
browser.

Controller

Points to Remember :

1. A Controller handles incomming URL requests. MVC routing sends request to appropriate
controller and action method based on URL and configured Routes.
2. All the public methods in the Controlle class are called Action methods.
3. A Controller class must be derived from System.Web.Mvc.Controller class.
4. A Controller class name must end with "Controller".
5. New controller can be created using different scaffolding templates. You can create
custom scaffolding template also.

Action method
In this section, you will learn about the action method of controller class.

All the public methods of a Controller class are called Action methods. They are like any
other normal methods with the following restrictions:
1. Action method must be public. It cannot be private or protected
2. Action method cannot be overloaded
3. Action method cannot be a static method.

The following is an example of Index action method of StudentController

Action Method

As you can see in the above figure, Index method is a public method and it returns
ActionResult using the View() method. The View() method is defined in the Controller
base class, which returns the appropriate ActionResult.

Default Action Method

Every controller can have default action method as per configured route in RouteConfig
class. By default, Index is a default action method for any controller, as per configured
default root as shown below.

Default Route:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}/{name}",
defaults: new { controller = "Home",
action = "Index",
id = UrlParameter.Optional
});

However, you can change the default action name as per your requirement in RouteConfig
class.

ActionResult

MVC framework includes various result classes, which can be return from an action
methods. There result classes represent different types of responses such as html, file,
string, json, javascript etc. The following table lists all the result classes available in
ASP.NET MVC.
Result Class Description

ViewResult Represents HTML and markup.

EmptyResult Represents No response.

ContentResult Represents string literal.

FileContentResult/ FilePathResult/
Represents the content of a file
FileStreamResult

JavaScriptResult Represent a JavaScript script.

JsonResult Represent JSON that can be used in AJAX

RedirectResult Represents a redirection to a new URL

Represent another action of same or other


RedirectToRouteResult
controller

PartialViewResult Returns HTML from Partial view

HttpUnauthorizedResult Returns HTTP 403 status

The ActionResult class is a base class of all the above result classes, so it can be return type
of action methods which returns any type of result listed above. However, you can specify
appropriate result class as a return type of action method.

The Index() method of StudentController in the above figure uses View() method to return
ViewResult (which is derived from ActionResult). The View() method is defined in base
Controller class. It also contains different methods, which automatically returns particular
type of result as shown in the below table.

Base Controller
Result Class Description
Method

ViewResult Represents HTML and markup. View()

EmptyResult Represents No response.

ContentResult Represents string literal. Content()

FileContentResult,
FilePathResult, Represents the content of a file File()
FileStreamResult

JavaScriptResult Represent a JavaScript script. JavaScript()

JsonResult Represent JSON that can be used in AJAX Json()


Base Controller
Result Class Description
Method

RedirectResult Represents a redirection to a new URL Redirect()

Represent another action of same or other


RedirectToRouteResult RedirectToRoute()
controller

PartialViewResult Returns HTML PartialView()

HttpUnauthorizedResult Returns HTTP 403 status

As you can see in the above table, View method returns ViewResult, Content method
returns string, File method returns content of a file and so on. Use different methods
mentioned in the above table, to return different types of results from an action method.

Action Method Parameters

Every action methods can have input parameters as normal methods. It can be primitive
data type or complex type parameters as shown in the below example.

Example: Action method parameters


[HttpPost]
public ActionResult Edit(Student std)
{
// update student to the database

return RedirectToAction("Index");
}

[HttpDelete]
public ActionResult Delete(int id)
{
// delete student from the database whose id matches with specified
id

return RedirectToAction("Index");
}

Please note that action method paramter can be Nullable Type.

By default, the values for action method parameters are retrieved from the request's data
collection. The data collection includes name/values pairs for form data or query string
values or cookie values. Model binding in ASP.NET MVC automatically maps the URL
query string or form data collection to the action method parameters if both names are
matching. Visit model binding section for more information on it.

Points to Remember :
1. All the public methods in the Controller class are called Action methods.
2. Action method has following restrictions.
    - Action method must be public. It cannot be private or protected.
    - Action method cannot be overloaded.
    - Action method cannot be a static method.
3. ActionResult is a base class of all the result type which returns from Action method.
4. Base Controller class contains methods that returns appropriate result type e.g. View(),
Content(), File(), JavaScript() etc.
5. Action method can include Nullable type parameters.

Action Selectors
Action selector is the attribute that can be applied to the action methods. It helps routing
engine to select the correct action method to handle a particular request. MVC 5 includes
the following action selector attributes:

1. ActionName
2. NonAction
3. ActionVerbs

ActionName

ActionName attribute allows us to specify a different action name than the method name.
Consider the following example.

Example: ActionName
public class StudentController : Controller
{
public StudentController()
{

[ActionName("find")]
public ActionResult GetById(int id)
{
// get student from the database
return View();
}
}

In the above example, we have applied ActioName("find") attribute to GetById action


method. So now, action name is "find" instead of "GetById". This action method will be
invoked on http://localhost/student/find/1 request instead of
http://localhost/student/getbyid/1 request.
NonAction

NonAction selector attribute indicates that a public method of a Controller is not an action
method. Use NonAction attribute when you want public method in a controller but do not
want to treat it as an action method.

For example, the GetStudent() public method cannot be invoked in the same way as action
method in the following example.

Example: NonAction
public class StudentController : Controller
{
public StudentController()
{

[NonAction]
public Student GetStudnet(int id)
{
return studentList.Where(s => s.StudentId ==
id).FirstOrDefault();
}
}

Points to Remember :

1. MVC framework routing engine uses Action Selectors attributes to determine which action
method to invoke.
2. Three action selectors attributes are available in MVC 5
   - ActionName
   - NonAction
   - ActionVerbs
3. ActionName attribute is used to specify different name of action than method name.
4. NonAction attribute marks the public method of controller class as non-action method. It
cannot be invoked.

ActionVerbs
In this section, you will learn about the ActionVerbs selectors attribute.

The ActionVerbs selector is used when you want to control the selection of an action
method based on a Http request method. For example, you can define two different action
methods with the same name but one action method responds to an HTTP Get request and
another action method responds to an HTTP Post request.
MVC framework supports different ActionVerbs, such as HttpGet, HttpPost, HttpPut,
HttpDelete, HttpOptions & HttpPatch. You can apply these attributes to action method to
indicate the kind of Http request the action method supports. If you do not apply any
attribute then it considers it a GET request by default.

The following figure illustrates the HttpGET and HttpPOST action verbs.

ActionVerbs

The following table lists the usage of http methods:

Http
Usage
method
To retrieve the information from the server. Parameters will be appended in
GET
the query string.
POST To create a new resource.
PUT To update an existing resource.
HEAD Identical to GET except that server do not return message body.
OPTIONS method represents a request for information about the
OPTIONS
communication options supported by web server.
DELETE To delete an existing resource.
PATCH To full or partial update the resource.

Visit W3.org for more information on Http Methods.

The following example shows different action methods supports different ActionVerbs:

Example: ActionVerbs
public class StudentController : Controller
{
public ActionResult Index()
{
return View();
}

[HttpPost]
public ActionResult PostAction()
{
return View("Index");
}

[HttpPut]
public ActionResult PutAction()
{
return View("Index");
}

[HttpDelete]
public ActionResult DeleteAction()
{
return View("Index");
}

[HttpHead]
public ActionResult HeadAction()
{
return View("Index");
}

[HttpOptions]
public ActionResult OptionsAction()
{
return View("Index");
}

[HttpPatch]
public ActionResult PatchAction()
{
return View("Index");
}
}

You can also apply multiple http verbs using AcceptVerbs attribute. GetAndPostAction
method supports both, GET and POST ActionVerbs in the following example:

Example: AcceptVerbs
[AcceptVerbs(HttpVerbs.Post | HttpVerbs.Get)]
public ActionResult GetAndPostAction()
{
return RedirectToAction("Index");
}

Points to Remember :
1. ActionVerbs are another Action Selectors which selects an action method based on
request methods e.g POST, GET, PUT etc.
2. Multiple action methods can have same name with different action verbs. Method
overloading rules are applicable.
3. Multiple action verbs can be applied to a single action method using AcceptVerbs
attribute.

Model in ASP.NET MVC


In this section, you will learn about the Model in ASP.NET MVC framework.

Model represents domain specific data and business logic in MVC architecture. It maintains
the data of the application. Model objects retrieve and store model state in the persistance
store like a database.

Model class holds data in public properties. All the Model classes reside in the Model
folder in MVC folder structure.

Let's see how to add model class in ASP.NET MVC.

Adding a Model

Open our first MVC project created in previous step in the Visual Studio. Right click on
Model folder -> Add -> click on Class..

In the Add New Item dialog box, enter class name 'Student' and click Add.
Create Model Class

This will add new Student class in model folder. Now, add Id, Name, Age properties as
shown below.

Example: Model class


namespace MVC_BasicTutorials.Models
{
public class Student
{
public int StudentId { get; set; }
public string StudentName { get; set; }
public int Age { get; set; }
}
}

So in this way, you can create a model class which you can use in View. You will learn
how to implement validations using model later.

Learn how to create a View in the next section.

View in ASP.NET MVC


In this section, you will learn about the View in ASP.NET MVC framework.
View is a user interface. View displays data from the model to the user and also enables
them to modify the data.

ASP.NET MVC views are stored in Views folder. Different action methods of a single
controller class can render different views, so the Views folder contains a separate folder
for each controller with the same name as controller, in order to accommodate multiple
views. For example, views, which will be rendered from any of the action methods of
HomeController, resides in Views > Home folder. In the same way, views which will be
rendered from StudentController, will resides in Views > Student folder as shown below.

View folders for Controllers

Note:

Shared folder contains views, layouts or partial views which will be shared among multiple views.

Razor View Engine

Microsoft introduced the Razor view engine and packaged with MVC 3. You can write a
mix of html tags and server side code in razor view. Razor uses @ character for server side
code instead of traditional <% %>. You can use C# or Visual Basic syntax to write server
side code inside razor view. Razor view engine maximize the speed of writing code by
minimizing the number of characters and keystrokes required when writing a view. Razor
views files have .cshtml or vbhtml extension.

ASP.NET MVC supports following types of view files:


View file extension Description

.cshtml C# Razor view. Supports C# with html tags.

.vbhtml Visual Basic Razor view. Supports Visual Basic with html tags.

.aspx ASP.Net web form

.ascx ASP.NET web control

Learn Razor syntax in the next section. Let's see how to create a new view using Visual
Studio 2013 for Web with MVC 5.

Create New View

We have already created StudentController and Student model in the previous section.
Now, let's create a Student view and understand how to use model into view.

We will create a view, which will be rendered from Index method of StudentContoller. So,
open a StudentController class -> right click inside Index method -> click Add View..

Create a View

In the Add View dialogue box, keep the view name as Index. It's good practice to keep the
view name the same as the action method name so that you don't have to specify view name
explicitly in the action method while returning the view.

Select the scaffolding template. Template dropdown will show default templates available
for Create, Delete, Details, Edit, List or Empty view. Select "List" template because we
want to show list of students in the view.
View

Now, select Student from the Model class dropdrown. Model class dropdown automatically
displays the name of all the classes in the Model folder. We have already created Student
Model class in the previous section, so it would be included in the dropdown.

View
Check "Use a layout page" checkbox and select _Layout.cshtml page for this view and then
click Add button. We will see later what is layout page but for now think it like a master
page in MVC.

This will create Index view under View -> Student folder as shown below:

View

The following code snippet shows an Index.cshtml created above.

Views\Student\Index.cshtml:
@model IEnumerable<MVC_BasicTutorials.Models.Student>

@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Index</h2>

<p>
@Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>
@Html.DisplayNameFor(model => model.StudentName)
</th>
<th>
@Html.DisplayNameFor(model => model.Age)
</th>
<th></th>
</tr>

@foreach (var item in Model) {


<tr>
<td>
@Html.DisplayFor(modelItem => item.StudentName)
</td>
<td>
@Html.DisplayFor(modelItem => item.Age)
</td>
<td>
@Html.ActionLink("Edit", "Edit", new { id=item.StudentId }) |
@Html.ActionLink("Details", "Details", new
{ id=item.StudentId }) |
@Html.ActionLink("Delete", "Delete", new { id =
item.StudentId })
</td>
</tr>
}

</table>

As you can see in the above Index view, it contains both Html and razor codes. Inline razor
expression starts with @ symbol. @Html is a helper class to generate html controls. You
will learn razor syntax and html helpers in the coming sections.
In
dex.cshtml

The above Index view would look like below.


Index View

Note:

Every view in the ASP.NET MVC is derived from WebViewPage class included in System.Web.Mvc
namespace.

Points to Remember :

1. View is a User Interface which displays data and handles user interaction.
2. Views folder contains separate folder for each controller.
3. ASP.NET MVC supports Razor view engine in addition to traditional .aspx engine.
4. Razor view files has .cshtml or .vbhtml extension.

Integrate Controller, View and Model


We have already created StudentController, model and view in the previous sections, but
we have not integrated all these components in-order to run it.
The following code snippet shows StudentController and Student model class & view
created in the previous sections.

Example: StudentController
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MVC_BasicTutorials.Controllers
{
public class StudentController : Controller
{
// GET: Student
public ActionResult Index()
{
return View();
}
}
}
Example: Student Model class
namespace MVC_BasicTutorials.Models
{
public class Student
{
public int StudentId { get; set; }
public string StudentName { get; set; }
public int Age { get; set; }
}
}
Example: Index.cshtml to display student list
@model IEnumerable<MVC_BasicTutorials.Models.Student>

@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>Index</h2>

<p>
@Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>
@Html.DisplayNameFor(model => model.StudentName)
</th>
<th>
@Html.DisplayNameFor(model => model.Age)
</th>
<th></th>
</tr>

@foreach (var item in Model) {


<tr>
<td>
@Html.DisplayFor(modelItem => item.StudentName)
</td>
<td>
@Html.DisplayFor(modelItem => item.Age)
</td>
<td>
@Html.ActionLink("Edit", "Edit", new { id=item.StudentId }) |
@Html.ActionLink("Details", "Details", new
{ id=item.StudentId }) |
@Html.ActionLink("Delete", "Delete", new { id =
item.StudentId })
</td>
</tr>
}

</table>

Now, to run it successfully, we need to pass a model object from controller to Index view.
As you can see in the above Index.cshtml, it uses IEnumerable of Student as a model
object. So we need to pass IEnumerable of Student model from the Index action method of
StudentController class as shown below.

Example: Passing Model from Controller


public class StudentController : Controller
{
// GET: Student
public ActionResult Index()
{
var studentList = new List<Student>{
new Student() { StudentId = 1, StudentName =
"John", Age = 18 } ,
new Student() { StudentId = 2, StudentName =
"Steve", Age = 21 } ,
new Student() { StudentId = 3, StudentName =
"Bill", Age = 25 } ,
new Student() { StudentId = 4, StudentName =
"Ram" , Age = 20 } ,
new Student() { StudentId = 5, StudentName =
"Ron" , Age = 31 } ,
new Student() { StudentId = 4, StudentName =
"Chris" , Age = 17 } ,
new Student() { StudentId = 4, StudentName =
"Rob" , Age = 19 }
};
// Get the students from the database in the real application

return View(studentList);
}
}
As you can see in the above code, we have created a List of student objects for an example
purpose (in real life applicatoin, you can fetch it from the database). We then pass this list
object as a parameter in the View() method. The View() method is defined in base
Controller class, which automatically binds model object to the view.

Now, you can run the MVC project by pressing F5 and navigate to http://localhost/Student.
You will see following view in the browser.

Razor Syntax
Razor is one of the view engine supported in ASP.NET MVC. Razor allows you to write
mix of HTML and server side code using C# or Visual Basic. Razor view with visual basic
syntax has .vbhtml file extension and C# syntax has .cshtml file extension.

Razor syntax has following Characteristics:

 Compact: Razor syntax is compact which enables you to minimize number of characters
and keystrokes required to write a code.
 Easy to Learn: Razor syntax is easy to learn where you can use your familiar language C#
or Visual Basic.
 Intellisense: Razor syntax supports statement completion within Visual Studio.

Now, let's learn how to write razor code.

Inline expression

Start with @ symbol to write server side C# or VB code with Html code. For example,
write @Variable_Name to display a value of a server side variable. For example,
DateTime.Now returns a current date and time. So, write @DateTime.Now to display
current datetime as shown below. A single line expression does not require a semicolon at
the end of the expression.

C# Razor Syntax
<h1>Razor syntax demo</h1>

<h2>@DateTime.Now.ToShortDateString()</h2>
Output:
Razor syntax demo
08-09-2014
Multi-statement Code block

You can write multiple line of server side code enclosed in braces @{ ... }. Each line
must ends with semicolon same as C#.

Example: Server side Code in Razor Syntax


@{
var date = DateTime.Now.ToShortDateString();
var message = "Hello World";
}

<h2>Today's date is: @date </h2>


<h3>@message</h3>
Output:
Today's date is: 08-09-2014
Hello World!
Display Text from Code Block

Use @: or <text>/<text> to display texts within code block.

Example: Display Text in Razor Syntax


@{
var date = DateTime.Now.ToShortDateString();
string message = "Hello World!";
@:Today's date is: @date <br />
@message
}
Output:
Today's date is: 08-09-2014
Hello World!

Display text using <text> within a code block as shown below.

Example: Text in Razor Syntax


@{
var date = DateTime.Now.ToShortDateString();
string message = "Hello World!";
<text>Today's date is:</text> @date <br />
@message
}
Output:
Today's date is: 08-09-2014
Hello World!
if-else condition

Write if-else condition starting with @ symbol. The if-else code block must be enclosed in
braces { }, even for single statement.

Example: if else in Razor


@if(DateTime.IsLeapYear(DateTime.Now.Year) )
{
@DateTime.Now.Year @:is a leap year.
}
else {
@DateTime.Now.Year @:is not a leap year.
}
Output:
2014 is not a leap year.
for loop
Example: for look in Razor
@for (int i = 0; i < 5; i++) {
@i.ToString() <br />
}
Output:
0
1
2
3
4
Model

Use @model to use model object anywhere in the view.

Example: Use Model in Razor


@model Student

<h2>Student Detail:</h2>
<ul>
<li>Student Id: @Model.StudentId</li>
<li>Student Name: @Model.StudentName</li>
<li>Age: @Model.Age</li>
</ul>
Output:
Student Detail:

- Student Id: 1
- Student Name: John
- Age: 18
Declare Variables

Declare a variable in a code block enclosed in brackets and then use those variables inside
html with @ symbol.

Example: Variable in Razor


@{
string str = "";

if(1 > 0)
{
str = "Hello World!";
}
}

<p>@str</p>
Output:
Hello World!

So this was some of the important razor syntaxes. Visit asp.net to learn razor syntax in
detail.

Points to Remember :

1. Use @ to write server side code.


2. Server side code block starts with @{* code * }
3. Use @: or <text></<text> to display text from code block.
4. if condition starts with @if{ }
5. for loop starts with @for
6. @model allows you to use model object anywhere in the view.

HTML Helpers
In this section, you will learn what are Html helpers and how to use them in the razor view.

HtmlHelper class generates html elements using the model class object in razor view. It
binds the model object to html elements to display value of model properties into html
elements and also assigns the value of the html elements to the model properties while
submitting web form. So always use HtmlHelper class in razor view instead of writing html
tags manually.

The following figure shows the use of HtmlHelper class in the razor view.

HTML Helpers

As you can see in the above figure, @Html is an object of HtmlHelper class . (@ symbol is
used to access server side object in razor syntax). Html is a property of type HtmlHelper
included in base class of razor view WebViewPage. ActionLink() and DisplayNameFor() is
extension methods included in HtmlHelper class.

HtmlHelper class generates html elements. For example, @Html.ActionLink("Create


New", "Create") would generate anchor tag <a href="/Student/Create">Create
New</a>.

There are many extension methods for HtmlHelper class, which creates different html
controls.
The following table lists HtmlHelper methods and html control each method generates.

Strogly Typed
HtmlHelper Html Control
HtmlHelpers

Html.ActionLink Anchor link

Html.TextBox Html.TextBoxFor Textbox

Html.TextArea Html.TextAreaFor TextArea

Html.CheckBox Html.CheckBoxFor Checkbox

Html.RadioButton Html.RadioButtonFor Radio button

Html.DropDownList Html.DropDownListFor Dropdown, combobox

Html.ListBox Html.ListBoxFor multi-select list box

Html.Hidden Html.HiddenFor Hidden field

Password Html.PasswordFor Password textbox

Html.Display Html.DisplayFor Html text

Html.Label Html.LabelFor Label

Generates Html controls based on data type of


specified model property e.g. textbox for string
Html.Editor Html.EditorFor
property, numeric field for int, double or other
numeric type.

The difference between calling the HtmlHelper methods and using an html tags is that the
HtmlHelper method is designed to make it easy to bind to view data or model data.

Learn about various HtmlHelper methods in the next few sections.

HtmlHelper - TextBox
Learn how to generate textbox control using HtmlHelper in razor view in this section.

HtmlHelper class includes two extension methods which creates a textbox (<input
type="text">) element in razor view: TextBox() and TextBoxFor(). The TextBox() method
is loosely typed method whereas TextBoxFor() is a strongly typed method.

We will use following Student model with TextBox() and TextBoxFor() method.
Example: Student Model
public class Student
{
public int StudentId { get; set; }
[Display(Name="Name")]
public string StudentName { get; set; }
public int Age { get; set; }
public bool isNewlyEnrolled { get; set; }
public string Password { get; set; }
}
TextBox()

The Html.TextBox() method creates <input type="text" > element with specified name,
value and html attributes.

TextBox() method signature


MvcHtmlString Html.TextBox(string name, string value, object
htmlAttributes)

TextBox method has many overloads. Please visit MSDN to know all the overloads of
TextBox() method.

The TextBox() method is a loosely typed method because name parameter is a string. The
name parameter can be a property name of model object. It binds specified property with
textbox. So it automatically displays a value of the model property in a textbox and visa-
versa.

Example: Html.TextBox() in Razor View


@model Student

@Html.TextBox("StudentName", null, new { @class = "form-control" })


Html Result:
<input class="form-control"
id="StudentName"
name="StudentName"
type="text"
value="" />

In the above example, the first parameter is "StudentName" property of Student model class
which will be set as a name & id of textbox. The second parameter is a value to display in a
textbox, which is null in the above example because TextBox() method will automatically
display a value of the StudentName property in the textbox. The third parameter will be set
as class attribute. HtmlAttributes parameter is an object type, so it can be anonymous object
and attributes name will be its properties starting with @ symbol.

You can also specify any name for the textbox. However, it will not be bind to a model.
Example: Html.TextBox() in Razor View
@Html.TextBox("myTextBox", "This is value", new { @class = "form-control"
})
Html Result:
<input class="form-control"
id="myTextBox"
name="myTextBox"
type="text"
value="This is value" />

  Output of TextBox() Html Helper method

TextBoxFor

TextBoxFor helper method is a strongly typed extension method. It generates a text input
element for the model property specified using a lambda expression. TextBoxFor method
binds a specified model object property to input text. So it automatically displays a value of
the model property in a textbox and visa-versa.

TextBoxFor() method Signature

MvcHtmlString TextBoxFor(Expression<Func<TModel,TValue>> expression, object


htmlAttributes)

Visit MSDN to know all the overloads of TextBoxFor() method.

Example: TextBoxFor() in Razor View


@model Student

@Html.TextBoxFor(m => m.StudentName, new { @class = "form-control" })


Html Result:
<input class="form-control"
id="StudentName"
name="StudentName"
type="text"
value="John" />

In the above example, the first parameter in TextBoxFor() method is a lambda expression
which specifies StudentName property to bind with the textbox. It generates an input text
element with id & name set to property name. The value attribute will be set to the value of
a StudentName property e.g John. The following figure shows the input text element
genered by above example.

Output of TextBoxFor() Html Helper method


Difference between TextBox and TextBoxFor

 @Html.TextBox() is loosely typed method whereas @Html.TextBoxFor() is a strongly typed


(generic) extension method.
 TextBox() requires property name as string parameter where as TextBoxFor() requires
lambda expression as a parameter.
 TextBox doesn't give you compile time error if you have specified wrong property name. It
will throw run time exception.
 TextBoxFor is generic method so it will give you compile time error if you have specified
wrong property name or property name changes. (Provided view is not compile at run
time. )

HtmlHelper - TextArea
Learn how to generate TextArea control using HtmlHelper in razor view in this section.

HtmlHelper class includes two extension methods to generate a multi line <textarea>
element in a razor view: TextArea() and TextAreaFor(). By default, it creates textarea with
rows=2 and cols=20.

We will use the following Student model with the TextArea() and TextAreaFor() method.

Example: Student Model


public class Student
{
public int StudentId { get; set; }
[Display(Name="Name")]
public string StudentName { get; set; }
public string Description { get; set; }
}
TextArea()

The Html.TextArea() method creates <textarea rows="2" cols="20" > element with
specified name, value and html attributes.

TextArea() method Signature


MvcHtmlString Html.TextArea(string name, string value, object
htmlAttributes)

TextArea method has many overloads. Please visit MSDN to know all the overloads of
TextArea method.
The TextArea() method is a loosely typed method because the name parameter is a string.
The name parameter can be a property name of model object. It binds a specified property
with the textarea. So it automatically displays a value of the model property in a textarea
and visa-versa.

Example: Html.TextArea() in Razor View


@model Student

@Html.TextArea("Description", null, new { @class = "form-control" })


Html Result:
<textarea class="form-control"
id="Description"
name="Description"
rows="2"
cols="20">This is value</textarea>

In the above example, the first parameter is the "Description" property of Student model
class which will be set as a name & id of textarea. The second parameter is a value to
display in a textarea, which is null in the above example because TextArea() method will
automatically display a value of the Description property in the textarea. The third
parameter will be set as class attribute. HtmlAttributes parameter is an object type, so it can
be anonymous object and attributes name will be its properties starting with @ symbol.

You can also specify any name for the textarea. However, it will not be bound to a model.

Example: Html.TextArea() in Razor View


@Html.TextArea("myTextArea", "This is value", new { @class = "form-
control" })
Html Result:
<textarea class="form-control"
cols="20"
id="myTextArea"
name="myTextArea"
rows="2">This is value</textarea>

The above example would generate input elements as shown below.

Output of TextArea() Helper method

TextAreaFor

TextAreaFor helper method is a strongly typed extension method. It generates a multi line
<textarea> element for the property in the model object specified using a lambda
expression. TextAreaFor method binds a specified model object property to textarea
element. So it automatically displays a value of the model property in a textarea and visa-
versa.

TextBoxFor() method Signature

MvcHtmlString TextAreaFor(<Expression<Func<TModel,TValue>> expression, object


htmlAttributes)

Visit MSDN to know all the overloads of TextAreaFor().

Example: TextAreaFor() in Razor View


@model Student

@Html.TextAreaFor(m => m.Description, new { @class = "form-control" })


Html Result:
<textarea class="form-control"
cols="20"
id="Description"
name="Description"
rows="2"></textarea>

In the above example, the first parameter in TextAreaFor() method is a lambda expression
that specifies the model property to be bound with the textarea element. We have specified
Description property in the above example. So, it generates <textarea> element with id &
name set to property name - Description. The value of textarea will be set to the value of a
Description property.

HtmlHelper - CheckBox
Learn how to generate checkbox control using HtmlHelper in razor view in this section.

HtmlHelper class includes two extension methods to generate a <input


type="checkbox"> element in razor view: CheckBox() and CheckBoxFor().

We will use following Student model with CheckBox() and CheckBoxFor() method.

Example: Student Model


public class Student
{
public int StudentId { get; set; }
[Display(Name="Name")]
public string StudentName { get; set; }
public int Age { get; set; }
public bool isNewlyEnrolled { get; set; }
public string Password { get; set; }
}
CheckBox()

The Html.CheckBox() is a loosely typed method which generates a <input


type="checkbox" > with the specified name, isChecked boolean and html attributes.

CheckBox() method Signature


MvcHtmlString CheckBox(string name, bool isChecked, object
htmlAttributes)

Please visit MSDN to know all the overloads of CheckBox() method.

Example: Html.CheckBox() in Razor View


@Html.CheckBox("isNewlyEnrolled", true)
Html Result:
<input checked="checked"
id="isNewlyEnrolled"
name="isNewlyEnrolled"
type="checkbox"
value="true" />

In the above example, first parameter is "isNewlyEnrolled" property of Student model class
which will be set as a name & id of textbox. The second parameter is a boolean value,
which checks or unchecks the checkbox.

CheckBoxFor

CheckBoxFor helper method is a strongly typed extension method. It generates <input


type="checkbox"> element for the model property specified using a lambda expression.
CheckBoxFor method binds a specified model object property to checkbox element. So it
automatically checked or unchecked a checkbox based on the property value.

CheckBoxFor() method Signature

MvcHtmlString CheckBoxFor(<Expression<Func<TModel,TValue>> expression, object


htmlAttributes)

Visit MSDN to know all the overloads of CheckBoxFor() method.

Example: Html.CheckBoxFor() in Razor View


@model Student

@Html.CheckBoxFor(m => m.isNewlyEnrolled)


Html Result:
<input data-val="true"
data-val-required="The isNewlyEnrolled field is required."
id="isNewlyEnrolled"
name="isNewlyEnrolled"
type="checkbox"
value="true" />

<input name="isNewlyEnrolled" type="hidden" value="false" />

In the above example, the first parameter in CheckBoxFor() method is a lambda expression
that specifies the model property to be bound with the checkbox element. We have
specified isNewlyEnrolled property in the above example. So, it generates <input
type="checkbox"> element with id & name set to property name - isNewlyEnrolled. The
value attribute will be set to the value of a isNewlyEnrolled boolean property.

In the above Html result, notice that it has generated additional hidden field with the same
name and value=false. This is because when you submit a form with a checkbox, the value
is only posted if the checkbox is checked. So, if you leave the checkbox unchecked then
nothing will be sent to the server when in many situations you would want false to be sent
instead. As the hidden input has the same name as the checkbox, then if the checkbox is
unchecked you'll still get a 'false' sent to the server.

HtmlHelper - RadioButton
Learn how to generate radio button control using HtmlHelper in razor view in this section.

HtmlHelper class include two extension methods to generate a <input type="radio">


element in a razor view: RadioButton() and RadioButtonFor().

We will use the following Student model with the RadioButton() and RadioButtonFor()
method.

Example: Student Model


public class Student
{
public int StudentId { get; set; }
[Display(Name="Name")]
public string StudentName { get; set; }
public int Age { get; set; }
public string Gender { get; set; }
}
RadioButton()

The Html.RadioButton() method creates an radio button element with a specified name,
isChecked boolean and html attributes.
RadioButton() method Signature

MvcHtmlString RadioButton(string name, object value, bool isChecked, object


htmlAttributes)

Please visit MSDN to know all the overloads of RadioButton() method.

Example: Html.RadioButton() in Razor View


Male: @Html.RadioButton("Gender","Male")
Female: @Html.RadioButton("Gender","Female")
Html Result:
Male: <input checked="checked"
id="Gender"
name="Gender"
type="radio"
value="Male" />

Female: <input id="Gender"


name="Gender"
type="radio"
value="Female" />

In the above example, we have created two radio button for the "Gender" property. The
second parameter is a value which will be sent to the server, if respective radio button is
checked. If the Male radio button is selected, then the string value "Male" will be assigned
to a model property Gender and submitted to the server. The above example creates two
radio buttons as shown below.

Output of RadioButton() method

RadioButtonFor

RadioButtonFor helper method is a strongly typed extension method. It generates <input


type="radio"> element for the property specified using a lambda expression.
RadioButtonFor method binds a specified model object property to RadioButton control.
So it automatically checked or unchecked a RadioButton based on the property value.

RadioButtonFor() method Signature

MvcHtmlString RadioButtonFor(<Expression<Func<TModel,TValue>> expression, object


value, object htmlAttributes)

Visit MSDN to know all the overloads of RadioButtonFor().

Example: Html.RadioButtonFor() in Razor View


@model Student

@Html.RadioButtonFor(m => m.Gender,"Male")


@Html.RadioButtonFor(m => m.Gender,"Female")
Html Result:
<input checked="checked"
id="Gender"
name="Gender"
type="radio"
value="Male" />

<input id="Gender"
name="Gender"
type="radio"
value="Female" />

In the above example, the first parameter in RadioButtonFor() method is a lambda


expression that specifies the model property to be bind with the RadioButton element. We
have created two radio button for the Gender property in the above example. So, it
generates two <input type="RadioButton"> element with id & name set to property name -
Gender. The second parameter is a value which will be sent to the server when form will be
submitted.

HtmlHelper - DropDownList
Learn how to generate dropdownlist control using HtmlHelper in razor view in this section.

HtmlHelper class includes two extension methods to generate a <select> element in a razor
view: DropDownList() and DropDownListFor().

We will use the following Student model with DropDownList() and DropDownListFor()
method.

Example: Student Model


public class Student
{
public int StudentId { get; set; }
[Display(Name="Name")]
public string StudentName { get; set; }
public Gender StudentGender { get; set; }
}

public enum Gender


{
Male,
Female
}
DropDownList()

The Html.DropDownList() method generates a select element with specified name, list
items and html attributes.

DropDownList() method signature

MvcHtmlString Html.DropDownList(string name, IEnumerable<SelectLestItem>


selectList, string optionLabel, object htmlAttributes)

Please visit MSDN to know all the overloads of DropDownList() method.

Example: Html.DropDownList() in Razor View


@using MyMVCApp.Models

@model Student

@Html.DropDownList("StudentGender",
new SelectList(Enum.GetValues(typeof(Gender))),
"Select Gender",
new { @class = "form-control" })
Html Result:
<select class="form-control" id="StudentGender" name="StudentGender">
<option>Select Gender</option>
<option>Male</option>
<option>Female</option>
</select>

In the above example, the first parameter is a property name for which we want to display
list items. The second parameter is list of values to be included in the dropdownlist. We
have used Enum methods to get the Gender enum values. The third parameter is a label
which will be the first list item and the fourth parameter is for html attributes like css to be
applied on the dropdownlist.

Please note that you can add MyMVCApp.Models namespace into <namespaces> section in
web.config in the Views folder instead of using @using to include namespces in all the
views.

DropDownListFor

DropDownListFor helper method is a strongly typed extension method. It generates


<select> element for the property specified using a lambda expression. DropDownListFor
method binds a specified model object property to dropdownlist control. So it automatically
list items in DropDownList based on the property value.

DropDownListFor() method signature


MvcHtmlString Html.DropDownListFor(Expression<Func<dynamic,TProperty>>
expression, IEnumerable<SelectLestItem> selectList, string optionLabel, object
htmlAttributes)

Visit MSDN to know all the overloads of DropDownListFor().

The following example creates dropdown list for the above Gender enum.

Example: Html.DropDownListFor() in Razor View


@using MyMVCApp.Models

@model Student

@Html.DropDownListFor(m => m.StudentGender,


new SelectList(Enum.GetValues(typeof(Gender))),
"Select Gender")
Html Result:
<select class="form-control" id="StudentGender" name="StudentGender">
<option>Select Gender</option>
<option>Male</option>
<option>Female</option>
</select>

In the above example, the first parameter in DropDownListFor() method is a lambda


expression that specifies the model property to be bind with the select element. We have
specified StudentGender property of enum type. The second parameter specifies the items
to show into dropdown list using SelectList. The third parameter is optionLabel which will
be the first item of dropdownlist. So now, it generates <select> element with id & name set
to property name - StudentGener and two list items - Male & Female as shown below.

Output of DropDownList() or DropDownListFor() method

HtmlHelper - Hidden field


Learn how to generate hidden field using HtmlHelper in razor view in this section.

HtmlHelper class includes two extension methods to generate a hidden field (<input
type="hidden">) element in a razor view: Hidden() and HiddenFor().

We will use the following Student model with Hidden() and HiddenFor() method.
Example: Student Model
public class Student
{
public int StudentId { get; set; }
[Display(Name="Name")]
public string StudentName { get; set; }
public int Age { get; set; }
public bool isNewlyEnrolled { get; set; }
public string Password { get; set; }
}
Hidden()

The Html.Hidden() method generates a input hidden field element with specified name,
value and html attributes.

Hidden() method signature


MvcHtmlString Html.Hidden(string name, object value, object
htmlAttributes)

Hidden() method has many overloads. Please visit MSDN to know all the overloads of
Hidden() method.

The following example creates a hidden field for StudentId property of Student model. It
binds StudentId with the hidden field, so that it can assign value of StudentId to the hidden
field and visa-versa.

Example: Html.Hidden() in Razor View


@model Student

@Html.Hidden("StudentId")
Html Result:
<input id="StudentId"
name="StudentId"
type="hidden"
value="1" />
HiddenFor

HiddenFor helper method is a strongly typed extension method. It generates a hidden input
element for the model property specified using a lambda expression. HiddenFor method
binds a specified model object property to <input type="hidden">. So it automatically sets
a value of the model property to hidden field and visa-versa.

HiddenFor() method signature


MvcHtmlString Html.HiddenFor(Expression<Func<dynamic,TProperty>>
expression)
Visit MSDN to know all the overloads of HiddenFor() method.

Example: HiddenFor() in Razor View


@model Student

@Html.HiddenFor(m => m.StudentId)


Html Result:
<input data-val="true"
data-val-number="The field StudentId must be a number."
data-val-required="The StudentId field is required."
id="StudentId"
name="StudentId"
type="hidden"
value="1" />

In the above example, the first parameter in HiddenFor() method is a lambda expression
that specifies the model property to be bind with the hidden field. We have specified
StudentId property in the above example. So, it generates input text element with id &
name set to property name. The value attribute will be set to the value of a StudentId
property which is 1 in the above example.

Please notice that it has created data- attribute of html5 that is used for the validation in
ASP.Net MVC.

HtmlHelper - Password
Learn how to generate Password field using HtmlHelper in razor view in this section.

HtmlHelper class includes two extension methods to generate a password field (<input
type="password">) element in a razor view: Password() and PasswordFor().

We will use following Student model with Password() and PasswordFor() method.

Example: Student Model


public class Student
{
public int StudentId { get; set; }
[Display(Name="Name")]
public string StudentName { get; set; }
public int Age { get; set; }
public bool isNewlyEnrolled { get; set; }
public string OnlinePassword { get; set; }
}
Password()

The Html.Password() method generates a input password element with specified name,
value and html attributes.

Password() method signature


MvcHtmlString Html.Password(string name, object value, object
htmlAttributes)

Password() method has many overloads. Please visit MSDN to know all the overloads of
Password() method.

Example: Html.Password() in Razor View


@model Student

@Html.Password("OnlinePassword")
Html Result:
<input
id="OnlinePassword"
name="OnlinePassword"
type="password"
value="" />

The above example will create password field for "OnlinePassword" property as shown
below.

Output of Password() or PasswordFor()


method

PasswordFor()

PasswordFor helper method is a strongly typed extension method. It generates a <input


type="password"> element for the model object property specified using a lambda
expression. PasswordFor method binds a specified model object property to <input
type="password">. So it automatically sets a value of the model property to password field
and visa-versa.

PasswordFor() method signature

MvcHtmlString Html.PasswordFor(Expression<Func<dynamic,TProperty>> expression,


object htmlAttributes)

Visit MSDN to know all the overloads of PasswordFor() method.

Example: PasswordFor() in Razor View


@model Student

@Html.PasswordFor(m => m.Password)


Html Result:
<input id="Password" name="Password" type="password" value="mypassword"
/>

In the above example, the first parameter in PasswordFor() method is a lambda expression
that specifies the model property to be bind with the password textbox. We have specified
Password property in the above example. So, it generates input password element with id &
name set to property name. The value attribute will be set to the value of a Password
property which is "mypassword" in the above example.

HtmlHelper - Display HTML String


Learn how to create html string literal using HtmlHelper in razor view in this section.

HtmlHelper class includes two extension methods to generate html string : Display() and
DisplayFor().

We will use the following Student model with the Display() and DisplayFor() method.

Example: Student Model


public class Student
{
public int StudentId { get; set; }
public string StudentName { get; set; }
public int Age { get; set; }
}
Display()

The Html.Display() is a loosely typed method which generates a string in razor view for the
specified property of model.

Display() method Signature: MvcHtmlString Display(string expression)

Display() method has many overloads. Please visit MSDN to know all the overloads of
Display() method

Example: Html.Display() in Razor View


@Html.Display("StudentName")
Html Result:
"Steve"
DisplayFor

DisplayFor helper method is a strongly typed extension method. It generates a html string
for the model object property specified using a lambda expression.

DisplayFor() method Signature: MvcHtmlString


DisplayFor(<Expression<Func<TModel,TValue>> expression)

Visit MSDN to know all the overloads of DisplayFor() method.

Example: DisplayFor() in Razor View


@model Student

@Html.DisplayFor(m => m.StudentName)


Html Result:
" Steve "

In the above example, we have specified StudentName property of Student model using
lambda expression in the DisplayFor() method. So, it generates a html string with the value
of StudentName property, which is "Steve" in the above example.

HtmlHelper - Label
Learn how to create <label> element using HtmlHelper in razor view in this section.

HtmlHelper class includes two extension methods to generate html label : Label() and
LabelFor().

We will use following Student model with to demo Label() and LabelFor() method.

Example: Student Model


public class Student
{
public int StudentId { get; set; }
[Display(Name="Name")]
public string StudentName { get; set; }
public int Age { get; set; }
}
Label()

The Html.Label() method generates a <label> element for a specified property of model
object.
Label() method Signature: MvcHtmlString Label(string expression, string
labelText, object htmlAttributes)

Label() method has many overloads. Please visit MSDN to know all the overloads of
Label() method

Example: Html.Label() in Razor View


@Html.Label("StudentName")
Html Result:
<label for="StudentName">Name</label>

In the above example, we have specified a StudentName property as a string. So, it will
create <label> element that display Name.

You can specify another label text instead of property name as shown below.

Example: Html.Label() in Razor View


@Html.Label("StudentName","Student-Name")
Html Result:
<label for="StudentName">Student-Name</label>
LabelFor

LabelFor helper method is a strongly typed extension method. It generates a html label
element for the model object property specified using a lambda expression.

LabelFor() method Signature: MvcHtmlString


LabelFor(<Expression<Func<TModel,TValue>> expression)

Visit MSDN to know all the overloads of LabelFor() method.

Example: LabelFor() in Razor View


@model Student

@Html.LabelFor(m => m.StudentName)


Html Result:
<label for="StudentName">Name</label>

In the above example, we have specified the StudentName property of Student model using
lambda expression in the LabelFor() method. So, it generates <label> and set label text to
the same as StudentName property name.
HtmlHelper - Editor
We have seen different HtmlHelper methods used to generated different html elements in
the previous sections. ASP.NET MVC also includes a method that generates html input
elements based on the datatype. Editor() or EditorFor() extension method generates html
elements based on the data type of the model object's property.

The following table list the html element created for each data type by Editor() or
EditorFor() method.

Property DataType Html Element

string <input type="text" >

int <input type="number" >

decimal, float <input type="text" >

boolean <input type="checkbox" >

Enum <input type="text" >

DateTime <input type="datetime" >

We will use the following model class with Editor and EditorFor method.

Example: Student Model


public class Student
{
public int StudentId { get; set; }
[Display(Name="Name")]
public string StudentName { get; set; }
public int Age { get; set; }
public bool isNewlyEnrolled { get; set; }
public string Password { get; set; }
public DateTime DoB { get; set; }
}
Editor()

Editor() method requires a string expression parameter to specify the property name. It
creats a html element based on the datatype of the specified property.

Editor() signature: MvcHtmlString Editor(string propertyname)

Visit MSDN to know all the overloads of Editor() method

Consider the following example to understand the Editor() method.


Example: Editor() in Razor view

StudentId: @Html.Editor("StudentId")
Student Name: @Html.Editor("StudentName")
Age: @Html.Editor("Age")
Password: @Html.Editor("Password")
isNewlyEnrolled: @Html.Editor("isNewlyEnrolled")
Gender: @Html.Editor("Gender")
DoB: @Html.Editor("DoB")

Output of Editor() and EditorFor() method

In the above example, we have specified property names of Student model as a string. So,
Editor() method created the appropriate input elements based on the datatype as shown in
the above figure.

EditorFor

EditorFor() method is a strongly typed method. It requires the lambda expression to specify
a property of the model object.

EditorFor() signature: MvcHtmlString


EditorFor(<Expression<Func<TModel,TValue>> expression)

Visit MSDN to know all the overloads of EditorFor() method

Example: EditorFor() in Razor view

StudentId: @Html.EditorFor(m => m.StudentId)


Student Name: @Html.EditorFor(m => m.StudentName)
Age: @Html.EditorFor(m => m.Age)
Password: @Html.EditorFor(m => m.Password)
isNewlyEnrolled: @Html.EditorFor(m => m.isNewlyEnrolled)
Gender: @Html.EditorFor(m => m.Gender)
DoB: @Html.EditorFor(m => m.DoB)
  Output of Editor() and EditorFor() method

In the above example of EditorFor() method, we have specified the property name using the
lambda expression. The result would be the same as the Editor() method as shown in the
above figure.

Model Binding
In this section, you will learn about model binding in MVC framework.

To understand the model binding in MVC, first let's see how you can get the http request
values in the action method using traditional ASP.NET style. The following figure shows
how you can get the values from HttpGET and HttpPOST request by using the Request
object directly in the action method.
Accessing
Request Data

As you can see in the above figure, we use the Request.QueryString and Request
(Request.Form) object to get the value from HttpGet and HttpPOST request. Accessing
request values using the Request object is a cumbersome and time wasting activity.

With model binding, MVC framework converts the http request values (from query string
or form collection) to action method parameters. These parameters can be of primitive type
or complex type.

Binding to Primitive type

HttpGET request embeds data into a query string. MVC framework automatically converts
a query string to the action method parameters. For example, the query string "id" in the
following GET request would automatically be mapped to the id parameter of the Edit()
action method.
Model
Binding  

This binding is case insensitive. So "id" parameter can be "ID" or "Id".

You can also have multiple parameters in the action method with different data types.
Query string values will be converted into paramters based on matching name.

For example, http://localhost/Student/Edit?id=1&name=John would map to id and name


parameter of the following Edit action method.

Example: Convert QueryString to Action Method Parameters


public ActionResult Edit(int id, string name)
{
// do something here

return View();
}
Binding to Complex type

Model binding also works on complex types. Model binding in MVC framework
automatically converts form field data of HttpPOST request to the properties of a complex
type parameter of an action method.

Consider the following model classes.

Example: Model classes in C#


public class Student
{
public int StudentId { get; set; }
[Display(Name="Name")]
public string StudentName { get; set; }
public int Age { get; set; }
public Standard standard { get; set; }
}
public class Standard
{
public int StandardId { get; set; }
public string StandardName { get; set; }
}

Now, you can create an action method which includes Student type parameter. In the
following example, Edit action method (HttpPost) includes Student type parameter.

Example: Action Method with Class Type Parameter


[HttpPost]
public ActionResult Edit(Student std)
{
var id = std.StudentId;
var name = std.StudentName;
var age = std.Age;
var standardName = std.standard.StandardName;

//update database here..

return RedirectToAction("Index");
}

So now, MVC framework will automatically maps Form collection values to Student type
parameter when the form submits http POST request to Edit action method as shown
below.

Model Binding

So thus, it automatically binds form fields to the complex type parameter of action method.

FormCollection

You can also include FormCollection type parameter in the action method instead of
complex type, to retrieve all the values from view form fields as shown below.
Model Binding

Bind Attribute

ASP.NET MVC framework also enables you to specify which properties of a model class
you want to bind. The [Bind] attribute will let you specify the exact properties a model
binder should include or exclude in binding.

In the following example, Edit action method will only bind StudentId and StudentName
property of a Student model.

Example: Binding Parameters


[HttpPost]
public ActionResult Edit([Bind(Include = "StudentId, StudentName")]
Student std)
{
var name = std.StudentName;

//write code to update student

return RedirectToAction("Index");
}

You can also use Exclude properties as below.

Example: Exclude Properties in Binding


[HttpPost]
public ActionResult Edit([Bind(Exclude = "Age")] Student std)
{
var name = std.StudentName;

//write code to update student

return RedirectToAction("Index");
}

The Bind attribute will improve the performance by only bind properties which you needed.
Inside Model Binding

As you have seen that Model binding automatically converts request values into a primitive
or complex type object. Model binding is a two step process. First, it collects values from
the incoming http request and second, populates primitive type or complex type with these
values.

Value providers are responsible for collecting values from request and Model Binders are
responsible for populating values.

Model
Binding in MVC

Default value provider collection evaluates values from the following sources:

1. Previously bound action parameters, when the action is a child action


2. Form fields (Request.Form)
3. The property values in the JSON Request body (Request.InputStream), but only when the
request is an AJAX request
4. Route data (RouteData.Values)
5. Querystring parameters (Request.QueryString)
6. Posted files (Request.Files)

MVC includes DefaultModelBinder class which effectively binds most of the model types.

Visit MSDN for detailed information on Model binding.

Create Edit View in ASP.NET MVC


We have already created the Index view in the previous section. In this section, we will
create the Edit view using a default scaffolding template as shown below. The user can
update existing student data using the Edit view.
Edit View

The Edit view will be rendered on the click of the Edit button in Index view. The following
figure describes the complete set of editing steps.
Editing Steps in MVC

The above figure illustrates the following steps.

1. The user clicks on the Edit link in Index view which will send HttpGET request
http://localhost/student/edit/{Id} with corresponding Id parameter in the query string. This
request will be handled by HttpGET Edit action method.(by default action method handles
HttpGET request if no attribute specified)

2. HttpGet Edit action method will fetch student data from the database, based on the
supplied Id parameter and render the Edit view with that particular Student data.

3. The user can edit the data and click on the Save button in the Edit view. The Save button
will send a HttpPOST request http://localhost/Student/Edit with the Form data collection.

4. The HttpPOST Edit action method in StudentController will finally update the data into
the database and render an Index page with the refreshed data using the RedirectToAction
method as a fourth step.

So this will be the complete process in order to edit the data using Edit view in ASP.NET
MVC.

So let's start to implement above steps.


We will be using following Student model class for our Edit view.

Student Model - C#:


public class Student
{
public int StudentId { get; set; }

[Display( Name="Name")]
public string StudentName { get; set; }

public int Age { get; set; }


}

Step: 1
We have already created an Index view in the previous section using a List scaffolding
template which includes an Edit action link as shown below.

Index View

An Edit link sends HttpGet request to the Edit action method of StudentController with
corresponding StudentId in the query string. For example, an Edit link with student John
will append a StudentId=1 query string to the request url because John's StudentId is 1.
Likewise all the Edit link will include a respective StudentId in the query string.

Step 2:
Now, create a HttpGET Edit action method in StudentController. The Index view shown
above will send the StudentId parameter to the HttpGet Edit action method on the click of
the Edit link.

The HttpGet Edit() action method must perform two tasks, first it should fetch the student
information from the underlaying data source, whose StudentId matches with the StudentId
in the query string. Second, it should render Edit view with the student information so that
the user can update it.

So, the Edit() action method should have a StudentId parameter. MVC framework will
automatically bind a query string to the parameters of an action method if the name is
matches. Please make sure that parameter name matches with the query string.

Example: HttpGet Edit() Action method - C#


using MVC_BasicTutorials.Models;

namespace MVC_BasicTutorials.Controllers
{
public class StudentController : Controller
{
IList<Student> studentList = new List<Student>() {
new Student(){ StudentId=1, StudentName="John", Age =
18 },
new Student(){ StudentId=2, StudentName="Steve", Age
= 21 },
new Student(){ StudentId=3, StudentName="Bill", Age =
25 },
new Student(){ StudentId=4, StudentName="Ram", Age =
20 },
new Student(){ StudentId=5, StudentName="Ron", Age =
31 },
new Student(){ StudentId=6, StudentName="Chris", Age
= 17 },
new Student(){ StudentId=7, StudentName="Rob", Age =
19 }
};

public ActionResult Edit(int StudentId)


{
//Get the student from studentList sample collection for demo
purpose.
//You can get the student from the database in the real
application
var std = studentList.Where(s => s.StudentId ==
StudentId).FirstOrDefault();

return View(std);
}
}
}

As you can see in the above Edit method, we have used a LINQ query to get the Student
from the sample studentList collection whose StudentId matches with supplied StudentId,
and then we inject that Student object into View. In a real life application, you can get the
student from the database instead of sample collection.

Now, if you click on the Edit link from Index view then you will get following error.

Edit View Error

The above error occurred because we have not created an Edit view yet. By default, MVC
framework will look for Edit.cshtml or Edit.vbhtml or Edit.aspx or Edit.ascx file in View -
> Student or Shared folder.

Step 3:
To create Edit view, right click inside Edit action method and click on Add View.. It will
open Add View dialogue.

In the Add View dialogue, keep the view name as Edit. (You can change as per your
requirement.)
Edit View

Select Edit in the Template dropdown and also select Student for Model class as shown
below.

Edit View

Now, click Add to generate Edit.cshtml view under View/Student folder as shown below.
Edit.cshtml:
@model MVC_BasicTutorials.Models.Student
@{
ViewBag.Title = "Edit";
Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>Edit</h2>

@using (Html.BeginForm())
{
@Html.AntiForgeryToken()

<div class="form-horizontal">
<h4>Student</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
@Html.HiddenFor(model => model.StudentId)

<div class="form-group">
@Html.LabelFor(model => model.StudentName, htmlAttributes:
new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.StudentName, new
{ htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.StudentName,
"", new { @class = "text-danger" })
</div>
</div>

<div class="form-group">
@Html.LabelFor(model => model.Age, htmlAttributes: new
{ @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Age, new { htmlAttributes
= new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Age, "", new
{ @class = "text-danger"< })
</div>
</div>

<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default"
/>
</div>
</div>
</div>
}

<div>
@Html.ActionLink("Back to List", "Index")
</div>
Please notice that Edit.cshtml includes HtmlHelper method @using (Html.BeginForm())
to create a html form element. Html.BeginForm sends a HttpPost request by default.

Now, click on the Edit link of any student in the Index view. Edit view will be display
student information whose Edit link clicked, as shown below.

Edit View

You can edit the Name or Age of Student and click on Save. Save method should send a
HttpPOST request because the POST request sends form data as a part of the request, not in
the querystring. So write a POST method as fourth step.

Step 4:
Now, write POST Edit action method to save the edited student as shown below.

Example: POST Method in MVC


[HttpPost]
public ActionResult Edit(Student std)
{
//write code to update student

return RedirectToAction("Index");
}

As you can see in the above code, the Edit() method requires a Student object as an input
parameter. The Edit() view will automatically binds form's data collection to the student
model parameter. Please visit Model Binding section for more information. Here, you can
update the information to the database and redirect it to Index action. (we have not written
code to update database here for demo purpose)

Now, clicking on the Save button in the Edit view will save the updated information and
redirect it to the Index() action method.

In this way, you can provide edit functionality using a default scaffolding Edit template.
However, you can also create an Edit view without using an Edit scaffolding template.

The following example demonstrates the StudentController class with all the action
methods.

Example: Controller in C#
using MVC_BasicTutorials.Models;

namespace MVC_BasicTutorials.Controllers
{
public class StudentController : Controller
{
IList<Student> studentList = new List<Student>() {
new Student(){ StudentId=1, StudentName="John", Age =
18 },
new Student(){ StudentId=2, StudentName="Steve", Age
= 21 },
new Student(){ StudentId=3, StudentName="Bill", Age =
25 },
new Student(){ StudentId=4, StudentName="Ram", Age =
20 },
new Student(){ StudentId=5, StudentName="Ron", Age =
31 },
new Student(){ StudentId=6, StudentName="Chris", Age
= 17 },
new Student(){ StudentId=7, StudentName="Rob", Age =
19 }
};
// GET: Student
public ActionResult Index()
{
return View(studentList);
}

public ActionResult Edit(int StudentId)


{
//Get the student from studentList sample collection for demo
purpose.
//You can get the student from the database in the real
application
var std = studentList.Where(s => s.StudentId ==
StudentId).FirstOrDefault();

return View(std);
}
[HttpPost]
public ActionResult Edit(Student std)
{
//write code to update student

return RedirectToAction("Index");
}
}
}

Learn how to implement validations in the razor view in the next section.

Implement Data Validation in MVC


In this section, you will learn how to implement data validations in the ASP.NET MVC
application.

We have created an Edit view for Student in the previous section. Now, we will implement
data validation in the Edit view, which will display validation messages on the click of
Save button, as shown below if Student Name or Age is blank.
Validation

DataAnnotations

ASP.NET MVC uses DataAnnotations attributes to implement validations.


DataAnnotations includes built-in validation attributes for different validation rules, which
can be applied to the properties of model class. ASP.NET MVC framework will
automatically enforce these validation rules and display validation messages in the view.

The DataAnnotations attributes included in System.ComponentModel.DataAnnotations


namespace. The following table lists DataAnnotations validation attributes.

Attribute Description

Required Indicates that the property is a required field

StringLength Defines a maximum length for string field

Range Defines a maximum and minimum value for a numeric field


Attribute Description

RegularExpression Specifies that the field value must match with specified Regular Expression

CreditCard Specifies that the specified field is a credit card number

CustomValidation Specified custom validation method to validate the field

EmailAddress Validates with email address format

FileExtension Validates with file extension

MaxLength Specifies maximum length for a string field

MinLength Specifies minimum length for a string field

Specifies that the field is a phone number using regular expression for phone
Phone
numbers

Let's start to implement validation in Edit view for student.

Step 1: First of all, apply DataAnnotation attribute on the properties of Student model
class. We want to validate that StudentName and Age is not blank. Also, Age should be
between 5 and 50. Visit Model section if you don't know how to create a model class.

Example: Apply DataAnnotation Attributes


public class Student
{
public int StudentId { get; set; }

[Required]
public string StudentName { get; set; }

[Range(5,50)]
public int Age { get; set; }
}

You can also apply multiple DataAnnotations validation attributes to a single property
if required.

In the above example, we have applied a Required attribute to the StudentName property.
So now, the MVC framework will automatically display the default error message, if the
user tries to save the Edit form without entering the Student Name. In the same way, the
Range attribute is applied with a min and max value to the Age property. This will validate
and display an error message if the user has either not entered Age or entered an age less
than 5 or more than 50.
Step 2: Create the GET and POST Edit Action method in the same as previous section. The
GET action method will render Edit view to edit the selected student and the POST Edit
method will save edited student as shown below.

Example: Edit Action methods:


using MVC_BasicTutorials.Models;

namespace MVC_BasicTutorials.Controllers
{
public class StudentController : Controller
{
public ActionResult Edit(int id)
{
var std = studentList.Where(s => s.StudentId == StudentId)
.FirstOrDefault();

return View(std);
}

[HttpPost]
public ActionResult Edit(Student std)
{
if (ModelState.IsValid) {

//write code to update student

return RedirectToAction("Index");
}

return View(std);
}
}
}

As you can see in the POST Edit method, we first check if the ModelState is valid or not. If
ModelState is valid then update the student into database, if not then return Edit view again
with the same student data.

ModelState.IsValid determines that whether submitted values satisfy all the


DataAnnotation validation attributes applied to model properties.

Step 3: Now, create an Edit view for Student.

To create an Edit view, right click inside Edit action method -> click Add View..
Create Edit View

In the Add View dialogue, keep the view name as Edit. (You can change as per your
requirement.)

Select the Edit template in the Template dropdown and also select Student Model class as
shown below.

Create Edit View


Now, click Add to generate Edit view under View/Student folder. Edit.cshtml will be
generated as shown below.

Edit.cshtml:
@model MVC_BasicTutorials.Models.Student

@{
ViewBag.Title = "Edit";
Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>Edit</h2>

@using (Html.BeginForm())
{
@Html.AntiForgeryToken()

<div class="form-horizontal">
<h4>Student</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
@Html.HiddenFor(model => model.StudentId)

<div class="form-group">
@Html.LabelFor(model => model.StudentName, htmlAttributes:
new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.StudentName, new
{ htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.StudentName,
"", new { @class = "text-danger" })
</div>
</div>

<div class="form-group">
@Html.LabelFor(model => model.Age, htmlAttributes: new
{ @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Age, new { htmlAttributes
= new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Age, "", new
{ @class = "text-danger" })
</div>
</div>

<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default"
/>
</div>
</div>
</div>
}

<div>
@Html.ActionLink("Back to List", "Index")
</div>

As you can see in the above Edit.cshtml, it calls Html Helper method
ValidationMessageFor for every field and ValidationSummary method at the top.
ValidationMessageFor is responsible to display error message for the specified field.
ValidationSummary displays a list of all the error messages at once.

So now, it will display default validation message when you submit an Edit form without
entering a Name or Age.

Validation

Thus, you can implement validations by applying various DataAnnotation attributes to the
model class and using ValidationMessage() or ValidationMessageFor() method in the view.

Learn how to implement client side validation in ASP.NET MVC.

Points to Remember :
1. ASP.NET MVC uses DataAnnotations attributes for validation.
2. DataAnnotations attributes can be applied to the properties of the model class to indicate
the kind of value the property will hold.
3. The following validation attributes available by default
1. Required
2. StringLength
3. Range
4. RegularExpression
5. CreditCard
6. CustomValidation
7. EmailAddress
8. FileExtension
9. MaxLength
10. MinLength
11. Phone
4. Use ValidationSummary to display all the error messages in the view.
5. Use ValidationMessageFor or ValidationMessage helper method to display field level
error messages in the view.
6. Check whether the model is valid before updating in the action method using
ModelState.IsValid.
7. Enable client side validation to display error messages without postback effect in the
browser.

ASP.NET MVC: ValidationMessage


You have learned how to implement validation in a view in the presious section. Here, we
will see the HtmlHelper extension method ValidtionMessage in detail.

The Html.ValidationMessage() is an extension method, that is a loosely typed method. It


displays a validation message if an error exists for the specified field in the
ModelStateDictionary object.

ValidationMessage() Signature

MvcHtmlString ValidateMessage(string modelName, string validationMessage,


object htmlAttributes)

Visit MSDN to know all the overloads of ValidationMessage() method.

Example: ValidationMessage
@model Student

@Html.Editor("StudentName") <br />


@Html.ValidationMessage("StudentName", "", new { @class = "text-
danger" })

In the above example, the first parameter in the ValidationMessage method is a property
name for which we want to show the error message e.g. StudentName. The second
parameter is for custom error message and the third parameter is for html attributes like css,
style etc.

The ValidationMessage() method will only display an error, if you have configured the
DataAnnotations attribute to the specifed property in the model class. The following is a
Student model class where the DataAnnotations attribute "Required" is applied to the
StudentName property.

Example: Student Model


public class Student
{
public int StudentId { get; set; }
[Required]
public string StudentName { get; set; }
public int Age { get; set; }
}

The above code will generate following html.

Html Result:
<input id="StudentName"
name="StudentName"
type="text"
value="" />

<span class="field-validation-valid text-danger"


data-valmsg-for="StudentName"
data-valmsg-replace="true">
</span>

Now, when the user submits a form without entering a StudentName, then ASP.NET MVC
uses a data- attribute of Html5 for the validation and a default validation message will be
injected, when the validation error occurs, as shown below.

Html with Validation message:


<span class="field-validation-error text-danger"
data-valmsg-for="StudentName"
data-valmsg-replace="true">The StudentName field is
required.</span>

The error message will look like below.


Output of
ValidationMessage() method

Custom Error Message

You can display your own error message instead of the default error message as shown
above. You can provide a custom error message either in the DataAnnotations attribute or
ValidationMessage() method.

Use the parameter of the DataAnnotation attributes to provide your own custom error
message as shown below.

Example: Custom error message in the Model


public class Student
{
public int StudentId { get; set; }
[Required(ErrorMessage="Please enter student name.")]
public string StudentName { get; set; }
public int Age { get; set; }
}

Also, you can specify a message as a second parameter in the ValidationMessage() method
as shown below.

Example: Custom error message


@model Student

@Html.Editor("StudentName") <br />


@Html.ValidationMessage("StudentName", "Please enter student name.", new
{ @class = "text-danger" })

ASP.NET MVC: ValidationMessageFor


The Html.ValidationMessageFor() is a strongly typed extension method. It displays a
validation message if an error exists for the specified field in the ModelStateDictionary
object.

ValidationMessageFor() Signature

MvcHtmlString ValidateMessage(Expression<Func<dynamic,TProperty>> expression,


string validationMessage, object htmlAttributes)
Visit MSDN to know all the overloads of ValidationMessageFor() method.

Consider the following ValidationMessageFor() example.

Example: ValidationMessageFor
@model Student

@Html.EditorFor(m => m.StudentName) <br />


@Html.ValidationMessageFor(m => m.StudentName, "", new { @class = "text-
danger" })

In the above example, the first parameter in ValidationMessageFor method is a lambda


expression to specify a property for which we want to show the error message. The second
parameter is for custom error message and the third parameter is for html attributes like css,
style etc.

The ValidationMessageFor() method will only display an error if you have configured
DataAnnotations attribute to the specifed property in the model class. The following
example is a Student model class where the DataAnnotations attribute "Required" is
applied to the StudentName property.

Example: Student Model


public class Student
{
public int StudentId { get; set; }
[Required]
public string StudentName { get; set; }
public int Age { get; set; }
}

The above code will generate the following html.

Html Result:
<input id="StudentName"
name="StudentName"
type="text"
value="" />

<span class="field-validation-valid text-danger"


data-valmsg-for="StudentName"
data-valmsg-replace="true">
</span>

Now, when the user submits a form without entering the StudentName then ASP.NET
MVC uses the data- attribute of Html5 for the validation and the default validation message
will be injected when validation error occurs, as shown below.

Html with Validation message:


<span class="field-validation-error text-danger"
data-valmsg-for="StudentName"
data-valmsg-replace="true">The StudentName field is
required.</span>

The error message will appear as the image shown below.

Output of
ValidationMessageFor() method

Custom Error Message

You can display your own error message instead of the default error message as above. You
can provide a custom error message either in the DataAnnotations attribute or the
ValidationMessageFor() method.

Use the ErrorMessage parameter of the DataAnnotation attributes to provide your own
custom error message as shown below.

Example: Custom error message in the Model


public class Student
{
public int StudentId { get; set; }
[Required(ErrorMessage="Please enter student name.")]
public string StudentName { get; set; }
public int Age { get; set; }
}

Also, you can specify a message as a second parameter in the ValidationMessage() method
as shown below.

Example: Custom error message


@model Student

@Html.Editor("StudentName") <br />


@Html.ValidationMessageFor(m => m.StudentName, "Please enter student
name.", new { @class = "text-danger" })

Learn about ValidationSummary method in the next section.

ASP.NET MVC: ValidationSummary


The ValidationSummary helper method generates an unordered list (ul element) of
validation messages that are in the ModelStateDictionary object.

The ValidationSummary can be used to display all the error messages for all the fields. It
can also be used to display custom error messages. The following figure shows how
ValidationSummary displays the error messages.

Va
lidationSummary

ValidationSummary() Signature

MvcHtmlString ValidateMessage(bool excludePropertyErrors, string message, object


htmlAttributes)

Visit MSDN to know all the overloads of ValidationMessage() method.

Display Field Level Error Messages using ValidationSummary

By default, ValidationSummary filters out field level error messages. If you want to display
field level error messages as a summary then specify excludePropertyErrors = false.

Example: ValidationSummary to display field errors


@Html.ValidationSummary(false, "", new { @class = "text-danger" })
So now, the following Edit view will display error messages as a summary at the top.
Please make sure that you don't have a ValidationMessageFor method for each of the fields.

Err
or Message using ValidationSummary

Display Custom Error Messages

You can also display a custom error message using ValidationSummary. For example, we
want to display a message if Student Name already exists in the database.

To display a custom error message, first of all, you need to add custom errors into the
ModelState in the appropriate action method.

Example: Add error in ModelState


if (ModelState.IsValid) {

//check whether name is already exists in the database or not


bool nameAlreadyExists = * check database *

if(nameAlreadyExists)
{
ModelState.AddModelError(string.Empty, "Student Name already
exists.");

return View(std);
}
}
As you can see in the above code, we have added custom error messages using the
ModelState.AddModelError method. The ValidationSummary method will automatically
display all the error messages added into ModelState.

Dis
play error message using ValidationSymmary

Thus, you can use the ValidationSummary helper method to display error messages.

Layout View
In this section, you will learn about the layout view in ASP.NET MVC.

An application may contain common parts in the UI which remains the same throughout the
application such as the logo, header, left navigation bar, right bar or footer section.
ASP.NET MVC introduced a Layout view which contains these common UI parts, so that
we don't have to write the same code in every page. The layout view is same as the master
page of the ASP.NET webform application.

For example, an application UI may contain Header, Left menu bar, right bar and footer
section that remains same in every page and only the centre section changes dynamically as
shown below.
Sample Application UI
Parts

The layout view allows you to define a common site template, which can be inherited in
multiple views to provide a consistent look and feel in multiple pages of an application. The
layout view eliminates duplicate coding and enhances development speed and easy
maintenance. The layout view for the above sample UI would contain a Header, Left Menu,
Right bar and Footer sections. It contains a placeholder for the center section that changes
dynamically as shown below.
Layout View

The razor layout view has same extension as other views, .cshtml or .vbhtml. Layout views
are shared with multiple views, so it must be stored in the Shared folder. For example,
when we created our first MVC application in the previous section, it also created
_Layout.cshtml in the Shared folder as shown below.

Layout Views in Shared Folder

The following is an auto-generated _Layout.cshtml.


_Layout.cshtml:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-
scale=1.0">
<title>@ViewBag.Title - My ASP.NET Application</title>
@Styles.Render("~/Content/css")
@Scripts.Render("~/bundles/modernizr")
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-
toggle="collapse" data-target=".navbar-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
@Html.ActionLink("Application name", "Index", "Home", new
{ area = "" }, new { @class = "navbar-brand" })
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li>@Html.ActionLink("Home", "Index", "Home")</li>
<li>@Html.ActionLink("About", "About", "Home")</li>
<li>@Html.ActionLink("Contact", "Contact",
"Home")</li>
</ul>
</div>
</div>
</div>
<div class="container body-content">
@RenderBody()
<hr />
<footer>
<p>&copy; @DateTime.Now.Year - My ASP.NET Application</p>
</footer>
</div>

@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/bootstrap")
@RenderSection("scripts", required: false)
</body>
</html>

As you can see, the layout view contains html Doctype, head and body as normal html, the
only difference is call to RenderBody() and RenderSection() methods. RenderBody acts
like a placeholder for other views. For example, Index.cshtml in the home folder will be
injected and rendered in the layout view, where the RenderBody() method is being called.
You will learn about these rendering methods later in this section.
Use Layout View

You must be wondering that how would the View know which layout view to use?

You can set the layout view in multiple ways, by using _ViewStart.cshtml or setting up
path of the layout page using Layout property in the individual view or specifying layout
view name in the action method.

_ViewStart.cshtml

_ViewStart.cshtml is included in the Views folder by default. It sets up the default layout
page for all the views in the folder and its subfolders using the Layout property. You can
assign a valid path of any Layout page to the Layout property.

For example, the following _ViewStart.cshtml in the Views folder, sets the Layout property
to "~/Views/Shared/_Layout.cshtml". So now, _layout.cshtml would be layout view of all
the views included in Views and its subfolders. So by default, all the views derived default
layout page from _ViewStart.cshtml of Views folder.

_ViewStart.cshtml

_ViewStart.cshtml can also be included in sub folder of View folder to set the default
layout page for all the views included in that particular subfolder only.

For example, the following _ViewStart.cshtml in Home folder, sets Layout property to
_myLayoutPage.cshtml. So this _ViewStart.cshtml will influence all the views included in
the Home folder only. So now, Index, About and Contact views will be rendered in
_myLayoutPage.cshtml instead of default _Layout.cshml.
Layout View

Setting Layout property in individual view

You can also override default layout page set by _ViewStart.cshtml by setting Layout
property in each individual .cshtml view. For example, the following Index view use
_myLayoutPage.cshtml even if _ViewStart.cshtml set _Layout.cshtml.

Index View:
@{
ViewBag.Title = "Home Page";
Layout = "~/Views/Shared/_myLayoutPage.cshtml";
}

<div class="jumbotron">
<h1>ASP.NET</h1>
<p class="lead">ASP.NET is a free web framework for building great
Web sites and Web applications using HTML, CSS and JavaScript.</p>
<p><a href="http://asp.net" class="btn btn-primary btn-lg">Learn more
&raquo;</a></p>
</div>

<div class="row">
<div class="col-md-4">
<h2>Getting started</h2>
<p>
ASP.NET MVC gives you a powerful, patterns-based way to build
dynamic websites that
enables a clean separation of concerns and gives you full
control over markup
for enjoyable, agile development.
</p>
<p><a class="btn btn-default"
href="http://go.microsoft.com/fwlink/?LinkId=301865">Learn more
&raquo;</a></p>
</div>
<div class="col-md-4">
<h2>Get more libraries</h2>
<p>NuGet is a free Visual Studio extension that makes it easy to
add, remove, and update libraries and tools in Visual Studio
projects.</p>
<p><a class="btn btn-default"
href="http://go.microsoft.com/fwlink/?LinkId=301866">Learn more
&raquo;</a></p>
</div>
<div class="col-md-4">
<h2>Web Hosting</h2>
<p>You can easily find a web hosting company that offers the
right mix of features and price for your applications.</p>
<p><a class="btn btn-default"
href="http://go.microsoft.com/fwlink/?LinkId=301867">Learn more
&raquo;</a></p>
</div>
</div>

Specify Layout Page in ActionResult Method

You can also specify which layout page to use in while rendering view from action method
using View() method.

The following example, View() method renders Index view using _myLayoutPage.cshtml.

Example: Specify Layout View in Action Method


public class HomeController : Controller
{
public ActionResult Index()
{
return View("Index", "_myLayoutPage");
}

public ActionResult About()


{
return View();
}

public ActionResult Contact()


{
return View();
}
}
Rendering Methods

ASP.NET MVC layout view renders child views using the following methods.

Method Description

Renders the portion of the child view that is not within a named section.
RenderBody()
Layout view must include RenderBody() method.

RenderSection(string Renders a content of named section and specifies whether the section is
name) required. RenderSection() is optional in Layout view.

The following figure illustrates the use of RenderBody and RenderSection methods.
Rendering Methods

As you can see in the above figure, _Layout.cshtml includes RenderBody() method and
RenderSection() method. RenderSection methods specify name of a section such as
LeftSection, MiddleSection and RightSection in the above figure. Index.cshtml defines
named section using @section where name of each section matches with the name specified
in RenderSection method of _Layout.cshtml, such as @Section RightSection etc. At run
time, the named sections of Index.cshtml such as LeftSection, RightSection and
MiddleSection will be rendered at appropriate place where RenderSection method is called.
Rest of the part of Index view, which is not in any of the named section will render where
RenderBody() method is being called.

Let's create a new layout view to understand the above render methods in the next section.

Learn the Difference between RenderBody and RenderSection methods.

Points to Remember :

1. The Layout view contains common parts of a UI. It is same like masterpage of ASP.NET
webforms.
2. _ViewStart.cshtml file can be used to specify path of layout page, which in turn will be
applicable to all the views of the folder and its subfolder.
3. You can set the Layout property in the individual view also, to override default layout page
setting of _ViewStart.cshtml
4. Layout view uses two rendering methods: RenderBody() and RenderSection().
5. RenderBody can be used only once in the layout view, whereas the RenderSection method
can be called multiple time with different name.
6. RenderBody method renders all the content of view which is not wrapped in named
section.
7. RenderSection method renders the content of a view which is wrapped in named section.
8. RenderSection can be configured as required or optional. If required, then all the child
views must included that named section.

Learn to create layout view next.

Create Layout View


To create a new layout view in Visual Studio, right click on shared folder -> select Add ->
click on New Item..

In the Add New Item dialogue box, select MVC 5 Layout Page (Razor) and give the layout
page name as "_myLayoutPage.cshtml" and click Add.
Rendering Methods

You will see _myLayoutPage.cshtml as shown below.

_myLayoutPage.cshtml:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>@ViewBag.Title</title>
</head>
<body>
<div>
@RenderBody()
</div>
</body>
</html>

Now, add the <footer> tag with the RenderSection("footer",true) method alongwith
some styling as shown below. Please notice that we made this section as required. This
means any view that uses _myLayoutPage as its layout view must include a footer section.

Example: Adding RenderSection


<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>@ViewBag.Title</title>
@Styles.Render("~/Content/css")
@Scripts.Render("~/bundles/modernizr")
</head>
<body>
<div>
@RenderBody()
</div>
<footer class="panel-footer">
@RenderSection("footer", true)
</footer>
</body>
</html>

Now, let's use this _myLayoutPage.cshtml with the Index view of HomeController.

You can add an empty Index view by right clicking on Index action method of
HomeController and select Add View. Select Empty as a scaffolding template and
_myLayoutPage.cshtml as layout view and click Add.

Add Index View

This will create Index.cshtml as shown below.

Index view:
@{
ViewBag.Title = "Home Page";
Layout = "~/Views/Shared/_myLayoutPage.cshtml";
}

<h2>Index</h2>
So now, we have created Index view that uses our _myLayoutPage.cshtml as a layout view.
We will now add footer section along with some styling because _myLayoutPage requires
footer section.

Index view:
@{
ViewBag.Title = "Home Page";
Layout = "~/Views/Shared/_myLayoutPage.cshtml";
}

<div class="jumbotron">
<h2>Index</h2>
</div>
<div class="row">
<div class="col-md-4">
<p>This is body.</p>
</div>
@section footer{
<p class="lead">
This is footer section.
</p>
}
</div>

Now, run the application and you will see Index view will contain body and footer part as
shown below.
Index View

Thus, you can create new layout view with different rendering methods.

Partial View
In this section you will learn about partial views in ASP.NET MVC.

Partial view is a reusable view, which can be used as a child view in multiple other views.
It eliminates duplicate coding by reusing same partial view in multiple places. You can use
the partial view in the layout view, as well as other content views.

To start with, let's create a simple partial view for the following navigation bar for demo
purposes. We will create a partial view for it, so that we can use the same navigation bar in
multiple layout views without rewriting the same code everywhere.
Partial View

The following figure shows the html code for the above navigation bar. We will cut and
paste this code in a seperate partial view for demo purposes.
Partial Views

Create a New Partial View

To create a partial view, right click on Shared folder -> select Add -> click on View..

Note:

If a partial view will be shared with multiple views of different controller folder then create it in
the Shared folder, otherwise you can create the partial view in the same folder where it is going to
be used.

In the Add View dialogue, enter View name and select "Create as a partial view" checkbox
and click Add.
Partial Views

We are not going to use any model for this partial view, so keep the Template dropdown as
Empty (without model) and click Add. This will create an empty partial view in Shared
folder.

Now, you can cut the above code for navigation bar and paste it in _HeaderNavBar.cshtml
as shown below:

Example: Partial View _HeaderNavBar.cshtml


<div class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-
toggle="collapse" data-target=".navbar-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
@Html.ActionLink("Application name", "Index", "Home", new
{ area = "" }, new { @class = "navbar-brand" })
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li>@Html.ActionLink("Home", "Index", "Home")</li>
<li>@Html.ActionLink("About", "About", "Home")</li>
<li>@Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>
</div>
</div>
</div>

Thus, you can create a new partial view. Let's see how to render partial view.
Render Partial View

You can render the partial view in the parent view using html helper methods: Partial() or
RenderPartial() or RenderAction(). Each method serves different purposes. Let's have an
overview of each method and then see how to render partial view using these methods.

Html.Partial()

@Html.Partial() helper method renders the specified partial view. It accept partial view
name as a string parameter and returns MvcHtmlString. It returns html string so you have a
chance of modifing the html before rendering.

The following table lists overloads of the Partial helper method:

Helper Method Description

MvcHtmlString Html.Partial(string Renders the given partial view content in the


partialViewName) referred view.

Renders the partial view content in the referred


MvcHtmlString Html.Partial(string
view. Model parameter passes the model object to
partialViewName,object model)
the partial view.

MvcHtmlString Html.Partial(string Renders the partial view content in the referred


partialViewName, ViewDataDictionary view. View data parameter passes view data
viewData) dictionary to the partial view.

Renders the partial view content in the referred


MvcHtmlString Html.Partial(string
view. Model parameter passes the model object and
partialViewName,object model,
View data passes view data dictionary to the partial
ViewDataDictionary viewData)
view.

Html.RenderPartial()

The RenderPartial helper method is same as the Partial method except that it returns void
and writes resulted html of a specified partial view into a http response stream directly.

Helper method Description

RenderPartial(String
Renders the specified partial view
partialViewName)

RenderPartial(String Renders the specified partial view and set the specified
partialViewName, Object model) model object

RenderPartial(String Renders the specified partial view, replacing its ViewData


partialViewName, ViewDataDictionary
Helper method Description

viewData) property with the specified ViewDataDictionary object.

Renders the specified partial view, replacing the partial


RenderPartial(String
view's ViewData property with the specified
partialViewName, Object model,
ViewDataDictionary object and set the specified model
ViewDataDictionary viewData)
object

Html.RenderAction()

The RenderAction helper method invokes a specified controller and action and renders the
result as a partial view. The specified Action method should return PartialViewResult using
the Partial() method.

Name Description

Invokes the specified child action method and


RenderAction(String actionName)
renders the result in the parent view.

Invokes the specified child action method using the


RenderAction(String actionName, Object
specified parameters and renders the result inline in
routeValue)
the parent view.

Invokes the specified child action method using the


RenderAction(String actionName, String
specified controller name and renders the result
controllerName)
inline in the parent view.

Invokes the specified child action method using the


RenderAction(String actionName,
specified parameters and renders the result inline in
RouteValueDictionary routeValues)
the parent view.

Invokes the specified child action method using the


RenderAction(String actionName, String
specified parameters and controller name and
controllerName, Object routeValue)
renders the result inline in the parent view.

RenderAction(String actionName, String Invokes the specified child action method using the
controllerName, RouteValueDictionary specified parameters and controller name and
routeValues) renders the result inline in the parent view.

So now, we can use any of the above rending methods to render the _HeaderNavBar partial
view into _Layout.cshtml. The following layout view renders partial view using the
RenderPartial() method.

Example: Html.RenderPartial()
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,
initial-scale=1.0">
<title>@ViewBag.Title - My ASP.NET Application</title>
@Styles.Render("~/Content/css")
@Scripts.Render("~/bundles/modernizr")
</head>
<body>
@{
Html.RenderPartial("_HeaderNavBar");
}
<div class="container body-content">
@RenderBody()

<hr />
<footer>
<p>&copy; @DateTime.Now.Year - My ASP.NET Application</p>
</footer>
</div>

@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/bootstrap")
@RenderSection("scripts", required: false)
</body>
</html>
Note:

RenderPartial returns void, so a semicolon is required at the end and so it must be enclosed in the
braces.

The following layout view uses the Partial method to render partial
view_HeaderNavBar.cshtml.

Example: Html.Partial()
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,
initial-scale=1.0">
<title>@ViewBag.Title - My ASP.NET Application</title>
@Styles.Render("~/Content/css")
@Scripts.Render("~/bundles/modernizr")
</head>
<body>
@Html.Partial("_HeaderNavBar")
<div class="container body-content">
@RenderBody()

<hr />
<footer>
<p>&copy; @DateTime.Now.Year - My ASP.NET Application</p>
</footer>
</div>

@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/bootstrap")
@RenderSection("scripts", required: false)
</body>
</html>
Note:

@Html.Partial() method doesn't need to be in code block because it returns a html string.

You will see following UI in browser when you run the application.

Index.cshtml

So in this way, you can use partial view without any differences in the UI.

Learn the Difference between html.Partial and Html.RenderPartial.

Points to Remember :

1. Partial view is a reusable view, which can be used as a child view in multiple other views.
2. Partial view can be rendered using Html.Partial(), Html.RenderPartial() or
Html.RenderAction() method.
ASP.NET MVC - ViewBag
We have learned in the previous section that the model object is used to send data in a razor
view. However, there may be some scenario where you want to send a small amount of
temporary data to the view. So for this reason, MVC framework includes ViewBag.

ViewBag can be useful when you want to transfer temporary data (which is not included in
model) from the controller to the view. The viewBag is a dynamic type property of
ControllerBase class which is the base class of all the controllers.

The following figure illustrates the ViewBag.

ViewBag

In the above figure, it attaches Name property to ViewBag with the dot notation and assigns
a string value "Bill" to it in the controller. This can be accessed in the view like
@ViewBag.Name. (@ is razor syntax to access the server side variable.)

You can assign a primitive or a complex type object as a value to ViewBag


property.

You can assign any number of properties and values to ViewBag. If you assign the same
property name multiple times to ViewBag, then it will only consider last value assigned to
the property.

Note:
ViewBag only transfers data from controller to view, not visa-versa. ViewBag values will
be null if redirection occurs.

The following example demonstrates how to transfer data from controller to view using
ViewBag.

Example: Set ViewBag in Action method


namespace MVC_BasicTutorials.Controllers
{
public class StudentController : Controller
{
IList<Student> studentList = new List<Student>() {
new Student(){ StudentID=1, StudentName="Steve", Age
= 21 },
new Student(){ StudentID=2, StudentName="Bill", Age =
25 },
new Student(){ StudentID=3, StudentName="Ram", Age =
20 },
new Student(){ StudentID=4, StudentName="Ron", Age =
31 },
new Student(){ StudentID=5, StudentName="Rob", Age =
19 }
};
// GET: Student
public ActionResult Index()
{
ViewBag.TotalStudents = studentList.Count();

return View();
}

}
}

In the above example, we want to display the total number of students in a view for the
demo. So, we have attached the TotalStudents property to the ViewBag and assigned the
student count using studentList.Count().

Now, in the Index.cshtml view, you can access ViewBag.TotalStudents property and
display all the student info as shown below.

Example: Acess ViewBag in a View


<label>Total Students:</label> @ViewBag.TotalStudents
Output:
Total Students: 5

ViewBag doesn't require typecasting while retriving values from it.

Internally, ViewBag is a wrapper around ViewData. It will throw a runtime exception, if


the ViewBag property name matches with the key of ViewData.

Points to Remember :

1. ViewBag transfers data from the controller to the view, ideally temporary data
which in not included in a model.
2. ViewBag is a dynamic property that takes advantage of the new dynamic features in
C# 4.0
3. You can assign any number of propertes and values to ViewBag
4. The ViewBag's life only lasts during the current http request. ViewBag values will
be null if redirection occurs.
5. ViewBag is actually a wrapper around ViewData.
ASP.NET MVC - ViewData
ViewData is similar to ViewBag. It is useful in transferring data from Controller to View.

ViewData is a dictionary which can contain key-value pairs where each key must be string.

The following figure illustrates the ViewData.

ViewData
Note:
ViewData only transfers data from controller to view, not vice-versa. It is valid only during
the current request.

The following example demonstrates how to transfer data from controller to view using
ViewData.

Example: ViewData in Action method


public ActionResult Index()
{
IList<Student> studentList = new List<Student>();
studentList.Add(new Student(){ StudentName = "Bill" });
studentList.Add(new Student(){ StudentName = "Steve" });
studentList.Add(new Student(){ StudentName = "Ram" });

ViewData["students"] = studentList;

return View();
}

In the above example, we have added a student list with the key "students" in the ViewData
dictionary. So now, the student list can be accessed in a view as shown below.

Example: Access ViewData in a Razor View


<ul>
@foreach (var std in ViewData["students"] as IList<Student>)
{
<li>
@std.StudentName
</li>
}
</ul>
Please notice that we must cast ViewData values to the appropriate data type.

You can also add a KeyValuePair into ViewData as shown below.

Example: Add KeyValuePair in ViewData


public ActionResult Index()
{
ViewData.Add("Id", 1);
ViewData.Add(new KeyValuePair<string, object>("Name", "Bill"));
ViewData.Add(new KeyValuePair<string, object>("Age", 20));

return View();
}

ViewData and ViewBag both use the same dictionary internally. So you cannot have
ViewData Key matches with the property name of ViewBag, otherwise it will throw a
runtime exception.

Example: ViewBag and ViewData


public ActionResult Index()
{
ViewBag.Id = 1;

ViewData.Add("Id", 1); // throw runtime exception as it already has


"Id" key
ViewData.Add(new KeyValuePair<string, object>("Name", "Bill"));
ViewData.Add(new KeyValuePair<string, object>("Age", 20));

return View();
}

Points to Remember :

1. ViewData transfers data from the Controller to View, not vice-versa.


2. ViewData is derived from ViewDataDictionary which is a dictionary type.
3. ViewData's life only lasts during current http request. ViewData values will be
cleared if redirection occurs.
4. ViewData value must be type cast before use.
5. ViewBag internally inserts data into ViewData dictionary. So the key of ViewData
and property of ViewBag must NOT match.

ASP.NET MVC - TempData


TempData in ASP.NET MVC can be used to store temporary data which can be used in the
subsequent request. TempData will be cleared out after the completion of a subsequent
request.
TempData is useful when you want to transfer non-sensitive data from one action method
to another action method of the same or a different controller as well as redirects. It is
dictionary type which is derived from TempDataDictionary.

You can add a key-value pair in TempData as shown in the below example.

Example: TempData
public class HomeController : Controller
{
// GET: Student
public HomeController()
{

}
public ActionResult Index()
{
TempData["name"] = "Test data";
TempData["age"] = 30;

return View();
}

public ActionResult About()


{
string userName;
int userAge;

if(TempData.ContainsKey("name"))
userName = TempData["name"].ToString();

if(TempData.ContainsKey("age"))
userAge = int.Parse(TempData["age"].ToString());

// do something with userName or userAge here

return View();
}
}

In the above example, we have added data into TempData and accessed the same data using
a key inside another action method. Please notice that we have converted values into the
appropriate type.

The following figure illustrates TempData.


TempData

TempData internally uses session to store the data. So the data must be serialized
if you decide you to switch away from the default Session-State Mode, and use State Server
Mode or SQL Server Mode.

As you can see in the above example, we add test data in TempData in the first request and
in the second subsequent request we access test data from TempData which we stored in
the first request. However, you can't get the same data in the third request because
TempData will be cleared out after second request.

Call TempData.Keep() to retain TempData values in a third consecutive request.

Example: TempData.Keep()
public class HomeController : Controller
{
public HomeController()
{

public ActionResult Index()


{
TempData["myData"] = "Test data";
return View();
}

public ActionResult About()


{
string data;

if(TempData["myData"] != null)
data = TempData["myData"] as string;
TempData.Keep();

return View();
}

public ActionResult Contact()


{
string data;

if(TempData["myData"] != null)
data = TempData["myData"] as string;

return View();
}
}

Points to Remember :

1. TempData can be used to store data between two consecutive requests. TempData
values will be retained during redirection.
2. TemData is a TempDataDictionary type.
3. TempData internaly use Session to store the data. So think of it as a short lived
session.
4. TempData value must be type cast before use. Check for null values to avoid
runtime error.
5. TempData can be used to store only one time messages like error messages,
validation messages.
6. Call TempData.Keep() to keep all the values of TempData in a third request.

ASP.NET MVC- Filters


In ASP.NET MVC, a user request is routed to the appropriate controller and action method.
However, there may be circumstances where you want to execute some logic before or after
an action method executes. ASP.NET MVC provides filters for this purpose.

ASP.NET MVC Filter is a custom class where you can write custom logic to execute before
or after an action method executes. Filters can be applied to an action method or controller
in a declarative or programmatic way. Declarative means by applying a filter attribute to an
action method or controller class and programmatic means by implementing a
corresponding interface.

MVC provides different types of filters. The following table list filter types, built-in filters
for the type and interface which must be implemented to create a custom filter class.
Filter Type Description Built-in Filter Interface

Authorization Performs authentication and authorizes [Authorize],


IAuthorizationFilter
filters before executing action method. [RequireHttps]

Performs some operation before and after


Action filters   IActionFilter
an action method executes.

Performs some operation before or after


Result filters [OutputCache] IResultFilter
the execution of view result.

Performs some operation if there is an


Exception
unhandled exception thrown during the [HandleError] IExceptionFilter
filters
execution of the ASP.NET MVC pipeline.

To understand the filter in detail, let's take an example of built-in Exception filter.

An exception filter executes when there is an unhandled exception occurs in your


application. HandleErrorAttribute ([HandlerError]) class is a built-in exception filter class
in MVC framework. This built-in HandleErrorAttribute class renders Error.cshtml included
in the Shared folder by default, when an unhandled exception occurs.

Error.cshtml

The following example demonstrates built-in exception filter HandErrorAttribute.

Example: Authorization Filter


[HandleError]
public class HomeController : Controller
{
public ActionResult Index()
{
//throw exception for demo
throw new Exception("This is unhandled exception");

return View();
}

public ActionResult About()


{
return View();
}

public ActionResult Contact()


{
return View();
}
}

Every attribute class must end with Attribute e.g. HanderErrorAttribute. Attribute must
be applied without Attribute suffix inside square brackets [ ] like [HandelError].

In the above example, we have applied [HandleError] attribute to HomeController. So


now it will display Error page if any action method of HomeController would throw
unhandled exception. Please note that unhandled exception is an exception which is not
handled by the try-catch block.

Filters applied to the controller will automatically be applicable to all the action methods of
a controller.

Please make sure that CustomError mode is on in System.web section of web.config, in


order for HandleErrorAttribute work properly.

Example: SetCustomError in web.config


<customErrors mode="On" />

Now, if you run the application. You would get following error page because we throw
exception in Index action method for the demo purpose.

HandleError Demo
Thus, HandleError attribute will display common error page for any unhandled exception
occurred in HomeController.

Register Filters

Filters can be applied at three levels.

1. Global Level

You can apply filters at global level in the Application_Start event of Global.asax.cs file by
using default FilterConfig.RegisterGlobalFilters() mehtod. Global filters will be applied to
all the controller and action methods of an application.

The [HandleError] filter is applied globaly in MVC Application by default in every MVC
application created using Visual Studio as shown below.

Example: Register Global Filters


// MvcApplication class contains in Global.asax.cs file
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
}
}

// FilterConfig.cs located in App_Start folder


public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection
filters)
{
filters.Add(new HandleErrorAttribute());
}
}

2. Controller level

Filters can also be applied to the controller class. So, filters will be applicable to all the
action method of Controller class if it is applied to a controller class.

Example: Action Filters on Controller

[HandleError]
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}

3. Action method level

You can apply filters to an individual action method also. So, filter will be applicable to
that particular action method only.

Example: Filters on Action Method


public class HomeController : Controller
{
[HandleError]
public ActionResult Index()
{
return View();
}

The same way, you can apply multiple built-in or custom filters globally or at controller or
action method level for different purpose such as [Authorize],[RequireHttps],
[ChildActionOnly],[OutputCache],[HandleError].

Filter Order

As mentioned above, MVC includes different types of filters and multiple filters can be
applied to a single controller class or action method. So, filters run in the following order.

1. Authorization filters
2. Action filters
3. Response filters
4. Exception filters

Create Custom Filter

You can create custom filter attributes by implementing an appropriate filter interface for
which you want to create a custom filter and also derive a FilterAttribute class so that you
can use that class as an attribute.

For example, implement IExceptionFilter and FilterAttribute class to create custom


exception filter. In the same way implement an IAuthorizatinFilter interface and
FilterAttribute class to create a custom authorization filter.

Example: Custom Exception Filter


class MyErrorHandler : FilterAttribute, IExceptionFilter
{
public override void IExceptionFilter.OnException(ExceptionContext
filterContext)
{
Log(filterContext.Exception);

base.OnException(filterContext);
}

private void Log(Exception exception)


{
//log exception here..

}
}

Alternatively, you can also derive a built-in filter class and override an appropriate method
to extend the functionality of built-in filters.

Let's create custom exception filter to log every unhandled exception by deriving built-in
HandleErrorAttribute class and overriding OnException method as shown below.

Example: Custom Exception Filter


class MyErrorHandler : HandleErrorAttribute
{
public override void OnException(ExceptionContext filterContext)
{
Log(filterContext.Exception);

base.OnException(filterContext);
}

private void Log(Exception exception)


{
//log exception here..

}
}

Now, you can apply MyErrorHandler attribute at global level or controller or action method
level, the same way we applied the HandleError attribute.

Example: Custom Action Filters to Controller


[MyErrorHandler]
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}

}
Points to Remember :

1. MVC Filters are used to execute custom logic before or after executing action method.
2. MVC Filter types:
1. Authorization filters
2. Action filters
3. Result filters
4. Exception filters
3. Filters can be applied globally in FilterConfig class, at controller level or action method
level.
4. Custom filter class can be created by implementing FilterAttribute class and corresponding
interface.

ASP.NET MVC - Action Filters


In the previous section, you learned about filters in MVC. In this section, you will learn
about another filter type called Action Filters in ASP.NET MVC.

Action filter executes before and after an action method executes. Action filter attributes
can be applied to an individual action method or to a controller. When action filter applied
to controller then it will be applied to all the action methods in that controller.

OutputCache is a built-in action filter attribute that can be apply to an action method for
which we want to cache the output. For example, output of the following action method
will be cached for 100 seconds.

Example: ActionFilter
[OutputCache(Duration=100)]
public ActionResult Index()
{
return View();
}

You can create custom action filter for your application. Let's see how to create custom
action filters.

Custom Action Filter

You can create custom action filter by two ways. First, by implementing IActionFilter
interface and FilterAttribute class. Second, by deriving ActionFilterAttribute abstract class.

IActionFilter interface include following methods to implement:


 void OnActionExecuted(ActionExecutedContext filterContext)
 void OnActionExecuting(ActionExecutingContext filterContext)

ActionFilterAttribute abstract class includes the following methods to override:

 void OnActionExecuted(ActionExecutedContext filterContext)


 void OnActionExecuting(ActionExecutingContext filterContext)
 void OnResultExecuted(ResultExecutedContext filterContext)
 void OnResultExecuting(ResultExecutingContext filterContext)

As you can see that ActionFilterAttribute class has four methods to overload. It includes
OnResultExecuted and OnResultExecuting methods, which can be used to execute custom
logic before or after result executes. Action filters are generally used to apply cross-cutting
concerns such as logging, caching, authorization etc.

Consider the following custom Log filter class for logging.

Example: Custom ActionFilter for Logging


public class LogAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext
filterContext)
{
Log("OnActionExecuted", filterContext.RouteData);
}

public override void OnActionExecuting(ActionExecutingContext


filterContext)
{
Log("OnActionExecuting", filterContext.RouteData);
}

public override void OnResultExecuted(ResultExecutedContext


filterContext)
{
Log("OnResultExecuted", filterContext.RouteData);
}

public override void OnResultExecuting(ResultExecutingContext


filterContext)
{
Log("OnResultExecuting ", filterContext.RouteData);
}

private void Log(string methodName, RouteData routeData)


{
var controllerName = routeData.Values["controller"];
var actionName = routeData.Values["action"];
var message = String.Format("{0}- controller:{1} action:{2}",
methodName,

controllerName,
actionName);
Debug.WriteLine(message);
}
}

As you can see, Log class derived ActionFilterAttribute class. It logs before and after action
method or result executes. You can apply Log attribute to any Controller or action methods
where you want to log the action. For example, by applying Log attribute to Controller, it
will log each action methods of that controller.

Example: Apply Log ActionFilter to Controller


[Log]
public class StudentController : Controller
{
public ActionResult Index()
{
return View();
}

public ActionResult About()


{
return View();
}

public ActionResult Contact()


{
return View();
}
}

The above example will show following output in the output window of Visual Studio on
http://localhost/student request.

Output:
OnActionExecuting- controller:Home action:Index
OnActionExecuted- controller:Home action:Index
OnResultExecuting - controller:Home action:Index
OnResultExecuted- controller:Home action:Index

Points to Remember :

1. Action filters allow pre and post processing logic to be applied to an action method.
2. Action filters are generally used to apply cross-cutting concerns such as logging, caching,
authorization etc.
3. Action filter can be registered as other filters at global, controller or action method level.
4. Custom action filter attribute can be created by deriving ActionFilterAttribute class or
implementing IActionFilter interface and FilterAttribute abstract class.
5. Every action filter must override OnActionExecuted, OnActionExecuting,
OnResultExecuted, OnResultExecuting methods.

Bundling
Bundling and minification techniques were introduced in MVC 4 to improve request load
time. Bundling allow us to load the bunch of static files from the server into one http
request.

The following figure illustrates the bundling techniques:

Load
script files in separate requests

In the above figure, browser sends two separate requests to load two different JavaScript
file MyJavaScriptFile-1.js and MyJavaScriptFile-2.js.

Bundling technique in MVC 4 allows us to load more than one JavaScript file,
MyJavaScriptFile-1.js and MyJavaScriptFile-2.js in one request as shown below.
Minification

Minification technique optimizes script or css file size by removing unnecessary white
space and comments and shortening variable names to one character.

For example, consider following JavaScript function.

Example: JavaScript
sayHello = function(name){
//this is comment
var msg = "Hello" + name;
alert(msg);
}

The above JavaScript will be optimized and minimized into following script.

Example: Minified JavaScript


sayHello=function(n){var t="Hello"+n;alert(t)}

As you can see above, it has removed unnecessary white space, comments and also
shortening variable names to reduce the characters which in turn will reduce the size of
JavaScript file.

Bundling and minification impacts on the loading of the page, it loads page faster by
minimizing size of the file and number of requests.

Bundle Types

MVC 5 includes following bundle classes in System.web.Optimization namespace:

ScriptBundle: ScriptBundle is responsible for JavaScript minification of single or multiple


script files.

StyleBundle: StyleBundle is responsible for CSS minification of single or multiple style


sheet files.

DynamicFolderBundle: Represents a Bundle object that ASP.NET creates from a folder


that contains files of the same type.

All the above bundle classes are included in System.Web.Optimization.Bundle namespace


and derived from Bundle class.

Learn about ScriptBundle in the next section.

Points to Remember :
1. Bundling and Minification minimize static script or css files loading time therby minimize
page loading time.
2. MVC framework provides ScriptBundle, StyleBundle and DynamicFolderBundle classes.
3. ScriptBundle does minification of JavaScript files.
4. StyleBundle does minification of CSS files.

ScriptBundle in ASP.NET MVC


We have learned how bundling technique works in ASP.NET MVC. Here, we will learn
how to create a bundle of multiple JavaScript files in one http request.

ASP.NET MVC API includes ScriptBundle class that does JavaScript minification and
bundling.

Open App_Start\BundleConfig.cs file in the MVC folders. The BundleConfig.cs file is


created by MVC framework by default. You should write your all bundling code in the
BundleConfig.RegisterBundles() method. (you can create your own custom class instead of
using BundleConfig class, but it is recommended to follow standard practice.) The
following code shows a portion of the RegisterBundles method.

Example: BundleConfig.RegisterBundle()
using System.Web;
using System.Web.Optimization;

public class BundleConfig


{
public static void RegisterBundles(BundleCollection bundles)
{
// create an object of ScriptBundle and
// specify bundle name (as virtual path) as constructor parameter
ScriptBundle scriptBndl = new
ScriptBundle("~/bundles/bootstrap");

//use Include() method to add all the script files with their
paths
scriptBndl.Include(
"~/Scripts/bootstrap.js",
"~/Scripts/respond.js"
);

//Add the bundle into BundleCollection


bundles.Add(scriptBndl);

BundleTable.EnableOptimizations = true;
}
}
In the above example, we have created a bundle of two JavaScript files, bootstrap.js and
respond.js using ScriptBundle for demo purposes.

1. First of all create an instance of ScriptBundle class by specifing the bundle name as a
constructor parameter. This bundle name is a virtual path starting with ~/. You can give
anything in virtual path but it's recommended to give a path that will be easy to identify as
a bundle. Here, we have given "~/bundles/bootstrap" path, so that we can easily identify
that this bundle includes bootstrap related files.
2. Use Include method to add one or more JS files into a bundle with its relative path after
root path using ~ sign.
3. Final, add the bundle into BundleCollection instance, which is specified as a parameter in
RegisterBundle() method.
4. Last, BundleTable.EnableOptimizations = true enables bundling and minification
in debug mode. If you set it to false then it will not do bundling and minification.

You can also use IncludeDirectory method of bundle class to add all the files under
particular directory as shown below.

ScriptBundle Example:
public static void RegisterBundles(BundleCollection bundles)
{
bundles.Add(new
ScriptBundle("~/bundles/scripts").IncludeDirectory("~/Scripts/","*.js",tr
ue));
}

Thus, you can create a bundle of JavaScript files using ScriptBundle. MVC framework
invokes BundleConfig.RegisterBundle() method from the Application_Start event in
Global.asax.cs file, so that it can add all the bundles into BundleCollection at the starting of
an application.

Example: Invoke RegisterBundle() in Application_Start event


public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
}
Using Wildcards

Sometime third party script files includes versions in a name of script file. So it is not
advisable to changes the code whenever you upgrade the version of script file. With the use
of wildcards, you don't have to specify a version of a script file. It automatically includes
files with the version available.

For example, Jquery files includes the version in a name. So you can use {version}
wildcard to pickup a version based on available version.
Example: Wildcard with bundle
public class BundleConfig
{
public static void RegisterBundles(BundleCollection bundles)
{
bundles.Add(new ScriptBundle("~/bundles/jquery")
.Include( "~/Scripts/jquery-{version}.js"));
}
}

Now, it will pick up jquery file added in a project. If you have included jquery-1.7.1.js then
it will render this file and when you upgrade jquery file to jquery-1.10.2.js then it will
automatically render 1.10 version file without changing or compiling code.

Using CDN

You can also use Content Delivery Network to load script files. For example, you can load
jquery library from CDN as shown below.

Example: Load files from CDN


public class BundleConfig
{
public static void RegisterBundles(BundleCollection bundles)
{
var cdnPath = "http://ajax.aspnetcdn.com/ajax/jQuery/jquery-
1.7.1.min.js";

bundles.Add(new ScriptBundle("~/bundles/jquery", cdnPath)


.Include( "~/Scripts/jquery-{version}.js"));
}
}

In the above code, jquery will be requested from the CDN while in release mode and in the
debug mode, jquery library will be loaded from a local source. Please note that you should
have a fallback mechanism to deal with a CDN request failure.

Now, let's see how to use the bundle into a razor view.

Include ScriptBundle in Razor View

We have create a script bundle above. Now, we will learn how to include bundle into razor
view.

The script bundles can be included using static Scripts class. Use Scripts.Render() method
to include specified script bundle at runtime.

Example: Scripts.Render()
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-
scale=1.0">
<title>@ViewBag.Title</title>
@Scripts.Render("~/bundles/bootstrap")
</head>
<body>
@*html code removed for clarity *@
</body>
</html>

Now, if you run the above example then you will find two script files is combined, minified
and loaded in a single request. Please make sure that you have set debug = false in
web.config <compilation debug="false" targetFramework="4.5"/>

Load Bundle in Browser

As you can see in the above figure that bootstrap bundle is loaded in a single request. It has
also combined and minified two JS files for bootstrap.

Points to Remember :

1. Bundling and Minification minimize static script or css files loading time therby minimize
page loading time.
2. ScriptBundle does minification of JavaScript files.
3. Create script or css bundles in BundleConfig class included in App_Start folder.
4. Use wildcard {version} to render available version files at runtime.
5. Use Scripts.Render("bundle name") method to include script bundle in a razor view.

StyleBundle
You have learned how to create a bundle of JavaScript files in the previous section. Here,
you will learn how to create a bundle of style sheet files (CSS).

ASP.NET MVC API includes StyleBundle class that does CSS minification and bundling.
StyleBundle is also derived from a Bundle class so it supports same methods as
ScriptBundle.

As mentioned in the previous section, you should create bundles of script and css files in
the RegisterBundles() method of BundleConfig class contained in App_Start ->
BundleConfig.cs file.

The following code shows a portion of the RegisterBundles() method.

Use ScriptsInclude or IncludeDerictory method to add css files into bundle as shown
below:

Example: StyleBundle
public class BundleConfig
{
public static void RegisterBundles(BundleCollection bundles)
{
bundles.Add(new StyleBundle("~/bundles/css").Include(

"~/Content/bootstrap.css",
"~/Content/site.css"
));
// add ScriptBundle here..

}
}

As you can see in the above example, we have created StyleBundle instance with bundle
name as virtual path. The bundle name (virtual path) must start with ~/. Use Include() or
IncludeDirectory() method with css file names as a string.

You can use wildcard and CDN path the same way as ScriptBundle as shown in the
previous section.

Include Style Bundle in Razor View

You can use StyleBundle in a layout view and render bunch of css files in a single request
using static Styles class. Styles is a helper class to render css bundles.

Example: Include Style Bundle in View


<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-
scale=1.0">
<title>@ViewBag.Title - My ASP.NET Application</title>
@Styles.Render("~/bundles/css")
</head>
<body>
@*html code removed for clarity *@
</body>
</html>

As shown in the above example, use Styles.Render() method to include specified css
bundle at runtime. Open developer tool of the browser and check that it has minified and
loaded css files as shown below.

Load Bundle in Browser

Learn how to set image path in StyleBundle.

Points to Remember :

1. Bundling and Minification minimize static script or css files loading time therby minimize
page loading time.
2. MVC framework provides ScriptBundle, StyleBundle and DynamicFolderBundle classes.
3. StyleBundle does minification of CSS files.
4. Create script or css bundles in the BundleConfig class included in App_Start folder.
5. Use wildcard {version} to render available version files at runtime.
6. Use Styles.Render("bundle name") method to include style bundles in a razor view.

Area
You have already learned that ASP.NET MVC framework includes separate folders for
Model, View and Controller. However, large application can include a large number of
controller, views and model classes. So to maintain a large number of views, models and
controllers with the default ASP.NET MVC project structure can become unmanageable

ASP.NET MVC 2 introduced Area. Area allows us to partition large application into
smaller units where each unit contains separate MVC folder structure, same as default
MVC folder structure. For example, large enterprise application may have different
modules like admin, finance, HR, marketing etc. So an Area can contain separate MVC
folder structure for all these modules as shown below.

Area

Create Area

You can create an Area using ASP.NET MVC 5 and Visual Studio 2013 for web by right
clicking on the project in the solution explorer -> Add -> Area..
Area

Enter Area name in Add Area dialogue box and click Add.

Area

This will add 'admin' folder under Area folder as shown below.
Area

As you can see, each area includes AreaRegistration class in {area name} +
AreaRegistration.cs file.

The following is adminAreaRegistration class created with admin area.

Area Registration:
public class adminAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "admin";
}
}

public override void RegisterArea(AreaRegistrationContext context)


{
context.MapRoute(
"admin_default",
"admin/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
}
}

AreaRegistration class overrides RegisterArea method to map the routes for the area. In the
above example, any URL that starts with admin will be handled by the controllers included
in the admin folder structure under Area folder. For example, http://localhost/admin/profile
will be handled by profile controller included in Areas/admin/controller/ProfileController
folder.

Finally, all the area must be registered in Application_Start event in Global.asax.cs as


AreaRegistration.RegisterAllAreas();
So in this way, you can create and maintain multiple areas for the large application.

Inversion of Control Tutorial


You must have heard about Inversion of Control (IoC), Dependency Inversion Principle
(DIP), Dependency Injection (DI), IoC containers and it's quite possible that you are
confused about some, or all of them.

These tutorials will help you understand these terms to achieve loose coupled design step
by step. These tutorials are broken down into chapters, where each chapter contains a
number of related topics that are packed with easy to understand explanations and real-
world examples.

These tutorials are designed for beginners and professionals who want to learn IoC, DIP, DI
and IoC Container step by step.

Prerequisites

Basic knowledge of C# and Object Oriented Programming is required.

So let's get started by clicking Next.

IoC Test

Test your IoC knowledge with a quick test. It includes 20 questions and each question
includes 4 options. Select an appropriate answer out of 4 options. There is no time limit for
this test.

IoC Introduction
The terms Inversion of Control (IoC), Dependency Injection Principle (DIP), Dependency
Injection (DI), and IoC containers may be familiar. But are you clear about what each term
means?
Here, you are going to learn about each term, with simple and real-world examples to clear
your confusion. Before you go further, it is important to understand the difference between
principle and pattern.

Now, let's understand the above buzz words. The following figure clears the confusion
whether on they are principles or patterns.

As illustrated in the above figure, IoC and DIP are high level design principles which
should be used while designing application classes. These are principles, so they only
recommend certain best practices but do not provide any specific implementation details.
Dependency Injection (DI) is a pattern and IoC container is a framework.

Let's have an overview of each before going into details.

Inversion of Control

IoC is a design principle which recommends inversion of different kinds of controls in


object oriented design to achieve loose coupling between the application classes. Here, the
control means any additional responsibilities a class has other than its main responsibility,
such as control over the flow of an application, control over the dependent object creation
and binding (Remember SRP-Single Responsibility Principle). If you want to do TDD
(Test Driven Development) then you must use IoC principle without which TDD is not
possible. Learn about IoC in detail in the next chapter.

Dependency Inversion Principle

DIP principle also helps in achieving loose coupling between the classes. It is highly
recommended to use DIP and IoC together in order to achieve loose coupling.

DIP suggests that high-level modules should not depend on low level modules. Both should
depend on abstraction.

DIP principle is invented by Robert Martin (a.k.a. Uncle Bob). He is a founder of SOLID
principles. Learn about DIP in the DIP chapter.

Dependency Injection

Dependency Injection (DI) is a design pattern which implements IoC principle to invert the
creation of dependent objects. We will learn about it in the DI chapter.

IoC Container

The IoC container is a framework to manage automatic dependency injection throughout


the application so that we as a programmer do not need to put more time and effort on it.
There are various IoC Containers for .NET such as Unity, Ninject, StructureMap, Autofac
etc. We will learn more about it in the IoC Container chapter.

We cannot achieve loosely couplde classes by only using IoC. Along with IoC we also need
to use DIP, DI and IoC container. The following figure illustrates how we are going to
achieve loosely coupled design step by step in the next few chapters.

Let's learn about each of the above steps, starting with IoC as the first step in the next
chapter.
Inversion of Control
In this chapter, we will learn about IoC and how to implement it. This would be the first
step towards achieving loose coupled design as illustrated by the following figure.

Inversion of Control (IoC) is a design principle (although, some people refer to it as a


pattern). As the name suggests, it is used to invert different kinds of controls in object
oriented design to achieve loose coupling. Here, the control means any additional
responsibilities a class has other than its main responsibility, such as control over the flow
of an application, control over the flow of an object creation or dependent object creation
and binding.

IoC is all about inverting the control. To explain in layman's term, suppose you drive a car
to your work place, it means you control the car. IoC principle suggests to invert the
control, meaning instead of driving the car yourself, you hire a cab where another person
will drive the car. Thus it is called inversion of the control from you to the cab driver. You
don't have to drive a car yourself and let the driver do the driving so that you can focus on
your main work.

IoC principle helps in designing loosely coupled classes which make them testable,
maintainable and extensible.

Let's understand how IoC inverts the different kinds of control.

Control Over the Flow of a Program

In a typical console application in C#, execution starts from the Main() function. The
Main() function controls the flow of a program or in other words sequence of user
interaction. Consider the following simple console program.
Example: Program Flow
namespace FlowControlDemo
{
class Program
{
static void Main(string[] args)
{
bool continueExecution = true;
do
{
Console.Write("Enter First Name:");
var firstName = Console.ReadLine();

Console.Write("Enter Last Name:");


var lastName = Console.ReadLine();

Console.Write("Do you want to save it? Y/N: ");

var wantToSave = Console.ReadLine();

if (wantToSave.ToUpper() == "Y")
SaveToDB(firstName, lastName);

Console.Write("Do you want to exit? Y/N: ");

var wantToExit = Console.ReadLine();

if (wantToExit.ToUpper() == "Y")
continueExecution = false;

}while (continueExecution);

private static void SaveToDB(string firstName, string lastName)


{
//save firstName and lastName to the database here..
}
}
}

In the above example, the Main() function of the program class controls the flow of a
program. It takes user's input for the first Name and last name. It saves the data, continues
or exits the console depending upon the user's input. So here, flow of the control through
the Main() function.

IoC can be applied to the above program by creating a GUI based application such as the
following windows based application wherein the framework will handle the flow of a
program using events.
This is a simple example of implementing IoC on the flow of a program.

Control Over the Dependent Object Creation

IoC can also be applied in the way we create objects of dependent class. First of all, let's
understand what we mean by dependency here.

Consider the following example.

public class A
{
B b;

public A()
{
b = new B();
}

public void Task1() {


// do something here..
b.SomeMethod();
// do something here..
}

public class B {

public void SomeMethod() {


//doing something..
}
}
In the above example, class A calls b.SomeMethod() to complete its task1. Class A cannot
complete its task without class B and so you can say "Class A is dependent on class B" or
"class B is a dependency of class A".

In object oriented design approach, classes need to interact with each other in order to
complete one or more functionalities of an application such as in the above classes A and
B. Class A creates and manages the life time of an object of class B. Essentially it controls
the creation and life time of objects of dependency class.

IoC principle suggests to invert the control, means separate the controlling stuff to another
class. In other words, invert the dependency creation control from the class A to another
class as shown below.

public class A
{
B b;

public A()
{
b = Factory.GetObjectOfB ();
}

public void Task1() {


// do something here..
b.SomeMethod();
// do something here..
}
}

public class Factory


{
public static B GetObjectOfB()
{
return new B();
}
}

As you can see above, class A uses Factory class to get an object of class B. Thus, we have
inverted the dependent object creation from class A to Factory. The class A no longer
creates an object of class B instead it uses Factory class to get the object of class B.

Let's understand this using a more practical example.

In an object oriented design, classes should be designed in loosely coupled way. Loosely
coupled means changes in one class should not force other classes to change, so the whole
application can become maintainable and extensible. Let's understand this by using typical
n-tier architecture as depicted by the following figure.
In the typical n-tier architecture, the User Interface (UI) uses Service layer to retrieve or
save the data. The service layer uses the BusinessLogic class to apply business rules on
the data. The BusinessLogic class depends on the DataAccess class which retrieves or
saves the data to the underlying database. This is simple n-tier architecture design. Let's
focus on the BusinessLogic and DataAccess class to understand IoC.

The following is an example of BusinessLogic and DataAccess classes for customer.

public class CustomerBusinessLogic


{
DataAccess _dataAccess;

public CustomerBusinessLogic()
{
_dataAccess = new DataAccess();
}

public string GetCustomerName(int id)


{
return _dataAccess.GetCustomerName(id);
}
}

public class DataAccess


{
public DataAccess()
{
}

public string GetCustomerName(int id) {


return "Dummy Customer Name"; // get it from DB in real app
}
}

As you can see in the above example, the CustomerBusinessLogic class depends on
DataAccess class. It creates an object of the DataAccess class to get customer data.

Now, let's understand what's wrong with the above classes.

In the above example, CustomerBusinessLogic and DataAccess are tightly coupled


classes because CustomerBusinessLogic class includes the reference of concrete
DataAccess class. It also creates an object of DataAccess class and manages the lifetime
of an object.

Problems in the above example classes:


1. CustomerBusinessLogic and DataAccess classes are tightly coupled classes. So,
changes in the DataAccess class will lead to changes in the
CustomerBusinessLogic class. For example, if we add, remove or rename any
method in DataAccess class then we need to change CustomerBusinessLogic
class accordingly.
2. Suppose, customer data comes from different databases or web service in future we
may need to create different classes for so it leads to changes in
CustomerBusinessLogic class.
3. CustomerBusinessLogic class creates an object of DataAccess class using new
keyword. There may be multiple classes which use DataAccess class and create its
object. So if you change the name of the class, then you need to find all the places in
your source code where you create objects of DataAccess and make the change
throughout the code. This is repetitive code for creating an object of same class and
maintaining its dependencies.
4. Because CustomerBusinessLogic class creates an object of concrete DataAccess
class, it cannot be tested independently (TDD). DataAccess class cannot be
replaced with mock class.

So, to solve the above problems and get a loosely coupled design, we can use IoC and DIP
principles together. Remember, IoC is a principle not a pattern. It just gives high level
design guidelines but does not give implementation details. You are free to implement IoC
principle the way you want.

The following pattern (but not limited) implements IoC principle.

Let's use Factory pattern to implement IoC in the above example as the first step towards
attaining loosely coupled classes.

First, create a simple Factory class which returns an object of DataAccess class as shown
below.

Example: DataAccess Factory


public class DataAccessFactory
{
public static DataAccess GetDataAccessObj()
{
return new DataAccess();
}
}

Now, use this DataAccessFactory class in CustomerBusinessLogic class to get an object


of DataAccess class.

Example: Use Factory Class to Retrieve Object


public class CustomerBusinessLogic
{

public CustomerBusinessLogic()
{
}

public string GetCustomerName(int id)


{
DataAccess _dataAccess = DataAccessFactory.GetDataAccessObj();

return _dataAccess.GetCustomerName(id);
}
}

As you can see, CustomerBusinessLogic class uses


DataAccessFactory.GetCustomerDataAccessObj() method to get an object of
DataAccess class instead of creating it using new keyword. Thus, we have inverted the
control of creating an object of dependent class from CustomerBusinessLogic class to
DataAccessFactory class.

This is a simple implementation of IoC and the first step towards achieving fully loose
coupled design. As mentioned in the previous chapter, we will not achieve complete
loosely coupled classes by only using IoC. Along with IoC we also need to use DIP,
Strategy pattern, and DI (Dependency Injection).

Let's move to the second step to understand DIP and how it helps in achieving loose
coupled design in the next chapter.

Dependency Inversion Principle


In the previous chapter, we learned about implementing IoC principle using Factory pattern
and achieved the first level of loosely coupled design. Here, we will learn and implement
Dependency Inversion Principle as the second step to achieve loosely coupled classes.
First of all, let's understand what is Dependency Inversion Principle (DIP)?

DIP is one of the SOLID object oriented principle invented by Robert Martin (a.k.a. Uncle
Bob)

DIP Definition

1. High-level modules should not depend on low-level modules. Both should depend on
abstraction.
2. Abstractions should not depend on details. Details should depend on abstractions.

To understand DIP, let's take an example from the previous chapter as shown below.

public class CustomerBusinessLogic


{
public CustomerBusinessLogic()
{
}

public string GetCustomerName(int id)


{
DataAccess _dataAccess = DataAccessFactory.GetDataAccessObj();

return _dataAccess.GetCustomerName(id);
}
}

public class DataAccessFactory


{
public static DataAccess GetDataAccessObj()
{
return new DataAccess();
}
}

public class DataAccess


{
public DataAccess()
{
}

public string GetCustomerName(int id) {


return "Dummy Customer Name"; // get it from DB in real app
}
}

In the above example, we implemented factory pattern to achieve IoC. But,


CustomerBusinessLogic class uses concrete DataAccess class. So still it is tightly
coupled even though we have inverted the dependent object creation to the factory class.

Let's use DIP on the CustomerBusinessLogic and DataAccess classes and make them
more loosely coupled.

As per DIP definition, a high-level module should not depend on low-level modules. Both
should depend on abstraction. So, first, decide which is the high-level module (class) and
low-level module. High-level module is a module which depends on other modules. In our
example, CustomerBusinessLogic depends on DataAccess class, so
CustomerBusinessLogic is high-level module and DataAccess is low-level module. So,
as per first rule of DIP, CustomerBusinessLogic should not depends on concrete
DataAccess class, instead both classes depends on abstraction.

The second rule in DIP is "Abstractions should not depend on details. Details should
depend on abstractions".

What is Abstraction?

Abstraction and encapsulation are important principles of object-oriented programming.


There are many different definitions from many people but let's understand abstraction
using the above example.

In English, abstraction means something which is non-concrete. In programming terms, the


above CustomerBusinessLogic and DataAccess are concrete classes, meaning we can
create objects of it. So, abstraction in programming is to create an interface or abstract class
which is non-concrete. This means we cannot create an object of interface or abstract class.
As per DIP, CustomerBusinessLogic (high-level module) should not depend on concrete
DataAccess (low-level module) class. Both classes depend on abstractions, meaning both
classes should depend on interface or abstract class.

Now, what should be in interface (or in abstract class)? As you can see,
CustomerBusinessLogic uses GetCustomerName() method of DataAccess class. (In real
life, there will be many customer related methods in DataAccess class). So, let's declare
GetCustomerName(int id) method in the interface as shown below.

public interface ICustomerDataAccess


{
string GetCustomerName(int id);
}

Now, implement ICustomerDataAccess in CustomerDataAccess class as shown below.


(So instead of DataAccess class, let's define new CustomerDataAccess class.)

public class CustomerDataAccess: ICustomerDataAccess


{
public CustomerDataAccess()
{
}

public string GetCustomerName(int id) {


return "Dummy Customer Name";
}
}

Now, we need to change our factory class which returns ICustomerDataAccess instead of
concrete DataAccess class as shown below.

public class DataAccessFactory


{
public static ICustomerDataAccess GetCustomerDataAccessObj()
{
return new CustomerDataAccess();
}
}

Now, change the CustomerBusinessLogic class which uses ICustomerDataAccess


instead of concrete DataAccess class as shown below.

public class CustomerBusinessLogic


{
ICustomerDataAccess _custDataAccess;

public CustomerBusinessLogic()
{
_custDataAccess = DataAccessFactory.GetCustomerDataAccessObj();
}

public string GetCustomerName(int id)


{
return _custDataAccess.GetCustomerName(id);
}
}

Thus, we have implemented DIP in our example where high-level module


(CustomerBusinessLogic) and low-level module (CustomerDataAccess) are depends on
abstraction (ICustomerDataAccess). Also, abstraction (ICustomerDataAccess) does not
depends on details (CustomerDataAccess) but details depend on abstraction.

The following is the complete DIP example discussed so far.


Example: DIP Implementation
public interface ICustomerDataAccess
{
string GetCustomerName(int id);
}

public class CustomerDataAccess: ICustomerDataAccess


{
public CustomerDataAccess() {
}

public string GetCustomerName(int id) {


return "Dummy Customer Name";
}
}

public class DataAccessFactory


{
public static ICustomerDataAccess GetCustomerDataAccessObj()
{
return new CustomerDataAccess();
}
}

public class CustomerBusinessLogic


{
ICustomerDataAccess _custDataAccess;

public CustomerBusinessLogic()
{
_custDataAccess = DataAccessFactory.GetCustomerDataAccessObj();
}

public string GetCustomerName(int id)


{
return _custDataAccess.GetCustomerName(id);
}
}

Advantages of implementing DIP in the above example is that CustomerBusinessLogic


and CustomerDataAccess classes are loosely coupled classes because
CustomerBusinessLogic does not depend on concrete DataAccess class, instead it
includes reference of ICustomerDataAccess interface. So now, we can easily use another
class which implements ICustomerDataAccess with different implementation.

Still, we have not achieved fully loosely coupled classes because CustomerBusinessLogic
class includes Factory class to get the reference of ICustomerDataAccess. This is where
Dependency Injection pattern helps us. In the next chapter, we will learn how to use DI and
Strategy pattern using the above example.
Dependency Injection
In the previous chapter of DIP, we created and used abstraction to make the classes loosely
coupled. Here, we are going to implement Dependency Injection and strategy pattern
together to move the dependency object creation completely out of the class. This is our
third step in making the classes completely loose coupled.

Dependency Injection (DI) is a design pattern used to implement IoC where it allows
creation of dependent objects outside of a class and provides those objects to a class
through different ways. Using DI, we move the creation and binding of the dependent
objects outside of the class that depends on it.

Dependency Injection pattern involves 3 types of classes.

1. Client Class: The client class (dependent class) is a class which depends on the service class
2. Service Class: The service class (dependency) is a class that provides service to the client
class.
3. Injector Class: The injector class injects service class object into the client class.

The following figure illustrates the relationship between these classes:


Dependency Injection

As you can see, injector class creates an object of service class, and injects that object to a
client object. This way DI pattern separates the responsibility of creating an object of
service class out of client class.

Types of Dependency Injection

As you have learned above, the injector class injects the service (dependency) to the client
(dependent). The injector class injects dependencies broadly in three ways: through
constructor, through property, or through method.

Constructor Injection: In the constructor injection, injector supplies service (dependency)


through the client class constructor.

Property Injection: In property injection (aka Setter Injection), injector supplies


dependency through a public property of the client class.

Method Injection: In this type of injection, client class implements an interface which
declares method(s) to supply dependency and the injector uses this interface to supply
dependency to the client class.

Let's take an example from the previous chapter to maintain the continuity. In the previous
section of DIP, we used Factory class inside CustomerBusinessLogic class to get an
object of CustomerDataAccess object as shown below.

public interface ICustomerDataAccess


{
string GetCustomerName(int id);
}

public class CustomerDataAccess: ICustomerDataAccess


{
public CustomerDataAccess() {
}

public string GetCustomerName(int id) {


return "Dummy Customer Name";
}
}

public class DataAccessFactory


{
public static ICustomerDataAccess GetCustomerDataAccessObj()
{
return new CustomerDataAccess();
}
}

public class CustomerBusinessLogic


{
ICustomerDataAccess _custDataAccess;

public CustomerBusinessLogic()
{
_custDataAccess = DataAccessFactory.GetCustomerDataAccessObj();
}

public string GetCustomerName(int id)


{
return _custDataAccess.GetCustomerName(id);
}
}

The problem with the above example is that we used DataAccessFactory inside
CustomerBusinessLogic class. So, suppose there is another implementation of
ICustomerDataAccess for some reason and we want to use that new class inside
CustomerBusinessLogic. Then, we need to change the source code of
CustomerBusinessLogic class also. Dependency injection pattern solves this problem by
injecting dependent objects via constructor, property, or interface.

The following figure illustrates the DI pattern implementation for the above example.

Dependency Injection

As you see, CustomerService class becomes injector class which sets an object of service
class (CustomerDataAccess) to the client class (CustomerBusinessLogic) either through
constructor, property, or method to achieve loose coupling. Let's explore each of these
options.
Constructor Injection

As mentioned before, when we provide dependency through the constructor then it's
constructor injection.

Consider the following example where we have implemented DI using constructor.

Example: Constructor Injection


public class CustomerBusinessLogic
{
ICustomerDataAccess _dataAccess;

public CustomerBusinessLogic(ICustomerDataAccess custDataAccess)


{
_dataAccess = custDataAccess;
}

public CustomerBusinessLogic()
{
_dataAccess = new CustomerDataAccess();
}

public string ProcessCustomerData(int id)


{
return _dataAccess.GetCustomerName(id);
}
}

public interface ICustomerDataAccess


{
string GetCustomerData(int id);
}

public class CustomerDataAccess: ICustomerDataAccess


{
public CustomerDataAccess()
{
}

public string GetCustomerName(int id)


{
//get the customer name from the db in real application
return "Dummy Customer Name";
}
}

In the above example, CustomerBusinessLogic includes constructor with one parameter


of type ICustomerDataAccess. Now, the calling class must inject an object of
ICustomerDataAccess.

Example: Inject Dependency


public class CustomerService
{
CustomerBusinessLogic _customerBL;

public CustomerService()
{
_customerBL = new CustomerBusinessLogic(new
CustomerDataAccess());
}

public string GetCustomerName(int id) {


return _customerBL.GetCustomerName(id);
}
}

As you can see in the above example, CustomerService class creates and injects
CustomerDataAccess object into CustomerBusinessLogic class. Thus,
CustomerBusinessLogic class need not create an object of CustomerDataAccess using
new keyword or using factory class. The calling class (CustomerService) creates and sets
appropriate DataAccess class to the CustomerBusinessLogic class. This way
CustomerBusinessLogic and CustomerDataAccess class become more loosely coupled
classes.

Property Injection

In the property injection, dependency is provided through public property. Consider the
following example.

Example: Property Injection


public class CustomerBusinessLogic
{
public CustomerBusinessLogic()
{
}

public string GetCustomerName(int id)


{
return DataAccess.GetCustomerName(id);
}

public ICustomerDataAccess DataAccess { get; set; }


}

public class CustomerService


{
CustomerBusinessLogic _customerBL;

public CustomerService()
{
_customerBL = new CustomerBusinessLogic();
_customerBL.DataAccess = new CustomerDataAccess();
}
public string GetCustomerName(int id) {
return _customerBL.GetCustomerName(id);
}
}

As you can see above, the CustomerBusinessLogic class includes public property named
DataAccess where you set an instance of a class that has implanted
ICustomerDataAccess. So, CustomerService class creates and sets
CustomerDataAccess class using this public property.

Method Injection

In the method injection, dependencies are provided through methods. This method can be a
class method or interface method.

The following example demonstrates method injection using interface based method.

Example: Interface Injection


interface IDataAccessDependency
{
void SetDependency(ICustomerDataAccess customerDataAccess);
}

public class CustomerBusinessLogic : IDataAccessDependency


{
ICustomerDataAccess _dataAccess;

public CustomerBusinessLogic()
{
}

public string GetCustomerName(int id)


{
return _dataAccess.GetCustomerName(id);
}

public void SetDependency(ICustomerDataAccess customerDataAccess)


{
_dataAccess = customerDataAccess;
}
}

public class CustomerService


{
CustomerBusinessLogic _customerBL;

public CustomerService()
{
_customerBL = new CustomerBusinessLogic();
((IDataAccessDependency)_customerBL).SetDependency(new
CustomerDataAccess());
}
public string GetCustomerName(int id) {
return _customerBL.GetCustomerName(id);
}
}

In the above example, CustomerBusinessLogic class implements


IDataAccessDependency interface which includes method SetDependency. So the injector
class (CustomerService) will now use this method to inject dependent class
(CustomerDataAccess) to the client class.

Thus, you can use DI and strategy pattern to create loose coupled classes.

So far, we have used couple of principles and patterns to achieve loosely coupled classes.
In professional projects, there would be many dependent classes and implementing these
patterns would be time consuming. Here IoC Container (aka DI container) helps us. Learn
about IoC Container in the next chapter.

Learn more about IoC and Dependency Injection at Martin Fowler.com

IoC Container
In the previous chapter, we learned how to implement Dependency Injection pattern to
achieve loose coupled classes. IoC Container (a.k.a. DI Container) is a framework for
implementing automatic dependency injection. It manages object creating and its life time
and also injects dependencies to the class.

IoC container creates an object of the specified class and also injects all the dependency
objects through constructor, property or method at run time and disposes it at the
appropriate time. This is done so that we don't have to create and manage objects manually.

All the containers must provide easy support for the following DI lifecycle.

 Register: The container must know which dependency to instantiate when it


encounters a particular type. This process is called registration. Basically, it must
include some way to register type-mapping.
 Resolve: When using IoC container, we don't need to create objects manually.
Container does it for us. This is called resolution. Container must include some
methods to resolve the specified type; container creates an object of specified type,
injects required dependencies if any and returns it.
 Dispose: Container must manage the lifetime of dependent objects. Most IoC
containers include different lifetimemanagers to manage an object's lifecycle and
dispose it.
There are many open source or commercial containers available for .NET. Some are listed
below.

 Unity
 StructureMap
 Castle Windsor
 Ninject
 Autofac
 DryIoc
 Simple Injector
 Light Inject

Learn about Unity Container in the next few chapters.

Unity Container
Unity container is an open source IoC container for .NET applications supported by
Microsoft. It is a lightweight and extensible IoC container.

Unity container source code is available at https://github.com/unitycontainer/unity.

Unity Container Features:

 Simplified type-mapping registration for interface type or base type.


 Supports registration of existing instance.
 Supports code-based registration as well as design time registration.
 Automatically injects registered type at runtime through constructor, property or method.
 Supports deferred resolution.
 Supports nested containers.
 Automatic disposing of instances based on lifetime managers such as hierarchical, per
resolve, externally controlled, per request and per thread life time manager.
 Supports service location capability; this allows clients to store or cache the container
 Supports type interception and instance interception.
 Easy to extend unity container.

Before we start working with Unity container, let's learn how to install it, in the next
chapter.

Install Unity Container in Visual Studio


Here, we are going to install Unity container in Visual Studio using NuGet.
First of all, we need to create a project in order to use Unity. It can be any type of project
such as class library, console, web, windows or any other C# or VB.NET project. We will
create a Console Application to demo Unity container. So, click on New Project from the
Start page of Visual Studio. It will open New Project popup as below.

Enter Name of the project and location as per your choice and click OK. This will create
new console application project.

Now, we need to install Unity in this project because we want to dependency injection in
our project. So, right click on the project node in the solution explorer and select Manage
NuGet Packages as shown below.
Now, we can search for unity from the browse tab of NuGet. Enter "unity" in the search
box and it will list all the libraries or plugins which contains "unity" word as shown below.
Now, click on Install button in the right pane as shown below.

This will add all the references of unity into your project as shown below.
So now, we are ready to use Unity to implement automatic dependency injection in our
project.

Unity Container: Register and Resolve


In the previous section, we installed unity framework in our console project. Here, we will
learn how to register type-mapping and resolve it using unity container.

As we learned in the IoC container chapter that every container must provide a way to
register and resolve dependencies. Unity container provides RegisterType() and Resolve()
methods for this.

We are going to use the following sample classes to demo registration and resolution of
dependencies throughout this chapter.

public interface ICar


{
int Run();
}
public class BMW : ICar
{
private int _miles = 0;

public int Run()


{
return ++_miles;
}
}

public class Ford : ICar


{
private int _miles = 0;

public int Run()


{
return ++_miles;
}
}

public class Audi : ICar


{
private int _miles = 0;

public int Run()


{
return ++_miles;
}

}
public class Driver
{
private ICar _car = null;

public Driver(ICar car)


{
_car = car;
}

public void RunCar()


{
Console.WriteLine("Running {0} - {1} mile ", _car.GetType().Name,
_car.Run());
}
}

As you can see sample classes, Driver class depends on ICar interface. So, when we
instantiate the Driver class object then we will have to pass an instance of a class which
implement ICar interface such as BMW, Audi or Ford class as shown below.

Driver driver = new Driver(new BMW());

driver.RunCar();
Output:
Running BMW - 1 mile

In the above example, we created and passed an object of BMW while creating an object of
Driver class. Thus, we injected dependency of Driver class manually. Now, use unity
container and understand different ways to register and resolve dependencies.

Using UnityContainer.

In order to use unity container, we first need to create an object of it. You can use any class
which implements IUnityContainer interface. Unity container includes UnityContainer
class in Microsoft.Practices.Unity namespace that implements IUnityContainer
interface. If you need to extend the container then you can create your own custom class
and implement IUnityContainer interface as per your need.

Example: Instantiate UnityContainer


using Microsoft.Practices.Unity;

IUnityContainer container = new UnityContainer();


//or
var container = new UnityContainer();

Now, we need to register type-mapping next.

Register

Before unity resolve dependencies, we first need to register the type-mapping with the
container, so that it can create the correct object for the given type. Use RegisterType()
method to register a type mapping. Basically, it configures which class to instantiate, for
which interface or base class. For example, if we want unity container to create and supply
an object of BMW class whenever it needs to supply dependency of ICar interface, then you
first need to register it as below.

Example: Register Type with Unity


IUnityContainer container = new UnityContainer();

container.RegisterType<ICar, BMW>();

The container.RegisterType<ICar, BMW>() asks unity that whenever you need to


inject an object of ICar, then create an object of BMW class and inject it through a
constructor by default.

The RegisterType method includes many overloads. Learn about all the overloads of
RegisterType on MSDN.

So now, after registration, we can resolve it using Resolve() method.


Resolve

Unity creates an object of the specified class and automatically injects dependencies using
resolve() method. We have registered BMW with ICar above. Now, we can instantiate the
Driver class using unity container without using new keyword as shown below.

Example: Resolve
IUnityContainer container = new UnityContainer();
container.RegisterType<ICar, BMW>();// Map ICar with BMW

//Resolves dependencies and returns Driver object


Driver drv = container.Resolve<Driver>();
drv.RunCar();
Output:
Running BMW - 1 mile

In the above example, unity container creates an object of a class Driver using
container.Resolve<driver>() method. The Driver class is a dependent on ICar. So,
container.Resolve<Driver>() returns an object of Driver class by automatically
creating and injecting BMW object in it. All this is behind the scene. It creates and injects BMW
object because we register BMW type with ICar.

Unity container will create new object and inject it every time whenever we resolve the
same type.

var container = new UnityContainer();


container.RegisterType<ICar, BMW>();

Driver driver1 = container.Resolve<Driver>();


driver1.RunCar();

Driver driver2 = container.Resolve<Driver>();


driver2.RunCar();
Output:
Running BMW - 1 mile
Running BMW - 1 mile

In the above example, container injects BMW object whenever it resolves Driver class e.g.
driver1 and driver2 both has a reference of separate BMW objects.

Thus, you can create an object of the specified type using unity container. Learn about all
the overloads of Resolve method on MSDN.

Multiple Registration

Unity container will inject last registered type if you register multiple mappings of the same
type.
IUnityContainer container = new UnityContainer();
container.RegisterType<ICar, BMW>();
container.RegisterType<ICar, Audi>();

Driver driver = container.Resolve<Driver>();


driver.RunCar();
Output:
Running Audi - 1 Mile

In the above example, ICar is mapped to both BMW and Audi. But, unity will inject Audi
every time because it has been registered last.

Register Named Type

You can register a type-mapping with a name which you can use with Resolve method.

Example: Register Named Type


IUnityContainer container = new UnityContainer();
container.RegisterType<ICar, BMW>();
container.RegisterType<ICar, Audi>("LuxuryCar");

ICar bmw = container.Resolve<ICar>(); // return BMW object


ICar audi = container.Resolve<ICar>("LuxuryCar"); // return Audi object

As you can see above, we have mapped ICar with both BMW and Audi class. However, we
have given a name "LuxuryCar" to ICar-Audi mapping. So now, Resolve() method will
return an object of Audi if we specify the mapping name.

Now, consider the following example.

var container = new UnityContainer();


container.RegisterType<ICar, BMW>();
container.RegisterType<ICar, Audi>("LuxuryCar");

// Register Driver type


container.RegisterType<Driver>("LuxuryCarDriver",
new
InjectionConstructor(container.Resolve<ICar>("LuxuryCar")));

Driver driver1 = container.Resolve<Driver>();// injects BMW


driver1.RunCar();

Driver driver2 = container.Resolve<Driver>("LuxuryCarDriver");// injects


Audi
driver2.RunCar();
Output:
Running BMW - 1 Mile
Running Audi - 1 Mile
In the above example, we registered Driver class with the name "LuxuryCarDriver" and
specified an object of InjectionConstructor. The new
InjectionConstructor(container.Resolve<ICar>("LuxuryCar")) specifies a
construction injection for Driver class which passes an object of Audi because
container.Resolve("LuxuryCar") returns Audi object. So now, we can use
container.Resolve<Driver>("LuxuryCarDriver") to resolve Driver with Audi even if
ICar is registered with BMW by default.

Register Instance

Unity container allows us to register an existing instance using RegisterInstance() method.


So, unity container will not create a new instance for the registered type and will use the
same instance every time.

var container = new UUnity Container: Property


Injection
In the previous chapter, we learned about constructor injection. Here, we will learn about
property injection using unity container.

Property injection is a type of dependency injection where dependencies are provided


through properties. Visit Dependency Injection chapter to learn more about it.

Let understand how we can perform property injection using unity container. Consider the
following example classes.

public interface ICar


{
int Run();
}

public class BMW : ICar


{
private int _miles = 0;

public int Run()


{
return ++_miles;
}
}

public class Ford : ICar


{
private int _miles = 0;

public int Run()


{
return ++_miles;
}
}

public class Audi : ICar


{
private int _miles = 0;

public int Run()


{
return ++_miles;
}

}
public class Driver
{
public Driver()
{
}

[Dependency]
public ICar Car { get; set; }

public void RunCar()


{
Console.WriteLine("Running {0} - {1} mile ",
this.Car.GetType().Name, this.Car.Run());
}
}

As you can see in the above sample classes, the Driver class is dependent on a property of
type ICar. So, we need to set an object of a class that implements ICar to the Car property
using unity container.

Property injection in unity container can be implemented in two ways:

1. Using [Dependency] attribute


2. Run-time configuration

[Dependency] Attribute

For the property injection, we first tell the unity container which property to inject. So, we
need to decorate the dependent properties with the [Dependency] attribute as shown in the
following Driver class.

Example: Apply [Dependency] Attribute


public class Driver
{

public Driver()
{
}
[Dependency]
public ICar Car { get; set; }

public void RunCar()


{
Console.WriteLine("Running {0} - {1} mile ",
this.Car.GetType().Name, this.Car.Run());
}
}

Now, we can register ICar type and resolve it as shown below.

Example: Property Injection using Unity Container


var container = new UnityContainer();
container.RegisterType<ICar, BMW>();

var driver = container.Resolve<Driver>();


driver.RunCar();
Output:
Running BMW - 1 mile

Named Mapping

We can specify a name in the [Dependency("name")] attribute, which can then be used to
set property value.

public class Driver


{
public Driver()
{
}

[Dependency("LuxuryCar")]
public ICar Car { get; set; }

public void RunCar()


{
Console.WriteLine("Running {0} - {1} mile ",
this.Car.GetType().Name, this.Car.Run());
}
}

So now, we can resolve it as below.

Example: Property Injection using Unity Container


var container = new UnityContainer();
container.RegisterType<ICar, BMW>();
container.RegisterType<ICar, Audi>("LuxuryCar");

var driver = container.Resolve<Driver>();


driver.RunCar();
Output:
Running Audi - 1 mile

Run-time Configuration

Unity container allows us to configure a property injection with RegisterType() method if a


method is not marked with [Dependency] attribute. Pass an object of InjectionProperty
class in the RegisterType() method to specify a property name and parameter value.

Note : InjectionProperty is derived from InjectionMember Class. The InjectionMember is an


abstract class which can be used to configure injection type. There are three subclasses of
InjectionMembers: InjectionConstruction to configure construction injection, InjectionProperty to
configure property injection and InjectionMethod to configure method injection.
var container = new UnityContainer();

//run-time configuration
container.RegisterType<Driver>(new InjectionProperty("Car", new BMW()));

var driver = container.Resolve<Driver>();


driver.RunCar();
Output:
Running BMW - 1 Mile

As you can see in the above example, container.RegisterType<driver>(new


InjectionProperty("Car", new BMW())) registers Driver class by passing an object of
InjectionProperty that specifies the property name "Car" and the BMW object as a value. So,
unity container will set an object of BMW to the Car property when we resolve it using
container.Resolve<Driver>().

nityContainer();
ICar audi = new Audi();
container.RegisterInstance<ICar>(audi);

Driver driver1 = container.Resolve<Driver>();


driver1.RunCar();
driver1.RunCar();

Driver driver2 = container.Resolve<Driver>();


driver2.RunCar();
Output:
Running Audi - 1 Mile
Running Audi - 2 Mile
Running Audi - 3 Mile

Thus, we can register and resolve different types using Unity container. Learn how Unity
container performs constructor injection in the next chapter.
Unity Container: Constructor Injection
In the previous chapter, we learned about registering and resolving types using unity. Here,
you will learn how unity container performs constructor injection.

Construction injection is a type of Dependency Injection where dependencies are provided


through a constructor. Visit Dependency Injection chapter to learn more about it.

We learned about Resolve() method in the previous chapter. By default, Resolve<T>()


performs construction injection to inject dependencies and returns an object of specified
type. Let's take the same examples from the previous chapter.

public interface ICar


{
int Run();
}

public class BMW : ICar


{
private int _miles = 0;

public int Run()


{
return ++_miles;
}
}

public class Ford : ICar


{
private int _miles = 0;
public int Run()
{
return ++_miles;
}
}

public class Audi : ICar


{
private int _miles = 0;

public int Run()


{
return ++_miles;
}

}
public class Driver
{
private ICar _car = null;
public Driver(ICar car)
{
_car = car;
}

public void RunCar()


{
Console.WriteLine("Running {0} - {1} mile ", _car.GetType().Name,
_car.Run());
}
}

As you can see above, the Driver class accepts an object of type ICar in the constructor.
So, the unity container will inject dependencies via constructor as shown below.

Example: Construction Injection using Unity Container


var container = new UnityContainer();
container.RegisterType<ICar, BMW>();

var driver = container.Resolve<Driver>();


driver.RunCar();
Output:
Running BMW - 1 mile

In the above example, container.RegisterType<ICar, BMW>() maps ICar to BMW. It


means whenever unity container needs to inject an object of type ICar, it will create and
inject an object of BMW class. The container.Resolve<driver>() method will create and
return an object of Driver class by passing an object of ICar into the constructor. As we
mapped ICar to BMW, it will create and inject BMW object to a constructor of Driver class
and return an object of Driver class.

Thus, the Resolve() method by default performs constructor injection while resolving types.

Multiple Parameters

You can also inject multiple parameters in the constructor. Consider the following example.

public interface ICarKey {

public class BMWKey : ICarKey


{

public class AudiKey : ICarKey


{

}
public class FordKey : ICarKey
{

public class Driver


{
private ICar _car = null;
private ICarKey _key = null;

public Driver(ICar car, ICarKey key)


{
_car = car;
_key = key;
}

public void RunCar()


{
Console.WriteLine("Running {0} with {1} - {2} mile ",
_car.GetType().Name , _key.GetType().Name, _car.Run());
}
}

So now, you can register ICar and ICarKey with unity and inject both the parameters as
shown below.

Example: Constructor Injection for Multiple Parameters


var container = new UnityContainer();

container.RegisterType<ICar, Audi>();
container.RegisterType<ICarKey, AudiKey>();

var driver = container.Resolve<Driver>();


driver.RunCar();
Output:
Running Audi with AudiKey - 1 mile

Multiple Constructors

If a class includes multiple constructors then use [InjectionConstructor] attribute to indicate


which constructor to use for construction injection.

public class Driver


{
private ICar _car = null;

[InjectionConstructor]
public Driver(ICar car)
{
_car = car;
}
public Driver(string name)
{
}

public void RunCar()


{
Console.WriteLine("Running {0} - {1} mile ", _car.GetType().Name,
_car.Run());
}
}

As you can see, Driver class includes two constructors. So, we have used
[InjectionConstructor] attribute to indicate which constructor to call when resolving the
Driver class.

You can configure the same thing as above at run time instead of applying
[InjectionConstructor] attribute by passing InjectionConstructor in the RegisterType()
method as shown below.

container.RegisterType<Driver>(new InjectionConstructor(new Ford()));

//or

container.RegisterType<ICar, Ford>();
container.RegisterType<Driver>(new
InjectionConstructor(container.Resolve<ICar>()));
Primitive Type Parameter

Unity also injects primitive type parameter in the constructor. Consider the following
Driver class with primitive type parameter in the constructor.

public class Driver


{
private ICar _car = null;
private string _name = string.Empty;

public Driver(ICar car, string driverName)


{
_car = car;
_name = driverName;
}

public void RunCar()


{
Console.WriteLine("{0} is running {1} - {2} mile ",
_name, _car.GetType().Name, _car.Run());
}
}
Use InjectionConstructor class to configure constructor's parameters values. Pass an object
of InjectionConstructor class in the RegisterType() method to specify a multiple parameters
values.

Note : InjectionConstructor is derived from InjectionMember Class. The InjectionMember is an


abstract class which can be used to configure injection type. There are three subclasses of
InjectionMember: InjectionConstruction to configure construction injection, InjectionProperty to
configure property injection and InjectionMethod to configure method injection.
var container = new UnityContainer();

container.RegisterType<Driver>(new InjectionConstructor(new object[] {


new Audi(), "Steve" }));

var driver = container.Resolve<Driver>(); // Injects Audi and Steve


driver.RunCar();
Output:
Steve is running Audi - 1 mile

Unity Container: Method Injection


In the previous chapter, we learned about property injection. Here, we will learn about
method injection using unity container.

In the method injection, dependencies are provided through method parameters. Visit
Dependency Injection chapter to learn more about method injection.

Let's understand how we can perform method injection using unity container. Consider the
following example classes.

public interface ICar


{
int Run();
}

public class BMW : ICar


{
private int _miles = 0;

public int Run()


{
return ++_miles;
}
}

public class Ford : ICar


{
private int _miles = 0;
public int Run()
{
return ++_miles;
}
}

public class Audi : ICar


{
private int _miles = 0;

public int Run()


{
return ++_miles;
}

}
public class Driver
{
private ICar _car = null;

public Driver()
{
}

public void UseCar(ICar car) {


_car = car;
}

public void RunCar()


{
Console.WriteLine("Running {0} - {1} mile ", _car.GetType().Name,
_car.Run());
}
}

As you can see in the above sample classes, the Driver class includes method UseCar() to
set the object of type ICar. Here, we have taken a simple method example. However, you
can also use interface based method injection explained in Dependency Injection chapter.

Method injection in unity can be implemented in two ways:

1. Using [InjectionMethod] attribute


2. Run-time configuration

[InjectionMethod] Attribute

For the method injection, we need to tell the unity container which method should be used
for dependency injection. So, we need to decorate a method with the [InjectionMethod]
attribute as shown in the following Driver class.

Example: Method Injection


public class Driver
{
private ICar _car = null;

public Driver()
{
}
[InjectionMethod]
public void UseCar(ICar car) {
_car = car;
}

public void RunCar()


{
Console.WriteLine("Running {0} - {1} mile ", _car.GetType().Name,
_car.Run());
}
}

We can implement method injection in unity container as shown below.

Example: Method Injection


var container = new UnityContainer();
container.RegisterType<ICar, BMW>();

var driver = container.Resolve<Driver>();


driver.RunCar();
Output:
Running BMW - 1 mile

Run-time Configuration

Unity container allows us to configure method injection with RegisterType() method if a


method is not marked with [InjectionMethod] attribute. Pass an object of InjectionMethod
class in the RegisterType() method to specify a method name and parameter value.

Note : InjectionMethod is derived from InjectionMember Class. The InjectionMember is an


abstract class which can be used to configure injection type. There are three subclasses of
InjectionMembers: InjectionConstruction to configure construction injection, InjectionProperty to
configure property injection and InjectionMethod to configure method injection.
var container = new UnityContainer();

//run-time configuration
container.RegisterType<Driver>(new InjectionMethod("UseCar", new
Audi()));

//to specify multiple parameters values


container.RegisterType<Driver>(new InjectionMethod("UseCar", new object[]
{ new Audi() }));

var driver = container.Resolve<Driver>();


driver.RunCar();
Output:
Running Audi - 1 Mile

As you can see in the above example, container.RegisterType<driver>(new


InjectionMethod("UseCar", new Audi())) registers Driver class by passing an object
of InjectionMethod that specifies the method name and parameter value. So, unity container
will inject an object of Audi when we resolve it using container.Resolve<Driver>().

Unity Container: Overrides


We have seen in the previous chapters that the unity container injects registered type by
default every time we resolve the specified type. But, what if we want to inject different
types other than the registered type?

Unity container allows us to override registered type by using ResolverOverride.


ResolverOverride is an abstract class that provides implementation for overriding
registration. There are three important classes which inherit ResolverOverride:

1. ParameterOverride: Used to override constructor parameters.


2. PropertyOverride: Used to override the value of specified property.
3. DependencyOverride: Used to override the type of dependency and its value.

Let's understand each override using the following example classes.

public interface ICar


{
int Run();
}

public class BMW : ICar


{
private int _miles = 0;

public int Run()


{
return ++_miles;
}
}

public class Ford : ICar


{
private int _miles = 0;

public int Run()


{
return ++_miles;
}
}

public class Audi : ICar


{
private int _miles = 0;

public int Run()


{
return ++_miles;
}

}
public class Driver
{
private ICar _car = null;

public Driver(ICar car)


{
_car = car;
}

public void RunCar()


{
Console.WriteLine("Running {0} - {1} mile ", _car.GetType().Name,
_car.Run());
}
}
ParameterOverride

The ParameterOverride can be used to override registered construction parameter values.

The following example demonstrates overriding constructor parameter.

Example: ParameterOverride
var container = new UnityContainer()
.RegisterType<ICar, BMW>();

var driver1 = container.Resolve<Driver>(); // Injects registered ICar


type
driver1.RunCar();

// Override registered ICar type


var driver2 = container.Resolve<Driver>(new ParameterOverride("car", new
Ford()));
driver2.RunCar();
Output:
Running BMW - 1 Mile
Running Audi - 1 Mile

In the above example, unity container injects BMW in driver1 which is default mapping.
However, we override default mapping and specify a different mapping for driver2 by
passing new ParameterOverride("car", new Ford()) into Resolve() method. The first
parameter is the name of the constructor parameter and second is the value of a parameter.
So, driver2 includes an object of Ford class instead of BMW class.

If a constructor includes multiple parameters then we can override them by passing an array
of ResolverOverride as shown below.

Example: Override Multiple Parameters


var container = new UnityContainer()
.RegisterType<ICar, BMW>();

var driver1 = container.Resolve<Driver>();


driver1.RunCar();

var driver2 = container.Resolve<Driver>( new ResolverOverride[] {


new ParameterOverride("car1", new Ford()),
new ParameterOverride("car2", new BMW()),
new ParameterOverride("car3", new Audi())
});
driver2.RunCar();
PropertyOverride

We learned about Property Injection in the previous chapter. Here, we will learn how to
override the registered value of the specified property using PropertyOverride.

You can override registered property injection and provide different property value when
you resolve it.

Example: PropertyOverride
var container = new UnityContainer();

//Configure default value of Car property


container.RegisterType<Driver>(new InjectionProperty("Car", new BMW()));

var driver1 = container.Resolve<Driver>();


driver1.RunCar();

//Override default value of Car property


var driver2 = container.Resolve<Driver>(
new PropertyOverride("Car", new Audi()
);

driver2.RunCar();
Output:
BMW - 1 mile
Audi - 1 mile
DependencyOverride

The DependencyOverride class can be used to override the type of dependency and its
value, irrespective of whether dependencies are provided through constructor, property or a
method.

You can override registered method injection and provide different parameter value when
you resolve it. Consider the following example.

Example: DependencyOverride
var container = new UnityContainer()
.RegisterType<ICar, BMW>();

var driver1 = container.Resolve<Driver>();


driver1.RunCar();

//Override dependency
var driver2 = container.Resolve<Driver>(new DependencyOverride<ICar>(new
Audi())
driver2.RunCar();
Output:
Running BMW - 1 mile
Running Audi - 1 mile

Learn more about resolving Objects by Using Overrides.

Lifetime Managers in Unity Container


The unity container manages the lifetime of objects of all the dependencies that it resolves
using lifetime managers.

Unity container includes different lifetime managers for different purposes. You can
specify lifetime manager in RegisterType() method at the time of registering type-mapping.
For example, the following code snippet shows registering a type-mapping with
TransientLifetimeManager.

var container = new UnityContainer()


.RegisterType<ICar, BMW>(new
TransientLifetimeManager());

The following table lists all the lifetime managers:

Lifetime Manager Description

TransientLifetimeManager Creates a new object of requested type every time you call
Lifetime Manager Description

Resolve or ResolveAll method.

Creates a singleton object first time you call Resolve or


ContainerControlledLifetimeManager ResolveAll method and then returns the same object on
subsequent Resolve or ResolveAll call.

Same as ContainerControlledLifetimeManager, the only


difference is that child container can create its own
HierarchicalLifetimeManager
singleton object. Parent and child container do not share
singleton object.

Similar to TransientLifetimeManager but it reuses the same


PerResolveLifetimeManager
object of registered type in the recursive object graph.

Creates singleton object per thread basis. It returns


PerThreadLifetimeManager
different objects from the container on different threads.

It manintains only weak reference of objects it creates


when you call Resolve or ResolveAll method. It does not
ExternallyControlledLifetimeManager maintain the lifetime of strong objects it creates and allow
you or garbage collector to control the lifetime. It enables
you to create your own custom lifetime manager

Let's understand each lifetime manager using the following example classes.

public interface ICar


{
int Run();
}

public class BMW : ICar


{
private int _miles = 0;

public int Run()


{
return ++_miles;
}
}

public class Ford : ICar


{
private int _miles = 0;
public int Run()
{
return ++_miles;
}
}
public class Audi : ICar
{
private int _miles = 0;

public int Run()


{
return ++_miles;
}
}

public class Driver


{
private ICar _car = null;

public Driver(ICar car)


{
_car = car;
}

public void RunCar()


{
Console.WriteLine("Running {0} - {1} mile ", _car.GetType().Name,
_car.Run());
}
}
TransientLifetimeManager

TransientLifetimeManager is the default lifetime manager. It creates a new object of


requested type every time you call Resolve() or ResolveAll() method.

var container = new UnityContainer()


.RegisterType<ICar, BMW>();

var driver1 = container.Resolve<Driver>();


driver1.RunCar();

var driver2 = container.Resolve<Driver>();


driver2.RunCar();
Output:
Running BMW - 1 Mile
Running BMW - 1 Mile

In the above example, unity container will create two new instances of BMW class and injects
into driver1 and driver2 object. This is because the default lifetime manager is
TransientLifetimeManager which creates new dependent object every time you call
Resolve or ResolveAll method. You can specify the lifetime manager at the time of
registering type using RegisterType() method.

The following example will display same output as above example because
TransientLifetimeManager is the default manager if not specified.

var container = new UnityContainer()


.RegisterType<ICar, BMW>(new
TransientLifetimeManager());

var driver1 = container.Resolve<Driver>();


driver1.RunCar();

var driver2 = container.Resolve<Driver>();


driver2.RunCar();
Output:
Running BMW - 1 Mile
Running BMW - 1 Mile

ContainerControlledLifetimeManager

Use ContainerControlledLifetimeManager when you want to create a singleton instance.

var container = new UnityContainer()


.RegisterType<ICar, BMW>(new
ContainerControlledLifetimeManager());

var driver1 = container.Resolve<Driver>();


driver1.RunCar();

var driver2 = container.Resolve<Driver>();


driver2.RunCar();
Output:
Running BMW - 1 mile
Running BMW - 2 mile

In the above example, we specified ContainerControlledLifetimeManager in


RegisterType() method. So unity container will create a single instance of BMW class and
inject it in all the instances of Driver.

HierarchicalLifetimeManager

The HierarchicalLifetimeManager is the same as ContainerControlledLifetimeManager


except that if you create a child container then it will create its own singleton instance of
registered type and will not share instance with parent container.

var container = new UnityContainer()


.RegisterType<ICar, BMW>(new
HierarchicalLifetimeManager());

var childContainer = container.CreateChildContainer();

var driver1 = container.Resolve<Driver>();


driver1.RunCar();

var driver2 = container.Resolve<Driver>();


driver2.RunCar();
var driver3 = childContainer.Resolve<Driver>();
driver3.RunCar();

var driver4 = childContainer.Resolve<Driver>();


driver4.RunCar();
Output:
Running BMW - 1 mile
Running BMW - 2 mile
Running BMW - 1 Mile
Running BMW - 2 Mile

As you can see, container and childContainer have their own singleton instance of BMW.

Visit Understand Lifetime Managers to learn more about it.

C# Tutorials
C# is a simple & powerful object-oriented programming language developed by Microsoft.
C# can be used to create various types of applications, such as web, windows, console
applications or other types of applications using Visual studio.

These C# tutorials will help you learn the essentials of C#, from the basic to advance level
topics. These tutorials are broken down into sections, where each section contains a number
of related topics that are packed with easy to understand explanations, real-world examples,
useful tips, informative notes and a "points to remember" section.

These tutorials are designed for beginners and professionals who want to learn C# step-by-
step.

So let's get started by clicking Next.

C# Version History
C# is a simple & powerful object-oriented programming language developed by Microsoft.

C# has evolved much since its first release in 2002. C# was introduced with .NET
Framework 1.0 and the current version of C# is 6.0.

The following table lists important features introduced in each version of C#:

Version .NET Framework Visual Studio Important Features


C# 1.0 .NET Framework Visual Studio .NET  Basic features
1.0/1.1 2002
Version .NET Framework Visual Studio Important Features

 Generics
 Partial types
 Anonymous methods
 Iterators
 Nullable types
 Private setters (properties)
C# 2.0 .NET Framework 2.0 Visual Studio 2005
 Method group conversions
(delegates)
 Covariance and Contra-
variance
 Static classes

 Implicitly typed local variables


 Object and collection
initializers
 Auto-Implemented properties
 Anonymous types
.NET Framework
C# 3.0 Visual Studio 2008  Extension methods
3.0\3.5
 Query expressions
 Lambda expressions
 Expression trees
 Partial Methods

 Dynamic binding (late binding)


 Named and optional arguments
C# 4.0 .NET Framework 4.0 Visual Studio 2010  Generic co- and contravariance
 Embedded interop types

 Async features
Visual Studio
C# 5.0 .NET Framework 4.5  Caller information
2012/2013
 Expression Bodied Methods
 Auto-property initializer
 nameof Expression
Visual Studio  Primary constructor
C# 6.0 .NET Framework 4.6
2013/2015  Await in catch block
 Exception Filter
 String Interpolation

C# 7.0 .NET Core Visual Studio 2017  out variables


 Tuples
 Discards
 Pattern Matching
Version .NET Framework Visual Studio Important Features
 Local functions
 Generalized async return types
 throw Expressions

Learn how to setup a development environment for C# in the next section.

Setup Developement Environment for C#


C# is used for server side execution for different kind of application like web, window
forms or console etc. In order to use C# with your .Net application, you need two things,
the .NET Framework and an IDE (Integrated Development Environment).

The .NET Framework

The .NET Framework is a platform where you can write different types of web and desktop
based applications. You can use C#, Visual Basic, F# and Jscript to write these
applications. If you have the Windows operating system, the .NET framework might
already be installed in your PC. Check MSDN to learn about .NET Framework
dependencies.

Integrated Development Environment (IDE)

An IDE is a tool that helps you write your programs. Visual Studio is an IDE provided by
Microsoft to write the code in languages such as C#, F#, VisualBasic, etc. Use latest
version of Visual Studio (2017) to learn C#.

You can write C# code with notepad also. Build your C# program using command line
tool csc.exe. Visit MSDN for more information.

Visual Studio Community edition is a free for individual developer for personal or
commercial use. However, you can purchase a license for Visual Studio Professional or
Enterprise edition. Download and install Visual Studio Community from visualstudio.com
for free.

C# can be used in a window-based, web-based, or console application. To start with, we


will create a console application to work with C#.

Open Visual Studio 2017 installed on your local machine. Click on File -> New Project...
from the top menu as shown below.
Create a New Project in Visual Studio 2017

From the New Project popup as shown below, select Visual C# in the left side panel and
select Console App in the right side panel.
Select Visual C# Console App Template

In the name section, give any appropriate project name, location where you want to create
all the project files and solution name.

Click OK to create the console project. Program.cs will be created as default a C# file in
Visual Studio where you can write your C# code in Program class as shown below. (The .cs
is a file extension for C# file.)
C# Console Program

Thus, you can create a C# console application in Visual Studio. Now, you can write C#
code in program.cs file to play with C#.

Advantages of Visual Studio

 Easy to create, edit and navigate different files or applications.


 Visual studio includes an excellent debugger that allows you to debug code easily. Step
through the application code to understand it line by line, or identify problems in your
code.
 Intellisense support for .Net Framework classes or custom classes.
 Nuget support for installing thrid party API/plug-ins in an application.
 Supports integration with many other third-party productive utilities which enhense the
development quality and speed.
 Easy to configure, build and publish .NET applications.
 Provides ALM (Application Life-cycle Management) support for different phases of the
development.

Let's write first C# console program in the next section.

First C# Program
In the previous section, we have created a console project. Now, let's write simple C# code
to understand important building blocks.

Every console application starts from the Main() method of Program class. The following
example code displays "Hello World!!" on the console.

Example: Simple Console Project with C#


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CSharpTutorials
{
class Program
{
static void Main(string[] args)
{
string message = "Hello World!!";

Console.WriteLine(message);
}
}
}

The following image illustrates the important parts of the above example.
C# Code Structure

Let's understand the above C# structure.

1. Every .NET application takes the reference of the necessary .NET framework namespaces
that it is planning to use with the "using" keyword e.g. using System.Text
2. Declare the namespace for the current class using the "namespace" keyword e.g.
namespace CSharpTutorials.FirstProgram
3. We then declared a class using the "class" keyword: class Program
4. The Main() is a method of Program class which is the entry point of the console
application.
5. String is a data type.
6. 'message' is a variable, that holds a value of a specified data type.
7. "Hello World!!" is the value of the message variable.
8. Console is a .NET framework class. WriteLine() is a method which you can use to display
messages to the console.

Note:
Every line or statement in C# must end with a semicolon (;).

Compile and Run C# Program

In order to see the output of the above C# program, we have to compile it and run it by
pressing Ctrl + F5, or clicking Run button or by clicking the "Debug" menu and clicking
"Start Without Debugging". You will see following output in the console:

Output:
Hello World!!
So this is the basic code items that you will probably use in every C# code. Let's learn
about C# Class in the next section.

C# Class
A class is like a blueprint of specific object. In the real world, every object has some color,
shape and functionalities. For example, the luxury car Ferrari. Ferrari is an object of the
luxury car type. The luxury car is a class that specify certain characteristic like speed, color,
shape, interior etc. So any company that makes a car that meet those requirements is an
object of the luxury car type. For example, every single car of BMW, lamborghini, cadillac
are an object of the class called 'Luxury Car'. Here, 'Luxury Car' is a class and every single
physical car is an object of the luxury car class.

Likewise, in object oriented programming, a class defines certain properties, fields, events,
method etc. A class defines the kinds of data and the functionality their objects will have.

A class enables you to create your own custom types by grouping together variables of
other types, methods and events.

In C#, a class can be defined by using the class keyword.

Example: C# Class
public class MyClass
{
public string myField = string.Empty;

public MyClass()
{
}

public void MyMethod(int parameter1, string parameter2)


{
Console.WriteLine("First Parameter {0}, second parameter
{1}",
parameter1,
parameter2);
}

public int MyAutoImplementedProperty { get; set; }

private int myPropertyVar;

public int MyProperty


{
get { return myPropertyVar; }
set { myPropertyVar = value; }
}
}

The following image shows the important building blocks of C# class.

C# Class

C# Access Modifiers

Access modifiers are applied on the declaration of the class, method, properties, fields and
other members. They define the accessibility of the class and its members. Public, private,
protected and internal are access modifiers in C#. We will learn about it in the keyword
section.

C# Field

Field is a class level variable that can holds a value. Generally field members should have a
private access modifier and used with a property.
C# Constructor

A class can have parameterized or parameter less constructors. The constructor will be
called when you create an instance of a class. Constructors can be defined by using an
access modifier and class name: <access modifiers> <class name>(){ }

Example: Constructor in C#
class MyClass
{
public MyClass()
{

}
}
C# Method

A method can be defined using the following template:

{access modifier} {return type} MethodName({parameterType parameterName})

Example: Method in C#
public void MyMethod(int parameter1, string parameter2)
{
// write your method code here..

}
Property

A property can be defined using getters and setters, as below:

Example: Property in C#
private int _myPropertyVar;

public int MyProperty


{
get { return _myPropertyVar; }
set { _myPropertyVar = value; }
}

Property encapsulates a private field. It provides getters (get{}) to retrieve the value of the
underlying field and setters (set{}) to set the value of the underlying field. In the above
example, _myPropertyVar is a private field which cannot be accessed directly. It will only
be accessed via MyProperty. Thus, MyProperty encapsulates _myPropertyVar.

You can also apply some addition logic in get and set, as in the below example.

Example: Property in C#
private int _myPropertyVar;

public int MyProperty


{
get {
return _myPropertyVar / 2;
}

set {
if (value > 100)
_myPropertyVar = 100;
else
_myPropertyVar = value; ;
}
}
Auto-implemented Property

From C# 3.0 onwards, property declaration has been made easy if you don't want to apply
some logic in get or set.

The following is an example of an auto-implemented property:

Example: Auto implemented property in C#


public int MyAutoImplementedProperty { get; set; }

Notice that there is no private backing field in the above property example. The backing
field will be created automatically by the compiler. You can work with an automated
property as you would with a normal property of the class. Automated-implemented
property is just for easy declaration of the property when no additional logic is required in
the property accessors.

Namespace

Namespace is a container for a set of related classes and namespaces. Namespace is also
used to give unique names to classes within the namespace name. Namespace and classes
are represented using a dot (.).

In C#, namespace can be defined using the namespace keyword.

Example: Namespace
namespace CSharpTutorials
{
class MyClass
{

}
}
In the above example, the fully qualified class name of MyClass is
CSharpTutorials.MyClass.

A namespace can contain other namespaces. Inner namespaces can be separated using (.).

Example: Namespace
namespace CSharpTutorials.Examples
{
class MyClassExample
{

}
}

In the above example, the fully qualified class name of MyClassExample is


CSharpTutorials.Example.MyClassExample

Learn about C# variables next.

C# Variable
In the first C# program chapter, we declared a variable called "message" as shown below.

Example: C# Variable
namespace CSharpTutorials
{
class Program
{
static void Main(string[] args)
{
string message = "Hello World!!";

Console.WriteLine(message);
}
}
}

The variable in C# is nothing but a name given to a data value. In the above example,
message is the name of the variable that stores the string data value "Hello World!!". As the
name suggests, the contents of a variable can vary, i.e., you can change the value of a
variable at any time.

In C#, a variable is always defined with a data type. The following is the syntax variable
declaration and initialization.

Variable Syntax:
<data type> <variable name>;

<datatype> <variable name> = <value>;

A variable can be declared and initialized later or it can be declared and initialized at the
same time. In the following example, the first statement declares a variable called
"message" without assigning any value to it. In the second statement, a value is assigned to
the "message" variable.

Example: Variable Declaration


string message;

// value can be assigned after it declared


message = "Hello World!!";

In the following example, variable is declared and initialized (a value is assigned to it) at
the same time.

Example: Variable Declaration & Initialization


string message = "Hello World!!";

Multiple variables of the same data type can be declared and initialized in a single line
separated by commas.

Example: Multiple Declarations


int i, j, k, l = 0;

int amount, num;

When declaring multiple variables of the same data type, you can put them in multiple lines
for the sake of readability; even if split across multiple lines, the compiler will consider it to
be one statement, until it encounters a semicolon (;).

Example: Multi-Line Declarations


int i, j,
k,
l = 0;

The value of a variable can be assigned to another variable of the same data type. However,
a value must be assigned to a variable before using it.

Example: Variable Assignment


int i = 100;

int j = i; // value of j will be 100

The following example would give a compile time error because string value cannot be
assinged to a int type variable.
Example: Invalid Variable Assignment
string message = "Hello World!!";

int i = message; // compile time error

You must assign a value to a variable before using it otherwise the compiler will give an
error. For example, in the following code, we have declared a variable called i without
assigning any value to it. If we then try to display the value of the variable on the console,
we will get a compile time error.

Example: Invalid Variable Assignment


int i;

//Following will give compile time error: "Use of unassigned local


variable 'i'"
int j = i;
Console.WriteLine(j);

Points to Remember :

1. The variable is a name given to a data value.


2. A variable holds the value of specific data type e.g string, int, float etc.
3. A variable can be declared and initialized in separate statements and also in the
single statement.
4. The value of a variable can be changed at any time throught out the program as long
as it is accessible.
5. Multiple variables can be defined seperated by comma (,) in a single or multiple line
till semicolon(;).
6. A value must be assigned to a variable before using it otherwise it will give compile
time error.

Learn about C# data types in the next section.

C# Data Types
In the previous section, we have seen that a variable must be declared with the data type
because C# is a strongly-typed language. For example,

string message = "Hello World!!";

Above, string is a data type, message is a variable, and "Hello World!!" is a string
value assigned to a variable message.

The data type tells the C# compiler what kind of value a variable can hold. C# includes
many in-built data types for different kinds of data, e.g. String, number, float, decimal, etc.
Example: Data types
class Program
{
static void Main(string[] args)
{
string stringVar = "Hello World!!";
int intVar = 100;
float floatVar = 10.2f;
char charVar = 'A';
bool boolVar = true;

}
}

Each data types includes specific range of values. For example, a variable of int data type
can have any value between -2,147,483,648 to 2,147,483,647. The same way, bool data
type can have only two value - true or false. The following table lists the data types
available in C# along with the range of values possible for each data type:

.NET Size
Alias Type Range (values)
Type (bits)

byte Byte Unsigned integer 8 0 to 255

sbyte SByte Signed integer 8 -128 to 127

int Int32 Signed integer 32 -2,147,483,648 to 2,147,483,647

uint UInt32 Unsigned integer 32 0 to 4294967295

short Int16 Signed integer 16 -32,768 to 32,767

ushort UInt16 Unsigned integer 16 0 to 65,535

-9,223,372,036,854,775,808 to
long Int64 Signed integer 64
9,223,372,036,854,775,807

ulong UInt64 Unsigned integer 64 0 to 18,446,744,073,709,551,615

Single-precision floating point


float Single 32 -3.402823e38 to 3.402823e38
type

Double-precision floating point -1.79769313486232e308 to


double Double 64
type 1.79769313486232e308

char Char A single Unicode character 16 Unicode symbols used in text

bool Boolean Logical Boolean type 8 True or False

object Object Base type of all other types


.NET Size
Alias Type Range (values)
Type (bits)

string String A sequence of characters

Precise fractional or integral


type that can represent decimal
decimal Decimal 128 (+ or -)1.0 x 10e-28 to 7.9 x 10e28
numbers with 29 significant
digits

0:00:00am 1/1/01 to 11:59:59pm


DateTime DateTime Represents date and time
12/31/9999

As you can see in the above table that each data types (except string and object) includes
value range. Compiler will give an error if value goes out of datatype's permitted range. For
example, int data type's range is -2,147,483,648 to 2,147,483,647. So if you assign value
which is not in this range then compiler would give error.

Example: Compile time error


// compile time error: Cannot implicitly convert type 'long' to 'int'.
int i = 21474836470;
Alias vs .Net Type

In the above table of data types, first column is for data type alias and second column is
actual .Net type name. For example, int is an alias (or short name) for Int32. Int32 is a
structure defined in System namespace. The same way, string represent String class.

Alias Type Name .Net Type

byte System.Byte struct

sbyte System.SByte struct

int System.Int32 struct

uint System.UInt32 struct

short System.Int16 struct

ushort System.UInt16 struct

long System.Int64 struct

ulong System.UInt64 struct

float System.Single struct

double System.Double struct


Alias Type Name .Net Type

char System.Char struct

bool System.Boolean struct

object System.Object Class

string System.String Class

decimal System.Decimal struct

DateTime System.DateTime struct

Data types are further classified as value type or reference type, depending on whether a
variable of a particular type stores its own data or a pointer to the data in the memory.

Learn about variables in value type and reference type in the next section.

Value Type and Reference Type


We have learned about the data types in the previous section. In C#, these data types are
categorized based on how they store their value in the memory. C# includes following
categories of data types:

1. Value type
2. Reference type

Value Type:

A data type is a value type if it holds a data value within its own memory space. It means
variables of these data types directly contain their values.

All the value types derive from System.ValueType, which in-turn, derives from
System.Object.

For example, consider integer variable int i = 100;

The system stores 100 in the memory space allocated for the variable 'i'. The following
image illustrates how 100 is stored at some hypothetical location in the memory
(0x239110) for 'i':
Memory allocation for Value Type

The following data types are all of value type:

 bool
 byte
 char
 decimal
 double
 enum
 float
 int
 long
 sbyte
 short
 struct
 uint
 ulong
 ushort

Passing by Value:

When you pass a value type variable from one method to another method, the system
creates a separate copy of a variable in another method, so that if value got changed in the
one method won't affect on the variable in another method.

Example: Value Type


static void ChangeValue(int x)
{
x = 200;

Console.WriteLine(x);
}

static void Main(string[] args)


{
int i = 100;

Console.WriteLine(i);

ChangeValue(i);

Console.WriteLine(i);
}
Output:
100
200
100

In the above example, variable i in Main() method remains unchanged even after we pass it
to the ChangeValue() method and change it's value there.

Reference Type

Unlike value types, a reference type doesn't store its value directly. Instead, it stores the
address where the value is being stored. In other words, a reference type contains a pointer
to another memory location that holds the data.

For example, consider following string variable:

string s = "Hello World!!";

The following image shows how the system allocates the memory for the above string
variable.

Memory allocation
for Reference type

As you can see in the above image, the system selects a random location in memory
(0x803200) for the variable 's'. The value of a variable s is 0x600000 which is the memory
address of the actual data value. Thus, reference type stores the address of the location
where the actual value is stored instead of value itself.

The following data types are of reference type:

 String
 All arrays, even if their elements are value types
 Class
 Delegates
Pass by Reference

When you pass a reference type variable from one method to another, it doesn't create a
new copy; instead, it passes the address of the variable. If we now change the value of the
variable in a method, it will also be reflected in the calling method.

Example: Reference Type Variable


static void ChangeReferenceType(Student std2)
{
std2.StudentName = "Steve";
}

static void Main(string[] args)


{
Student std1 = new Student();
std1.StudentName = "Bill";

ChangeReferenceType(std1);

Console.WriteLine(std1.StudentName);
}
Output:
Steve

In the above example, since Student is an object, when we send the Student object std1 to
the ChangeReferenceType() method, what is actually sent is the memory address of std1.
Thus, when the ChangeReferenceType() method changes StudentName, it is actually
changing StudentName of std1, because std1 and std2 are both pointing to the same address
in memory. Therefore, the output is Steve.

Null

Reference types have null value by default, when they are not initialized. For example, a
string variable (or any other variable of reference type datatype) without a value assigned to
it. In this case, it has a null value, meaning it doesn't point to any other memory location,
because it has no value yet.

Null Reference
type
A value type variable cannot be null because it holds a value not a memory address.
However, value type variables must be assigned some value before use. The compiler will
give an error if you try to use a local value type variable without assigning a value to it.

Example: Compile Time Error


void someFunction()
{
int i;

Console.WriteLine(i);
}

C# 2.0 introduced nullable types for value types so that you can assign null to a value
type variable or declare a value type variable without assigning a value to it.

However, value type field in a class can be declared without initialization (field not a local
variable in the function) . It will have a default value if not assigned any value, e.g., int will
have 0, boolean will have false and so on.

Example: Value Type Field


class myClass
{
public int i;
}

myClass mcls = new myClass();

Console.WriteLine(mcls.i);
 

Output:
0

Points to Remember :

1. Value type stores the value in its memory space, whereas reference type stores the
address of the value where it is stored.
2. Primitive data types and struct are of the 'Value' type. Class objects, string, array,
delegates are reference types.
3. Value type passes byval by default. Reference type passes byref by default.
4. Value types and reference types stored in Stack and Heap in the memory depends on the
scope of the variable.

Further Reading
 Read Eric Lippert's blog part 1 and part 2 for more details about value type and reference
type.
 Visit MSDN to know default values of value types.

C# Keywords
C# contains reserved words, that have special meaning for the compiler. These reserved
words are called "keywords". Keywords cannot be used as a name (identifier) of a variable,
class, interface, etc.

Keywords in C# are distributed under the following categories:

Modifier Keywords

Modifier keywords are certain keywords that indicate who can modify types and type
members. Modifiers allow or prevent certain parts of programs from being modified by
other parts.

Modifier keywords

abstract

async

const

event

extern

new

override

partial

readonly

sealed

static

unsafe

virtual

volatile
Modifier keywords

Access Modifier Keywords:

Access modifiers are applied on the declaration of the class, method, properties, fields and
other members. They define the accessibility of the class and its members.

Access
Usage
Modifiers

The Public modifier allows any part of the program in the same assembly or another
public
assembly to access the type and its members.

The Private modifier restricts other parts of the program from accessing the type
private
and its members. Only code in the same class or struct can access it.

The Internal modifier allows other program code in the same assembly to access the
internal
type or its members. This is default access modifiers if no modifier is specified.

The Protected modifier allows codes in the same class or a class that derives from
protected
that class to access the type or its members.

Statement Keywords

Statement keywords are related to program flow.

Statement Keywords

if

else

switch

case

do

for

foreach

in

while

break
Statement Keywords

continue

default

goto

return

yield

throw

try

catch

finally

checked

unchecked

fixed

lock

Method Parameter Keywords

These keywords are applied on the parameters of a method.

Method Parameter Keywords

params

ref

out

Namespace Keywords

These keywords are applied with namespace and related operators.

Namespace Keywords

using

. operator

:: operator
Namespace Keywords

extern alias

Operator Keywords

Operator keywords perform miscellaneous actions.

Operator Keywords

as

await

is

new

sizeof

typeof

stackalloc

checked

unchecked

Access Keywords

Access keywords are used to access the containing class or the base class of an object or
class.

Access keywords

base

this

Literal Keywords

Literal keywords apply to the current instance or value of an object.

Literal Keywords

null

false

true
Literal Keywords

value

void

Type Keywords

Type keywords are used for data types.

Type keywords

bool

byte

char

class

decimal

double

enum

float

int

long

sbyte

short

string

struct

uint

ulong

ushort

Contextual Keywords

Contextual keywords are considered as keywords, only if used in certain contexts. They are
not reserved and so can be used as names or identifiers.
Contextual Keywords

add

var

dynamic

global

set

value

Contextual keywords are not converted into blue color (default color for keywords in visual
studio) when used as an identifier in Visual Studio. For example, var in the below figure is
not in blue color whereas color of this is blue color. So var is a contextual keyword.

C# Keywords

Query Keywords

Query keywords are contextual keywords used in LINQ queries.

Query Keywords

from

where

select

group

into

orderby

join

let
Query Keywords

in

on

equals

by

ascending

descending

As mentioned above, keyword cannot be used as an identifier (name of variable, class,


interface etc). However, they can be used with the prefix '@'. For example, class is a
reserved keyword so it cannot be used as an identifier, but @class can be used as shown
below.

Example: Use Keyword as Identifier


public class @class
{
public static int MyProperty { get; set; }
}

@class.MyProperty = 100;

Visit MSDN for more information on keywords.

Points to Remember :

1. Keywords are reserved words that cannot be used as name or identifier.


2. Prefix '@' with keywords if you want to use it as identifier.
3. C# includes various categories of keywords e.g. modifier keywords, access modifiers
keywords, statement keywords, method param keywords etc.
4. Contextual keywords can be used as identifier.

C# Interface:
An interface in C# contains only the declaration of the methods, properties, and events, but
not the implementation. It is left to the class that implements the interface by providing
implementation for all the members of the interface. Interface makes it easy to maintain a
program.
In C#, an interface can be defined using the interface keyword. For example, the following
is a simple interface for a logging string message:

Interface Declaration:
interface ILog
{
void Log(string msgToLog);
}

Now, different classes can implement ILog by providing an implementation of the Log()
method, for example, the ConsoleLog class logs the string on the console whereas FileLog
logs the string into a text file.

Implement interface using <Class Name> : <Interface Name > syntax.

Implement Interface
class ConsoleLog: ILog
{
public void Log(string msgToPrint)
{
Console.WriteLine(msgToPrint);
}
}

class FileLog :ILog


{
public void Log(string msgToPrint)
{
File.AppendText(@"C:\Log.txt").Write(msgToPrint);
}
}

Now, you can instantiate an object of either the ConsoleLog or FileLog class:

Instantiate Object
ILog log = new ConsoleLog();

//Or

ILog log = new FileLog();


Explicit Implementation:

You can implement interface explicitly by prefixing interface name with method name, as
below:

Impliment Interface Explicitly


class ConsoleLog: ILog
{
public void ILog.Log(string msgToPrint) // explicit
implementation
{
Console.WriteLine(msgToPrint);
}
}

Explicit implementation is useful when class is implementing multiple interface thereby it


is more readable and eliminates the confusion. It is also useful if interfaces have same
method name coincidently.

Visit MSDN for more information on C# interface.

Points to Remember :

1. An interface only contains declarations of method, events & properties.


2. An interface can be implement implicitly or explicitly.
3. An interface cannot include private members. All the members are public by default.

C# Operators
Operator in C# is a special symbol that specifies which operations to perform on operands.
For example, in mathematics the plus symbol (+) signifies the sum of the left and right
numbers. In the same way, C# has many operators that have different meanings based on
the data types of the operands. C# operators usually have one or two operands. Operators
that have one operand are called Unary operators.

The following table list some of the operators available in C#.

Operator category Operators

Primary x.y

Unary +x

Multiplicative x*y

Additive x+y

Shift x << y

Relational and type testing x<y

Equality x == y

Logical AND x&y


Operator category Operators

Logical XOR x^y

Logical OR x|y

Conditional AND x && y

Conditional OR x || y

Null-coalescing x ?? y

Conditional ?:

Assignment and lambda expression x = y

As mentioned before, certain operators have different meanings based on the datatype of
the operand. For example, if the + operator is used with numbers, it will add the numbers
but if it is used with strings, it will concatenate the two strings.

When an operator does different things based on the datatype of the operands, it is called
operator over loading.

The following C# code shows the use of the + sign operator on different datatypes:

Example: + Operator
static void Main(string[] args)
{
string message1 = "Hello";

string message2 = message1 + " World!!";

Console.WriteLine(message2);

int i = 10, j = 20;

int sum = i + j;

Console.WriteLine("{0} + {1} = {2}", i, j, sum);

Output:
Hello World!!
10 + 20 = 30.
This tutorial doesn't cover detail of each operators. Visit MSDN to learn all the operators in
detail.

if Statement
C# provides many decision making statements that help the flow of the C# program based
on certain logical conditions. C# includes the following decision making statements.

1. if statement
2. if-else statement
3. switch statement
4. Ternary operator :?

Here, you will learn about the if statements.

Syntax:
if(boolean expression)
{
// execute this code block if expression evalutes to true
}

The if statement contains boolean expression inside brackets followed by a single or multi
line code block. At runtime, if a boolean expression is evalutes to true then the code block
will be executed.

Consider the following example where the if condition contains true as an expression.

Example: if condition
if(true)
{
Console.WriteLine("This will be displayed.");
}

if(false)
{
Console.WriteLine("This will not be displayed.");
}

As mentioned above, if statement can contain boolean expression. An expression which


returns either true or false. Following example uses logical expression as a condition:

Example: if condition
int i = 10, j = 20;
if (i > j)
{
Console.WriteLine("i is greater than j");
}

if (i < j)
{
Console.WriteLine("i is less than j");
}

if (i == j)
{
Console.WriteLine("i is equal to j");
}
Output:
i is less than j

In the above example, the boolen expression i < j in the second 'if' statement evalutes to
be true, only the second 'if' statement's code block will be executed. The first and third 'if'
condition evalutes to false, so their code blocks will not be executed.

if-else Statement

C# also provides for a second part to the if statement, that is else. The else statement must
follow if or else if statement. Also, else statement can appear only one time in a if-else
statement chain.

Syntax:
if(boolean expression)
{
// execute this code block if expression evalutes to true
}
else
{
// always execute this code block when above if expression is false
}

As you can see in the above syntax, the else stament cannot contain any expression. The
code block that follows else statement will always be executed, when the 'if' condition
evalutes to be false.

Example: if else
int i = 10, j = 20;

if (i > j)
{
Console.WriteLine("i is greater than j");
}
else
{
Console.WriteLine("i is either equal to or less than j");
}
Output:
i is either equal to or less than j

else if Statement

The 'if' statement can also follow an 'else' statement, if you want to check for another
condition in the else part.

Example: else if
static void Main(string[] args)
{
int i = 10, j = 20;

if (i > j)
{
Console.WriteLine("i is greater than j");
}
else if (i < j)
{
Console.WriteLine("i is less than j");
}
else
{
Console.WriteLine("i is equal to j");
}

}
Output:
i is less than j

You can use multiple else-if statements in a single 'if' statment chain. Also, you can remove
the curly brackets, when the 'if' block has only one line to execute:

C#- if..else condition:


int i = 10, j = 20;

if (i > j)
Console.WriteLine("i is greater than j");
else if (i < j)
Console.WriteLine("i is less than j");
else if (i == j)
Console.WriteLine("i is equal to j");
Output:
i is less than j
Nested if Statements

C# alows nested if else statements. The nested 'if' statement makes the code more readable.

Example: Nested if statements


int i = 10;

if (i > 0)
{
if (i <= 100)
{
Console.WriteLine("i is positive number less than 100");
}
else
{
Console.WriteLine("i is positive number greater than
100");
}
}
Output:
i is positive number less than 100

The if-else statement can be replaced by ternary operator. Learn about ternary operator in
the next section.

Points to Remember :

1. if-else statement controls the flow of program based on the evaluation of the boolean
expression.
2. It should start from the if statement followed by else or else-if statements.
3. Only one else statement is allowed in the if-else chain.
4. Multiple else-if statements are allowed in a single if-else chain.
5. Nested if-else statement is allowed.

C# - Ternary operator ?:
C# includes a special type of decision making operator '?:' called the ternary operator.

Variable Syntax:
Boolean Expression ? First Statement : Second Statement

As you can see in the above syntax, ternary operator includes three parts. First part
(before ?) includes conditional expression that returns boolean value true or false. Second
part (after ? and before :) contains a statement which will be returned if the conditional
expression in the first part evalutes to true. The third part includes another statement which
will be returned if the conditional expression returns false.

Note:

Ternary operator returns a value or expression included in the second or third part of it. It does
not execute the statements.

Consider the following example where conditional expression x > y returns false, so it the
returns the first statement after ?.

Example: Ternary operator


int x = 20, y = 10;

var result = x > y ? "x is greater than y" : "x is less than or equal to
y";

Console.WriteLine(result);

output:
x is greater than y

The ternary operator can return a value of any data type. So it is advisable to store it in
implicitly typed variable - var.

For example, it can return an integer value as shown below.

Example: Ternary operator


int x = 20, y = 10;

var result = x > y ? x : y;

Console.WriteLine(result);

output:
20

Ternary operator can also be used instead of if-else statement. The above example can be
written using if-else statement as shown below.

Example: Ternary operator replaces if statement


int x = 20, y = 10;
int result = 0;

if (x > y)
result = x;
else if (x < y)
result = y;

Console.WriteLine(result);

output:
20

Nested Ternary operator:

Nested ternary operators are possible by including conditional expression as a second (after
?) or third part (after :) of the ternary operator..Consider the following example.

Example: Nested ternary operator


int x = 2, y = 10;

string result = x > y ? "x is greater than y" : x < y ?


"x is less than y" : x == y ?
"x is equal to y" : "No result";

The ternary operator is right-associative. The expression a ? b : c ? d : e is evaluated


as a ? b : (c ? d : e), not as (a ? b : c) ? d : e.

Points to Remember :

1. Ternary operator: boolean expression ? first statement : second


statement;
2. Ternary operator returns a value, it does not execute it.
3. It can be used to replace a short if-else statement.
4. A nested ternary operator is allowed. It will be evaluted from right to left.

Learn about C# switch statement next

C# - switch
C# includes another decision making statement called switch. The switch statement
executes the code block depending upon the resulted value of an expression.

Syntax:
switch(expression)
{
case <value1>
// code block
break;
case <value2>
// code block
break;
case <valueN>
// code block
break;
default
// code block
break;
}

As per the syntax above, switch statement contains an expression into brackets. It also
includes multiple case labels, where each case represents a particular literal value. The
switch cases are seperated by a break keyword which stops the execution of a particular
case. Also, the switch can include a default case to execute if no case value satisfies the
expression.

Note:

Case label in switch must be unique. It can be bool, char, string, integer, enum, or corresponding
nullable type.

Consider the following example of a simple switch statement.

Example: switch
int x = 10;

switch (x)
{
case 5:
Console.WriteLine("Value of x is 5");
break;
case 10:
Console.WriteLine("Value of x is 10");
break;
case 15:
Console.WriteLine("Value of x is 15");
break;
default:
Console.WriteLine("Unknown value");
break;
}
Output:
Value of x is 10

The switch statement can include expression or variable of any data type such as string,
bool, int, enum, char etc.

Example: switch statement


string statementType = "switch";

switch (statementType)
{
case "if.else":
Console.WriteLine("if...else statement");
break;
case "ternary":
Console.WriteLine("Ternary operator");
break;
case "switch":
Console.WriteLine("switch statement");
break;
}
Output:
switch statement

Goto in switch:

The switch case can use goto to jump over a different case.

Example: goto in switch case


string statementType = "switch";

switch (statementType)
{
case "DecisionMaking":
Console.Write("if-else is a decision making statement.");
break;
case "if.else":
Console.Write("if-else");
break;
case "ternary":
Console.Write("Ternary operator");
break;
case "switch":
Console.Write("switch statement");
goto case "DecisionMaking";
}
Output:
switch statement is a decision making statement.

Nested switch:

Nested switch statments are allowed in C# by writing inner switch statement inside a outer
switch case.

Example: Nested switch statements


int j = 5;

switch (j)
{
case 5:
Console.WriteLine(5);
switch (j - 1)
{
case 4:
Console.WriteLine(4);
switch (j - 2)
{
case 3:
Console.WriteLine(3);
break;
}
break;
}
break;
case 10:
Console.WriteLine(10);
break;
case 15:
Console.WriteLine(15);
break;
default:
Console.WriteLine(100);
break;
}
Output:
5
4
3

Points to Remember :

1. The switch statement tests the variable against a set of constants.


2. The switch statement contains multiple case labels.
3. The switch case includes break keyword to stop the execution of switch case.
4. The default case executes when no case satisfies the expression.
5. A nested switch statement is allowed.

C# - for loop
The for keyword indicates a loop in C#. The for loop executes a block of statements
repeatedly until the specified condition returns false.

Syntax:
for (variable initialization; condition; steps)
{
//execute this code block as long as condition is satisfied
}

As per the syntax above, the for loop contains three parts: initialization, conditional
expression and steps, which are separated by a semicolon.

1. variable initialization: Declare & initialize a variable here which will be used in conditional
expression and steps part.
2. condition: The condition is a boolean expression which will return either true or false.
3. steps: The steps defines the incremental or decremental part

Consider the following example of a simple for loop.

Example: for loop


for (int i = 0; i < 10; i++)
{
Console.WriteLine("Value of i: {0}", i);
}
Output:
Value of i: 0
Value of i: 1
Value of i: 2
Value of i: 3
Value of i: 4
Value of i: 5
Value of i: 6
Value of i: 7
Value of i: 8
Value of i: 9

The below figure illustrates the execution steps of above example.

for loop
execution steps

As you can see in the above example, first step is to declare & initialize an int type variable.
The second step is to check the condition. The third step is to execute the code block if the
'if' condition returns true. The fourth step is to increment the int variable and last step is to
eveluate the condition again and repeat the steps.
It is not necessary to put the initialization, condition and steps into brackets. You can
initialize a variable before the 'for' loop, and the condition and steps can be defined inside
the for loop.

Example: for loop C#


int i = 0;

for(;;)
{
if (i < 10)
{
Console.WriteLine("Value of i: {0}", i);
i++;
}
else
break;
}
Output:
Value of i: 0
Value of i: 1
Value of i: 2
Value of i: 3
Value of i: 4
Value of i: 5
Value of i: 6
Value of i: 7
Value of i: 8
Value of i: 9

Infinite for Loop

Be careful with infinite loop. It will be an infinite loop if for loop does not contain
initialization, condition or steps part. Also, make sure that conditional expression will
return false at some point of time to stop the looping.

Example: Infinite loop


for ( ; ; )
{
Console.Write(1);
}
Output:
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1.....

The control variable for the for loop can be of any numeric data type, such as double,
decimal, etc.

Example: for loop


for (double d = 1.01D; d < 1.10; d+= 0.01D)
{
Console.WriteLine("Value of i: {0}", d);
}
Output:
Value of i: 1.01
Value of i: 1.02
Value of i: 1.03
Value of i: 1.04
Value of i: 1.05
Value of i: 1.06
Value of i: 1.07
Value of i: 1.08
Value of i: 1.09

The steps part in a for loop can either increase or decrease the value of a variable.

Example: for loop


for(int i = 10; i> 0;i--)
{
Console.WriteLine("Value of i: {0}", i);
}
Output:
Value of i: 10
Value of i: 9
Value of i: 8
Value of i: 7
Value of i: 6
Value of i: 5
Value of i: 4
Value of i: 3
Value of i: 2
Value of i: 1

break in for loop

You can also exit from a for loop by using the break keyword.

Example: break in for loop


for (int i = 0; i < 10; i++)
{
if( i == 5 )
break;

Console.WriteLine("Value of i: {0}", i);


}
Output:
Value of i: 0
Value of i: 1
Value of i: 2
Value of i: 3
Value of i: 4

Nested for Loop

C# allows a for loop inside another for loop.

Example: Nested for loop


for (int i = 0; i < 10; i++)
{
for(int j =i; j< 10; j++)
Console.WriteLine("Value of i: {0}, J: {1} ", i,j);
}
Output:
Value of i: 0 , j: 0
Value of i: 0 , j: 1
Value of i: 0 , j: 2
Value of i: 0 , j: 3
Value of i: 0 , j: 4
Value of i: 0 , j: 5
Value of i: 0 , j: 6
Value of i: 0 , j: 7
Value of i: 0 , j: 8
Value of i: 0 , j: 9
Value of i: 1 , j: 1
Value of i: 1 , j: 2
Value of i: 1 , j: 3
Value of i: 1 , j: 4
Value of i: 1 , j: 5
Value of i: 1 , j: 6
Value of i: 1 , j: 7
Value of i: 1 , j: 8
Value of i: 1 , j: 9
Value of i: 2 , j: 2
Value of i: 2 , j: 3
Value of i: 2 , j: 4
Value of i: 2 , j: 5
Value of i: 2 , j: 6
Value of i: 2 , j: 7

Points to Remember :

1. The for loop executes the block of code repeatedly.


2. The for loop has three steps: initialization, condition and increment/decrement.
3. The for loop can use control variable of any numeric data type.
4. Use break keyword to stop the execution and exit from for loop.
5. Nested for loop is allowed in C#.

C# - while loop:
C# includes the while loop to execute a block of code repeatedly.

Syntax:
While(boolean expression)
{
//execute code as long as condition returns true

As per the while loop syntax, the while loop includes a boolean expression as a condition
which will return true or false. It executes the code block, as long as the specified
conditional expression returns true. Here, the initialization should be done before the loop
starts and increment or decrement steps should be inside the loop.

Example: while loop in C#


int i = 0;

while (i < 10)


{
Console.WriteLine("Value of i: {0}", i);

i++;
}
Output:
Value of i: 0
Value of i: 1
Value of i: 2
Value of i: 3
Value of i: 4
Value of i: 5
Value of i: 6
Value of i: 7
Value of i: 8
Value of i: 9

In the above example, while loop inclues an expression i < 10. Inside while loop, value of
i increased to 1 (using i++). So, the above while loop will be executed till the value of i will
be 10.
Use the break keyword to exit from a while loop as shown below.

Example: break in while loop


int i = 0;

while (true)
{
Console.WriteLine("Value of i: {0}", i);

i++;

if (i > 10)
break;
}
Output:
Value of i: 0

Nested while loop:

Nested while loop is allowed in C#

Example: Nested while loop


int i = 0;

while (i < 2)
{
Console.WriteLine("Value of i: {0}", i);
int j = 1;

i++;

while (j < 2)
{
Console.WriteLine("Value of j: {0}", j);
j++;
}
}
Output:
Value of i: 0
Value of j: 1
Value of i: 1
Value of j: 1

Note:

Please make sure that conditional expression evaluates to false at some point to avoid infinite
loop.

Points to Remember :
1. The while loop executes the block of code repeatedly.
2. The while loop includes condition expression. Increment/decrement step should be inside
the loop.
3. Use break keyword to stop the execution and exit from while loop.
4. An nested while loop is allowed.

C# - do while
The do-while loop is the same as a 'while' loop except that the block of code will be
executed at least once, because it first executes the block of code and then it checks the
condition.

Syntax:
do
{
//execute code block

} while(boolean expression);

As per the syntax above, do-while loop starts with the 'do' keyword followed by a code
block and boolean expression with 'while'.

Example: do while loop


int i = 0;

do
{
Console.WriteLine("Value of i: {0}", i);

i++;

} while (i < 10);

Output:
Value of i: 0
Value of i: 1
Value of i: 2
Value of i: 3
Value of i: 4
Value of i: 5
Value of i: 6
Value of i: 7
Value of i: 8
Value of i: 9
Just as in the case of the for and while loops, you can break out of the do-while loop using
the break keyword.

Example: break inside do-while


int i = 0;

do
{
Console.WriteLine("Value of i: {0}", i);

i++;

if (i > 5)
break;

} while (true);

Output:
Value of i: 0
Value of i: 1
Value of i: 2
Value of i: 3
Value of i: 4
Value of i: 5

Nested do-while

The do-while loop can be used inside another do-while loop.

Example: Nested do while loop


int i = 0;

do
{
Console.WriteLine("Value of i: {0}", i);
int j = i;

i++;

do
{
Console.WriteLine("Value of j: {0}", j);
j++;

} while (j < 2);

} while (i < 2);

Output:
Value of i: 0
Value of j: 0
Value of j: 1
Value of i: 1
Value of j: 1

Points to Remember :

1. The do-while loop executes the block of code repeatedly.


2. The do-while loop execute the code atleast once. It includes the conditional expression
after the code block and the increment/decrement step should be inside the loop.
3. Use the break keyword to stop the execution and exit from a do-while loop.
4. An nested do-while loop is allowed.

Learn about C# structure next.

C# - struct
We have learned class in the previous section. Class is a reference type. C# includes a value
type entity, which is called Structure. A structure is a value type that can contain
constructors, constants, fields, methods, properties, indexers, operators, events and nested
types. A structure can be defined using the struct keyword.

Example: Structure
public struct Discounts
{
public int Cloths { get; set; }
public int HomeDecor { get; set; }
public int Grocery { get; set; }
}

A struct can be initialized with or without the new keyword same as primitive variable or
an object. You can then assign values to the members of the structure as shown below.

Example: Initialize Structure


Discounts saleDiscounts = new Discounts();

saleDiscounts.Cloths = 10;
saleDiscounts.HomeDecor = 5;
saleDiscounts.Grocery = 2;

A struct is a value type so it is faster than a class object. Use struct whenever you want to
just store the data. Generally structs are good for game programming. However, it is easier
to transfer a class object than a struct. So do not use struct when you are passing data across
the wire or to other classes.

Example: Structure
struct Point
{
private int _x, _y;

public int x, y;

public static int X, Y;

public int XPoint {


get
{
return _x;
}

set
{
_x = value;
PointChanged(_x);
}
}

public int YPoint


{
get
{
return _y;
}
set
{
_y = value;
PointChanged(_y);
}
}

public event Action<int> PointChanged;

public void PrintPoints()


{
Console.WriteLine(" x: {0}, y: {1}", _x, _y);
}

public static void StaticMethod()


{
Console.WriteLine("Inside Static method");
}
}

The above structure consists of different types of properties and events for the demo
purpose. It includes private fields _x, _y, public fields x and y, static fields X and Y, public
properties XPoint and YPoint, and PointChanged event. It also includes static and non-
static methods. Notice that we raise the PointChanged event whenever XPoint or YPoint
changes.

In the following code, we initialize the above Point struct with the new keyword as we
initialize the class and also handle the PointChanged event:

Example: Initialize Structure using new keyword


class Program
{
static void StructEventHandler(int point)
{
Console.WriteLine("Point changed to {0}", point);
}

static void Main(string[] args)


{
Point.StaticMethod();

Point p = new Point();

p.PointChanged += StructEventHandler;
p.XPoint = 123;

p.PrintPoints();
}
}
Output:
Inside Static Method
Point changed to 123
X: 123, y: 0

Please note that if you want to use properties, methods or events, you MUST initialize the
struct with the new keyword. The following will give a compile time error:

Example: structure
Point pto;

pto.XPoint = 100; // compile time error


Characteristics of Structure:

 Structure can include constructors, constants, fields, methods, properties, indexers,


operators, events & nested types.
 Structure cannot include default constructor or destructor.
 Structure can implement interfaces.
 A structure cannot inherit another structure or class.
 Structure members cannot be specified as abstract, virtual, or protected.
 Structures must be initialized with new keyword in order to use it's properties, methods or
events.
Difference between Struct and Class:

 Class is reference type whereas struct is value type


 Struct cannot declare a default constructor or destructor. However, it can have
parametrized constructors.
 Struct can be instasntiated without the new keyword. However, you won't be able to use
any of its methods, events or properties if you do so.
 Struct cannot be used as a base or cannot derive another struct or class.

Points to Remember :

1. Structure is a value type and defined using struct keyword.


2. Structure can be initialized with or without new keyword.
3. Structure must be initialized with new keyword to use its' properties, methods and events.

Further Reading

 Eric Lippert's blog on struct


 Choosing between class and structure

C# - enum
In C#, enum is a value type data type. The enum is used to declare a list of named integer
constants. It can be defined using the enum keyword directly inside a namespace, class, or
structure. The enum is used to give a name to each constant so that the constant integer can
be referred using its name.

Example: enum
enum WeekDays
{
Monday = 0,
Tuesday =1,
Wednesday = 2,
Thursday = 3,
Friday = 4,
Saturday =5,
Sunday = 6
}

Console.WriteLine(WeekDays.Friday);
Console.WriteLine((int)WeekDays.Friday);
Output:
Friday
4
By default, the first member of an enum has the value 0 and the value of each successive
enum member is increased by 1. For example, in the following enumeration, Monday is 0,
Tuesday is 1, Wednesday is 2 and so forth.

Example: enum
enum WeekDays
{
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday
}

Console.WriteLine((int)WeekDays.Monday);
Console.WriteLine((int)WeekDays.Friday);
Output:
0
4

An explicit cast is necessary to convert from enum type to an integral type. For example, to
get the int value from an enum:

Example: enum
int dayNum = (int)WeekDays.Friday;

Console.WriteLine(dayNum);
Output:
4

A change in the value of the first enum member will automatically assign incremental
values to the other members sequentially. For example, changing the value of Monday to
10, will assign 11 to Tuesday, 12 to Wednesday, and so on:

Example: enum
enum WeekDays
{
Monday = 10,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday
}
Console.WriteLine((int)WeekDays.Monday);
Console.WriteLine((int)WeekDays.Friday);
Output:
10
14

The enum can includes named constants of numeric data type e.g. byte, sbyte, short, ushort,
int, uint, long, or ulong.

enum cannot be used with string type.

Enum is mainly used to make code more readable by giving related constants a meaningful
name. It also improves maintainability.

Enum methods:

Enum is an abstract class that includes static helper methods to work with enums.

Enum method Description

Converts the specified value of enum type to the specified


Format
string format.

Returns the name of the constant of the specified value of


GetName
specified enum.

Returns an array of string name of all the constant of


GetNames
specified enum.

Returns an array of the values of all the constants of


GetValues
specified enum.

Converts the string representation of the name or numeric


object Parse(type, string) value of one or more enumerated constants to an
equivalent enumerated object.

Converts the string representation of the name or numeric


value of one or more enumerated constants to an
bool TryParse(string, out TEnum)
equivalent enumerated object. The return value indicates
whether the conversion succeeded.

Example: enum mehtods


enum WeekDays
{
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday
}

Console.WriteLine(Enum.GetName(typeof(WeekDays), 4));

Console.WriteLine("WeekDays constant names:");

foreach (string str in Enum.GetNames(typeof(WeekDays)))


Console.WriteLine(str);

Console.WriteLine("Enum.TryParse():");

WeekDays wdEnum;
Enum.TryParse<WeekDays>("1", out wdEnum);
Console.WriteLine(wdEnum);
Output:
Friday
WeekDays constant names:
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
Sunday
Enum.TryParse():
Tuesday

Visit MSDN to know more about C# enum methods.

Points to Remember :

1. The enum is a set of named constant.


2. The value of enum constants starts from 0. Enum can have value of any valid numeric
type.
3. String enum is not supported in C#.
4. Use of enum makes code more readable and manageable.

C# - StringBuilder
A String is immutable, meaning String cannot be changed once created. For example, new
string "Hello World!!" will occupy a memory space on the heap. Now, by changing the
initial string "Hello World!!" to "Hello World!! from Tutorials Teacher" will create a new
string object on the memory heap instead of modifying the initial string at the same
memory address. This behaviour will hinder the performance if the same string changes
multiple times by replacing, appending, removing or inserting new strings in the initial
string.

Memory allocation for String

To solve this problem, C# introduced StringBuilder. StringBuilder is a dynamic object that


allows you to expand the number of characters in the string. It doesn't create a new object
in the memory but dynamically expands memory to accommodate the modified string.

Memory allocation for StringBuilder


StringBuilder Initialization

StringBuilder can be initialized the same way as class.

Example: StringBuilder
StringBuilder sb = new StringBuilder();

//or

StringBuilder sb = new StringBuilder("Hello World!!");

You can give an initial capacity of characters by passing an int value in the constructor. For
example, the following will allocate memory of 50 characters sequentially on the memory
heap. The memory allocation automatically expands once it reaches the capacity.

Example: StringBuilder
StringBuilder sb = new StringBuilder(50);

//or

StringBuilder sb = new StringBuilder("Hello World!!",50);


Important Methods of StringBuilder
Method Name Description

Appends the passed values to the end of the current


StringBuilder.Append(valueToAppend)
StringBuilder object.

Replaces a format specifier passed in a string with


StringBuilder.AppendFormat()
formatted text.

StringBuilder.Insert(index, Inserts a string at the specified index of the current


valueToAppend) StringBuilder object.

Removes the specified number of characters from the


StringBuilder.Remove(int startIndex, int
given starting position of the current StringBuilder
length)
object.

StringBuilder.Replace(oldValue,
Replaces characters with new characters.
newValue)

Append()/AppendLine()

Use Append method of StringBuilder to add or append a string to StringBuilder.


AppendLine() method appends the string with a newline at the end.

Example: Append()
StringBuilder sb = new StringBuilder("Hello ",50);

sb.Append("World!!");
sb.AppendLine("Hello C#!");
sb.AppendLine("This is new line.");

Console.WriteLine(sb);
Output:
Hello World!! Hello C#!.
This is new line.  

Note : StringBuilder performs faster than string when concatenating multiple strings. Use
StringBuilder if you want to append more than three-four string. Appending two or three string is
more efficient than using StringBuilder.

AppendFormat()

Use AppendFormat method to format input string into specified format and then append it.

Example: AppendFormat()
StringBuilder amountMsg = new StringBuilder("Your total amount is ");
amountMsg.AppendFormat("{0:C} ", 25);

Console.WriteLine(amountMsg);
Output:
Your total amount is $ 25.00

Insert()

The Insert() method inserts the string at specified index in StringBuilder.

Example: Insert()
StringBuilder sb = new StringBuilder("Hello World!!",50);
sb.Insert(5," C#");

Console.WriteLine(sb);
Output:
Hello C# World!!

Remove()

The Remove() method removes the string at specified index with specified length.

Example: Remove()
StringBuilder sb = new StringBuilder("Hello World!!",50);
sb.Remove(6, 7);
Console.WriteLine(sb);
Output:
Hello

Replace()

The Replace() method replaces all occurance of a specified string with a specified
replacement string.

Example: Replace()
StringBuilder sb = new StringBuilder("Hello World!!",50);
sb.Replace("World", "C#");

Console.WriteLine(sb);
Output:
Hello C#!!

Indexer

You can use indexer with StringBuilder to get or set a character at specified index. The
following example uses indexer to get all the characters of StringBuilder using for loop.

Example: StringBuilder as Indexer


StringBuilder sb = new StringBuilder("Hello World!!");

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


Console.Write(sb[i]);
Output:
Hello World!!

ToString()

Use ToString() method to get string from StringBuilder.

Example: ToString()
StringBuilder sb = new StringBuilder("Hello World!!");

string str = sb.ToString(); // "Hello World!!"

Points to Remember :

1. StringBuilder is mutable.
2. StringBuilder performs faster than string when appending multiple string values.
3. Initialize StringBuilder as class e.g. StringBuilder sb = new StringBuilder()
4. Use StringBuilder when you need to append more than three or four strings.
5. Use Append() method to add or append strings with StringBuilder.
6. Use ToString() method to get the string from StringBuilder.

C# - Array
We have learned that a variable can hold only one literal value, for example int x = 1;.
Only one literal value can be assigned to a variable x. Suppose, you want to store 100
different values then it will be cumbersome to create 100 different variables. To overcome
this problem, C# introduced an array.

An array is a special type of data type which can store fixed number of values sequentially
using special syntax.

The following image shows how an array stores values sequentially.

Array
Representation

As you can see in the above figure, index is a number starting from 0, which stores the
value. You can store a fixed number of values in an array. Array index will be increased by
1 sequentially till the maximum specified array size.

Array Declaration

An array can be declare using a type name followed by square brackets [].

Example: Array declaration in C#


int[] intArray; // can store int values

bool[] boolArray; // can store boolean values

string[] stringArray; // can store string values

double[] doubleArray; // can store double values

byte[] byteArray; // can store byte values

Student[] customClassArray; // can store instances of Student class


Initialization

An array can be declared and initialized at the same time using the new keyword. The
following example shows the way of initializing an array.

Example: Array Declaration & Initialization


// defining array with size 5. add values later on
int[] intArray1 = new int[5];

// defining array with size 5 and adding values at the same time
int[] intArray2 = new int[5]{1, 2, 3, 4, 5};

// defining array with 5 elements which indicates the size of an array


int[] intArray3 = {1, 2, 3, 4, 5};

In the above example, the first statement declares & initializes int type array that can store
five int values. The size of the array is specified in square brackets. The second statement,
does the same thing, but it also assignes values to each indexes in curley brackets { }. The
third statement directly initializes an int array with the values without giving any size. Here,
size of an array will automatically be number of values.

Initialization without giving size is NOT valid. For example, the following example would
give compile time error.

Example: Wrong way of initializing an array


int[] intArray = new int[]; // compiler error: must give size of an array
Late initialization

Arrays can be initialized after declaration. It is not necessary to declare and initialize at the
same time using new keyword. Consider the following example.

Example: Late initialization of an Array


string[] strArray1, strArray2;

strArray1 = new string[5]{ "1st Element",


"2nd Element",
"3rd Element",
"4th Element",
"5th Element"
};

strArray2 = new string[]{ "1st Element",


"2nd Element",
"3rd Element",
"4th Element",
"5th Element"
};
However, in the case of late initialization, it must be initialized with the new keyword as
above. It cannot be initialize by only assigning values to the array.

The following initialization is NOT valid:

Example: Wrong way of initializing an array


string[] strArray;

strArray = {"1st Element","2nd Element","3rd Element","4th Element" };


Accessing Array Elements

As shown above, values can be assigned to an array at the time of initialization. However,
value can also be assigned to individual index randomly as shown below.

Example: Assigning values to array index


int[] intArray = new int[5];

intArray[0] = 10;

intArray[1] = 20;

intArray[2] = 30;

intArray[3] = 40;

intArray[4] = 50;

In the same way, you can retrieve values at a particular index, as below:

Example: Accessing Array elements

intArray[0]; //returns 10

intArray[2]; //returns 30

Use a for loop to access the values from all the indexes of an array by using length property
of an array.

Example: Accessing Array elements using for loop


int[] intArray = new int[5]{10, 20, 30, 40, 50 };

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


Console.WriteLine(intArray[i]);
Output:
10
20
30
40
50

Array properties and methods


Method Name Description

GetLength(int dimension) Returns the number of elements in the specified dimension.

GetLowerBound(int
Returns the lowest index of the specified dimension.
dimension)

GetUpperBound(int
Returns the highest index of the specified dimension.
dimension)

GetValue(int index) Returns the value at the specified index.

Property Description

Returns the total number of elements in


Length
the array.

Array Helper Class

.NET provides an abstract class, Array, as a base class for all arrays. It provides static
methods for creating, manipulating, searching, and sorting arrays.

For example, use the Array.Sort() method to sort the values:

Example: Array Helper class


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

Array.Sort(intArr);

Array.Reverse(intArr);

You can create an instance of an Array that starts with index 1 (not default starting index 0)
using Array class as shown below:

Example: Array Helper class


Array array = Array.CreateInstance(typeof(int),new int[1]{5},new int[1]
{1});

array.SetValue(1, 1);
array.SetValue(2, 2);
array.SetValue(3, 3);
array.SetValue(4, 4);
array.SetValue(5, 5);

for (int i = 1; i <= array.Length; i++)


Console.WriteLine("Array value {0} at position {1}",
array.GetValue(i), i);
Output:
Array value 1 at position 1
Array value 2 at position 2
Array value 3 at position 3
Array value 4 at position 4
Array value 5 at position 5

Points to Remember :

1. An Array stores values in a series starting with a zero-based index.


2. The size of an array must be specified while initialization.
3. An Array values can be accessed using indexer.
4. An Array can be single dimensional, multi-dimensional and jagged array.
5. The Array helper class includes utility methods for arrays.

C# - Multi-dimensional Array
We have learned about single dimensional arrays in the previous section. C# also supports
multi-dimensional arrays. A multi-dimensional array is a two dimensional series like rows
and columns.

Example: Multi-dimensional Array:


int[,] intArray = new int[3,2]{
{1, 2},
{3, 4},
{5, 6}
};

// or
int[,] intArray = { {1, 1}, {1, 2}, {1, 3} };

As you can see in the above example, multi dimensional array is initialized by giving size
of rows and columns. [3,2] specifies that array can include 3 rows and 2 columns.

The following figure shows a multi-dimensional array divided into rows and columns:
Multi-dimensional Array

The values of a multi-dimensional array can be accessed using two indexes. The first index
is for the row and the second index is for the column. Both the indexes start from zero.

Example: Access Multi-dimensional Array


int[,] intArray = new int[3,2]{
{1, 2},
{3, 4},
{5, 6}
};

intArray[0,0]; //Output: 1
intArray[0,1]; // 2

intArray[1,0]; // 3
intArray[1,1]; // 4

intArray[2,0]; // 5
intArray[2,1]; // 6

In the above example, intArray[2,1] returns 6. Here, 2 means the third row and 1 means the
second column (rows and columns starts with zero index).

C# - Jagged Array
A jagged array is an array of an array. Jagged arrays store arrays instead of any other data
type value directly.

A jagged array is initialized with two square brackets [][]. The first bracket specifies the
size of an array and the second bracket specifies the dimension of the array which is going
to be stored as values. (Remember, jagged array always store an array.)

The following jagged array stores a two single dimensional array as a value:

Example: Jagged Array


int[][] intJaggedArray = new int[2][];

intJaggedArray[0] = new int[3]{1,2,3};

intJaggedArray[1] = new int[2]{4,5};

Console.WriteLine(intJaggedArray[0][0]); // 1

Console.WriteLine(intJaggedArray[0][2]); // 3

Console.WriteLine(intJaggedArray[1][1]); // 5

The following jagged array stores a multi-dimensional array as a value. Second bracket [,]
indicates multi-dimension.

Example: Jagged Array


int[][,] intJaggedArray = new int[3][,];

intJaggedArray[0] = new int[3, 2] { { 1, 2 }, { 3, 4 }, { 5, 6 } };


intJaggedArray[1] = new int[2, 2] { { 3, 4 }, { 5, 6 } };
intJaggedArray[2] = new int[2, 2];

Console.WriteLine(intJaggedArray[0][1,1]); // 4

Console.WriteLine(intJaggedArray[1][1,0]); // 5

Console.WriteLine(intJaggedArray[1][1,1]); // 6
Note:

Be careful while working with jagged arrays. It will throw an IndexOutOfRange exception if the
index does not exist.

C# Collection:
We have learned about an array in the previous section. C# also includes specialized classes
that hold many values or objects in a specific series, that are called 'collection'.

There are two types of collections available in C#: non-generic collections and generic
collections. We will learn about non-generic collections in this section.

Every collection class implements the IEnumerable interface so values from the collection
can be accessed using a foreach loop.

The System.Collections namespace includes following non-generic collections.


Non-generic
Usage
Collections

ArrayList stores objects of any type like an array. However, there is no need to
ArrayList
specify the size of the ArrayList like with an array as it grows automatically.

SortedList stores key and value pairs. It automatically arranges elements in


SortedList ascending order of key by default. C# includes both, generic and non-generic
SortedList collection.

Stack stores the values in LIFO style (Last In First Out). It provides a Push() method
Stack to add a value and Pop() & Peek() methods to retrieve values. C# includes both,
generic and non-generic Stack.

Queue stores the values in FIFO style (First In First Out). It keeps the order in which
the values were added. It provides an Enqueue() method to add values and a
Queue
Dequeue() method to retrieve values from the collection. C# includes generic and
non-generic Queue.

Hashtable stores key and value pairs. It retrieves the values by comparing the hash
Hashtable
value of the keys.

BitArray manages a compact array of bit values, which are represented as


BitArray Booleans, where true indicates that the bit is on (1) and false indicates the bit is off
(0).

Let's see each type of collection in the next sections.

C# - ArrayList
ArrayList is a non-generic type of collection in C#. It can contain elements of any data
types. It is similar to an array, except that it grows automatically as you add items in it.
Unlike an array, you don't need to specify the size of ArrayList.

Example: Initialize ArrayList


ArrayList myArryList = new ArrayList();
Important Properties and Methods of ArrayList
Property Description

Capacity Gets or sets the number of elements that the ArrayList can contain.

Count Gets the number of elements actually contained in the ArrayList.


Property Description

IsFixedSize Gets a value indicating whether the ArrayList has a fixed size.

IsReadOnly Gets a value indicating whether the ArrayList is read-only.

Item Gets or sets the element at the specified index.

Method Description

Add() method adds single elements at the end of ArrayList.


Add()/AddRange() AddRange() method adds all the elements from the specified
collection into ArrayList.

Insert() method insert a single elements at the specified index


in ArrayList.
Insert()/InsertRange()
InsertRange() method insert all the elements of the specified
collection starting from specified index in ArrayList.

Remove() method removes the specified element from the


ArrayList.
Remove()/RemoveRange()
RemoveRange() method removes a range of elements from
the ArrayList.

Removes the element at the specified index from the


RemoveAt()
ArrayList.

Sort() Sorts entire elements of the ArrayList.

Reverse() Reverses the order of the elements in the entire ArrayList.

Checks whether specified element exists in the ArrayList or


Contains
not. Returns true if exists otherwise false.

Clear Removes all the elements in ArrayList.

Copies all the elements or range of elements to compitible


CopyTo
Array.

Returns specified number of elements from specified index


GetRange
from ArrayList.

Search specified element and returns zero based index if


IndexOf
found. Returns -1 if element not found.

ToArray Returns compitible array from an ArrayList.


Add Elements into ArrayList

The AddRange() method can take any type of collection that implements the
ICollection interface e.g. List, ArrayList, SortedList, Queue, Stack, HashSet, Hashtable, etc.

Use the Add()method to add a single element or the AddRange() method to add multiple
elements from the other collections into an ArrayList. Here, the element means the literal
value of a primitive or non-primitive type.

Add() signature: int Add(Object value)

AddRange() signature:void AddRange(ICollection c)

Example: Add elements into ArrayList


ArrayList arryList1 = new ArrayList();
arryList1.Add(1);
arryList1.Add("Two");
arryList1.Add(3);
arryList1.Add(4.5);

ArrayList arryList2 = new ArrayList();


arryList2.Add(100);
arryList2.Add(200);

//adding entire arryList2 into arryList1


arryList1.AddRange(arryList2);

You can also add items when you initialize it using object initializer syntax.

ArrayList arrayList = new ArrayList() { 100, "Two", 12.5, 200 };


Access ArrayList Elements

ArrayList elements can be accessed using indexer, in the same way as an array. However,
you need to cast it to the appropriate type or use the implicit type var keyword while
accessing it.

Example: Access individual element


ArrayList myArryList = new ArrayList();
myArryList.Add(1);
myArryList.Add("Two");
myArryList.Add(3);
myArryList.Add(4.5f);

//Access individual item using indexer


int firstElement = (int) myArryList[0]; //returns 1
string secondElement = (string) myArryList[1]; //returns "Two"
int thirdElement = (int) myArryList[2]; //returns 3
float fourthElement = (float) myArryList[3]; //returns 4.5
//use var keyword
var firstElement = myArryList[0]; //returns 1

Use a foreach or a for loop to iterate an ArrayList.

Example: Iterate ArrayList


ArrayList myArryList = new ArrayList();
myArryList.Add(1);
myArryList.Add("Two");
myArryList.Add(3);
myArryList.Add(4.5);

foreach (var val in myArryList)


Console.WriteLine(val);

//Or
for(int i = 0 ; i< myArryList.Count; i++)
Console.WriteLine(myArryList[i]);
Output:
1
Two
3
4.5

Note:

An ArrayList can contain multiple null and duplicate values.

Insert Elements into ArrayList

Use the Insert() method to insert a single item at the specified index.

Insert() signature: void Insert(int index, Object value)

Example: Insert()
ArrayList myArryList = new ArrayList();
myArryList.Add(1);
myArryList.Add("Two");
myArryList.Add(3);
myArryList.Add(4.5);

myArryList.Insert(1, "Second Item");


myArryList.Insert(2, 100);

foreach (var val in myArryList)


Console.WriteLine(val);
Output:
1
Second Item
100
Two
3
4.5

Use the InsertRange() method to insert all the values from another collection into ArrayList
at the specfied index.

InsertRange() method signature: Void InsertRange(int index, ICollection c)

Example: InsertRange()
ArrayList arryList1 = new ArrayList();
arryList1.Add(100);
arryList1.Add(200);

ArrayList arryList2 = new ArrayList();


arryList2.Add(10);
arryList2.Add(20);
arryList2.Add(30);

arryList2.InsertRange(2, arryList1);

foreach(var item in arryList2)


Console.WriteLine(item);
Output:
10
20
100
200
30

Remove Elements from ArrayList

Use the Remove() method to remove a specified element from an ArrayList.

Remove() signature: void Remove(Object obj)

Example: Remove()
ArrayList arryList1 = new ArrayList();
arryList1.Add(100);
arryList1.Add(200);
arryList1.Add(300);

arryList1.Remove(100); //Removes 1 from ArrayList

foreach (var item in arryList1)


Console.WriteLine(item);
Output:
200
300

Use the RemoveAt() method to remove an element from the specified index location.

RemoveAt() method signature: void RemoveAt(int index)

Example: RemoveAt()
ArrayList arryList1 = new ArrayList();
arryList1.Add(100);
arryList1.Add(200);
arryList1.Add(300);

arryList1.RemoveAt(1); //Removes the first element from an ArrayList

foreach (var item in arryList1)


Console.WriteLine(item);
Output:
100
300

Use the RemoveRange() method to remove multiple elements from the specified index till
the specified number of elements in the ArrayList.

RemoveRange() signature: void RemoveRange(int index, int count)

Example: RemoveRange()
ArrayList arryList1 = new ArrayList();
arryList1.Add(100);
arryList1.Add(200);
arryList1.Add(300);

arryList1.RemoveRange(0,2);//Removes two elements starting from 1st item


(0 index)

foreach(var item in arryList1)


Console.WriteLine(item);
Output:
300

ArrayList Sorting

ArrayList includes Sort() and Reverse() method. Sort() method arranges elements in
ascending order. However, all the elements should have same data type so that it can
compare with default comparer otherwise it will throw runtime exception.

Reverse() method arranges elements in reverse order. Last element at zero index and so on.
Example: Sort(), Reverse()
ArrayList arryList1 = new ArrayList();
arryList1.Add(300);
arryList1.Add(200);
arryList1.Add(100);
arryList1.Add(500);
arryList1.Add(400);

Console.WriteLine("Original Order:");

foreach(var item in arryList1)


Console.WriteLine(item);

arryList1.Reverse();
Console.WriteLine("Reverse Order:");

foreach(var item in arryList1)


Console.WriteLine(item);

arryList1.Sort();
Console.WriteLine("Ascending Order:");

foreach(var item in arryList1)


Console.WriteLine(item);
Output:
Original Order:
300
200
100
500
400
Reverse Order:
400
500
100
200
300
Ascending Order:
100
200
300
400
500

Check for an Existing Elements in ArrayList

ArrayList.Contains() method checks whether specified element exists in the ArrayList or


not. Returns true if exists otherwise false.

Example: Contains()
ArrayList myArryList = new ArrayList();
myArryList.Add(100);
myArryList.Add("Hello World");
myArryList.Add(300);

Console.WriteLine(myArryList.Contains(100));
Output:
True

Further Reading

 Difference between Array & ArrayList


 ArrayList's Methods & Properties

Points to Remember :

1. ArrayList can store items(elements) of any datatype.


2. ArrayList resizes automatically as you add the elements.
3. ArrayList values must be cast to appropriate data types before using it.
4. ArrayList can contain multiple null and dulplicate items.
5. ArrayList can be accessed using foreach or for loop or indexer.
6. Use Add(), AddRange(), Remove(), RemoveRange(), Insert(), InsertRange(), Sort(),
Reverse() methods.

C# - SortedList
The SortedList collection stores key-value pairs in the ascending order of key by default.
SortedList class implements IDictionary & ICollection interfaces, so elements can be
accessed both by key and index.

C# includes two types of SortedList, generic SortedList and non-generic SortedList. Here,
we will learn about non-generic SortedList.

Important Properties and Methods of SortedList


Property Description

Capacity Gets or sets the number of elements that the SortedList instance can store.

Count Gets the number of elements actually contained in the SortedList.

IsFixedSize Gets a value indicating whether the SortedList has a fixed size.

IsReadOnly Gets a value indicating whether the SortedList is read-only.


Property Description

Item Gets or sets the element at the specified key in the SortedList.

Keys Get list of keys of SortedList.

Values Get list of values in SortedList.

Method Description

Add(object key, object value) Add key-value pairs into SortedList.

Remove(object key) Removes element with the specified key.

RemoveAt(int index) Removes element at the specified index.

Contains(object key) Checks whether specified key exists in SortedList.

Clear() Removes all the elements from SortedList.

GetByIndex(int index) Returns the value by index stored in internal array

Returns the key stored at specified index in internal


GetKey(int index)
array

Returns an index of specified key stored in internal


IndexOfKey(object key)
array

Returns an index of specified value stored in


IndexOfValue(object value)
internal array

Add elements in SortedList

Use the Add() method to add key-value pairs into a SortedList.

Add() method signature: void Add(object key, object value)

Key cannot be null but value can be null. Also, datatype of all keys must be same, so that it
can compare otherwise it will throw runtime exception.

Example: Add key-value pairs in SortedList


SortedList sortedList1 = new SortedList();
sortedList1.Add(3, "Three");
sortedList1.Add(4, "Four");
sortedList1.Add(1, "One");
sortedList1.Add(5, "Five");
sortedList1.Add(2, "Two");

SortedList sortedList2 = new SortedList();


sortedList2.Add("one", 1);
sortedList2.Add("two", 2);
sortedList2.Add("three", 3);
sortedList2.Add("four", 4);

SortedList sortedList3 = new SortedList();


sortedList3.Add(1.5, 100);
sortedList3.Add(3.5, 200);
sortedList3.Add(2.4, 300);
sortedList3.Add(2.3, null);
sortedList3.Add(1.1, null);
Note : Internally, SortedList maintains two object[] array, one for keys and another for values. So
when you add key-value pair, it runs a binary search using the key to find an appropriate index to
store a key and value in respective arrays. It re-arranges the elements when you remove the
elements from it.

SortedList collection sorts the elements everytime you add the elements. So if you debug
the above example, you will find keys in ascending order even if they are added randomly,
as below:

SortedList in debug view

Please notice that sortedList2 sorts the key in alphabetical order for string key in the above
image.

SortedList key can be of any data type, but you cannot add keys of different data types in
the same SortedList. The following example will throw run time exception because we are
trying to add the second item with a string key:

Example: Key of different datatypes throws exception:


SortedList sortedList = new SortedList();

sortedList.Add(3, "Three");
sortedList.Add("Four", "Four"); // Throw exception:
InvalidOperationException
sortedList.Add(1, "One");
sortedList.Add(8, "Five");
sortedList.Add(2, "Two");

Access SortedList

SortedList can be accessed by index or key. Unlike other collection, SortedList requires key
instead of index to access a value for that key.

Example: Access SortedList


SortedList sortedList = new SortedList();
sortedList.Add("one", 1);
sortedList.Add("two", 2);
sortedList.Add("three", 3);
sortedList.Add("four", "Four");

int i = (int) sortedList["one"];


int j = (int) sortedList["two"];
string str = (string) sortedList["four"];

Console.WriteLine(i);
Console.WriteLine(j);
Console.WriteLine(str);
Output:
1
2
Four

Note : Non-generic SortedList collection can contain key and value of any data type. So values
must be cast to the appropriate data type otherwise it will give compile-time error.

Example: Access values using for loop


SortedList sortedList2 = new SortedList();
sortedList2.Add("one", 1);
sortedList2.Add("two", 2);
sortedList2.Add("three", 3);
sortedList2.Add("four", 4);

for (int i = 0; i < sortedList2.Count; i++)


{
Console.WriteLine("key: {0}, value: {1}",
sortedList2.GetKey(i),
sortedList2.GetByIndex(i));
}
Output:
key: four, value: 4
key: one, value: 1
key: three, value: 3
key: two, value: 2
Access SortedList using foreach Loop

The foreach statement in C# can be use to access the SortedList collection. SortedList
element includes both key and value. so, type of element would be DictionaryEntry rather
than type of key or value.

Example: Access values using foreach


SortedList sortedList1 = new SortedList();
sortedList1.Add("one", 1);
sortedList1.Add("two", 2);
sortedList1.Add("three", 3);
sortedList1.Add("four", 4);

foreach(DictionaryEntry kvp in sortedList1 )


Console.WriteLine("key: {0}, value: {1}", kvp.Key ,
kvp.Value );
Output:
key: four, value: 4
key: one, value: 1
key: three, value: 3
key: two, value: 2

Remove elements from SortedList

Use the Remove() or RemoveAt() method to remove elements from a SortedList.

Remove() signature: void Remove(object key)

RemoveAt() signature: void RemoveAt(int index)

Example: Remove elements in SortedList


SortedList sortedList1 = new SortedList();
sortedList1.Add("one", 1);
sortedList1.Add("two", 2);
sortedList1.Add("three", 3);
sortedList1.Add("four", 4);

sortedList1.Remove("one");//removes element whose key is 'one'


sortedList1.RemoveAt(0);//removes element at zero index i.e first
element: four

foreach(DictionaryEntry kvp in sortedList1 )


Console.WriteLine("key: {0}, value: {1}", kvp.Key ,
kvp.Value );
Output:
key: three, value: 3
key: two, value: 2
Check for an existing key in SortedList

The Contains() & ContainsKey() methods determine whether the specified key exists in the
SortedList collection or not.

Contains() signature: bool Contains(object key)

ContainsKey() signature: bool ContainsKey(object key)

The ContainsValue() method determines whether the specified value exists in the
SortedList or not.

ContainValue() signature: bool ContainValue(object value)

Example: Contains
SortedList sortedList = new SortedList();
sortedList.Add(3, "Three");
sortedList.Add(2, "Two");
sortedList.Add(4, "Four");
sortedList.Add(1, "One");
sortedList.Add(8, "Five");

sortedList.Contains(2); // returns true


sortedList.Contains(4); // returns true
sortedList.Contains(6); // returns false

sortedList.ContainsKey(2); // returns true


sortedList.ContainsKey(6); // returns false

sortedList.ContainsValue("One"); // returns true


sortedList.ContainsValue("Ten"); // returns false

Visit MSDN for more information on the properties and methods of SortedList.

Points to Remember :

1. C# has generic and non-generic SortedList.


2. SortedList stores the key-value pairs in ascending order of the key. Key must be unique
and cannot be null whereas value can be null or duplicate.
3. Non-generic SortedList stores keys and values of any data types. So values needs to be
cast to appropriate data type.
4. Key-value pair can be cast to DictionaryEntry.
5. Access individual value using indexer. SortedList indexer accepts key to return value
associated with it.
C# - Stack
C# includes a special type of collection which stores elements in LIFO style(Last In First
Out). C# includes a generic and non-generic Stack. Here, you are going to learn about the
non-generic stack.

Stack allows null value and also duplicate values. It provides a Push() method to add a
value and Pop() or Peek() methods to retrieve values.

C# Stack Representation

Important Properties and Methods of Stack:


Property Usage

Count Returns the total count of elements in the Stack.

Method Usage

Push Inserts an item at the top of the stack.

Peek Returns the top item from the stack.

Pop Removes and returns items from the top of the stack.

Contains Checks whether an item exists in the stack or not.

Clear Removes all items from the stack.

Add Values into Stack

The Push() method adds values into the Stack. It allows value of any datatype.

Push() method signature: void Push(object obj);

Example: Push()
Stack myStack = new Stack();
myStack.Push("Hello!!");
myStack.Push(null);
myStack.Push(1);
myStack.Push(2);
myStack.Push(3);
myStack.Push(4);
myStack.Push(5);
Accessing Stack Elements

You can retrieve stack elements by various ways. Use a foreach statement to iterate the
Stack collection and get all the elements in LIFO style.

Example: Access Stack


Stack myStack = new Stack();
myStack.Push("Hello!!");
myStack.Push(null);
myStack.Push(1);
myStack.Push(2);
myStack.Push(3);
myStack.Push(4);
myStack.Push(5);

foreach (var itm in myStack)


Console.Write(itm);
Output:
5
4
3
2
1

Hello!!

Peek()

The Peek() method returns the last (top-most) value from the stack. Calling Peek() method
on empty stack will throw InvalidOperationException. So always check for elements in the
stack before retrieving elements using the Peek() method.

Peek() method signature: object Peek();

Example: Stack.Peek()
Stack myStack = new Stack();
myStack.Push(1);
myStack.Push(2);
myStack.Push(3);
myStack.Push(4);
myStack.Push(5);
Console.WriteLine(myStack.Peek());
Console.WriteLine(myStack.Peek());
Console.WriteLine(myStack.Peek());
Output:
5
5
5

Pop()

You can also retrieve the value using the Pop() method. The Pop() method removes and
returns the value that was added last to the Stack. The Pop() method call on an empty stack
will raise an InvalidOperationException. So always check for number of elements in stack
must be greater than 0 before calling Pop() method.

Pop() signature: object Pop();

Example: Access Stack


Stack myStack = new Stack();
myStack.Push(1);
myStack.Push(2);
myStack.Push(3);
myStack.Push(4);
myStack.Push(5);

Console.Write("Number of elements in Stack: {0}", myStack.Count);

while (myStack.Count > 0)


Console.WriteLine(myStack.Pop());

Console.Write("Number of elements in Stack: {0}", myStack.Count);


Output:
Number of elements in Stack: 5
5
4
3
2
1
Number of elements in Stack: 0

Contains()

The Contains() method checks whether the specified item exists in a Stack collection or
not. It returns true if it exists; otherwise it returns false.

Contains() method signature: bool Contains(object obj);


Example: Stack.Contains()
Stack myStack = new Stack();
myStack.Push(1);
myStack.Push(2);
myStack.Push(3);
myStack.Push(4);
myStack.Push(5);

myStack.Contains(2); // returns true


myStack.Contains(10); // returns false
Clear()

The Clear() method removes all the values from the stack.

Clear() signature: void Clear();

Example: Stack.Contains()
Stack myStack = new Stack();
myStack.Push(1);
myStack.Push(2);
myStack.Push(3);
myStack.Push(4);
myStack.Push(5);

myStack.Clear(); // removes all elements

Console.Write("Number of elements in Stack: {0}", myStack.Count);


Output:
Number of elements in Stack: 0

Points to Remember :

1. Stack stores the values in LIFO (Last in First out) style. The element which is added last will
be the element to come out first.
2. Use the Push() method to add elements into Stack.
3. The Pop() method returns and removes elements from the top of the Stack. Calling the
Pop() method on the empty Stack will throw an exception.
4. The Peek() method always returns top most element in the Stack.

Visit MSDN for more information on Stack member properties and methods.

C# - Queue
C# includes a Queue collection class in the System.Collection namespace. Queue stores the
elements in FIFO style (First In First Out), exactly opposite of the Stack collection. It
contains the elements in the order they were added.

Queue collection allows multiple null and duplicate values. Use the Enqueue() method to
add values and the Dequeue() method to retrieve the values from the Queue.

Important Properties and Methods of Queue:


Property Usage

Count Returns the total count of elements in the Queue.

Method Usage

Enqueue Adds an item into the queue.

Dequeue Removes and returns an item from the beginning of the queue.

Peek Returns an first item from the queue

Contains Checks whether an item is in the queue or not

Clear Removes all the items from the queue.

Sets the capacity of the queue to the actual number of items in


TrimToSize
the queue.

Add elements in Queue

Queue is a non-generic collection. So you can add elements of any datatype into a queue
using the Enqueue() method.

Enqueue() signature: void Enqueue(object obj)

Example: Enqueue()
Queue queue = new Queue();
queue.Enqueue(3);
queue.Enqueue(2);
queue.Enqueue(1);
queue.Enqueue("Four");
Access Queue

Dequeue() method is used to retrieve the top most element in a queue collection. Dequeue()
removes and returns a first element from a queue because the queue stores elements in
FIFO order. Calling Dequeue() method on empty queue will throw InvalidOperation
exception. So always check that the total count of a queue is greater than zero before
calling the Dequeue() method on a queue.

Dequeue() method signature: object Dequeue()

Example: Dequeue()
Queue queue = new Queue();
queue.Enqueue(3);
queue.Enqueue(2);
queue.Enqueue(1);
queue.Enqueue("Four");

Console.WriteLine("Number of elements in the Queue: {0}", queue.Count);

while (queue.Count > 0)


Console.WriteLine(queue.Dequeue());

Console.WriteLine("Number of elements in the Queue: {0}", queue.Count);


Output:
Number of elements in the Queue: 4
3
2
1
Four
Number of elements in the Queue: 0

Peek()

The Peek() method always returns the first item from a queue collection without removing
it from the queue. Calling Peek() and Dequeue() methods on an empty queue collection will
throw a run time exception "InvalidOperationException".

Peek() Method Signature: object Peek();

Example: Peek()
Queue queue = new Queue();
queue.Enqueue(3);
queue.Enqueue(2);
queue.Enqueue(1);
queue.Enqueue("Four");

Console.WriteLine("Number of elements in the Queue: {0}", queue.Count);

Console.WriteLine(queue.Peek());
Console.WriteLine(queue.Peek());
Console.WriteLine(queue.Peek());

Console.WriteLine("Number of elements in the Queue: {0}", queue.Count);


Output:
Number of elements in the Queue: 4
3
3
3
Number of elements in the Queue: 4

You can iterate a Queue without removing elements of it by converting in to an Array, as


below:

Example: Iterate Queue


Queue queue = new Queue();
queue.Enqueue(3);
queue.Enqueue(2);
queue.Enqueue(1);
queue.Enqueue("Four");

Console.WriteLine("Number of elements in Queue: {0}", queue.Count);

foreach (var i in queue.ToArray())


Console.WriteLine(i);

Console.WriteLine("Number of elements in Queue: {0}", queue.Count);


Output:
Number of elements in Queue: 4
3
2
1
Four
Number of elements in Queue: 4

Contains()

The Contains() method checks whether an item exists in a queue. It returns true if the
specified item exists; otherwise it returns false.

Contains() Signature: bool Contains(object obj);


Example: Contains
Queue queue = new Queue();
queue.Enqueue(3);
queue.Enqueue(2);
queue.Enqueue(1);
queue.Enqueue("Four");

queue.Contains(2); // true
queue.Contains(100); //false
Clear()

The Clear() method removes all the items from a queue.

Clear() Signature: void Clear();

Example: Clear()
Queue queue = new Queue();
queue.Enqueue(3);
queue.Enqueue(2);
queue.Enqueue(1);
queue.Enqueue("Four");

Console.WriteLine("Number of elements in the Queue: {0}", queue.Count);

queue.Clear();

Console.WriteLine("Number of elements in the Queue: {0}", queue.Count);


Output:
Number of elements in the Queue: 4
Number of elements in the Queue: 0

Visit MSDN for more information on members of Queue.

Points to Remember :

1. The Queue stores the values in FIFO (First in First out) style. The element which is added
first will come out First.
2. Use the Enqueue() method to add elements into Queue
3. The Dequeue() method returns and removes elements from the beginning of the Queue.
Calling the Dequeue() method on an empty queue will throw an exception.
4. The Peek() method always returns top most element.

C# - Hashtable
C# includes Hashtable collection in System.Collections namespace, which is similar to
generic Dictionary collection. The Hashtable collection stores key-value pairs. It optimizes
lookups by computing the hash code of each key and stores it in a different bucket
internally and then matches the hash code of the specified key at the time of accessing
values.

Important Propertis and Methods of Hashtable


Property Description

Count Gets the total count of key/value pairs in the Hashtable.

IsReadOnly Gets boolean value indicating whether the Hashtable is read-only.

Item Gets or sets the value associated with the specified key.

Keys Gets an ICollection of keys in the Hashtable.

Values Gets an ICollection of values in the Hashtable.

Methods Usage

Add Adds an item with a key and value into the hashtable.

Remove Removes the item with the specified key from the hashtable.

Clear Removes all the items from the hashtable.

Contains Checks whether the hashtable contains a specific key.

ContainsKey Checks whether the hashtable contains a specific key.

ContainsValue Checks whether the hashtable contains a specific value.

GetHash Returns the hash code for the specified key.

Add key-value into Hashtable

The Add() method adds an item with a key and value into the Hashtable. Key and value can
be of any data type. Key cannot be null whereas value can be null.

Add() Signature: void Add(object key, object value);

Example: Add()
Hashtable ht = new Hashtable();

ht.Add(1, "One");
ht.Add(2, "Two");
ht.Add(3, "Three");
ht.Add(4, "Four");
ht.Add(5, null);
ht.Add("Fv", "Five");
ht.Add(8.5F, 8.5);

You can also assign key and value at the time of initialization using object initializer
syntax:

Example: Add()
Hashtable ht = new Hashtable()
{
{ 1, "One" },
{ 2, "Two" },
{ 3, "Three" },
{ 4, "Four" },
{ 5, null },
{ "Fv", "Five" },
{ 8.5F, 8.5 }
};

Hashtable can include all the elements of Dictionary as shown below.

Example: Add()
Dictionary<int, string> dict = new Dictionary<int, string>();

dict.Add(1, "one");
dict.Add(2, "two");
dict.Add(3, "three");

Hashtable ht = new Hashtable(dict);


 

Note : Add() will throw an exception if you try to add a key that already exists in the Hashtable. So
always check the key using the Contains() or ContainsKey() method before adding a key-value pair
into the Hashtable.

Access Hashtable

You can retrive the value of an existing key from the Hashtable using indexer. Please note
that the hashtable indexer requires a key.

Example: Access Hashtable


Hashtable ht = new Hashtable();

ht.Add(1, "One");
ht.Add(2, "Two");
ht.Add(3, "Three");
ht.Add(4, "Four");
ht.Add("Fv", "Five");
ht.Add(8.5F, 8.5F);

string strValue1 = (string)ht[2];


string strValue2 = (string)ht["Fv"];
float fValue = (float) ht[8.5F];

Console.WriteLine(strValue1);
Console.WriteLine(strValue2);
Console.WriteLine(fValue);
Output:
Two
Five
8.5

Note:

Hashtable is a non-generic collection so it can contains a key and a value of any data type. So
values must be cast to an appropriate data type otherwise it will give compile-time error.

Hashtable elements are key-value pairs stored in DictionaryEntry. So you cast each element
in Hashtable to DictionaryEntry. Use the foreach statement to iterate the Hashtable, as
shown below:

Example: Iterate Hashtable


Hashtable ht = new Hashtable();

ht.Add(1, "One");
ht.Add(2, "Two");
ht.Add(3, "Three");
ht.Add(4, "Four");
ht.Add("Fv", "Five");
ht.Add(8.5F, 8.5);

foreach (DictionaryEntry item in ht)


Console.WriteLine("key:{0}, value:{1}",item.Key,
item.Value);
Output:
Key: Fv, Value: Five
Key: 8.5, Value: 8.5
Key: 4, Value: Four
Key: 3, Value: Three
Key: 2, Value: Two
Key: 1, Value: One

Hashtable has a Keys and a Values property that contain all the keys and values
respectively. You can use these properties to get the keys and values.

Example: Access Hashtable using Keys & Values


Hashtable ht = new Hashtable();
ht.Add(1, "One");
ht.Add(2, "Two");
ht.Add(3, "Three");
ht.Add(4, "Four");
ht.Add("Fv", "Five");
ht.Add(8.5F, 8.5);

foreach (var key in ht.Keys )


Console.WriteLine("Key:{0}, Value:{1}",key , ht[key]);

Console.WriteLine("***All Values***");

foreach (var value in ht.Values)


Console.WriteLine("Value:{0}", value);
Output:
Key: Fv, Value: Five
Key: 8.5, Value: 8.5
Key: 4, Value: Four
Key: 3, Value: Three
Key: 2, Value: Two
Key: 1, Value: One
***All Values***
Value: Five
Value: 8.5
Value: Four
Value: Three
Value: Two
Value: One

Remove elements in Hashtable

The Remove() method removes the item with the specified key from the hashtable.

Remove() Method Signature: void Remove(object key)

Example: Remove()
Hashtable ht = new Hashtable();
ht.Add(1, "One");
ht.Add(2, "Two");
ht.Add(3, "Three");
ht.Add(4, "Four");
ht.Add("Fv", "Five");
ht.Add(8.5F, 8.5);

ht.Remove("Fv"); // removes {"Fv", "Five"}


Check for Existing Elements

Contains() and ContainsKey() check whether the specified key exists in the Hashtable
collection. ContainsValue() checks whether the specified value exists in the Hashtable.

Contains(), ContainsKey() and ContainsValue() Signatures:

bool Contains(object key)


bool ContainsKey(object key)
bool ContainsValue(object value)
Example: Contains
Hashtable ht = new Hashtable();
ht.Add(1, "One");
ht.Add(2, "Two");
ht.Add(3, "Three");
ht.Add(4, "Four");

ht.Contains(2);// returns true


ht.ContainsKey(2);// returns true
ht.Contains(5); //returns false
ht.ContainsValue("One"); // returns true
Clear()

Clear() method removes all the key-value pairs in the Hashtable.

Clear() Method Signature: void Clear()

Example: Clear()
Hashtable ht = new Hashtable();
ht.Add(1, "One");
ht.Add(2, "Two");
ht.Add(3, "Three");
ht.Add(4, "Four");
ht.Add("Fv", "Five");
ht.Add(8.5F, 8.5);

ht.Clear(); // removes all elements


Console.WriteLine("Total Elements: {0}", ht.Count);
Output:
Total Elements: 0

Points to Remember :

1. Hashtable stores key-value pairs of any datatype where the Key must be unique.
2. The Hashtable key cannot be null whereas the value can be null.
3. Hashtable retrieves an item by comparing the hashcode of keys. So it is slower in
performance than Dictionary collection.
4. Hashtable uses the default hashcode provider which is object.GetHashCode(). You can also
use a custom hashcode provider.
5. Use DictionaryEntry with foreach statement to iterate Hashtable.

Further Reading

 Difference between Hashtable and Dictionary


 Hashtable Class members
C# - Indexer
An Indexer is a special type of property that allows a class or structure to be accessed the
same way as array for its internal collection. It is same as property except that it defined
with this keyword with square bracket and paramters.

Syntax:
Public <return type> this[<parameter type> index]
{
Get{
// return the value from the specified index
}
Set{
// set values at the specified index
}
}

The following example shows how to use indexer in the custom class.

Example: Indexer
class StringDataStore
{

private string[] strArr = new string[10]; // internal


data storage

public string this[int index]


{
get
{
if (index < 0 && index >= strArr.Length)
throw new IndexOutOfRangeException("Cannot store more
than 10 objects");

return strArr[index];
}

set
{
if (index < 0 && index >= strArr.Length)
throw new IndexOutOfRangeException("Cannot store more
than 10 objects");

strArr[index] = value;
}
}
}

class Program
{
static void Main(string[] args)
{
StringDataStore strStore = new StringDataStore();

strStore[0] = "One";
strStore[1] = "Two";
strStore[2] = "Three";
strStore[3] = "Four";

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


Console.WriteLine(strStore[i]);
}
}
Output:
One
Two
Three
Four

The array operator [] is nothing but an indexer implemented in all the data type in C#.
For example, string[] is an indexer in the String class.

In the above example, StringDataStore class implements an indexer for its internal string
array. So now, object of StringDataStore can be used like an array to add or retrive string
data. We have used string array in the above example, you can also you any collection type
as per your requirement.

Override Indexer

You can override an indexer by having different index types. The following example shows
how an indexer can be of int type as well as string type.

Example: Indexer
class StringDataStore
{

private string[] strArr = new string[10]; // internal data storage

public StringDataStore()
{

public string this[int index]


{
get
{
if (index < 0 && index >= strArr.Length)
throw new IndexOutOfRangeException("Cannot store more than 10
objects");
return strArr[index];
}

set
{
if (index < 0 && index >= strArr.Length)
throw new IndexOutOfRangeException("Cannot store more than 10
objects");

strArr[index] = value;
}
}

public string this[string name]


{
get
{
foreach (string str in strArr){
if(str.ToLower() == name.ToLower())
return str;
}

return null;
}
}
}

class Program
{
static void Main(string[] args)
{
StringDataStore strStore = new StringDataStore();

strStore[0] = "One";
strStore[1] = "Two";
strStore[2] = "Three";
strStore[3] = "Four";

Console.WriteLine(strStore["one"]);
Console.WriteLine(strStore["two"]);
Console.WriteLine(strStore["Three"]);
Console.WriteLine(strStore["FOUR"]);
}
}
 

Output:
One
Two
Three
Four
Insert Indexer Code snippet in VisualStudio

Vsual studio provides shortcut way to insert a code snippet for an indexer so that you don't
have to write entire syntax manually. To insert a snippet for an indexer in Visual Studio,
write idexer and press tab or do right click (or Ctrl + K,S) -> select "Insert Snippet.." ->
select "Visual C#.." -> select "indexer".

Indexer
snippet in Visual Studio

Points to Remember :

1. An indexer is same as property except that it defined with this keyword with square
bracket that takes paramter.
2. Indexer can be override by having different types of parameters.
3. Ref and out parameter with the indexer is not supported.
4. Indexer can be included as an interface member.
5. Use code snippet to insert indexer syntax automatically in the visual studio.

C# - Stream
C# includes following standard IO (Input/Output) classes to read/write from different
sources like a file, memory, network, isolated storage, etc.

Stream: System.IO.Stream is an abstract class that provides standard methods to transfer


bytes (read, write, etc.) to the source. It is like a wrapper class to transfer bytes. Classes that
need to read/write bytes from a particular source must implement the Stream class.

The following classes inherits Stream class to provide functionality to Read/Write bytes
from a particular source:

FileStream reads or writes bytes from/to a physical file whether it is a .txt, .exe, .jpg or any
other file. FileStream is derived from the Stream class.

MemoryStream: MemoryStream reads or writes bytes that are stored in memory.


BufferedStream: BufferedStream reads or writes bytes from other Streams to improve the
performance of certain I/O operations.

NetworkStream: NetworkStream reads or writes bytes from a network socket.

PipeStream: PipeStream reads or writes bytes from different processes.

CryptoStream: CryptoStream is for linking data streams to cryptographic transformations.

The following diagram shows the hierarchy of stream classes:

Stream Classes Hierarchy

Stream Readers and Writers

StreamReader: StreamReader is a helper class for reading characters from a Stream by


converting bytes into characters using an encoded value. It can be used to read strings
(characters) from different Streams like FileStream, MemoryStream, etc.

StreamWriter: StreamWriter is a helper class for writing a string to a Stream by


converting characters into bytes. It can be used to write strings to different Streams such as
FileStream, MemoryStream, etc.

BinaryReader: BinaryReader is a helper class for reading primitive datatype from bytes.

BinaryWriter: BinaryWriter writes primitive types in binary.


Stream IO

The above image shows that FileStream reads bytes from a physical file and then
StreamReader reads strings by converting those bytes to strings. In the same way,
StreamWriter takes a string and converts it into bytes and writes to FileStream and then
FileStream writes the bytes to a physical file. So FileStream deals with bytes where as
StreamReader & StreamWriter deals with strings.

Points to Remember :

1. Stream is an abstract class for transfering bytes from different sources. It is base class for
all other class that reads\writes bytes to different sources.
2. FileStream class provides reading and writing functionality of bytes to physical file.
3. Reader & writer classes provides functionality to read bytes from Stream classes
(FileStream, MemoryStream etc) and converts bytes into appropriate encoding.
4. StreamReader provides a helper method to read string from FileStream by converting
bytes into strings. StreamWriter provides a helper method to write string to FileStream by
converting strings into bytes.

Learn how to read/write to the File system in the next section.

Working with Files & Directories in C#


C# provides the following classes to work with the File system. They can be used to access
directories, access files, open files for reading or writing, create a new file or move existing
files from one location to another, etc.

Class Name Usage

File is a static class that provides different functionalities like copy, create, move,
File delete, open for reading or /writing, encrypt or decrypt, check if a file exists, append
lines or text to a file’s content, get last access time, etc.

The FileInfo class provides the same functionality as a static File class. You have
FileInfo more control on how you do read/write operations on a file by writing code
manually for reading or writing bytes from a file.
Class Name Usage

Directory is a static class that provides functionality for creating, moving, deleting
Directory
and accessing subdirectories.

DirectoryInfo provides instance methods for creating, moving, deleting and


DirectoryInfo
accessing subdirectories.

Path is a static class that provides functionality such as retrieving the extension of a
Path file, changing the extension of a file, retrieving the absolute physical path, and other
path related functionalities.

File

C# includes static File class to perform I/O operation on physical file system. The static
File class includes various utility method to interact with physical file of any type e.g.
binary, text etc.

Use this static File class to perform some quick operation on physical file. It is not
recommended to use File class for multiple operations on multiple files at the same time
due to performance reasons. Use FileInfo class in that scenario.

Important Methods of Static File Class


Method Usage

Appends lines to a file, and then closes the file. If the specified file does not
AppendAllLines exist, this method creates a file, writes the specified lines to the file, and then
closes the file.

Opens a file, appends the specified string to the file, and then closes the file. If
AppendAllText the file does not exist, this method creates a file, writes the specified string to
the file, then closes the file.

Creates a StreamWriter that appends UTF-8 encoded text to an existing file, or


AppendText
to a new file if the specified file does not exist.

Copies an existing file to a new file. Overwriting a file of the same name is not
Copy
allowed.

Create Creates or overwrites a file in the specified path.

CreateText Creates or opens a file for writing UTF-8 encoded text.

Decrypts a file that was encrypted by the current account using the Encrypt
Decrypt
method.

Delete Deletes the specified file.

Encrypt Encrypts a file so that only the account used to encrypt the file can decrypt it.
Method Usage

Exists Determines whether the specified file exists.

Gets a FileSecurity object that encapsulates the access control list (ACL) entries
GetAccessControl
for a specified file.

Moves a specified file to a new location, providing the option to specify a new
Move
file name.

Open Opens a FileStream on the specified path with read/write access.

Opens a binary file, reads the contents of the file into a byte array, and then
ReadAllBytes
closes the file.

ReadAllLines Opens a text file, reads all lines of the file, and then closes the file.

ReadAllText Opens a text file, reads all lines of the file, and then closes the file.

Replaces the contents of a specified file with the contents of another file,
Replace
deleting the original file, and creating a backup of the replaced file.

Creates a new file, writes the specified byte array to the file, and then closes
WriteAllBytes
the file. If the target file already exists, it is overwritten.

Creates a new file, writes a collection of strings to the file, and then closes the
WriteAllLines
file.

Creates a new file, writes the specified string to the file, and then closes the file.
WriteAllText
If the target file already exists, it is overwritten.

Append Text Lines

Use AppendAllLines() method to append multiple text lines to the specified file as shown
below.

Example: Append all text lines to a file


string dummyLines = "This is first line." + Environment.NewLine +
"This is second line." + Environment.NewLine +
"This is third line.";

//Opens DummyFile.txt and append lines. If file is not exists then create
and open.
File.AppendAllLines(@"C:\DummyFile.txt",
dummyLines.Split(Environment.NewLine.ToCharArray()).ToList<string>());
Append String

Use File.AppendAllText() method to append string to a file in single line of code as shown
below.

Example: Append string to a file


//Opens DummyFile.txt and append Text. If file is not exists then create
and open.
File.AppendAllText(@"C:\ DummyFile.txt", "This is File testing");
Overwrite Text

Use File.WriteAllText() method to write texts to the file. Please note that it will not append
text but overwrite existing texts.

Example: Overwrite existing texts


//Opens DummyFile.txt and write texts. If file is not exists then create
and open.
File.WriteAllText(@"C:\DummyFile.txt", "This is dummy text");

The following example shows how to perform different operations using static File class.

Example: Multiple File operations


//Check whether file is exists or not at particular location
bool isFileExists = File.Exists(@"C:\ DummyFile.txt"); // returns false

//Copy DummyFile.txt as new file DummyFileNew.txt


File.Copy(@"C:\DummyFile.txt", @"D:\NewDummyFile.txt");

//Get when the file was accessed last time


DateTime lastAccessTime = File.GetLastAccessTime(@"C:\DummyFile.txt");

//get when the file was written last time


DateTime lastWriteTime = File.GetLastWriteTime(@"C:\DummyFile.txt");

// Move file to new location


File.Move(@"C:\DummyFile.txt", @"D:\DummyFile.txt");

//Open file and returns FileStream for reading bytes from the file
FileStream fs = File.Open(@"D:\DummyFile.txt", FileMode.OpenOrCreate);

//Open file and return StreamReader for reading string from the file
StreamReader sr = File.OpenText(@"D:\DummyFile.txt");

//Delete file
File.Delete(@"C:\DummyFile.txt");

Thus, it is easy to work with physical file using static File class. However, if you want more
flexibility then use FileInfo class. The same way, use static Directory class to work with
physical directories.
Visit MSDN to know all the methods of the static File class.

Points to Remember :

1. File is a static class to read\write from physical file with less coding.
2. Static File class provides functionalities such as create, read\write, copy, move, delete and
others for physical files.
3. Static Directory class provides functionalities such as create, copy, move, delete etc for
physical directories with less coding.
4. FileInfo and DirectoryInfo class provides same functionality as static File and Directory
class.

C# - FileInfo
You have learned how to perform different tasks on physical files using static File class in
the previous section. Here, we will use FileInfo class to perform read/write operation on
physical files.

The FileInfo class provides the same functionality as the static File class but you have more
control on read/write operations on files by writing code manually for reading or writing
bytes from a file.

Important Properties and Methods of FileInfo:


Property Usage

Directory Gets an instance of the parent directory.

DirectoryName Gets a string representing the directory's full path.

Exists Gets a value indicating whether a file exists.

Extension Gets the string representing the extension part of the file.

FullName Gets the full path of the directory or file.

IsReadOnly Gets or sets a value that determines if the current file is read only.

LastAccessTime Gets or sets the time the current file or directory was last accessed

LastWriteTime Gets or sets the time when the current file or directory was last written to

Length Gets the size, in bytes, of the current file.

Name Gets the name of the file.

Method Usage
Property Usage

Creates a StreamWriter that appends text to the file


AppendText
represented by this instance of the FileInfo.

Copies an existing file to a new file, disallowing the overwriting


CopyTo
of an existing file.

Create Creates a file.

CreateText Creates a StreamWriter that writes a new text file.

Decrypts a file that was encrypted by the current account using


Decrypt
the Encrypt method.

Delete Deletes the specified file.

Encrypts a file so that only the account used to encrypt the file
Encrypt
can decrypt it.

Gets a FileSecurity object that encapsulates the access control


GetAccessControl
list (ACL) entries for a specified file.

Moves a specified file to a new location, providing the option to


MoveTo
specify a new file name.

Open Opens a in the specified FileMode.

OpenRead Creates a read-only FileStream.

Creates a StreamReader with UTF8 encoding that reads from an


OpenText
existing text file.

OpenWrite Creates a write-only FileStream.

Replaces the contents of a specified file with the file described


Replace by the current FileInfo object, deleting the original file, and
creating a backup of the replaced file.

ToString Returns a path as string.

The following example shows how to read bytes from a file manually and then convert
them to a string using UTF8 encoding:

Example: Read file using FileInfo class


//Create object of FileInfo for specified path
FileInfo fi = new FileInfo(@"D:\DummyFile.txt");
//Open file for Read\Write
FileStream fs = fi.Open(FileMode.OpenOrCreate, FileAccess.ReadWrite,
FileShare.ReadWrite);

//create byte array of same size as FileStream length


byte[] fileBytes = new byte[fs.Length];

//define counter to check how much butes to read. Decrease the counter as
you read each byte
int numBytesToRead = (int)fileBytes.Length;

//Counter to indicate number of bytes already read


int numBytesRead = 0;

//iterate till all the bytes read from FileStream


while (numBytesToRead > 0)
{
int n = fs.Read(fileBytes, numBytesRead, numBytesToRead);

if (n == 0)
break;

numBytesRead += n;
numBytesToRead -= n;
}

//Once you read all the bytes from FileStream, you can convert it into
string using UTF8 encoding
string filestring = Encoding.UTF8.GetString(fileBytes);

As you have seen in the above code, you have to write lot of code for reading/writing a
string from a FileSream. The same read/write operation can be done easily using
StreamReader and StreamWriter.

The following example shows how StreamReader makes it easy to read strings from a file:

Example: Read file using StreamReader


//Create object of FileInfo for specified path
FileInfo fi = new FileInfo(@"D:\DummyFile.txt");

//Open file for Read\Write


FileStream fs = fi.Open(FileMode.OpenOrCreate, FileAccess.Read ,
FileShare.Read);

//Create object of StreamReader by passing FileStream object on which it


needs to operates on
StreamReader sr = new StreamReader(fs);

//Use ReadToEnd method to read all the content from file


string fileContent = sr.ReadToEnd();

//Close StreamReader object after operation


sr.Close();
fs.Close();
Notice that fi.Open() has three parameters: The first parameter is FileMode for creating
and opening a file if it does not exist; the second parameter, FileAccess, is to indicate a
Read operation; and the third parameter is to share the file for reading with other users
while the file is open.

The following example shows how StreamWriter makes it easy to write strings to a File:

Example: Write texts to file using StreamWriter


//Create object of FileInfo for specified path
FileInfo fi = new FileInfo(@"D:\DummyFile.txt");

//Open file for Read\Write


FileStream fs = fi.Open(FileMode.OpenOrCreate, FileAccess.Write,
FileShare.Read );

//Create StreamWriter object to write string to FileSream


StreamWriter sw = new StreamWriter(fs);
sw.WriteLine("Another line from streamwriter");
sw.Close();

Read and Write operations are not possible on the same FileStream object simultaneously.
If you are already reading from a file, create a separate FileStream object to write to the
same file, as shown below:

Example: StreamReader & StreamWriter


//Create FileInfo object for DummyFile.txt
FileInfo fi = new FileInfo(@"D:\DummyFile.txt");

//open DummyFile.txt for read operation


FileStream fsToRead = fi.Open(FileMode.OpenOrCreate, FileAccess.ReadWrite
, FileShare.ReadWrite);

//open DummyFile.txt for write operation


FileStream fsToWrite = fi.Open(FileMode.OpenOrCreate,
FileAccess.ReadWrite, FileShare.ReadWrite);

//get the StreamReader

StreamReader sr = new StreamReader(fsToRead);


//read all texts using StreamReader object
string fileContent = sr.ReadToEnd();
sr.Close();

//get the StreamWriter


StreamWriter sw = new StreamWriter(fsToWrite);
//write some text using StreamWriter
sw.WriteLine("Another line from streamwriter");
sw.Close();

//close all Stream objects


fsToRead.Close();
fsToWrite.Close();
Thus you can use FileInfo, StreamReader and StreamWriter class to read/write contents
from physical file.

Further Reading

 FileInfo class members


 StreamReader class members
 StreamWriter class members

Exception in C#
An application may encounter an error during the execution. When an error occurs, either
CLR or program code throws an exception which contains necessary information about the
error. There are two types of exceptions in .Net, exceptions generated by the executing
program and exceptions generated by the CLR.

C# includes built-in classes for every possible exception. All the exception classes are
directly or indirectly derived from the Exception class. There are two main classes for
exceptions - SystemException and ApplicationException. SystemException is a base class
for all CLR generated errors whereas ApplicationException serves as a base class for all
application related exceptions, which you want to raise on business rule violation.

The following is a hierarchy of some of the exception classes in .Net:


Exception Classes Hierarchy

As you can see in the above figure, SystemException class is a base class for all the
exception that can occurs during execution of the program. No other class derives
ApplicationException class by default, because you as a programmer need to derive this
class to create your own exeception classes as per the business rules.

The following figure shows how NullReferenceException is thrown in Visual Studio debug
mode, when it accesses a property of a null object at runtime:

NullReferenceException
Important Exception Classes:

The following table lists important exception classes available in .Net.

Exception Description

Raised when a non-null argument that is passed to a method is


ArgumentException
invalid.

ArgumentNullException Raised when null argument is passed to a method.

Raised when the value of an argument is outside the range of


ArgumentOutOfRangeException
valid values.

DivideByZeroException Raised when an integer value is divide by zero.

Raised when a physical file does not exist at the specified


FileNotFoundException
location.

Raised when a value is not in an appropriate format to be


FormatException
converted from a string by a conversion method such as Parse.

Raised when an array index is outside the lower or upper bounds


IndexOutOfRangeException
of an array or collection.

InvalidOperationException Raised when a method call is invalid in an object's current state.

InvalidCastException Raised when incompitible types are being converted.

Raised when the specified key for accessing a member in a


KeyNotFoundException
collection is not exists.

NotSupportedException Raised when a method or operation is not supported.

NullReferenceException Raised when program access members of null object.

Raised when an arithmetic, casting, or conversion operation


OverflowException
results in an overflow.

Raised when a program does not get enough memory to execute


OutOfMemoryException
the code.

StackOverflowException Raised when a stack in memory overflows.

TimeoutException The time interval allotted to an operation has expired.

Every exception class in .Net is derived from the base Exception class. It includes the
following important properties using which you can use to get information about the
exception when you handle the exception.
Property Description

Message Provides details about the cause of the exception.

StackTrace Provides information about where the error occurred.

InnerException Provides information about the series of exceptions that might have occurred.

HelpLink This property can hold the help URL for a particular exception.

Data This property can hold arbitrary data in key-value pairs.

TargetSite Provides the name of the method where this exception was thrown.

When an error occurs, either application code or the default handler handles the exception.
Learn how to handle the excetion in the next section.

Points to Remember :

1. Exception is a base class for any type of exception class in C#.


2. Exception types: SystemException and ApplicationException.
3. SystemException class is used for CLR related runtime errors.
4. Exception class includes important properties e.g Message, StackTrack, InnerException,
data etc. to associate important information with every exception.

Exception Handling in C#
We have seen in the previous section that an exception is thrown by the CLR or program
code if there is an error in the program. These exceptions need to be handle to prevent
crashing of program. C# provides built-in support to handle the exception using try, catch
& finally block.

Syntax:
try
{
// code that may raise exceptions
}
catch(Exception ex)
{
// handle exception
}
finally
{
// final cleanup code
}
As per the above syntax, put the code in the try block that may raise an exception followed
by a catch or finally block. Keep variable declarations out of the try block so that they can
be accessed in the catch and finally blocks.

Let's see how to use try & catch block to handle the exception. Consider the following code
which can raise an exception.

Example: Program throws an Exception


class Program
{
static void Main(string[] args)
{
Console.Write("Enter Student Name: ");

string studentName = Console.ReadLine();

IList<String> studentList =
FindAllStudentFromDatabase(studentName);

Console.WriteLine("Total {0}: {1}", studentName,


studentList.Count());

Console.ReadKey();
}

private static IList<String> FindAllStudentFromDatabase(string


studentName)
{
var studentList = // find all students with same name from the
database

return studentList;
}
}

In the above example, it display total number of students with the same name. Assume that
FindAllStudentFromDatabase() method gets student list with the same name from the
database.

The above example will work fine if at least one student exists for the specified name,
otherwise it will raise NullReferenceException. We don't want to show exception message
to the user and stop the execution. So, we need to handle exception using try catch block as
shown below.

Example: Exception handling using try catch block


class Program
{
static void Main(string[] args)
{
Console.Write("Enter Student Name: ");
string studentName = Console.ReadLine();

try
{
IList<String> studentList =
FindAllStudentFromDatabase(studentName);

Console.WriteLine("Total {0}: {1}", studentName,


studentList.Count());
}
catch(Exception ex)
{
Console.Write("No Students exists for the specified name.");
}

Console.ReadKey();
}

private static IList<String> FindAllStudentFromDatabase(string


studentName)
{
var studentList = // find all students with same name from the
database

return studentList;
}
}

As you can see in the above example, studentList.Count() can raise an exception if
studentList is null. So wrap this code into try block. The try block simple tells the
compiler to monitor the code for an exception. Exception raised within try block must be
handled using catch block.

Note:

try block must be followed by catch or finally or both blocks. The try block without a catch or
finally block will give a compile time error.

Catch block:

Exception raised within try block can be handled using the catch block as shown in the
above example. Code in the catch block will only execute when an exception occurs.

A multiple catch block can also be specified with a different exception type is called
exception filters. A multiple catch block is useful when you want to handle different
exceptions in different ways.

Example: Multiple catch block


class Program
{
static void Main(string[] args)
{
Console.Write("Please enter two numbers: ");

try
{
int num1 = int.Parse(Console.ReadLine());
int num2 = int.Parse(Console.ReadLine());

int result = num1 / num2;

Console.WriteLine("{0} / {1} = {2}", num1, num2, result);


}
catch(DivideByZeroException ex)
{
LogError(ex);
Console.Write("Cannot divide by zero. Please try
again.");
}
catch(InvalidOperationException ex)
{
LogError(ex);
Console.Write("Not a valid number. Please try again.");
}
catch(FormatException ex)
{
LogError(ex);
Console.Write("Not a valid number. Please try again.");
}

Console.ReadKey();
}

In the above example, we have specified a multiple catch block with different exception
types, so that we can display the appropriate message to the user, depending upon the error
and so the user does not repeat the same mistake again.

Note:

A multiple catch block with the same exception type is not allowed. It will give a compile time
error.

Invalid catch Block

Parameterless catch block and a catch block with an Exception parameter are not allowed in
the same try-catch statements, because they both do the same thing.

Example: Invalid catch blocks


try
{
//code that may raise an exception
}
catch //cannot have both catch and catch(Exception ex)
{
Console.WriteLine("Exception occurred");
}
catch(Exception ex) //cannot have both catch and catch(Exception ex)
{
Console.WriteLine("Exception occurred");
}

Also, parameterless catch block catch{ } or general catch block catch(Exception ex)
{ } must be the last block. The compiler will give an error if you have other catch blocks
after a catch{ } or catch(Exception ex) block.

Example: Invalid catch block


try
{
//code that may raise an exception
}
catch
{
// this catch block must be last block
}
catch (NullReferenceException nullEx)
{
Console.WriteLine(nullEx.Message);
}
catch (InvalidCastException inEx)
{
Console.WriteLine(inEx.Message);
}
Finally Block

The finally block must come after a try or catch block. The finally block will always be
executed whether or not an exception is thrown. The finally block is generally used for
cleaning-up code e.g. for disposing an unmanaged objects etc.

Example: finally block


static void Main(string[] args)
{
int zero = 0;

try
{
int result = 5/zero; // this will throw an exception
}

catch(Exception ex)
{
Console.WriteLine("Inside catch block. Exception: {0}",
ex.Message );
}

finally
{
Console.WriteLine("Inside finally block.");
}
}
Output:
Inside catch block. Exception: Attempted to divide by zero.
Inside finally

Note:

Multiple finally blocks are not allowed. Also, the finally block cannot have the return, continue, or
break keywords. It doesn't allow control to leave the finally block.

Nested try-catch

C# allows nested try catch blocks. In the nested try catch block, an exception will be caught
in the catch block that follows the try block where an exception occurred.

Example: Nested try-catch


static void Main(string[] args)
{
Student std = null;

try
{
try
{
std.StudentName = "";
}
catch
{
Console.WriteLine("Inner catch");
}
}
catch
{
Console.WriteLine("Outer catch");
}
}

Output:
Inner catch

If there isn't any inner catch block with appropriate exception type, then exception will flow
to the outer catch block until it finds the appropriate exception filter. Consider the
following example.

Example: Nested try-catch


static void Main(string[] args)
{
Student std = null;

try
{
try
{
// following throws NullReferenceException
std.StudentName = "";
}
catch (InvalidOperationException innerEx)
{
Console.WriteLine("Inner catch");
}
}
catch
{
Console.WriteLine("Outer catch");
}
}
Output:
Outer catch

In the above example, std.StudentName will raise a NullReferenceException, but there is


not any catch block that handles NullReferenceException or Exception type. So, it will be
handled by the outer catch block.

Points to Remember :

1. Use the try, catch and finally blocks to handle exceptions in C#.
2. The try block must be followed by a catch or finally block or both.
3. A multiple catch block is allowed with different exception filters. General catch{..} block
must come last.
4. catch{..} and catch(Exception ex){ } both cannot be used.
5. The finally block must come after the try or catch block.
6. The finally block will always execute irrespective of whether an exception occured or not.
7. The finally block is appropriate place for disposing objects.
8. The finally block cannot have a return or break because it isn't allow to leave the control.
9. Nested try-catch blocks are allowed in C#.
10. An Exception will be catched in the inner catch block if appropriate filter found, otherwise
will be catched by outer catch block.

Learn how to raise an exception manually in the next section.

C# - throw keyword
We have seen in the previous section how to handle exceptions which are automatically
raised by CLR. Here, we will see how to raise an exception manually.

An exception can be raised manually by using the throw keyword. Any type of exceptions
which is derived from Exception class can be raised using the throw keyword.

Example: throw an exception


static void Main(string[] args)
{
Student std = null;

try
{
PrintStudentName(std);
}
catch(Exception ex)
{
Console.WriteLine(ex.Message );
}

Console.ReadKey();
}

private static void PrintStudentName( Student std)


{
if (std == null)
throw new NullReferenceException("Student object is null.");

Console.WriteLine(std.StudentName);
}
Output:
Student object is null.

In the above example, PrintStudentName() method raises NullReferenceException if


Student object is null.

Please notice that throw creates an object of any valid exception type using the new
keyword. The throw keyword cannot be used with any other type which does not derive
from the Exception class.

Learn how to create custom exception type in the next section.

Create Custom Exception Class in C#


We have seen built-in exception classes in the previous section. However, you often like to
raise an exception when the business rule of your application gets violated. So, for this you
can create a custom exception class by deriving Exception or ApplicationException class.

The .Net framework includes ApplicationException class since .Net v1.0. It was designed
to use as a base class for the custom exception class. However, Microsoft now recommends
Exception class to create a custom exception class.

For example, create InvalidStudentNameException class in a school application, which


does not allow any special character or numeric value in a name of any of the students.

Example: ApplicationException
class Student
{
public int StudentID { get; set; }
public string StudentName { get; set; }
}

[Serializable]
class InvalidStudentNameException : Exception
{
public InvalidStudentNameException()
{

public InvalidStudentNameException(string name)


: base(String.Format("Invalid Student Name: {0}", name))
{

Now, you can raise InvalidStudentNameException in your program whenever the name
contains special characters or numbers. Use the throw keyword to raise an exception.

Example: throw custom exception


class Program
{
static void Main(string[] args)
{
Student newStudent = null;

try
{
newStudent = new Student();
newStudent.StudentName = "James007";

ValidateStudent(newStudent);
}
catch(InvalidStudentNameException ex)
{
Console.WriteLine(ex.Message );
}

Console.ReadKey();
}

private static void ValidateStudent(Student std)


{
Regex regex = new Regex("^[a-zA-Z]+$");

if (!regex.IsMatch(std.StudentName))
throw new InvalidStudentNameException(std.StudentName);

}
}
Output:
Invalid Student Name: James000

Thus, you can create custom exception classes to differentiate from system exceptions.

C# - Delegate
A function can have one or more parameters of different data types, but what if you want to
pass a function itself as a parameter? How does C# handle the callback functions or event
handler? The answer is - delegate.

A delegate is like a pointer to a function. It is a reference type data type and it holds the
reference of a method. All the delegates are implicitly derived from System.Delegate
class.

A delegate can be declared using delegate keyword followed by a function signature as


shown below.

Delegate Syntax:
<access modifier> delegate <return type> <delegate_name>(<parameters>)

The following example declares a Print delegate.

Example: Declare delegate


public delegate void Print(int value);
The Print delegate shown above, can be used to point to any method that has same return
type & parameters declared with Print. Consider the following example that declares and
uses Print delegate.

Example: C# delegate
class Program
{
// declare delegate
public delegate void Print(int value);

static void Main(string[] args)


{
// Print delegate points to PrintNumber
Print printDel = PrintNumber;

printDel(100000);
printDel(200);

// Print delegate points to PrintMoney


printDel = PrintMoney;

printDel(10000);
printDel(200);
}

public static void PrintNumber(int num)


{
Console.WriteLine("Number: {0,-12:N0}",num);
}

public static void PrintMoney(int money)


{
Console.WriteLine("Money: {0:C}", money);
}
}
Output:
Number: 10,000
Number: 200
Money: $ 10,000.00
Money: $ 200.00

In the above example, we have declared Print delegate that accepts int type parameter and
returns void. In the Main() method, a variable of Print type is declared and assigned a
PrintNumber method name. Now, invoking Print delegate will in-turn invoke PrintNumber
method. In the same way, if the Print delegate variable is assigned to the PrintMoney
method, then it will invoke the PrintMoney method.

The following image illustrates the delegate.


delegate in C#

Invoking Delegate

The delegate can be invoked like a method because it is a reference to a method. Invoking a
delegate will in-turn invoke a method which id refered to. The delegate can be invoked by
two ways: using () operator or using the Invoke() method of delegate as shown below.

Example: Invoking a delegate


Print printDel = PrintNumber;
printDel.Invoke(10000);

//or
printDel (10000);
Number: 200
Number: 200

Pass Delegate as a Parameter

A method can have a parameter of a delegate type and can invoke the delegate parameter.

Example: Delegate Parameter


public static void PrintHelper(Print delegateFunc, int numToPrint)
{
delegateFunc(numToPrint);
}
In the above example, PrintHelper method has a delegate parameter of Print type and
invokes it like a function:delegateFunc(numToPrint).

The following example shows how to use PrintHelper method that includes delegate type
parameter.

Example: Delegate parameter


class Program
{
public delegate void Print(int value);

static void Main(string[] args)


{
PrintHelper(PrintNumber, 10000);
PrintHelper(PrintMoney, 10000);
}

public static void PrintHelper(Print delegateFunc, int numToPrint)


{
delegateFunc(numToPrint);
}

public static void PrintNumber(int num)


{
Console.WriteLine("Number: {0,-12:N0}",num);
}

public static void PrintMoney(int money)


{
Console.WriteLine("Money: {0:C}", money);
}
}
Output:
Number: 10,000
Money: $ 10,000.00

Multicast Delegate

The delegate can points to multiple methods. A delegate that points multiple methods is
called a multicast delegate. The "+" operator adds a function to the delegate object and the
"-" operator removes an existing function from a delegate object.

Example: Multicast delegate


public delegate void Print(int value);

static void Main(string[] args)


{
Print printDel = PrintNumber;
printDel += PrintHexadecimal;
printDel += PrintMoney;
printDel(100000);
}
public static void PrintNumber(int num)
{
Console.WriteLine("Number: {0,-12:N0}",num);
}

public static void PrintMoney(int money)


{
Console.WriteLine("Money: {0:C}", money);
}

public static void PrintHexadecimal(int dec)


{
Console.WriteLine("Hexadecimal: {0:X}", dec);
}
Output:
Number: 1,00,000
Hexadecimal: 186A0
Money: $ 1,00,000.00

As you can see in the above example, Print delegates becomes a multicast delegate because
it points to three methods - PrintNumber, PrintMoney & PrintHexadecimal. So invoking
printDel will invoke all the methods sequentially.

Delegate is also used with Event, Anonymous method, Func delegate, Action delegate.

Points to Remember :

1. Delegate is a function pointer. It is reference type data type.


2. Syntax: public delegate void <function name>(<parameters>)
3. A method that is going to assign to delegate must have same signature as delegate.
4. Delegates can be invoke like a normal function or Invoke() method.
5. Multiple methods can be assigned to the delegate using "+" operator. It is called multicast
delegate.

C# - Event
In general terms, an event is something special that is going to happen. For example,
Microsoft launches events for developers, to make them aware about the features of new or
existing products. Microsoft notifies the developers about the event by email or other
advertisement options. So in this case, Microsoft is a publisher who launches (raises) an
event and notifies the developers about it and developers are the subscribers of the event
and attend (handle) the event.
Events in C# follow a similar concept. An event has a publisher, subscriber, notification
and a handler. Generally, UI controls use events extensively. For example, the button
control in a Windows form has multiple events such as click, mouseover, etc. A custom
class can also have an event to notify other subscriber classes about something that has
happened or is going to happen. Let's see how you can define an event and notify other
classes that have event handlers.

An event is nothing but an encapsulated delegate. As we have learned in the previous


section, a delegate is a reference type data type. You can declare the delegate as shown
below:

Example: Delegate
public delegate void someEvent();

public someEvent someEvent;

Now, to declare an event, use the event keyword before declaring a variable of delegate
type, as below:

Example: Event Declaration


public delegate void someEvent();

public event someEvent someEvent;

Thus, a delegate becomes an event using the event keyword.

Now, let's see a practical example of an event. Consider the following PrintHelper class
that prints integers in different formats like number, money, decimal, temperature and
hexadecimal. It includes a beforePrintEvent to notify the subscriber of the BeforePrint
event before it going to print the number.

Example: Event
public class PrintHelper
{
// declare delegate
public delegate void BeforePrint();

//declare event of type delegate


public event BeforePrint beforePrintEvent;

public PrintHelper()
{

public void PrintNumber(int num)


{
//call delegate method before going to print
if (beforePrintEvent != null)
beforePrintEvent();

Console.WriteLine("Number: {0,-12:N0}", num);


}

public void PrintDecimal(int dec)


{
if (beforePrintEvent != null)
beforePrintEvent();

Console.WriteLine("Decimal: {0:G}", dec);


}

public void PrintMoney(int money)


{
if (beforePrintEvent != null)
beforePrintEvent();

Console.WriteLine("Money: {0:C}", money);


}

public void PrintTemperature(int num)


{
if (beforePrintEvent != null)
beforePrintEvent();

Console.WriteLine("Temperature: {0,4:N1} F", num);


}
public void PrintHexadecimal(int dec)
{
if (beforePrintEvent != null)
beforePrintEvent();

Console.WriteLine("Hexadecimal: {0:X}", dec);


}
}

The delegate can also be invoked using the Invoke() method, e.g.,
beforePrintEvent.Invoke().

PrintHelper is a publisher class that publishes the beforePrint event. Notice that in each
print method, it first checks to see if beforePrintEvent is not null and then it calls
beforePrintEvent(). beforePrintEvent is an object of type BeforPrint delegate, so it would
be null if no class is subscribed to the event and that is why it is necessary to check for null
before calling a delegate.

Now, let's create a subscriber. Consider the following simple Number class for example.

Example: Event subscriber


class Number
{
private PrintHelper _printHelper;
public Number(int val)
{
_value = val;

_printHelper = new PrintHelper();


//subscribe to beforePrintEvent event
_printHelper.beforePrintEvent += printHelper_beforePrintEvent;
}
//beforePrintevent handler
void printHelper_beforePrintEvent()
{
Console.WriteLine("BeforPrintEventHandler: PrintHelper is going
to print a value");
}

private int _value;

public int Value


{
get { return _value; }
set { _value = value; }
}

public void PrintMoney()


{
_printHelper.PrintMoney(_value);
}

public void PrintNumber()


{
_printHelper.PrintNumber(_value);
}
}

All the subscribers must provided a handler function, which is going to be called when a
publisher raises an event. In the above example, the Number class creates an instance of
PrintHelper and subscribes to the beforePrintEvent with the "+=" operator and gives the
name of the function which will handle the event (it will be get called when publish fires an
event). printHelper_beforePrintEvent is the event handler that has the same signature as the
BeforePrint delegate in the PrintHelper class.

So now, create an instance of Number class and call print methods:

Example: Event
Number myNumber = new Number(100000);
myNumber.PrintMoney();
myNumber.PrintNumber();
Output:
BeforePrintEventHandler: PrintHelper is going to print value
Money: $ 1,00,000.00
BeforePrintEventHandler: PrintHelper is going to print value
Number: 1,00,000

The following image illustrates an event model:

Event
publisher-Subscriber

Event Arguments

Events can also pass data as an argument to their subscribed handler. An event passes
arguments to the handler as per the delegate signature. In the following example,
PrintHelper declares the BeforePrint delegate that accepts a string argument. So now, you
can pass a string when you raise an event from PrintNumber or any other Print method.

Example: Event Arguments


public class PrintHelper
{
public delegate void BeforePrint(string message);
public event BeforePrint beforePrintEvent;

public void PrintNumber(int num)


{
if (beforePrintEvent != null)
beforePrintEvent.Invoke("PrintNumber");

Console.WriteLine("Number: {0,-12:N0}", num);


}

public void PrintDecimal(int dec)


{
if (beforePrintEvent != null)
beforePrintEvent("PrintDecimal");
Console.WriteLine("Decimal: {0:G}", dec);
}

public void PrintMoney(int money)


{
if (beforePrintEvent != null)
beforePrintEvent("PrintMoney");

Console.WriteLine("Money: {0:C}", money);


}

public void PrintTemperature(int num)


{
if (beforePrintEvent != null)
beforePrintEvent("PrintTemerature");

Console.WriteLine("Temperature: {0,4:N1} F", num);


}

public void PrintHexadecimal(int dec)


{
if (beforePrintEvent != null)
beforePrintEvent("PrintHexadecimal");

Console.WriteLine("Hexadecimal: {0:X}", dec);


}
}

Now, the subscriber class should have an event handler that has a string parameter.

In the following example, Number class has a printHelper_beforePrintEvent function with


string parameter.

Example: Event
class Number
{
private PrintHelper _printHelper;

public Number(int val)


{
_value = val;

_printHelper = new PrintHelper();


//subscribe to beforePrintEvent event
_printHelper.beforePrintEvent += printHelper_beforePrintEvent;
}
//beforePrintevent handler
void printHelper_beforePrintEvent(string message)
{
Console.WriteLine("BeforePrintEvent fires from {0}",message);
}

private int _value;


public int Value
{
get { return _value; }
set { _value = value; }
}

public void PrintMoney()


{
_printHelper.PrintMoney(_value);
}

public void PrintNumber()


{
_printHelper.PrintNumber(_value);
}

}
Output:
BeforePrintEvent fires from PrintMoney.
Money: $ 1,00,000.00
BeforePrintEvent fires from PrintNumber.
Number: 1,00,000

Further Reading

 Delegates and Events

Points to Remember :

1. Use event keyword with delegate type to declare an event.


2. Check event is null or not before raising an event.
3. Subscribe to events using "+=" operator. Unsubscribe it using "-=" operator.
4. Function that handles the event is called event handler. Event handler must have same
signature as declared by event delegate.
5. Events can have arguments which will be passed to handler function.
6. Events can also be declared static, virtual, sealed and abstract.
7. An Interface can include event as a member.
8. Events will not be raised if there is no subscriber
9. Event handlers are invoked synchronously if there are multiple subscribers
10. The .NET framework uses an EventHandler delegate and an EventArgs base class.

Generics in C#
Generics introduced in C# 2.0. Generics allow you to define a class with placeholders for
the type of its fields, methods, parameters, etc. Generics replace these placeholders with
some specific type at compile time.

A generic class can be defined using angle brackets <>. For example, the following is a
simple generic class with a generic member variable, generic method and property.

Example: Generic class


class MyGenericClass<T>
{
private T genericMemberVariable;

public MyGenericClass(T value)


{
genericMemberVariable = value;
}

public T genericMethod(T genericParameter)


{
Console.WriteLine("Parameter type: {0}, value: {1}",
typeof(T).ToString(),genericParameter);
Console.WriteLine("Return type: {0}, value: {1}",
typeof(T).ToString(), genericMemberVariable);

return genericMemberVariable;
}

public T genericProperty { get; set; }


}

As you can see in the above code, MyGenericClass is defined with <T>. <> indicates that
MyGenericClass is generic and the underlying type would be defined later, for now
consider it as T. You can take any character or word instead of T.

Now, the compiler assigns the type based on the type passed by the caller when
instantiating a class. For example, the following code uses the int data type:

Example: Instantiate Generic Class


MyGenericClass<int> intGenericClass = new MyGenericClass<int>(10);

int val = intGenericClass.genericMethod(200);


Output:
Parameter type: int, value: 200
Return type: int, value: 10

The following figure illustrates how the compiler will replace T with int in
MyGenericClass.
C# Generic Class

The above MyGenericClass<int> class would be compiled, as shown below.

Example: Compiled Generic class


class MyGenericClass
{
private int genericMemberVariable;

public MyGenericClass(int value)


{
genericMemberVariable = value;
}

public int genericMethod(int genericParameter)


{
Console.WriteLine("Parameter type: {0}, value: {1}",
typeof(int).ToString(), genericParameter);
Console.WriteLine("Return type: {0}, value: {1}",
typeof(int).ToString(), genericMemberVariable);

return genericMemberVariable;
}

public int genericProperty { get; set; }


}
You can use any type while instantiating a MyGenricClass. For example, the following
example uses a string type.

Example: Generic class


MyGenericClass<string> strGenericClass = new
MyGenericClass<string>("Hello Generic World");

strGenericClass.genericProperty = "This is a generic property example.";


string result = strGenericClass.genericMethod("Generic Parameter");
Output:
Parameter type: string, value: Generic Parameter
Return type: string, value: Hello Generic World

Generic Class as Base Class

When deriving from a generic base class, you must provide a type argument instead of the
base-class's generic type parameter as shown below.

Example: Generic
class MyDerivedClass : MyGenericClass<string>
{
//implementation
}

If you want the derived class to be generic then no need to specify type for the generic base
class.

Example: Generic derived class


class MyDerivedClass<U> : MyGenericClass<U>
{
//implementation
}

If the generic base class has constraints, the derived class must use the same constraints.

Example: Constraints
class MyGenericClass<T> where T: class
{
// Implementation
}

class MyDerivedClass<U> : MyGenericClass<U> where U: class


{
//implementation
}
Generic Delegates

As you have already learned in the previous section, the delegate defines the signature of
the method which it can invoke. A generic delegate can be defined the same way as
delegate but with generic type.

For example, consider the following generic delegate that takes two generic parameters.

Example: Generic Delegate


class Program
{
public delegate T add<T>(T param1, T param2);

static void Main(string[] args)


{
add<int> sum = AddNumber;

Console.WriteLine(sum(10, 20));

add<string> conct = Concate;

Console.WriteLine(conct("Hello","World!!"));
}

public static int AddNumber(int val1, int val2)


{
return val1 + val2;
}

public static string Concate(string str1, string str2)


{
return str1 + str2;
}
}
Output:
30
Hello World!!

In the above example, add delegate is generic. In the Main() method, it has defined add
delegate of int type variable sum. So it can point to the AddNumber() method which has int
type parameters. Another variable of add delegate uses string type, so it can point to the
Concate method. In this way, you can use generic delegates for different methods of
different types of parameters.

Note:

A generic delegate can point to methods with different parameter types. However, the number of
parameters should be the same.

Generics can be applied to the following:


 Interface
 Abstract class
 Class
 Method
 Static method
 Property
 Event
 Delegates
 Operator

Advantages of Generics

1. Increases the reusability of the code.


2. Generic are type safe. You get compile time errors if you try to use a different type of data
than the one specified in the definition.
3. Generic has a performance advantage because it removes the possibilities of boxing and
unboxing.

Further Reading

 Advantages and limitations of generics.


 Generic delegates.

Points to Remember :

1. Generics denotes with angel bracket <>.


2. Compiler applys specified type for generics at compile time.
3. Generics can be applied to interface, abstrct class, method, static method, property,
event, delegate and operator.
4. Generics performs faster by not doing boxing & unboxing.

C#: Constraints in Generics


You have learned abut the generics in the previous section. Generics allow you to define a
class with placeholders for the type of its fields, methods, parameters, etc. Consider the
following example of a generic class.

Example: Generic class


class MyGenericClass<T>
{
private T genericMemberVariable;

public MyGenericClass(T value)


{
genericMemberVariable = value;
}

public T genericMethod(T genericParameter)


{
Console.WriteLine("Parameter type: {0}, value: {1}",
typeof(T).ToString(),genericParameter);
Console.WriteLine("Return type: {0}, value: {1}",
typeof(T).ToString(), genericMemberVariable);

return genericMemberVariable;
}

public T genericProperty { get; set; }


}

In the above example, the generic class MyGenericClass defines a placeholder for the type,
but the placeholder is like a black box, because MyGenericClass doesn't know anything
about the placeholder type, whether it is primitive or non-primitive type, or an interface or
custom class etc.

C# includes Constraints to specify which type of placeholder type with the generic class is
allowed. It will give a compile time error if you try to instantiate a generic class using a
placeholder type that is not allowed by a constraints. For example, if the generic constraints
specifies that only reference type can be used with the generic class then you cannot use
value type to create an object of generic type.

Constraints can be applied using the where keyword. In the following example,
MyGenericClass specifies the constraints that only a reference type can be used with
MyGenericClass. This means that only a class can be a placeholder type not the primitive
types, struct etc.

Example: Generic Class with Constraints


class MyGenericClass<T> where T: class
{
private T genericMemberVariable;

public MyGenericClass(T value)


{
genericMemberVariable = value;
}

public T genericMethod(T genericParameter)


{
Console.WriteLine("Parameter type: {0}, value: {1}",
typeof(T).ToString(),genericParameter);
Console.WriteLine("Return type: {0}, value: {1}",
typeof(T).ToString(), genericMemberVariable);

return genericMemberVariable;
}
public T genericProperty { get; set; }
}

So now, you cannot use int as a placeholder type. The following would give a compile time
error.

Example: Compile Time Error


MyGenericClass<int> intGenericClass = new MyGenericClass<int>(10);

String or any class type is a valid type because it is a reference type.

Example: Intantiate Constrained Generic Class:


MyGenericClass<string> strGenericClass = new
MyGenericClass<string>("Hello World");

MyGenericClass<Student> strGenericClass = new MyGenericClass<Student>(new


Student());

The following table lists the types of generic constraints.

Constraint Description

where T : class Type must be reference type.

where T: struct Type must be value type.

where T: new() Type must have public parameterless constructor.

where T: <base class


Type must be or derive from the specified base class
name>

where T: <interface name> Type must be or implement the specified interface.

Type supplied for T must be or derive from the argument supplied for
where T: U
U.

Multiple constraints:

A generic class can have multiple constraints as shown below.

Multiple constraints:
class MyGenericClass<T, U> where T: class where U:struct
{
...
}
Constraint on Generic Methods

You can apply constraints on the generic methods also.

Method constraint:
class MyGenericClass<T> where T: class
{
public T genericMethod<U>(T genericParameter, U anotherGenericType)
where U: struct
{
Console.WriteLine("Generic Parameter of type {0}, value {1}",
typeof(T).ToString(),genericParameter);
Console.WriteLine("Return value of type {0}, value {1}",
typeof(T).ToString(), genericMemberVariable);

return genericMemberVariable;
}
}

Thus, constraints can be applied on generic types.

Points to Remember :

1. Constraints specifies the kind of types allowed with the generics.


2. Constraints can be applied using the where keyword.
3. Six types of constraints can be applied: class, struct, new(), base class name, interface and
derived type.
4. Multiple constraints also can be applied.

C# - Generic Collection
You have learned about the collection in the previous section, e.g. ArrayList, BitArray,
SortedList, Queue, Stack and Hashtable. These types of collections can store any type of
items. For example, ArrayList can store items of different data types:

Example: C# ArrayList Collection


ArrayList arList = new ArrayList();

arList.Add(1);
arList.Add("Two");
arList.Add(true);
arList.Add(100.45);
arList.Add(DateTime.Now);
The limitation of these collections is that while retrieving items, you need to cast into the
appropriate data type, otherwise the program will throw a runtime exception. It also affects
on performance, because of boxing and unboxing.

To overcome this problem, C# includes generic collection classes in the


System.Collections.Generic namespace.

The following are widely used generic collections:

Generic Collections Description

Generic List<T> contains elements of specified type. It grows


List<T>
automatically as you add elements in it.

Dictionary<TKey,TValue> Dictionary<TKey,TValue> contains key-value pairs.

SortedList stores key and value pairs. It automatically adds the elements
SortedList<TKey,TValue>
in ascending order of key by default.

Hashset<T> contains non-duplicate elements. It eliminates duplicate


Hashset<T>
elements.

Queue<T> stores the values in FIFO style (First In First Out). It keeps the
order in which the values were added. It provides an Enqueue() method
Queue<T>
to add values and a Dequeue() method to retrieve values from the
collection.

Stack<T> stores the values as LIFO (Last In First Out). It provides a Push()
Stack<T>
method to add a value and Pop() & Peek() methods to retrieve values.

A generic collection gets all the benefit of generics. It doesn't need to do boxing and
unboxing while storing or retrieving items and so performance is improved.

Learn generic collectoin List<T> in the next section.

C# - Generic List<T>
You have already learned about ArrayList in the previous section. An ArrayList resizes
automatically as it grows. The List<T> collection is the same as an ArrayList except that
List<T> is a generic collection whereas ArrayList is a non-generic collection.

List<T> can be initialized in the following two ways.

Example: Generic List<T> Initialization


List<int> intList = new List<int>();

//Or

IList<int> intList = new List<int>();

In the above example, the first statement uses List type variable, whereas the second
statement uses IList type variable to initialize List. List<T> is a concreate implementation
of IList<T> interface. In the object-oriented programming, it is advisable to program to
interface rather than concreate class. So use IList<T> type variable to create an object of
List<T>.

List<T> includes more helper methods than IList<T> interface. The table shown below
lists important properties and methods of List<T>, which are initialized using a List<T>:

Property Usage

Items Gets or sets the element at the specified index

Count Returns the total number of elements exists in the List<T>

Method Usage

Add Adds an element at the end of a List<T>.

AddRange Adds elements of the specified collection at the end of a List<T>.

BinarySearch Search the element and returns an index of the element.

Clear Removes all the elements from a List<T>.

Contains Checks whether the speciied element exists or not in a List<T>.

Find Finds the first element based on the specified predicate function.

Foreach Iterates through a List<T>.

Insert Inserts an element at the specified index in a List<T>.

InsertRange Inserts elements of another collection at the specified index.

Remove Removes the first occurence of the specified element.

RemoveAt Removes the element at the specified index.

Removes all the elements that match with the supplied predicate
RemoveRange
function.

Sort Sorts all the elements.

TrimExcess Sets the capacity to the actual number of elements.


Property Usage

Determines whether every element in the List<T> matches the


TrueForAll
conditions defined by the specified predicate.

Add Elements into List

Use the Add() method to add an element into a List collection. The following example adds
int value into a List<T> of int type.

Add() signature: void Add(T item)

Example: Adding elements into List


IList<int> intList = new List<int>();
intList.Add(10);
intList.Add(20);
intList.Add(30);
intList.Add(40);

IList<string> strList = new List<string>();


strList.Add("one");
strList.Add("two");
strList.Add("three");
strList.Add("four");
strList.Add("four");
strList.Add(null);
strList.Add(null);

IList<Student> studentList = new List<Student>();


studentList.Add(new Student());
studentList.Add(new Student());
studentList.Add(new Student());

You can also add elements at the time of initialization using object initializer syntax as
below:

Example: Add elements using object initializer syntax


IList<int> intList = new List<int>(){ 10, 20, 30, 40 };

//Or

IList<Student> studentList = new List<Student>() {


new Student(){ StudentID=1, StudentName="Bill"},
new Student(){ StudentID=2, StudentName="Steve"},
new Student(){ StudentID=3, StudentName="Ram"},
new Student(){ StudentID=1, StudentName="Moin"}
};

AddRange()
The AddRange() method adds all the elements from another collection.

AddRange() signature: void AddRange(IEnumerable<T> collection)

Example: AddRange
IList<int> intList1 = new List<int>();
intList1.Add(10);
intList1.Add(20);
intList1.Add(30);
intList1.Add(40);

List<int> intList2 = new List<int>();

intList2.AddRange(intList1);
 

Note : The AddRange() method will only be applicable if you initialized with a List<T> variable.
IList<T> doesn't include the AddRange() method.

Accessing List

Use a foreach or for loop to iterate a List<T> collection.

Example: Accessing List


List<int> intList = new List<int>() { 10, 20, 30 };

intList.ForEach(el => Console.WriteLine(el));

If you have initialized the List<T> with an IList<T> interface then use seperate foreach
statement with implicitly typed variable:

Example: Accessing List


IList<int> intList = new List<int>() { 10, 20, 30, 40 };

foreach (var el in intList)


Console.WriteLine(el);
Output:
10
20
30
40

Access individual items by using an indexer (i.e., passing an index in square brackets):

Example: Accessing List


IList<int> intList = new List<int>() { 10, 20, 30, 40 };
int elem = intList[1]; // returns 20

Use the Count property to get the total number of elements in the List.

Example: Access List elements


IList<int> intList = new List<int>() { 10, 20, 30, 40 };

Console.Write("Total elements: {0}", intList.Count);


Output:
Total elements: 4

Use for loop to access list as shown below:

Example: Accessing List using for loop example:


IList<int> intList = new List<int>() { 10, 20, 30, 40 };

for (int i = 0; i < intList.Count; i++)


Console.WriteLine(intList[i]);
Output:
10
20
30
40

List<T> implements IList<T>, so List<T> implicitly type cast to IList<T>.

Example: Access List


static void Print(IList<string> list)
{
Console.WriteLine("Count: {0}", list.Count);
foreach (string value in list)
{
Console.WriteLine(value);
}
}

static void Main(string[] args)


{

string[] strArray = new string[2];


strArray[0] = "Hello";
strArray[1] = "World";
Print(strArray);

List<string> strList = new List<string>();


strList.Add("Hello");
strList.Add("World");
Print(strList);
}
Output:
Hello
World
Hello
World

Insert Elements into List

The Insert() method inserts an element into a List<T> collection at the specified index.

Insert() signature:void Insert(int index, T item);

Example: Insert elements into List


IList<int> intList = new List<int>(){ 10, 20, 30, 40 };

intList.Insert(1, 11);// inserts 11 at 1st index: after 10.

foreach (var el in intList)


Console.Write(el);
Output:
10
11
20
30
40

Remove Elements from List

The Remove() and RemoveAt() methods remove items from a List<T> collection.

Remove() signature: bool Remove(T item)

RemoveAt() signature: void RemoveAt(int index)

Example: Remove elements from List


IList<int> intList = new List<int>(){ 10, 20, 30, 40 };

intList.Remove(10); // removes the 10 from a list

intList.RemoveAt(2); //removes the 3rd element (index starts from 0)

foreach (var el in intList)


Console.Write(el);
Output:
20
30
TrueForAll()

TrueForAll() is a method of the List<T> class. It returns true if the specified condition turns
out to be true, otherwise false. Here, the condition can be specified as a predicate type
deligate or lambda expression.

TrueForAll() signature: bool TrueForAll(Predicate<T> match)

Example: TrueForAll()
List<int> intList = new List<int>(){ 10, 20, 30, 40 };

bool res = intList.TrueForAll(el => el%2 == 0);// returns true

The following example uses isPositiveInt() as a Predicate<int> type delegate as a parameter


to TrueForAll.

Example: TrueForAll()
static bool isPositiveInt(int i)
{
return i > 0;
}

static void Main(string[] args)


{
List<int> intList = new List<int>(){10, 20, 30, 40};

bool res = intList.TrueForAll(isPositiveInt);

Visit MSDN to for more information on the methods & properties of IList<T> or List<T>.

Points to Remember :

1. List<T> stores elements of the specified type and it grows automatically.


2. List<T> can store multiple null and duplicate elements.
3. List<T> can be assigned to IList<T> or List<T> type of variable. It provides more helper
method When assigned to List<T> variable
4. List<T> can be access using indexer, for loop or foreach statement.
5. LINQ can be use to query List<T> collection.
6. List<T> is ideal for storing and retrieving large number of elements.

C# - Generic SortedList
A generic SortedList SortedList<TKey,TValue> represents a collection of key-value pairs
that are sorted by key based on associated IComparer<T> A SortedList collection stores
key and value pairs in ascending order of key by default. Generic SortedList implements
IDictionary<TKey,TValue> & ICollection<KeyValuePair<TKey,TValue>> interfaces
so elements can be access by key and index both.

C# includes two type of SortedList, generic SortedList and non-generic SortedList. Generic
SortedList denotes with angel bracket: SortedList<TKey,TValue> where TKey is for type
of key and TValue is for type of value. Non-generic type do not specify the type of key and
values.

Internally, SortedList maintains a two object[] array, one for keys and another for values.
So when you add key-value pair, it does binary search using key to find an appropriate
index to store a key and value in respective arrays. It also re-arranges the elements when
you remove the elements from it.

Initialize Generic SortedList:

You can initialize generic SortedList by specifying type for key and value as shown below.

Example: Initialize Generic SortedList


SortedList<int,string> mySortedList = new SortedList<int,string>();

In the above example, mySortedList will store key of int type and value (element) of string
type.

Important Properties and Methods of Generic SortedList


Property Description

Capacity Gets or sets the number of elements that the SortedList<TKey,TValue> can store.

Count Gets the total number of elements exists in the SortedList<TKey,TValue>.

IsReadOnly Returns a boolean indicating whether the SortedList<TKey,TValue> is read-only.

Item Gets or sets the element with the specified key in the SortedList<TKey,TValue>.

Keys Get list of keys of SortedList<TKey,TValue>.

Values Get list of values in SortedList<TKey,TValue>.

Method Description

Add Add key-value pairs into SortedList<TKey, TValue>.

Remove Removes element with the specified key.

RemoveAt Removes element at the specified index.


Property Description

ContainsKey Checks whether the specified key exists in SortedList<TKey, TValue>.

ContainsValue Checks whether the specified key exists in SortedList<TKey, TValue>.

Clear Removes all the elements from SortedList<TKey, TValue>.

Returns an index of specified key stored in internal array of SortedList<TKey,


IndexOfKey
TValue>.

Returns an index of specified value stored in internal array of SortedList<TKey,


IndexOfValue
TValue>

Returns true and assigns the value with specified key, if key does not exists then
TryGetValue
return false.

Add Elements into SortedList

Use the Add() method to add key value pairs into a SortedList. The key cannot be null, but
the value can be null. Also, the datatype of key and value must be same as specified,
otherwise it will give compile time error.

Add() method signature: void Add(TKey key, TValue value)

The following example shows how to add key-value pair in the generic SortedList
collection.

Example:Add Elements into SortedList<TKey, TValue>


SortedList<int,string> sortedList1 = new SortedList<int,string>();
sortedList1.Add(3, "Three");
sortedList1.Add(4, "Four");
sortedList1.Add(1, "One");
sortedList1.Add(5, "Five");
sortedList1.Add(2, "Two");

SortedList<string,int> sortedList2 = new SortedList<string,int>();


sortedList2.Add("one", 1);
sortedList2.Add("two", 2);
sortedList2.Add("three", 3);
sortedList2.Add("four", 4);
// Compile time error: cannot convert from <null> to <int>
// sortedList2.Add("Five", null);

SortedList<double,int?> sortedList3 = new SortedList<double,int?>();


sortedList3.Add(1.5, 100);
sortedList3.Add(3.5, 200);
sortedList3.Add(2.4, 300);
sortedList3.Add(2.3, null);
sortedList3.Add(1.1, null);
SortedList collection sorts the elements everytime you add the elements. So if you debug
the above example, you will keys in ascending order even if they are added randomly. The
following image shows SortedList in debug view.

SortedList<TKey, TValue> in debug view

As you can see in the above image, sortedList1 stores key-value pairs in ascending order of
key and sortedList2 stores items in alphabetical order of key even if they are not added in
that ordered. sortedList3 includes nullable int so that it includes null as a value.

Accessing Generic SortedList

The SortedList can be accessed by the index or key. Unlike other collection types, Indexer
of SortedList requires key and returns value for that key. However, please make sure that
key exists in the SortedList, otherwise it will throw KeyNotFoundException.

Example: Access SortedList<TKey, TValue> using indexer


SortedList<string,int> sortedList2 = new SortedList<string,int>();
sortedList2.Add("one", 1);
sortedList2.Add("two", 2);
sortedList2.Add("three", 3);
sortedList2.Add("four", 4);

Console.WriteLine(sortedList2["one"]);
Console.WriteLine(sortedList2["two"]);
Console.WriteLine(sortedList2["three"]);

//Following will throw runtime exception: KeyNotFoundException


Console.WriteLine(sortedList2["ten"]);
Output:
1
2
3

Keys and Values indexers can use the access key and value of SortedList using for loop as
shown below:

Example: Access Key and Value using indexer


SortedList<string,int> sortedList2 = new SortedList<string,int>();
sortedList2.Add("one", 1);
sortedList2.Add("two", 2);
sortedList2.Add("three", 3);
sortedList2.Add("four", 4);

for (int i = 0; i < sortedList2.Count; i++)


{
Console.WriteLine("key: {0}, value: {1}",
sortedList2.Keys[i], sortedList2.Values[i]);
}
Output:
key: four, value: 4
key: one, value: 1
key: three, value: 3
key: two, value: 2

Accessing Elements using foreach loop

The foreach statement in C# can be used to access the SortedList collection. SortedList
element includes both key and value pair. so, the type of element would be KeyValuePair
structure rather than type of key or value.

foreach statement to access generic SortedList:


SortedList<string,int> sortedList2 = new SortedList<string,int>();
sortedList2.Add("one", 1);
sortedList2.Add("two", 2);
sortedList2.Add("three", 3);
sortedList2.Add("four", 4);

foreach(KeyValuePair<string,int> kvp in sortedList2 )


Console.WriteLine("key: {0}, value: {1}", kvp.Key , kvp.Value );
Output:
key: four, value: 4
key: one, value: 1
key: three, value: 3
key: two, value: 2

Accessing key

If you are not sure that particular key exists or not than use TryGetValue method to retrieve
the value of specified key. If key doesn't exists than it will return false instead of throwing
exception.

Example: TryGetValue
SortedList<string,int> sortedList2 = new SortedList<string,int>();
sortedList2.Add("one", 1);
sortedList2.Add("two", 2);
sortedList2.Add("three", 3);
sortedList2.Add("four", 4);

int val;

if (sortedList2.TryGetValue("ten",out val))
Console.WriteLine("value: {0}", val);
else
Console.WriteLine("Key is not valid.");

if (sortedList2.TryGetValue("one",out val))
Console.WriteLine("value: {0}", val);
Output:
Key is not valid.
value: 1

Remove Elements from Generic SortedList

Use the Remove(key) and RemoveAt(index) methods to remove values from a SortedList.

Remove() signature: bool Remove(TKey key)

RemoveAt() signature: void RemoveAt(int index)

Example: Remove Elements


SortedList<string,int> sortedList2 = new SortedList<string,int>();
sortedList2.Add("one", 1);
sortedList2.Add("two", 2);
sortedList2.Add("three", 3);
sortedList2.Add("four", 4);

sortedList2.Remove("one");//removes the element whose key is 'one'


sortedList2.RemoveAt(0);//removes the element at zero index i.e first
element: four
foreach(KeyValuePair<string,int> kvp in sortedList2 )
Console.WriteLine("key: {0}, value: {1}", kvp.Key , kvp.Value );
Output:
key: three, value: 3
key: two, value: 2

ContainsKey() and ContainsValue()

The ContainsKey() checks whether the specified key exists in the SortedList or not.

ContainsKey() signature: bool ContainsKey(object key)

The ContainsValue() method determines whether the specified value exists in the
SortedList or not.

ContainValue() signature: bool ContainValue(object value)

Example: Contain()
SortedList<string,int> sortedList = new SortedList<string,int>();
sortedList.Add("one", 1);
sortedList.Add("two", 2);
sortedList.Add("three", 3);
sortedList.Add("four", 4);
sortedList.Add("five", 5);

sortedList.ContainsKey("One"); // returns true


sortedList.ContainsKey("Ten"); // returns false

sortedList.ContainsValue(2); // returns true


sortedList.ContainsValue(6); // returns false
Accessing SortedList using LINQ

You can use LINQ query syntax or method syntax to access SortedList collection using
different criterias.

Example: Access SortedList using LINQ Method Syntax


SortedList<string,int> sortedList = new SortedList<string,int>();
sortedList.Add("one", 1);
sortedList.Add("two", 2);
sortedList.Add("three", 3);
sortedList.Add("four", 4);
sortedList.Add("five", 5);

var result = sortedList.Where(kvp => kvp.Key == "two").FirstOrDefault();

Console.WriteLine("key: {0}, value: {1}", result.Key, result.Value);


Example: Accessing Generic SortedList using LINQ Query Syntax
SortedList<string,int> sortedList = new SortedList<string,int>();
sortedList.Add("one", 1);
sortedList.Add("two", 2);
sortedList.Add("three", 3);
sortedList.Add("four", 4);
sortedList.Add("five", 5);

var query = from kvp in sortedList


where kvp.Key == "two"
select kvp;

var result = query.FirstOrDefault();

Console.WriteLine("key: {0}, value: {1}", result.Key, result.Value);


Output:
key: two, value: 2

Points to Remember :

1. C# has a generic and non-generic SortedList.


2. SortedList stores the key-value pairs in ascending order of the key. The key must be
unique and cannot be null whereas value can be null or duplicate.
3. Generic SortedList stores keys and values of specified data types. So no need for casting.
4. Key-value pair can be cast to a KeyValuePair<TKey,TValue>.
5. An individual value can be accessed using an indexer. SortedList indexer accepts key to
return value associated with it.

Further Reading

 Sort the SortedList in descending order.


 Properties and methods of SortedList<TKey,TValue> .

C# - Dictionary
Dictionary in C# is same as English dictionary. English dictionary is a collection of words
and their definitions, often listed alphabetically in one or more specific languages. In the
same way, the Dictionary in C# is a collection of Keys and Values, where key is like word
and value is like definition.

Every class includes System.Collection.Generics namespace by default while creating a


new class in visual studio.
Dictionary<TKey, TValue> is a generic collection included in the
System.Collection.Generics namespace. TKey denotes the type of key and TValue is the
type of TValue.

Dictionary Initialization

A Dictionary can be initialized with a variable of IDictionary<Tkey, TValue> interface


as well as with a Dictionary<TKey, Tvalue> class:

Example: Dictionary Initialization


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

//or

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

In the above example, we have specified types of key and value while declaring a
dictionary object. An int is a type of key and string is a type of value that will be stored into
a dictionary object named dict. You can use any valid C# data type for keys and values.

It is recommended to program to the interface rather than to the class. So, use
IDictionary<TKey, TValue> type variable to initialize a dictionary object.

Note:

Dictionary cannot include duplicate or null keys, where as values can be duplicated or set as null.
Keys must be unique otherwise it will throw a runtime exception.

Important Properties and Methods of IDictionary


Property Description

Count Gets the total number of elements exists in the Dictionary<TKey,TValue>.

IsReadOnly Returns a boolean indicating whether the Dictionary<TKey,TValue> is read-only.

Item Gets or sets the element with the specified key in the Dictionary<TKey,TValue>.

Keys Returns collection of keys of Dictionary<TKey,TValue>.

Values Returns collection of values in Dictionary<TKey,TValue>.

Method Description

Add Adds an item to the Dictionary collection.

Add Add key-value pairs in Dictionary<TKey, TValue> collection.

Remove Removes the first occurance of specified item from the Dictionary<TKey, TValue>.

Remove Removes the element with the specified key.


Property Description

ContainsKey Checks whether the specified key exists in Dictionary<TKey, TValue>.

ContainsValue Checks whether the specified key exists in Dictionary<TKey, TValue>.

Clear Removes all the elements from Dictionary<TKey, TValue>.

Returns true and assigns the value with specified key, if key does not exists then
TryGetValue
return false.

Add Elements into Dictionary

Use Add() method to add the key-value pair in dictionary.

Add() Signature: void Add(TKey, Tvalue)

Example: Add elements in dictionary


IDictionary<int, string> dict = new Dictionary<int, string>();
dict.Add(1,"One");
dict.Add(2,"Two");
dict.Add(3,"Three");

Check whether a dictionary already stores specified key before adding a key-value pair.

The IDictionary type instance has one more overload for the Add() method. It accepts a
KeyValuePair<TKey, TValue> struct as a parameter.

Add() Signature:void Add(KeyValuePair<TKey,TValue> item);

Example: Add key-value pair in dictionary


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

dict.Add(new KeyValuePair<int, string>(1, "One"));


dict.Add(new KeyValuePair<int, string>(2, "Two"));

//The following is also valid


dict.Add(3, "Three");

It can also be initialized using collecton initializer syntax with keys and values as shown
below.

Example: Dictionary Initialization


IDictionary<int, string> dict = new Dictionary<int, string>()
{
{1,"One"},
{2, "Two"},
{3,"Three"}
};
Accessing Dictionary Elements

Dictionary elements can be accessed by many ways e.g. foreach, for loop or indexer.

Use foreach or for loop to iterate access all the elements of dictionary. The dictionary stores
key-value pairs. So you can use a KeyValuePair<TKey, TValue> type or an implicitly
typed variable var in foreach loop as shown below.

Example: Access elements using foreach


Dictionary<int, string> dict = new Dictionary<int, string>()
{
{1,"One"},
{2, "Two"},
{3,"Three"}
};

foreach (KeyValuePair<int, string> item in dict)


{
Console.WriteLine("Key: {0}, Value: {1}", item.Key, item.Value);
}
Output:
Key: 1, Value: One
Key: 2, Value: Two
Key: 3, Value: Three

Use for loop to access all the elements. Use Count property of dictionary to get the total
number of elements in the dictionary.

Example: Access Elements using for Loop


Dictionary<int, string> dict = new Dictionary<int, string>()
{
{1,"One"},
{2, "Two"},
{3,"Three"}
};

for (int i = 0; i < dict.Count; i++)


{
Console.WriteLine("Key: {0}, Value: {1}",
dict.Keys.ElementAt(i),

dict[ dict.Keys.ElementAt(i)]);
}
Output:
Key: 1, Value: One
Key: 2, Value: Two
Key: 3, Value: Three

Dictionary can be used like an array to access its individual elements. Specify key (not
index) to get a value from a dictionary using indexer like an array.

Example: Access Individual Element


Dictionary<int, string> dict = new Dictionary<int, string>()
{
{1,"One"},
{2, "Two"},
{3,"Three"}
};

Console.WriteLine(dict[1]); //returns One


Console.WriteLine(dict[2]); // returns Two
Output:
One
Two

Note:

Indexer takes the key as a parameter. If the specified key does not exist then a
KeyNotFoundException will be thrown.

If you are not sure about the key then use the TryGetValue() method. The TryGetValue()
method will return false if it could not found keys instead of throwing an exception.

TryGetValue() Signature: bool TryGetValue(TKey key, out TValue value)

Example: TryGetValue()
Dictionary<int, string> dict = new Dictionary<int, string>()
{
{1,"One"},
{2, "Two"},
{3,"Three"}
};

string result;

if(dict.TryGetValue(4, out result))


{
Console.WriteLine(result);
}
else
{
Console.WriteLine("Could not find the specified key.");
}
Output:
Could not find the specified key.

Check for an Existing Elements

Dictionary includes various methods to determine whether a dictionary contains specified


elements or keys. Use the ContainsKey() method to check whether a specified key exists in
the dictionary or not.

Use the Contains() method to check whether a specified Key and Value pair exists in the
dictionary or not.

ContainsKey() Signature: bool ContainsKey(TKey key)

Contains() signature: bool Contains(KeyValuePair<TKey, TValue> item)

Example: ContainsKey() & Contains()


Dictionary<int, string> dict = new Dictionary<int, string>()
{
{1,"One"},
{2, "Two"},
{3,"Three"}
};
dict.ContainsKey(1); // returns true
dict.ContainsKey(4); // returns false

dict.Contains(new KeyValuePair<int,string>(1,"One")); // returns true

Another overload of the Contains() method takes IEqualityComperer as a second


parameter. An instance of IEqualityComparer is used when you want to customize the
equality comparison. For example, consider the following example of a dictionary that
stores a Student objects.

Example: Custom Comparer


public class Student
{
public int StudentID { get; set; }
public string StudentName { get; set; }
}

class StudentDictionaryComparer :
IEqualityComparer<KeyValuePair<int,Student>>
{
public bool Equals(KeyValuePair<int, Student> x, KeyValuePair<int,
Student> y)
{
if (x.Key == y.Key && (x.Value.StudentID == y.Value.StudentID) &&
(x.Value.StudentName == y.Value.StudentName))
return true;

return false;
}

public int GetHashCode(KeyValuePair<int, Student> obj)


{
return obj.Key.GetHashCode();
}
}

class Program
{
static void Main(string[] args)
{
IDictionary<int, Student> studentDict = new Dictionary<int,
Student>()
{
{ 1, new Student(){ StudentID =1, StudentName =
"Bill"}},
{ 2, new Student(){ StudentID =2, StudentName =
"Steve"}},
{ 3, new Student(){ StudentID =3, StudentName =
"Ram"}}
};

Student std = new Student(){ StudentID = 1, StudentName =


"Bill"};

KeyValuePair<int, Student> elementToFind = new KeyValuePair<int,


Student>(1, std);

bool result = studentDict.Contains(elementToFind, new


StudentDictionaryComparer()); // returns true

Console.WriteLine(result);
}
}
Output:
true

In the above example, we have used StudentDictionaryComparer which derives


IEqualityComparer to compare Student objects in the dictionary. The default comparer will
only work with primitive data types.

Remove Elements in Dictionary

Use the Remove() method to remove an existing item from the dictionary. Remove() has
two overloads, one overload method accepts a key and the other overload method accepts a
KeyValuePair<> as a parameter.

Remove() signature:

 bool Remove(TKey key)


 bool Remove(KeyValuePair<TKey,TValue>)
Example: Remove elements from Dictionary
Dictionary<int, string> dict = new Dictionary<int, string>()
{
{1,"One"},
{2, "Two"},
{3,"Three"}
};

dict.Remove(1); // removes the item which has 1 as a key

Both Key and Value must match to remove an item. The item will not be removed if both
are not matched. For example, the following example will not remove any item:

// removes nothing because value One1 is not matching


dict.Remove(new KeyValuePair<int, string>(2, "Two1"));

Points to Remember :

1. A Dictionary stores Key-Value pairs where the key must be unique.


2. Before adding a KeyValuePair into a dictionary, check that the key does not exist using the
ContainsKey() method.
3. Use the TryGetValue() method to get the value of a key to avoid possible runtime
exceptions.
4. Use a foreach or for loop to iterate a dictionary.
5. Use dictionary indexer to access individual item.
6. Use custom class that derives IEqualityComparer to compare object of custom class with
Contains() method.

C# - Partial Class
Each class in C# resides in a separate physical file with a .cs extension. C# provides the
ability to have a single class implementation in multiple .cs files using the partial modifier
keyword. The partial modifier can be applied to a class, method, interface or structure.

For example, the following MyPartialClass splits into two files, PartialClassFile1.cs and
PartialClassFile2.cs:

Example: PartialClassFile1.cs
public partial class MyPartialClass
{
public MyPartialClass()
{
}

public void Method1(int val)


{
Console.WriteLine(val);
}
}
Example: PartialClassFile2.cs
public partial class MyPartialClass
{
public void Method2(int val)
{
Console.WriteLine(val);
}
}

MyPartialClass in PartialClassFile1.cs defines the constructor and one public method,


Method1, whereas PartialClassFile2 has only one public method, Method2. The compiler
combines these two partial classes into one class as below:

Example: Partial class


public class MyPartialClass
{
public MyPartialClass()
{
}

public void Method1(int val)


{
Console.WriteLine(val);
}

public void Method2(int val)


{
Console.WriteLine(val);
}
}

Partial Class Requirements:

 All the partial class definitions must be in the same assembly and namespace.
 All the parts must have the same accessibility like public or private, etc.
 If any part is declared abstract, sealed or base type then the whole class is declared of the
same type.
 Different parts can have different base types and so the final class will inherit all the base
types.
 The Partial modifier can only appear immediately before the keywords class, struct,
or interface.
 Nested partial types are allowed.

Advantages of Partial Class

 Multiple developers can work simultaneously with a single class in separate files.
 When working with automatically generated source, code can be added to the class
without having to recreate the source file. For example, Visual Studio separates HTML
code for the UI and server side code into two separate files: .aspx and .cs files.

Partial Methods

A partial class or struct may contain partial methods. A partial method must be declared in
one of the partial classes. A partial method may or may not have an implementation. If the
partial method doesn't have an implementation in any part then the compiler will not
generate that method in the final class. For example, consider the following partial method
with a partial keyword:

Example: PartialClassFile1.cs:
public partial class MyPartialClass
{
partial void PartialMethod(int val);

public MyPartialClass()
{

public void Method2(int val)


{
Console.WriteLine(val);
}
}
Example: PartialClassFile2.cs:
public partial class MyPartialClass
{
public void Method1(int val)
{
Console.WriteLine(val);
}

partial void PartialMethod(int val)


{
Console.WriteLine(val);
}
}

PartialClassFile1.cs contains the declaration of the partial method and PartialClassFile2.cs


contains the implementation of the partial method.

Requirements for Partial Method

 The partial method declaration must began with the partial modifier.
 The partial method can have a ref but not an out parameter.
 Partial methods are implicitly private methods.
 Partial methods can be static methods.
 Partial methods can be generic.

The following image illustrates partial class and partial method:

Partial Method

The compiler combines the two partial classes into a single final class:
Partial
Class

Points to Remember :

1. Use the partial keyword to split interface, class, method or structure into multiple .cs files.
2. The partial method must be declared before implementation.
3. All the partial class, method , interface or structs must have the same access modifiers.

C# - Static
C# includes static keyword just like other programming languages such as C++, Java,
etc. The static keyword can be applied on classes, variables, methods, properties,
operators, events and constructors. However, it cannot be used with indexers, destructors or
types other than classes.
The static modifier makes an item non-instantiable, it means the static item cannot be
instantiated. If the static modifier is applied to a class then that class cannot be instantiated
using the new keyword. If the static modifier is applied to a variable, method or property of
class then they can be accessed without creating an object of the class, just use
className.propertyName, className.methodName.

Example: C# Static class


public static class MyStaticClass
{
public static int myStaticVariable = 0;

public static void MyStaticMethod()


{
Console.WriteLine("This is a static method.");
}

public static int MyStaticProperty { get; set; }


}

class Program
{
static void Main(string[] args)
{

Console.WriteLine(MyStaticClass.myStaticVariable);

MyStaticClass.MyStaticMethod();

MyStaticClass.MyStaticProperty = 100;

Console.WriteLine(MyStaticClass.MyStaticProperty);
}
}
Output:
0
This is a static method.
100

In the above example, MyStaticClass is a static class with static variable, method and
property. All the static members can be access using className without creating an object
of a class e.g. MyStaticClass.MyStaticMethod().

Static method can only access other static items.

It is also possible to have static members in non-static classes just like a normal class. You
can instantiate non static classes using the new keyword as usual. However, the instance
variable can only access the non-static methods and variables, it cannot access the static
methods and variables.
For example, consider the following myNonStaticClass with mix of static and non-static
methods:

Example: Static members in non-static class


public class MyNonStaticClass
{
private static int myStaticVariable = 0;

public static void MyStaticMethod()


{
Console.WriteLine("This is static method.");
}

public void myNonStaticMethod()


{
Console.WriteLine("Non-static method");
}
}

In the above example, MyNonStaticClass can be instantiated and access the non-static
members. However, you cannot access static members. The following figure shows the
debug view.

Non-Static method

C# Static Constructor

A static or non-static class can have a static constructor without any access modifiers like
public, private, protected, etc.

A static constructor in a non-static class runs only once when the class is instantiated for the
first time.

A static constructor in a static class runs only once when any of its static members accessed
for the first time.

Example: Static Constructor in Static Class


public static class MyStaticClass
{
static MyStaticClass()
{
Console.WriteLine("Inside static constructor.");
}
public static int myStaticVariable = 0;

public static void myStaticMethod()


{
Console.WriteLine("This is static method.");
}

public static int MyStaticProperty { get; set; }

class Program
{

static void Main(string[] args)


{

MyStaticClass.myStaticVariable = 100;

MyStaticClass.MyStaticProperty = 200;

MyStaticClass.myStaticVariable = 300;

MyStaticClass.MyStaticProperty = 400;

}
}
Output:
Inside static constructor.

In the above example, the static members was accessed multiple times. However, static
constructor got called only once when any of its static members was accessed for the first
time.

Example: Static constructor in a non-static class


public class MyNonStaticClass
{
static MyNonStaticClass()
{
Console.WriteLine("Inside static constructor.");
}

public void myNonStaticMethod()


{
Console.WriteLine("Non-static method");
}
}

class Program
{
static void Main(string[] args)
{
MyNonStaticClass mnsObj1 = new MyNonStaticClass();
MyNonStaticClass mnsObj2 = new MyNonStaticClass();
MyNonStaticClass mnsObj3 = new MyNonStaticClass();
}
}
Output:
Inside static constructor

In the above example, we instantiate MyNonStaticClass three times but the static
constructor got called only once when it instantiated for the first time.

Memory Allocation for Static Items

As you know, the main parts of an application's memory are stack and heap. Static
members are stored in a special area inside the heap called High Frequency Heap. Static
members of non-static classes are also stored in the heap and shared across all the instances
of the class. So the changes done by one instance will be reflected in all the other instances.

As mentioned earlier, a static member can only contain or access other static members,
because static members are invoked without creating an instance and so they cannot access
non-static members.

The following image illustrates how static members are stored in memory:

Memory allocation for Static fields

Points to Remember :

1. Static classes cannot be instantiated using the new keyword


2. Static items can only access other static items. For example, a static class can only contain
static members, e.g., variables, methods, etc. A static method can only contain static
variables and can only access other static items.
3. Static items share the resources between multiple users.
4. Static cannot be used with indexers, destructors or types other than classes.
5. A static constructor in a non-static class runs only once when the class is instantiated for
the first time.
6. A static constructor in a static class runs only once when any of its static members
accessed for the first time.
7. Static members are allocated in high frequency heap area of the memory.

C# - Anonymous Method
As the name suggests, an anonymous method is a method without a name. Anonymous
methods in C# can be defined using the delegate keyword and can be assigned to a variable
of delegate type.

Example: Anonymous Method


public delegate void Print(int value);

static void Main(string[] args)


{
Print print = delegate(int val) {
Console.WriteLine("Inside Anonymous method. Value: {0}",
val);
};

print(100);
}
Output:
Inside Anonymous method. Value: 100

Anonymous methods can access variables defined in an outer function.

Example: Anonymous Method


public delegate void Print(int value);

static void Main(string[] args)


{
int i = 10;

Print prnt = delegate(int val) {


val += i;
Console.WriteLine("Anonymous method: {0}", val);
};
prnt(100);
}
Output:
Anonymous method: 110

Anonymous methods can also be passed to a method that accepts the delegate as a
parameter.

In the following example, PrintHelperMethod() takes the first parameters of the Print
delegate:

Example: Anonymous Method as Parameter


public delegate void Print(int value);

class Program
{
public static void PrintHelperMethod(Print printDel,int
val)
{
val += 10;
printDel(val);
}

static void Main(string[] args)


{
PrintHelperMethod(delegate(int val)
{ Console.WriteLine("Anonymous method: {0}", val); }, 100);
}
}
Output:
Anonymous method: 110

Anonymous methods can be used as event handlers:

Example: Anonymous Method as Event Handler


saveButton.Click += delegate(Object o, EventArgs e)
{
System.Windows.Forms.MessageBox.Show("Save
Successfully!");
};

C# 3.0 introduced the lambda expression which also works like an anonymous method.

Anonymous Method Limitations

 It cannot contain jump statement like goto, break or continue.


 It cannot access ref or out parameter of an outer method.
 It cannot have or access unsafe code.
 It cannot be used on the left side of the is operator.

Points to Remember :

1. Anonymous method can be defined using the delegate keyword


2. Anonymous method must be assigned to a delegate.
3. Anonymous method can access outer variables or functions.
4. Anonymous method can be passed as a parameter.
5. Anonymous method can be used as event handlers.

Nullable Type in C#
As you know, a value type cannot be assigned a null value. For example, int i = null will
give you a compile time error.

C# 2.0 introduced nullable types that allow you to assign null to value type variables. You
can declare nullable types using Nullable<t> where T is a type.

Example: Nullable type


Nullable<int> i = null;

A nullable type can represent the correct range of values for its underlying value type, plus
an additional null value. For example, Nullable<int> can be assigned any value from -
2147483648 to 2147483647, or a null value.

The Nullable types are instances of System.Nullable<T> struct. Think it as something like
the following structure.

Example: Nullable struct


[Serializable]
public struct Nullable<T> where T : struct
{
public bool HasValue { get; }

public T Value { get; }

// other implementation
}

A nullable of type int is the same as an ordinary int plus a flag that says whether the int has
a value or not (is null or not). All the rest is compiler magic that treats "null" as a valid
value.
Example: HasValue
static void Main(string[] args)
{
Nullable<int> i = null;

if (i.HasValue)
Console.WriteLine(i.Value); // or Console.WriteLine(i)
else
Console.WriteLine("Null");
}
Output:
Null

The HasValue returns true if the object has been assigned a value; if it has not been
assigned any value or has been assigned a null value, it will return false.

Accessing the value using NullableType.value will throw a runtime exception if nullable
type is null or not assigned any value. For example, i.Value will throw an exception if i is
null:

In
valid use of Nullable Type

Use the GetValueOrDefault() method to get an actual value if it is not null and the default
value if it is null. For example:

Example: GetValueOrDefault()
static void Main(string[] args)
{
Nullable<int> i = null;

Console.WriteLine(i.GetValueOrDefault());
}
Shorthand Syntax for Nullable Types

You can use the '?' operator to shorthand the syntax e.g. int?, long? instead of using
Nullable<T>.

Example: Shorthand syntax for Nullable types


int? i = null;
double? D = null;

?? Operator

Use the '??' operator to assign a nullable type to a non-nullable type.

Example: ?? operator with Nullable Type


int? i = null;

int j = i ?? 0;

Console.WriteLine(j);
Output:
0

In the above example, i is a nullable int and if you assign it to the non-nullable int j then it
will throw a runtime exception if i is null. So to mitigate the risk of an exception, we have
used the '??' operator to specify that if i is null then assign 0 to j.

Assignment Rules

A nullable type has the same assignment rules as a value type. It must be assigned a value
before using it if nullable types are declared in a function as local variables. If it is a field of
any class then it will have a null value by default.

For example, the following nullable of int type is declared and used without assigning any
value. The compiler will give "Use of unassigned local variable 'i'" error:

Unassigned
nullable type-error

In the following example, a nullable of int type is a field of the class, so it will not give any
error.

Example: Nullable type as Class Field


class MyClass
{
public Nullable<int> i;
}
class Program
{
static void Main(string[] args)
{
MyClass mycls = new MyClass();

if(mycls.i == null)
Console.WriteLine("Null");
}
}
Output:
Null

Nullable Helper Class

Null is considered to be less than any value. So comparison operators won't work against
null. Consider the following example where i is neither less than j, greater than j nor equal
to j:

Example: Nullable Type Comparison


static void Main(string[] args)
{
int? i = null;
int j = 10;

if (i < j)
Console.WriteLine("i < j");
else if( i > 10)
Console.WriteLine("i > j");
else if( i == 10)
Console.WriteLine("i == j");
else
Console.WriteLine("Could not compare");
}
Output:
Could not compare

Nullable static class is a helper class for Nullable types. It provides a compare method to
compare nullable types. It also has a GetUnderlyingType method that returns the
underlying type argument of nullable types.

Example: Helper Class


static void Main(string[] args)
{
int? i = null;
int j = 10;

if (Nullable.Compare<int>(i, j) < 0)
Console.WriteLine("i < j");
else if (Nullable.Compare<int>(i, j) > 0)
Console.WriteLine("i > j");
else
Console.WriteLine("i = j");
}

Output:
i < j

Characteristics of Nullable Types

1. Nullable types can only be used with value types.


2. The Value property will throw an InvalidOperationException if value is null; otherwise it
will return the value.
3. The HasValue property returns true if the variable contains a value, or false if it is null.
4. You can only use == and != operators with a nullable type. For other comparison use the
Nullable static class.
5. Nested nullable types are not allowed. Nullable<Nullable<int>> i; will give a compile time
error.

Points to Remember :

1. Nullable<T> type allows assignment of null to value types.


2. ? operator is a shorthand syntax for Nullable types.
3. Use value property to get the value of nullable type.
4. Use HasValue property to check whether value is assigned to nullable type or not.
5. Static Nullable class is a helper class to compare nullable types.

Covariance and Contravariance in C#


Covariance and contravariance allow us to be flexible when dealing with class hierarchy.

Consider the following class hierarchy before we learn about covariance and
contravariance:

Example: Class Hierarchy


class Small
{

}
class Big: Small
{

}
class Bigger : Big
{

As per the above example classes, small is a base class for big and big is a base class for
bigger. The point to remember here is that a derived class will always have something more
than a base class, so the base class is relatively smaller than the derived class.

Now, consider the following initialization:

Class initialization

As you can see above, a base class can hold a derived class but a derived class cannot hold
a base class. In other word, an instance can accept big even if it demands small, but it
cannot accept small if it demands big.

Now, let's learn about covariance and contravariance.

Covariance in C#

Covariance enables you to pass a derived type where a base type is expected. Co-variance
is like variance of the same kind. The base class and other derived classes are considered to
be the same kind of class that adds extra functionalities to the base type. So covariance
allows you to use a derived class where a base class is expected (rule: can accept big if
small is expected).

Covariance can be applied on delegate, generic, array, interface, etc.

Covariance with Delegate

Covariance in delegates allows flexiblity in the return type of delegate methods.

Example: Covariance with Delegate


public delegate Small covarDel(Big mc);

class Program
{

static Big Method1(Big bg)


{
Console.WriteLine("Method1");

return new Big();


}
static Small Method2(Big bg)
{
Console.WriteLine("Method2");

return new Small();


}

static void Main(string[] args)


{
covarDel del = Method1;

Small sm = del(new Big());


}
}
Output:
Method1
Method2

As you can see in the above example, delegate expects a return type of small (base class)
but we can still assign Method1 that returns Big (derived class) and also Method2 that has
same signature as delegate expects.

Thus, covariance allows you to assign a method to the delegate that has a less derived
return type.

C# Contravariance

Contravariane is applied to parameters. Cotravariance allows a method with the parameter


of a base class to be assigned to a delegate that expects the parameter of a derived class.

Continuing with the example above, add Method3 that has a different parameter type than
delegate:

Example: Contravariance with Delegte


delegate Small covarDel(Big mc);

class Program
{
static Big Method1(Big bg)
{
Console.WriteLine("Method1");
return new Big();
}
static Small Method2(Big bg)
{
Console.WriteLine("Method2");
return new Small();
}

static Small Method3(Small sml)


{
Console.WriteLine("Method3");

return new Small();


}
static void Main(string[] args)
{
covarDel del = Method1;
del += Method2;
del += Method3;

Small sm = del(new Big());


}
Output:
Method1
Method2
Method3

As you can see, Method3 has a parameter of Small class whereas delegate expects a
parameter of Big class. Still, you can use Method3 with the delegate.

You can also use covariance and contravariance in the same method as shown below.

Example: Covariance and Contravariance


delegate Small covarDel(Big mc);

class Program
{

static Big Method4(Small sml)


{
Console.WriteLine("Method3");

return new Big();


}

static void Main(string[] args)


{
covarDel del = Method4;

Small sm = del(new Big());


}
}
Output:
Method4
Further Reading

 Visit Eric Lippert's blog to know more about covariance and contravarince.

Covariance and Contravariance in C#


Covariance and contravariance allow us to be flexible when dealing with class hierarchy.

Consider the following class hierarchy before we learn about covariance and
contravariance:

Example: Class Hierarchy


class Small
{

}
class Big: Small
{

}
class Bigger : Big
{

As per the above example classes, small is a base class for big and big is a base class for
bigger. The point to remember here is that a derived class will always have something more
than a base class, so the base class is relatively smaller than the derived class.

Now, consider the following initialization:

Class initialization
As you can see above, a base class can hold a derived class but a derived class cannot hold
a base class. In other word, an instance can accept big even if it demands small, but it
cannot accept small if it demands big.

Now, let's learn about covariance and contravariance.

Covariance in C#

Covariance enables you to pass a derived type where a base type is expected. Co-variance
is like variance of the same kind. The base class and other derived classes are considered to
be the same kind of class that adds extra functionalities to the base type. So covariance
allows you to use a derived class where a base class is expected (rule: can accept big if
small is expected).

Covariance can be applied on delegate, generic, array, interface, etc.

Covariance with Delegate

Covariance in delegates allows flexiblity in the return type of delegate methods.

Example: Covariance with Delegate


public delegate Small covarDel(Big mc);

class Program
{

static Big Method1(Big bg)


{
Console.WriteLine("Method1");

return new Big();


}
static Small Method2(Big bg)
{
Console.WriteLine("Method2");

return new Small();


}

static void Main(string[] args)


{
covarDel del = Method1;

Small sm = del(new Big());


}
}
Output:
Method1
Method2
As you can see in the above example, delegate expects a return type of small (base class)
but we can still assign Method1 that returns Big (derived class) and also Method2 that has
same signature as delegate expects.

Thus, covariance allows you to assign a method to the delegate that has a less derived
return type.

C# Contravariance

Contravariane is applied to parameters. Cotravariance allows a method with the parameter


of a base class to be assigned to a delegate that expects the parameter of a derived class.

Continuing with the example above, add Method3 that has a different parameter type than
delegate:

Example: Contravariance with Delegte


delegate Small covarDel(Big mc);

class Program
{
static Big Method1(Big bg)
{
Console.WriteLine("Method1");
return new Big();
}
static Small Method2(Big bg)
{
Console.WriteLine("Method2");
return new Small();
}

static Small Method3(Small sml)


{
Console.WriteLine("Method3");

return new Small();


}
static void Main(string[] args)
{
covarDel del = Method1;
del += Method2;
del += Method3;

Small sm = del(new Big());


}
Output:
Method1
Method2
Method3
As you can see, Method3 has a parameter of Small class whereas delegate expects a
parameter of Big class. Still, you can use Method3 with the delegate.

You can also use covariance and contravariance in the same method as shown below.

Example: Covariance and Contravariance


delegate Small covarDel(Big mc);

class Program
{

static Big Method4(Small sml)


{
Console.WriteLine("Method3");

return new Big();


}

static void Main(string[] args)


{
covarDel del = Method4;

Small sm = del(new Big());


}
}
Output:
Method4

Further Reading

 Visit Eric Lippert's blog to know more about covariance and contravarince.

C# LINQ
LINQ (Language Integrated Query) is uniform query syntax in C# and VB.Net to save and
retrieve data from different sources. It is integrated in C# or VB, thereby eliminating the
impedance mismatch between programming languages and databases, as well as providing
a single querying interface for different types of data sources.

For example, SQL is a Structured Query Language to save and retrieve data from the
database the same way LINQ is a structured query syntax built in C# and VB.Net to save
and retrieve data from different types of data sources like an Object Collection, an SQL
server database, XML, a web service etc.

Learn LINQ step by step in LINQ tutorials section.


Lamda Expression

C# 3.0/.Net 3.5 introduced lamda expression along with LINQ. Lambda expression is a
shorter way of representing anonymous method using some special syntax.

s => s.age > 18;

Learn lamda expression in detail in LINQ tutorials section.

C# - Func
We have learned in the previous section, that a delegates can be defined as shown below.

Example: C# Delegate
public delegate int SomeOperation(int i, int j);

class Program
{
static int Sum(int x, int y)
{
return x + y;
}

static void Main(string[] args)


{
SomeOperation add = Sum;

int result = add(10, 10);

Console.WriteLine(result);
}
}
Output:
20

C# 3.0 includes built-in generic delegate types Func and Action, so that you don't need to
define custom delegates as above.

Func is a generic delegate included in the System namespace. It has zero or more input
parameters and one out parameter. The last parameter is considered as an out parameter.

For example, a Func delegate that takes one input parameter and one out parameter is
defined in the System namespace as below:

Example: Func
namespace System
{
public delegate TResult Func<in T, out TResult>(T arg);
}

The last parameter in the angle brackets <> is considered as the return type and remaining
parameters are considered as input parameter types as shown in the following figure.

Func delegate

A Func delegate with two input parameters and one out parameters will be represent as
below.

Func delegate

The following Func type delegate is the same as the above SomeOperation delegate, where
it takes two input parameters of int type and returns a value of int type:

Func<int, int, int> sum;

You can assign any method to the above func delegate that takes two int parameters and
returns an int value. Now, you can take Func delegate instead of someOperation delegate in
the first example.

Example: Func
class Program
{
static int Sum(int x, int y)
{
return x + y;
}
static void Main(string[] args)
{
Func<int,int, int> add = Sum;

int result = add(10, 10);

Console.WriteLine(result);
}
}
Output:
20

A Func delegate type can include 0 to 16 input parameters of different types. However, it
must include one out parameter for result. For example, the following func delegate doesn't
have any input parameter, it includes only a out parameter.

Example: Func with Zero Input Parameter


Func<int> getRandomNumber;
C# Func with an Anonymous Method

You can assign an anonymous method to the Func delegate by using the delegate keyword.

Example: Func with Anonymous Method


Func<int> getRandomNumber = delegate()
{
Random rnd = new Random();
return rnd.Next(1, 100);
};
Func with Lambda Expression

A Func delegate can also be used with a lambda expression, as shown below:

Example: Func with lambda expression


Func<int> getRandomNumber = () => new Random().Next(1, 100);

//Or

Func<int, int, int> Sum = (x, y) => x + y;

Points to Remember :

1. Func is built-in delegate type.


2. Func delegate type must return a value.
3. Func delegate type can have zero to 16 input parameters.
4. Func delegate type can be used with an anonymous method or lambda expression.
C# - Action Delegate
Action is also a delegate type defined in the System namespace. An Action type delegate is
the same as Func delegate except that the Action delegate doesn't return a value. In other
words, an Action delegate can be used with a method that has a void return type.

For example, the following delegate prints an int value.

Example: C# Delegate
public delegate void Print(int val);

static void ConsolePrint(int i)


{
Console.WriteLine(i);
}

static void Main(string[] args)


{
Print prnt = ConsolePrint;
Prnt(10);
}
Output:
10

You can use an Action delegate instead of defining the above Print delegate, for example:

Example: Action delegate


static void ConsolePrint(int i)
{
Console.WriteLine(i);
}

static void Main(string[] args)


{
Action<int> printActionDel = ConsolePrint;
printActionDel(10);
}

You can initialize an Action delegate using the new keyword or by directly assigning a
method:

Action<int> printActionDel = ConsolePrint;

//Or

Action<int> printActionDel = new Action<int>(ConsolePrint);

An Action delegate can take up to 16 input parameters of different types.


An Anonymous method can also be assigned to an Action delegate, for example:

Example: Anonymous method with Action delegate


static void Main(string[] args)
{
Action<int> printActionDel = delegate(int i)
{
Console.WriteLine(i);
};

printActionDel(10);
}
Output:
10

A Lambda expression also can be used with an Action delegate:

Example: Lambda expression with Action delegate


static void Main(string[] args)
{

Action<int> printActionDel = i => Console.WriteLine(i);

printActionDel(10);
}

Thus, you can use any method that doesn't return a value with Action delegate types.

Advantages of Action and Func Delegates

1. Easy and quick to define delegates.


2. Makes code short.
3. Compatible type throughout the application.

Points to Remember :

1. Action delegate is same as func delegate except that it does not return anything. Return
type must be void.
2. Action delegate can have 1 to 16 input parameters.
3. Action delegate can be used with anonymous methods or lambda expressions.

C# - Predicate Delegate
A predicate is also a delegate like Func and Action delegates. It represents a method that
contains a set of criteria and checks whether the passed parameter meets those criteria or
not. A predicate delegate methods must take one input parameter and it then returns a
boolean value - true or false.

The Predicate delegate is defined in the System namespace as shown below:

Predicate signature: public delegate bool Predicate<in T>(T obj);

Same as other delegate types, Predicate can also be used with any method, anonymous
method or lambda expression.

Example: Predicate delegate


static bool IsUpperCase(string str)
{
return str.Equals(str.ToUpper());
}

static void Main(string[] args)


{
Predicate<string> isUpper = IsUpperCase;

bool result = isUpper("hello world!!");

Console.WriteLine(result);
}
Output:
false

An anonymous method can also be assigned to a Predicate delegate type as shown below.

Example: Predicate delegate with anonymous method


static void Main(string[] args)
{
Predicate<string> isUpper = delegate(string s) { return
s.Equals(s.ToUpper());};
bool result = isUpper("hello world!!");
}

A lambda expression can also be assigned to a Predicate delegate type as shown below.

Example: Predicate delegate with lambda expression


static void Main(string[] args)
{
Predicate<string> isUpper = s => s.Equals(s.ToUpper());
bool result = isUpper("hello world!!");
}

Points to Remember :

1. Predicate delegate takes one input parameter and boolean return type.
2. Predicate delegate must contains some criateria to check whether supplied
parameter meets those criateria or not.
3. Anonymous method and Lambda expression can be assigned to the predicate
delegate.

C# - Extension Method
Extension methods, as the name suggests, are additional methods. Extension methods allow
you to inject additional methods without modifying, deriving or recompiling the original
class, struct or interface. Extension methods can be added to your own custom class, .NET
framework classes, or third party classes or interfaces.

In the following example, IsGreaterThan() is an extension method for int type, which
returns true if the value of the int variable is greater than the supplied integer parameter.

Example: Extension Method


int i = 10;

bool result = i.IsGreaterThan(100); //returns false

The IsGreaterThan() method is not a method of int data type (Int32 struct). It is an
extension method written by the programmer for the int data type. The IsGreaterThan()
extension method will be available throughout the application by including the namespace
in which it has been defined.

The extension methods have a special symbol in intellisense of the visual studio, so that
you can easily differentiate between class methods and extension methods.

Extension Method Symbol in


visual studio intellisense

Now let's see how to write an extension method.


LINQ is built upon extension methods that operate on IEnumerable and
IQeryable type.

An extension method is actually a special kind of static method defined in a static class. To
define an extension method, first of all, define a static class.

For example, we have created an IntExtensions class under the ExtensionMethods


namespace in the following example. The IntExtensions class will contain all the extension
methods applicable to int data type. (You may use any name for namespace and class.)

Example: Create a Class for Extension Methods


namespace ExtensionMethods
{
public static class IntExtensions
{

}
}

Now, define a static method as an extension method where the first parameter of the
extension method specifies the type on which the extension method is applicable. We are
going to use this extension method on int type. So the first parameter must be int preceded
with the this modifier.

For example, the IsGreaterThan() method operates on int, so the first parameter would
be, this int i.

Example: Define an Extension Method


namespace ExtensionMethods
{
public static class IntExtensions
{
public static bool IsGreaterThan(this int i, int value)
{
return i > value;
}
}
}

Now, you can include the ExtensionMethods namespace wherever you want to use this
extension method.

Example: Extension method


using ExtensionMethods;

class Program
{
static void Main(string[] args)
{
int i = 10;

bool result = i.IsGreaterThan(100);

Console.WriteLine(result);
}
}
Output:
false
Note:
The only difference between a regular static method and an extension method is that the
first parameter of the extension method specifies the type that it is going to operator on,
preceded by the this keyword.
Points to Remember :

1. Extension methods are additional custom methods which were originally not
included with the class.
2. Extension methods can be added to custom, .NET Framework or third party classes,
structs or interfaces.
3. The first parameter of the extension method must be of the type for which the
extension method is applibable, preceded by the this keyword.
4. Extension methods can be used anywhere in the application by including the
namespace of the extension method.

C# - Anonymous Type
Anonymous type, as the name suggests, is a type that doesn't have any name. C# allows
you to create an object with the new keyword without defining its class. The implicitly
typed variable- var is used to hold the reference of anonymous types.

Example: Anonymous Type


static void Main(string[] args)
{
var myAnonymousType = new { firstProperty = "First",
secondProperty = 2,
thirdProperty = true
};
}

In the above example, myAnonymousType is an object of anonymous type created using


the new keyword and object initializer syntax It includes three properties of different data
types.
An anonymous type is a temporary data type that is inferred based on the data that you
include in an object initializer. Properties of anonymous types will be read-only properties
so you cannot change their values.

Anonymous types have intellisense support in Visual Studio:

Intellisense support for anonymous type

Notice that the compiler applies the appropriate type to each property based on the value
expression. For example, firstProperty is a string type, secondProperty is an int type and
thirdProperty is a bool.

Internally, the compiler automatically generates the new type for anonymous types. You
can check the type of an anonymous type as shown below.

static void Main(string[] args)


{
var myAnonymousType = new { firstProperty = "First",
secondProperty = 2,
thirdProperty = true
};

Console.WriteLine(myAnonymousType.GetType().ToString());
}
Output:
<>f__AnonymousType0'3[System.String,System.Int32,System.Boolean]

As you can see in the above output, the compiler generates a type with some cryptic name
for an anonymous type. If you see the above anonymous type in reflector, it looks like
below.
Dis
assembled Anonymous Type

Disassembled Anonymous Type

Notice that it is derived from the System.Object class. Also, it is a sealed class and all the
properties are created as read only properties.

Nested Anonymous Type

An anonymous type can have another anonymous type as a property.

Example: Nested Anonymous Type


var myAnonymousType = new
{
firstProperty = "First",
secondProperty = 2,
thirdProperty = true,
anotherAnonymousType = new { nestedProperty =
"Nested"}
};
Nested anonymous types also have intellisense support.

Scope of Anonymous Type

An anonymous type will always be local to the method where it is defined. Usually, you
cannot pass an anonymus type to another method; however, you can pass it to a method that
accepts a parameter of dynamic type. Please note that Passing anonymous types using
dynamic is not recommended.

Example: Passing Anonymous Type


static void Main(string[] args)
{

var myAnonymousType = new


{
firstProperty = "First Property",
secondProperty = 2,
thirdProperty = true
};

DoSomethig(myAnonymousType);
}

static void DoSomethig(dynamic param)


{
Console.WriteLine(param.firstProperty);
}
Output:
First Property

Anonymous Types with a LINQ Query

Linq Select clause creates an anonymous type as a result of a query to include various
properties which is not defined in any class. Consider the following example.

Example: Return Anonymous Type from LINQ Query


public class Student
{
public int StudentID { get; set; }
public string StudentName { get; set; }
public int age { get; set; }
}

class Program
{
static void Main(string[] args)
{
IList<Student> studentList = new List<Student>() {
new Student() { StudentID = 1, StudentName =
"John", age = 18 } ,
new Student() { StudentID = 2, StudentName =
"Steve", age = 21 } ,
new Student() { StudentID = 3, StudentName =
"Bill", age = 18 } ,
new Student() { StudentID = 4, StudentName =
"Ram" , age = 20 } ,
new Student() { StudentID = 5, StudentName =
"Ron" , age = 21 }
};

var studentNames = from s in studentList


select new { StudentID = s.StudentID,
StudentName = s.StudentName
};
}
}

In the above example, Student class includes various properties. In the Main() method, Linq
select clause creates an anonymous type to include only StudentId and StudentName
instead of including all the properties in a result. Thus, it is useful in saving memory and
unnecessary code. The query result collection includes only StudentID and StudentName
properties as shown in the following debug view.

Anonymous Type in debug view

Points to Remember :

1. Anonymous type can be defined using the new keyword and object initializer syntax.
2. The implicitly typed variable- var, is used to hold an anonymous type.
3. Anonymous type is a reference type and all the properties are read-only.
4. The scope of an anonymous type is local to the method where it is defined.

C# - Dynamic Type
C# 4.0 (.NET 4.5) introduced a new type that avoids compile time type checking. You have
learned about the implicitly typed variable- var in the previous section where the compiler
assigns a specific type based on the value of the expression. A dynamic type escapes type
checking at compile time; instead, it resolves type at run time.

A dynamic type can be defined using the dynamic keyword.

Example: dynamic type variable


dynamic dynamicVariable = 1;

The compiler compiles dynamic types into object types in most cases. The above statement
would be compiled as:

dynamic type at compile time:


object dynamicVariable = 1;

The actual type of dynamic would resolve at runtime. You can check the type of the
dynamic variable, as below:

Example: Get the actual type of dynamic type at runtime


static void Main(string[] args)
{
dynamic dynamicVariable = 1;

Console.WriteLine(dynamicVariable.GetType().ToString());
}
Output:
System.Int32

A dynamic type changes its type at runtime based on the value of the expression to the right
of the "=" operator. The following example shows how a dynamic variable changes its type
based on its value:

Example: dynamic
static void Main(string[] args)
{
dynamic dynamicVariable = 100;
Console.WriteLine("Dynamic variable value: {0}, Type:
{1}",dynamicVariable, dynamicVariable.GetType().ToString());

dynamicVariable = "Hello World!!";


Console.WriteLine("Dynamic variable value: {0}, Type: {1}",
dynamicVariable, dynamicVariable.GetType().ToString());

dynamicVariable = true;
Console.WriteLine("Dynamic variable value: {0}, Type: {1}",
dynamicVariable, dynamicVariable.GetType().ToString());

dynamicVariable = DateTime.Now;
Console.WriteLine("Dynamic variable value: {0}, Type: {1}",
dynamicVariable, dynamicVariable.GetType().ToString());
}
Output:
Dynamic variable value: 100, Type: System.Int32
Dynamic variable value: Hello World!!, Type: System.String
Dynamic variable value: True, Type: System.Boolean
Dynamic variable value: 01-01-2014, Type: System.DateTime

Methods and Properties of Dynamic Type

If you assign class object to the dynamic type then the compiler would not check for correct
methods and properties name of a dynamic type that holds the custom class object.
Consider the following example.

Example: dynamic
public class Student
{
public int StudentID { get; set; }
public string StudentName { get; set; }
public int Age { get; set; }
public int StandardID { get; set; }

public void DisplayStudentDetail()


{
Console.WriteLine("Name: {0}", this.StudentName);
Console.WriteLine("Age: {0}", this.Age);
Console.WriteLine("Standard: {0}", this.StandardID);
}
}

class Program
{
static void Main(string[] args)
{
dynamic dynamicStudent = new Student();

dynamicStudent.FakeMethod();
}
}

Intellisense in Visual Studio does not give any help for the dymanic type.

In the above example, we have assigned Student object to a dynamic variable. In the second
statement in Main() method, we call FakeMethod() method, which is not exists in the
Student class. However, the compiler will not give any error for FakeMethod() because it
skips type checking for dynamic type, instead you will get a runtime exception for it as
shown below.
Dynamic Type Fake Method Error

Dynamic Type as a Method Parameter

A method can have dynamic type parameters so that it can accept any type of parameter at
run time.

Example: dynamic as a Parameter


class Program
{
static void PrintValue(dynamic val)
{
Console.WriteLine(val);
}

static void Main(string[] args)


{

PrintValue("Hello World!!");
PrintValue(100);
PrintValue(100.50);
PrintValue(true);
PrintValue(DateTime.Now);
}
}
Output:
Hello World!!
100
100.50
True
01-01-2014 10:10:50

Points to Remember :
1. The dynamic types are resolved at runtime instead of compile time.
2. The compiler skips the type checking for dynamic type. So it doesn't give any error about
dynamic types at compile time.
3. The dynamic types do not have intellisense support in visual studio.
4. A method can have parameters of the dynamic type.
5. An exception is thrown at runtime if a method or property is not compatible.

C# - Object Initializer Syntax


C# 3.0 (.NET 3.5) introduced Object Initializer Syntax, a new way to initialize an object of
a class or collection. Object initializers allow you to assign values to the fields or properties
at the time of creating an object without invoking a constructor.

Example: Object Initializer Syntax


public class Student
{
public int StudentID { get; set; }
public string StudentName { get; set; }
public int Age { get; set; }
public string Address { get; set; }
}

class Program
{
static void Main(string[] args)
{
Student std = new Student() { StudentID = 1,
StudentName = "Bill",
Age = 20,
Address = "New York"
};
}
}

In the above example, Student class is defined without any constructors. In the Main()
method, we have created Student object and assigned values to all or some properties in the
curly bracket at the same time. This is called object initializer syntax.

The compiler compiles the above initializer into something like the following.

Example: Object Initializer Syntax at Compile time


Student __student = new Student();
__student.StudentID = 1;
__student.StudentName = "Bill";
__student.Age = 20;
__student.StandardID = 10;
__student.Address = "Test";
Student std = __student;
Collection Initializer Syntax

Collection can be initialized the same way as class objects using collection initializer
syntax.

Example: Object initializer Syntax


var student1 = new Student() { StudentID = 1, StudentName = "John" };
var student2 = new Student() { StudentID = 2, StudentName = "Steve" };
var student3 = new Student() { StudentID = 3, StudentName = "Bill" } ;
var student4 = new Student() { StudentID = 3, StudentName = "Bill" };
var student5 = new Student() { StudentID = 5, StudentName = "Ron" };

IList<Student> studentList = new List<Student>() {


student1,
student2,
student3,
student4,
student5
};

You can also initialize collections and objects at the same time.

Example: Collection initializer Syntax


IList<Student> studentList = new List<Student>() {
new Student() { StudentID = 1, StudentName =
"John"} ,
new Student() { StudentID = 2, StudentName = "Steve"}
,
new Student() { StudentID = 3, StudentName =
"Bill"} ,
new Student() { StudentID = 3, StudentName =
"Bill"} ,
new Student() { StudentID = 4, StudentName =
"Ram" } ,
new Student() { StudentID = 5, StudentName = "Ron" }
};

You can also specify null as an element:

Example: Collection initializer Syntax


IList<Student> studentList = new List<Student>() {
new Student() { StudentID = 1,
StudentName = "John"} ,
null
};
Advantages of Initializers

 Initializer syntax makes a code more readable, easy to add elements into the collection.
 Useful in multi-threading.

C# - Tuple
The Tuple<T> class was introduced in .NET Framework 4.0. A tuple is a data structure that
contains a sequence of elements of different data types. It can be used where you want to
have a data structure to hold an object with properties, but you don't want to create a
separate type for it.

Tuple<T1, T2, T3, T4, T5, T6, T7, TRest>

The following example creates a tuple with three elements:

Tuple<int, string, string> person =


new Tuple <int, string, string>(1, "Steve",
"Jobs");

In the above example, we created an instance of the Tuple which holds a record of a
person. We specified a type for each element and passed values to the constructor.
Specifying the type of each element is cumbersome. So, C# includes a static helper class
Tuple which returns an instance of the Tuple<T> without specifying the type of each
element, as shown below.

var person = Tuple.Create(1, "Steve", "Jobs");

A tuple can only include maximum eight elements. It gives a compiler error when you try
to include more than eight elements.

var numbers = Tuple.Create(1, 2, 3, 4, 5, 6, 7, 8);


Accessing Tuple Elements

The elements of a tuple can be accessed with Item<elementNumber> properties e.g. Item1,
Item2, Item3 and so on up to Item7 property. The Item1 property returns the first element,
Item2 returns the second element and so on. The last element (the 8th element) will be
returned using the Rest property.

Example: Accessing Tuple Elements


var person = Tuple.Create(1, "Steve", "Jobs");
person.Item1; // returns 1
person.Item2; // returns "Steve"
person.Item3; // returns "Jobs"

var numbers = Tuple.Create("One", 2, 3, "Four", 5, "Six", 7, 8);


numbers.Item1; // returns "One"
numbers.Item2; // returns 2
numbers.Item3; // returns 3
numbers.Item4; // returns "Four"
numbers.Item5; // returns 5
numbers.Item6; // returns "Six"
numbers.Item7; // returns 7
numbers.Rest; // returns (8)
numbers.Rest.Item1; // returns 8

Generally, the 8th position is for the nested tuple which you can access using the Rest
property.

Nested Tuples

If you want to include more than eight elements in a tuple, you can do that by nesting
another tuple object as the eighth element. The last nested tuple can be accessed using the
Rest property. To access the nested tuple's element, use the
Rest.Item1.Item<elelementNumber> property.

Example: Nested Tuple


var numbers = Tuple.Create(1, 2, 3, 4, 5, 6, 7, Tuple.Create(8, 9, 10,
11, 12, 13));
numbers.Item1; // returns 1
numbers.Item7; // returns 7
numbers.Rest.Item1; //returns (8, 9, 10, 11, 12, 13)
numbers.Rest.Item1.Item1; //returns 8
numbers.Rest.Item1.Item2; //returns 9

You can include the nested tuple object anywhere in the sequence. However, it is
recommended to place the nested tuple at the end of the sequence so that it can be accessed
using the Rest property.

Example: Nested Tuple


var numbers = Tuple.Create(1, 2, Tuple.Create(3, 4, 5, 6, 7, 8), 9, 10,
11, 12, 13 );
numbers.Item1; // returns 1
numbers.Item2; // returns 2
numbers.Item3; // returns (3, 4, 5, 6, 7, 8)
numbers.Item3.Item1; // returns 3
numbers.Item4; // returns 9
numbers.Rest.Item1; //returns 13
Tuple as a Method Parameter

A method can have a tuple as a parameter.

static void Main(string[] args)


{
var person = Tuple.Create(1, "Steve", "Jobs");
DisplayTuple(person);
}
static void DisplayTuple(Tuple<int,string,string> person)
{
Console.WriteLine($"Id = { person.Item1}");
Console.WriteLine($"First Name = { person.Item2}");
Console.WriteLine($"Last Name = { person.Item3}");
}
Tuple as a Return Type

A Tuple can be return from a method.

static void Main(string[] args)


{
var person = GetPerson();
}

static Tuple<int, string, string> GetPerson()


{
return Tuple.Create(1, "Bill", "Gates");
}
Usage of Tuple

Tuples can be used in the following scenarios:

1. When you want to return multiple values from a method without using ref or out
parameters.
2. When you want to pass multiple values to a method through a single parameter.
3. When you want to hold a database record or some values temporarily without creating a
separate class.

Tuple Limitations:

1. Tuple is a reference type and not a value type. It allocates on heap and could result in CPU
intensive operations.
2. Tuple is limited to include 8 elements. You need to use nested tuples if you need to store
more elements. However, this may result in ambiguity.
3. Tuple elements can be accessed using properties with a name pattern
Item<elementNumber> which does not make sense.

C# 7 includes ValueTuple to overcome the limitations of Tuple and also makes it even
easier to work with Tuple. Learn about it in the next chapter.

C# - ValueTuple
C# 7.0 (.NET Framework 4.7) introduced ValueTuple, a structure which is a value type
representation of the Tuple.
The ValueTuple is only available in .NET Framework 4.7. If you don't see ValueTuple in
your project then you need to install the ValueTuple. (.NET Framework 4.7 or higher,
or .NET Standard Library 2.0 or higher already includes ValueTuple.)

To install the ValueTuple package, right click on the project in the solution explorer and
select Manage NuGet Packages... This will open the NuGet Package Manager. Click the
Browse tab, search for ValueTuple in the search box and select the System.ValueTuple
package, as shown below.

ValueTuple Initialization

It is easy to create and initialize ValueTuple. It can be created and initialized using
parentheses () and specifying the values between them.

var person = (1, "Bill", "Gates");


//equivalent Tuple
//var person = Tuple.Create(1, "Bill", "Gates");

ValueTuple can also be initialized by specifying the type of each element, as shown below.

ValueTuple<int, string,string> person = (1, "Bill", "Gates");


person.Item1; // returns 1
person.Item2; // returns "Bill"
person.Item3; // returns "Gates"

The following is a short way of declaring types for each member.

(int, string, string) person = (1, "Bill", "Gates");


person.Item1; // returns 1
person.Item2; // returns "Bill"
person.Item3; // returns "Gates"

Please notice that we have not used var in the above tuple initialization statement; instead
we provided the type of each member values inside the brackets.

Tuple requires at least two values. The following is NOT a tuple.

var number = (1); // int type, NOT a tuple


var numbers = (1,2); //valid tuple

Unlike Tuple, a ValueTuple can include more than eight values.

var numbers = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14);


Named Members:

We can assign names to ValueTuple properties instead of having the default property
names Item1, Item2 and so on.

(int Id, string FirstName, string LastName) person = ("Bill", "Gates",


60);
person.Id; // returns 1
person.FirstName; // returns "Bill"
person.LastName; // returns "Gates"

We can also assign member names at the right side with values, as below.

var person = (Id:1, FirstName:"Bill", LastName: "Gates");

Please note that we can provide member names either at the left side or at the right side but
not at both side. The left side has precedence over the left side. The following will ignore
names at the right side.

// PersonId, FName, LName will be ignored.


(int Id, string FirstName, string LastName) person = (PersonId:1,
FName:"Bill", LName: "Gates");

// PersonId, FirstName, LastName will be ignored. It will have the


default names: Item1, Item2, Item3.
(string, string, int) person = (PersonId:1, FName:"Bill", LName:
"Gates");

We can also assign variables as member values.

string firstName = "Bill", lastName = "Gates";


var per = (FirstName: firstName, LastName: lastName);
ValueTuple as Return Type:

The following method returns a ValueTuple.

static void Main(string[] args)


{
DisplayTuple(1, "Bill", "Gates");
}

static void DisplayTuple((int, string, string) person)


{
Console.WriteLine($"Id = { person.Item1}");
Console.WriteLine($"First Name = { person.Item2}");
Console.WriteLine($"Last Name = { person.Item3}");
}

We can also specify different member names for a ValueTuple returned from a method.

static void Main(string[] args)


{
var person = GetPerson();
}

static (int, string, string) GetPerson()


{
return (Id:1, FirstName: "Bill", LastName: "Gates");
}
Deconstruction

Individual members of a ValueTuple can be retrieved by deconstructing it. A


deconstructing declaration syntax splits a ValueTuple into its parts and assigns those parts
individually to fresh variables.

static void Main(string[] args)


{
// change property names
(int PersonId, string FName, string LName) person = GetPerson();
}
static (int, string, string) GetPerson()
{
return (Id:1, FirstName: "Bill", LastName: "Gates");
}

We can also use var instead of explicit data type names.

static void Main(string[] args)


{
// use var as datatype
(var PersonId, var FName, var LName) person = GetPerson();
}
static (int, string, string) GetPerson()
{
return (Id:1, FirstName: "Bill", LastName: "Gates");
}

ValueTuple also allows "discards" in deconstruction for the members you are not going to
use.

// use discard _ for the unused member LName


(var id, var FName, _) = GetPerson();

LINQ Tutorial
Language-Integrated Query (LINQ) is a powerful query language introduced with .Net 3.5
& Visual Studio 2008. LINQ can be used with C# or Visual Basic to query different data
sources.

LINQ tutorials will help you to learn the LINQ language using topics which go from basic
to advanced. These tutorials are broken down into series of related topics, so that you start
from a topic which must be understand first, and then gradually learn other features of
LINQ sequentially. LINQ tutorials are packed with easy to understand explanations, real-
world examples, useful tips, informative notes and points to remember.

These tutorials are designed for beginners and professionals who want to learn LINQ step-
by-step.

Prerequisites

Basic knowledge of .Net Framework3.5/4.5, C#, Visual Studio is required.

So let's get started by clicking Next.

LINQ Test
Test your LINQ knowledge with a quick test. It includes 20 questions and each question
includes 4 options. Select an appropriate answer out of 4 options. There is no time limit for
this test.

What is LINQ?
LINQ (Language Integrated Query) is uniform query syntax in C# and VB.NET used to
save and retrieve data from different sources. It is integrated in C# or VB, thereby
eliminating the mismatch between programming languages and databases, as well as
providing a single querying interface for different types of data sources.

For example, SQL is a Structured Query Language used to save and retrieve data from a
database. In the same way, LINQ is a structured query syntax built in C# and VB.NET used
to save and retrieve data from different types of data sources like an Object Collection,
SQL server database, XML, web service etc.

LINQ always works with objects so you can use the same basic coding patterns to query
and transform data in XML documents, SQL databases, ADO.NET Datasets, .NET
collections, and any other format for which a LINQ provider is available.

LINQ Usage

Learn why should we use LINQ in the next section.


Why LINQ?
To understand why we should use LINQ, let's look at some examples. Suppose you want to
find list of teenage students from an array of Student objects.

Before C# 2.0, we had to use a 'foreach' or a 'for' loop to traverse the collection to find a
particular object. For example, we had to write the following code to find all Student
objects from an array of Students where the age is between 12 and 20 (for teenage 13 to
19):

Example: Use for loop to find elements from the collection in C# 1.0
class Student
{
public int StudentID { get; set; }
public String StudentName { get; set; }
public int Age { get; set; }
}

class Program
{
static void Main(string[] args)
{
Student[] studentArray = {
new Student() { StudentID = 1, StudentName = "John", Age = 18
},
new Student() { StudentID = 2, StudentName = "Steve", Age =
21 },
new Student() { StudentID = 3, StudentName = "Bill", Age =
25 },
new Student() { StudentID = 4, StudentName = "Ram" , Age = 20
},
new Student() { StudentID = 5, StudentName = "Ron" , Age = 31
},
new Student() { StudentID = 6, StudentName = "Chris", Age =
17 },
new Student() { StudentID = 7, StudentName = "Rob",Age =
19 },
};

Student[] students = new Student[10];

int i = 0;

foreach (Student std in studentArray)


{
if (std.Age > 12 && std.Age < 20)
{
students[i] = std;
i++;
}
}
}
}

Use of for loop is cumbersome, not maintainable and readable. C# 2.0 introduced delegate,
which can be used to handle this kind of a scenario, as shown below.

Example: Use Delegates to Find Elements from the Collection in C# 2.0


delegate bool FindStudent(Student std);

class StudentExtension
{
public static Student[] where(Student[] stdArray, FindStudent del)
{
int i=0;
Student[] result = new Student[10];
foreach (Student std in stdArray)
if (del(std))
{
result[i] = std;
i++;
}

return result;
}
}

class Program
{
static void Main(string[] args)
{
Student[] studentArray = {
new Student() { StudentID = 1, StudentName = "John", Age = 18
} ,
new Student() { StudentID = 2, StudentName = "Steve", Age =
21 } ,
new Student() { StudentID = 3, StudentName = "Bill", Age =
25 } ,
new Student() { StudentID = 4, StudentName = "Ram" , Age = 20
} ,
new Student() { StudentID = 5, StudentName = "Ron" , Age = 31
} ,
new Student() { StudentID = 6, StudentName = "Chris", Age =
17 } ,
new Student() { StudentID = 7, StudentName = "Rob",Age =
19 } ,
};

Student[] students = StudentExtension.where(studentArray,


delegate(Student std){
return std.Age > 12 && std.Age < 20;
});
}
}
}
So, with C# 2.0, you got the advantage of delegate in finding students with any criteria.
You don't have to use a for loop to find students using different criteria. For example, you
can use the same delegate function to find a student whose StudentId is 5 or whose name is
Bill, as below:

Student[] students = StudentExtension.where(studentArray,


delegate(Student std) {
return std.StudentID == 5;
});

//Also, use another criteria using same delegate


Student[] students = StudentExtension.where(studentArray,
delegate(Student std) {
return std.StudentName == "Bill";
});

The C# team felt that they still needed to make the code even more compact and readable.
So they introduced the extension method, lambda expression, expression tree, anonymous
type and query expression in C# 3.0. You can use these features of C# 3.0, which are
building blocks of LINQ to query to the different types of collection and get the resulted
element(s) in a single statement.

The example below shows how you can use LINQ query with lambda expression to find a
particular student(s) from the student collection.

Example: LINQ
class Program
{
static void Main(string[] args)
{
Student[] studentArray = {
new Student() { StudentID = 1, StudentName = "John",
age = 18 } ,
new Student() { StudentID = 2, StudentName = "Steve",
age = 21 } ,
new Student() { StudentID = 3, StudentName = "Bill",
age = 25 } ,
new Student() { StudentID = 4, StudentName = "Ram" ,
age = 20 } ,
new Student() { StudentID = 5, StudentName = "Ron" ,
age = 31 } ,
new Student() { StudentID = 6, StudentName = "Chris",
age = 17 } ,
new Student() { StudentID = 7, StudentName =
"Rob",age = 19 } ,
};

// Use LINQ to find teenager students


Student[] teenAgerStudents = studentArray.Where(s => s.age > 12
&& s.age < 20).ToArray();

// Use LINQ to find first student whose name is Bill


Student bill = studentArray.Where(s => s.StudentName ==
"Bill").FirstOrDefault();

// Use LINQ to find student whose StudentID is 5


Student student5 = studentArray.Where(s => s.StudentID ==
5).FirstOrDefault();
}
}

As you can see in the above example, we specify different criteria using LINQ operator and
lambda expression in a single statement. Thus, LINQ makes code more compact and
readable and it can also be used to query different data sources. For example, if you have a
student table in a database instead of an array of student objects as above, you can still use
the same query to find students using the Entity Framework.

Advantages of LINQ

 Familiar language: Developers don’t have to learn a new query language for each type of
data source or data format.
 Less coding: It reduces the amount of code to be written as compared with a more
traditional approach.
 Readable code: LINQ makes the code more readable so other developers can easily
understand and maintain it.
 Standardized way of querying multiple data sources: The same LINQ syntax can be used
to query multiple data sources.
 Compile time safety of queries: It provides type checking of objects at compile time.
 IntelliSense Support: LINQ provides IntelliSense for generic collections.
 Shaping data: You can retrieve data in different shapes.

LINQ API
LINQ is nothing but the collection of extension methods for classes that implements
IEnumerable and IQueryable interface. System.Linq namespace includes the necessary
classes & interfaces for LINQ. Enumerable and Queryable are two main static classes of
LINQ API that contain extension methods.

System.Linq namespace is included by default when you add a new class in Visual Studio,
so that you can use LINQ by default.
Enumerable

Enumerable class includes extension methods for the classes that implement
IEnumerable<T> interface, this include all the collection types in
System.Collections.Generic namespaces such as List<T>, Dictionary<T>, SortedList<T>,
Queue<T>, HashSet<T>, LinkedList<T> etc.

The following figure illustrates that the extension methods included in Enumerable class
can be used with generic collection in C# or VB.Net.

IEnumerable<T> extension methods in Enumerable class

Queryable

The Queryable class includes extension methods for classes that implement IQueryable<t>
interface. IQueryable<T> is used to provide querying capabilities against a specific data
source where the type of the data is known. For example, Entity Framework api implements
IQueryable<T> interface to support LINQ queries with underlaying database like SQL
Server.

Also, there are APIs available to access third party data; for example, LINQ to Amazon
provides the ability to use LINQ with Amazon web services to search for books and other
items by implementing IQueryable interface.

The following figure illustrates that the extension methods included in Queryable class can
be used with various native or third party data providers.
IQueryable extension methods in Queryable class

Visit MSDN to know all the extension methods of Enumerable and Queryable class.

Points to Remember :

1. Use System.Linq namespace to use LINQ.


2. LINQ api includes two main static class Enumerable & Queryable.
3. The static Enumerable class includes extension methods for classes that implements
IEnumerable<T> interface.
4. IEnumerable<T> type of collections are in-memory collection like List, Dictionary,
SortedList, Queue, HashSet, LinkedList
5. The static Queryable class includes extension methods for classes that implements
IQueryable<T> interface
6. Remote query provider implements IQueryable<T>. eg. Linq-to-SQL, LINQ-to-Amazon etc.

LINQ Query Syntax


There are two basic ways to write a LINQ query to IEnumerable collection or IQueryable
data sources.

1. Query Syntax or Query Expression Syntax


2. Method Syntax or Method extension syntax or Fluent

Query Syntax

Query syntax is similar to SQL (Structured Query Language) for the database. It is defined
within the C# or VB code.
LINQ Query Syntax:
from <range variable> in <IEnumerable<T> or IQueryable<T> Collection>

<Standard Query Operators> <lambda expression>

<select or groupBy operator> <result formation>

The LINQ query syntax starts with from keyword and ends with select keyword. The
following is a sample LINQ query that returns a collection of strings which contains a word
"Tutorials".

Example: LINQ Query Syntax in C#


// string collection
IList<string> stringList = new List<string>() {
"C# Tutorials",
"VB.NET Tutorials",
"Learn C++",
"MVC Tutorials" ,
"Java"
};

// LINQ Query Syntax


var result = from s in stringList
where s.Contains("Tutorials")
select s;

The following figure shows the structure of LINQ query syntax.

LINQ Query Syntax

Query syntax starts with a From clause followed by a Range variable. The From clause is
structured like "From rangeVariableName in IEnumerablecollection". In English,
this means, from each object in the collection. It is similar to a foreach loop:
foreach(Student s in studentList).

After the From clause, you can use different Standard Query Operators to filter, group, join
elements of the collection. There are around 50 Standard Query Operators available in
LINQ. In the above figure, we have used "where" operator (aka clause) followed by a
condition. This condition is generally expressed using lambda expression.
LINQ query syntax always ends with a Select or Group clause. The Select clause is used to
shape the data. You can select the whole object as it is or only some properties of it. In the
above example, we selected the each resulted string elements.

In the following example, we use LINQ query syntax to find out teenager students from the
Student collection (sequence).

Example: LINQ Query Syntax in C#


// Student collection
IList<Student> studentList = new List<Student>>() {
new Student() { StudentID = 1, StudentName = "John", Age = 13} ,
new Student() { StudentID = 2, StudentName = "Moin", Age =
21 } ,
new Student() { StudentID = 3, StudentName = "Bill", Age =
18 } ,
new Student() { StudentID = 4, StudentName = "Ram" , Age = 20} ,
new Student() { StudentID = 5, StudentName = "Ron" , Age = 15 }
};

// LINQ Query Syntax to find out teenager students


var teenAgerStudent = from s in studentList
where s.Age > 12 && s.Age < 20
select s;
Example: LINQ Query Syntax in VB.Net
// Student collection
Dim studentList = New List(Of Student) From {
New Student() With {.StudentID = 1, .StudentName = "John", .Age =
13},
New Student() With {.StudentID = 2, .StudentName = "Moin", .Age =
21},
New Student() With {.StudentID = 3, .StudentName = "Bill", .Age =
18},
New Student() With {.StudentID = 4, .StudentName = "Ram", .Age =
20},
New Student() With {.StudentID = 5, .StudentName = "Ron", .Age =
15}
}

// LINQ Query Syntax to find out teenager students


Dim teenAgerStudents As IList(Of Student) = (From s In studentList _
Where s.Age > 12 And s.Age <
20 _
Select s).ToList()

Points to Remember :

1. As name suggest, Query Syntax is same like SQL (Structure Query Language) syntax.
2. Query Syntax starts with from clause and can be end with Select or GroupBy clause.
3. Use various other opertors like filtering, joining, grouping, sorting operators to construct
the desired result.
4. Implicitly typed variable - var can be used to hold the result of the LINQ query.
LINQ Method Syntax
In the previous section, you have learned about LINQ Query Syntax. Here, you will learn
about Method syntax.

The compiler converts query syntax into method syntax at compile time.

Method syntax (also known as fluent syntax) uses extension methods included in the
Enumerable or Queryable static class, similar to how you would call the extension method
of any class.

The following is a sample LINQ method syntax query that returns a collection of strings
which contains a word "Tutorials".

Example: LINQ Method Syntax in C#


// string collection
IList<string> stringList = new List<string>() {
"C# Tutorials",
"VB.NET Tutorials",
"Learn C++",
"MVC Tutorials" ,
"Java"
};

// LINQ Query Syntax


var result = stringList.Where(s => s.Contains("Tutorials"));

The following figure illustrates the structure of LINQ method syntax.

LINQ Method Syntax Structure

As you can see in the above figure, method syntax comprises of extension methods and
Lambda expression. The extension method Where() is defined in the Enumerable class.

If you check the signature of the Where extension method, you will find the Where method
accepts a predicate delegate as Func<Student, bool>. This means you can pass any delegate
function that accepts a Student object as an input parameter and returns a Boolean value as
shown in the below figure. The lambda expression works as a delegate passed in the Where
clause. Learn lambda expression in the next section.

Func delegate in Where

The following example shows how to use LINQ method syntax query with the
IEnumerable<T> collection.

Example: Method Syntax in C#


// Student collection
IList<Student> studentList = new List<Student>() {
new Student() { StudentID = 1, StudentName = "John", Age = 13} ,
new Student() { StudentID = 2, StudentName = "Moin", Age =
21 } ,
new Student() { StudentID = 3, StudentName = "Bill", Age =
18 } ,
new Student() { StudentID = 4, StudentName = "Ram" , Age = 20} ,
new Student() { StudentID = 5, StudentName = "Ron" , Age = 15 }
};

// LINQ Method Syntax to find out teenager students


var teenAgerStudents = studentList.Where(s => s.Age > 12 && s.Age < 20)
.ToList<Student>();
Example: Method Syntax in VB.Net
// Student collection
Dim studentList = New List(Of Student) From {
New Student() With {.StudentID = 1, .StudentName = "John", .Age =
13},
New Student() With {.StudentID = 2, .StudentName = "Moin", .Age =
21},
New Student() With {.StudentID = 3, .StudentName = "Bill", .Age =
18},
New Student() With {.StudentID = 4, .StudentName = "Ram", .Age =
20},
New Student() With {.StudentID = 5, .StudentName = "Ron", .Age =
15}
}

// LINQ Method Syntax to find out teenager students


Dim teenAgerStudents As IList(Of Student) = studentList.Where(Function(s)
s.Age > 12 And s.Age < 20)
.ToList()
Points to Remember :

1. As name suggest, Method Syntax is like calling extension method.


2. LINQ Method Syntax aka Fluent syntax because it allows series of extension
methods call.
3. Implicitly typed variable - var can be used to hold the result of the LINQ query.

Anatomy of the Lambda Expression


C# 3.0(.NET 3.5) introduced the lambda expression along with LINQ. The lambda
expression is a shorter way of representing anonymous method using some special syntax.

For example, following anonymous method checks if student is teenager or not:

Example: Anonymous Method in C#


delegate(Student s) { return s.Age > 12 && s.Age < 20; };
Example: Anonymous method in VB.Net
Dim isStudentTeenAger = Function(s As Student) As Boolean
Return s.Age > 12 And s.Age < 20
End Function

The above anonymous method can be represented using a Lambda Expression in C# and
VB.Net as below:

Example: Lambda Expression in C#


s => s.Age > 12 && s.Age < 20
Example: Lambda Expression in VB.Net
Function(s) s.Age > 12 And s.Age < 20

Let's see how the lambda expression evolved from the following anonymous method.

Example: Anonymous method in C#


delegate(Student s) { return s.Age > 12 && s.Age < 20; };

The Lambda expression evolves from anonymous method by first removing the delegate
keyword and parameter type and adding a lambda operator =>.
Lambda Expression from Anonymous Method

The above lambda expression is absolutely valid, but we don't need the curly braces, return
and semicolon if we have only one statement that returns a value. So we can eliminate it.

Also, we can remove parenthesis (), if we have only one parameter.

Lambda Expression from Anonymous Method

Thus, we got the lambda expression: s => s.Age > 12 && s.Age < 20 where s is a
parameter, => is the lambda operator and s.Age > 12 && s.Age < 20 is the body
expression:

Lambda Expression Structure in C#

Same way we got lambda expression in VB.Net can be written as below:


Lambda Expression Structure in VB.Net

The lambda expression can be invoked same way as delegate using ().

Note:

VB.Net doesn't support lambda operator =>

Lambda Expression with Multiple Parameters

You can wrap the parameters in parenthesis if you need to pass more than one parameter, as
below:

Example: Specify Multiple Parameters in Lambda Expression C#


(s, youngAge) => s.Age >= youngage;

You can also give type of each parameters if parameters are confusing:

Example: Specify Parameter Type


(Student s,int youngAge) => s.Age >= youngage;
Example: Specify Multiple Parameters in Lambda Expression VB.Net
Function(s, youngAge) s.Age >= youngAge
Lambd Expression without Parameter

It is not necessary to have atleast one parameter in a lambda expression. The lambda
expression can be specify without any parameter also.

Example: Lambda Expression without Parameter


() => Console.WriteLine("Parameter less lambda expression")
Multiple Statements in Lambda Expression Body

You can wrap expressions in curly braces if you want to have more than one statement in
the body:

Example: Multi Statements Lambda expression C#


(s, youngAge) =>
{
Console.WriteLine("Lambda expression with multiple statements in the
body");

Return s.Age >= youngAge;


}
Example: Multi Statements Lambda Expression VB.Net
Function(s , youngAge)

Console.WriteLine("Lambda expression with multiple statements in the


body")

Return s.Age >= youngAge

End Function
Declare Local Variable in Lambda Expression Body

You can declare a variable in the expression body to use it anywhere in the expression
body, as below:

Example: Local Variable in Lambda expression C#


s =>
{
int youngAge = 18;

Console.WriteLine("Lambda expression with multiple statements in the


body");

return s.Age >= youngAge;


}
Example: Local Variable in Lambda Expression VB.Net
Function(s)

Dim youngAge As Integer = 18

Console.WriteLine("Lambda expression with multiple statements in


the body")

Return s.Age >= youngAge

End Function

Lambda expression can also be assigned to built-in delegates such as Func, Action and
Predicate.

Assign Lambda Expression to Delegate

The lambda expression can be assigned to Func<in T, out TResult> type delegate. The
last parameter type in a Func delegate is the return type and rest are input parameters. Visit
Func delegate section of C# tutorials to know more about it.

Consider the following lambda expression to find out whether a student is a teenager or not.

Example: Lambda Expression Assigned to Func Delegate C#


Func<Student, bool> isStudentTeenAger = s => s.age > 12 && s.age < 20;

Student std = new Student() { age = 21 };

bool isTeen = isStudentTeenAger(std);// returns false


Example: Lamda Expression Assigned to Func Delegate VB.Net
Dim isStudentTeenAger As Func(Of Student, Boolean) = Function(s) s.Age >
12 And s.Age < 20

Dim stud As New Student With {.Age = 21}

Dim isTeen As Boolean = isStudentTeenAger(stud) // returns false

In the above example, the Func delegate expects the first input parameter to be of Student
type and the return type to be boolean. The lambda expression s => s.age > 12 &&
s.age < 20 satisfies the Func<Student, bool> delegate requirement, as shown below:

Func
delegate with Lambda Expression

The Func<> delegate shown above, would turn out to be a function as shown below.

bool isStudentTeenAger(Student s)
{
return s.Age > 12 && s.Age < 20;
}
Action Delegate

Unlike the Func delegate, an Action delegate can only have input parameters. Use the
Action delegate type when you don't need to return any value from lambda expression.

Example: Lamda Expression Assigned to Action Delegate C#


Action<Student> PrintStudentDetail = s => Console.WriteLine("Name: {0},
Age: {1} ", s.StudentName, s.Age);

Student std = new Student(){ StudentName = "Bill", Age=21};

PrintStudentDetail(std);//output: Name: Bill, Age: 21


Example: Lamda Expression Assigned to Action Delegate VB.Net
Dim printStudentDetail As Action(Of Student) = Sub(s)
Console.WriteLine("Name: {0}, Age: {1} ", s.StudentName, s.Age)
Dim stud As New Student With {.StudentName = "Bill", .Age = 21}

printStudentDetail(stud)//output: Name: Bill, Age: 21


Lambda Expression in LINQ Query

Usually lambda expression is used with LINQ query. Enumerable static class includes
Where extension method for IEnumerable<T> that accepts Func<TSource,bool>. So, the
Where() extension method for IEnumerable<Student> collection is required to pass
Func<Student,bool>, as shown below:

Func delegate parameter in Where extension method

So now, you can pass the lambda expression assigned to the Func delegate to the Where()
extension method in the method syntax as shown below:

Example: Func Delegate in LINQ Method Syntax


IList<Student> studentList = new List<Student>(){...};

Func<Student, bool> isStudentTeenAger = s => s.age > 12 && s.age < 20;

var teenStudents =
studentList.Where(isStudentTeenAger).ToList<Student>();
Example: Func Delegate in LINQ Query Syntax
IList<Student> studentList = new List<Student>(){...};

Func<Student, bool> isStudentTeenAger = s => s.age > 12 && s.age < 20;

var teenStudents = from s in studentList


where isStudentTeenAger(s)
select s;

You can follow the same method in VB.Net to pass Func delegate.

Points to Remember :

1. Lambda Expression is a shorter way of representing anonymous method.


2. Lambda Expression syntax: parameters => body expression
3. Lambda Expression can have zero parameter.
4. Lambda Expression can have multiple parameters in parenthesis ().
5. Lambda Expression can have multiple statements in body expression in curly brackets {}.
6. Lambda Expression can be assigned to Func, Action or Predicate delegate.
7. Lambda Expression can be invoked in a similar way to delegate.

Standard Query Operators


Standard Query Operators in LINQ are actually extension methods for the
IEnumerable<T> and IQueryable<T> types. They are defined in the
System.Linq.Enumerable and System.Linq.Queryable classes. There are over 50
standard query operators available in LINQ that provide different functionalities like
filtering, sorting, grouping, aggregation, concatenation, etc.

Standard Query Operators in Query Syntax

Standard Query
Operators in Query Syntax

Standard Query Operators in Method Syntax

Standard Query Operators in Method Syntax

Standard query operators in query syntax is converted into extension methods at compile
time. So both are same.

Standard Query Operators can be classified based on the functionality they provide. The
following table lists all the classification of Standard Query Operators:

Classification Standard Query Operators

Filtering Where, OfType

Sorting OrderBy, OrderByDescending, ThenBy, ThenByDescending, Reverse


Classification Standard Query Operators

Grouping GroupBy, ToLookup

Join GroupJoin, Join

Projection Select, SelectMany

Aggregation Aggregate, Average, Count, LongCount, Max, Min, Sum

Quantifiers All, Any, Contains

ElementAt, ElementAtOrDefault, First, FirstOrDefault, Last, LastOrDefault, Single,


Elements
SingleOrDefault

Set Distinct, Except, Intersect, Union

Partitioning Skip, SkipWhile, Take, TakeWhile

Concatenation Concat

Equality SequenceEqual

Generation DefaultEmpty, Empty, Range, Repeat

Conversion AsEnumerable, AsQueryable, Cast, ToArray, ToDictionary, ToList

Learn each Standard Query Operators in the next sections.

Filtering Operators - Where


Filtering operators in LINQ filter the sequence (collection) based on some given criteria.

The following table lists all the filtering operators available in LINQ.

Filtering
Description
Operators

Where Returns values from the collection based on a predicate function

Returns values from the collection based on a specified type. However, it will
OfType
depend on their ability to cast to a specified type.
Where

The Where operator (Linq extension method) filters the collection based on a given criteria
expression and returns a new collection. The criteria can be specified as lambda expression
or Func delegate type.

The Where extension method has following two overloads. Both overload methods accepts
a Func delegate type parameter. One overload required Func<TSource,bool> input
parameter and second overload method required Func<TSource, int, bool> input parameter
where int is for index:

Where method Overloads:


public static IEnumerable<TSource> Where<TSource>(this
IEnumerable<TSource> source,
Func<TSource, bool>
predicate);

public static IEnumerable<TSource> Where<TSource>(this


IEnumerable<TSource> source,
Func<TSource, int,
bool> predicate);

Where clause in Query Syntax

The following query sample uses a Where operator to filter the students who is teen ager
from the given collection (sequence). It uses a lambda expression as a predicate function.

Example: Where clause - LINQ query syntax C#


IList<Student> studentList = new List<Student>() {
new Student() { StudentID = 1, StudentName = "John", Age = 13} ,
new Student() { StudentID = 2, StudentName = "Moin", Age =
21 } ,
new Student() { StudentID = 3, StudentName = "Bill", Age =
18 } ,
new Student() { StudentID = 4, StudentName = "Ram" , Age = 20} ,
new Student() { StudentID = 5, StudentName = "Ron" , Age = 15 }
};

var filteredResult = from s in studentList


where s.Age > 12 && s.Age < 20
select s.StudentName;
Example: Where clause - LINQ query syntax in VB.Net
Dim studentList = New List(Of Student) From {
New Student() With {.StudentID = 1, .StudentName = "John", .Age =
13},
New Student() With {.StudentID = 2, .StudentName = "Moin", .Age =
21},
New Student() With {.StudentID = 3, .StudentName = "Bill", .Age =
18},
New Student() With {.StudentID = 4, .StudentName = "Ram", .Age =
20},
New Student() With {.StudentID = 5, .StudentName = "Ron", .Age =
15}
}

Dim filteredResult = From s In studentList


Where s.Age > 12 And s.Age < 20
Select s.StudentName

In the above example, filteredResult will include following students after query execution.

John
Bill
Ron

In the above sample query, the lambda expression body s.Age > 12 && s.Age < 20 is
passed as a predicate function Func<TSource, bool> that evaluates every student in the
collection.

Alternatively, you can also use a Func type delegate with an anonymous method to pass as
a predicate function as below (output would be the same):

Exapmle: Where clause


Func<Student,bool> isTeenAger = delegate(Student s) {
return s.Age > 12 && s.Age < 20;
};

var filteredResult = from s in studentList


where isTeenAger(s)
select s;

You can also call any method that matches with Func parameter with one of Where()
method overloads.

Exapmle: Where clause


public static void Main()
{
var filteredResult = from s in studentList
where isTeenAger(s)
select s;
}

public static bool IsTeenAger(Student stud)


{
return stud.Age > 12 && stud.Age < 20;
}

Where extension method in Method Syntax


Unlike the query syntax, you need to pass whole lambda expression as a predicate function
instead of just body expression in LINQ method syntax.

Example: Where in method syntax in C#


var filteredResult = studentList.Where(s => s.Age > 12 && s.Age < 20);
Example: Where in method syntax in VB.Net
Dim filteredResult = studentList.Where(Function(s) s.Age > 12 And s.Age <
20 )

As mentioned above, the Where extension method also have second overload that includes
index of current element in the collection. You can use that index in your logic if you need.

The following example uses the Where clause to filter out odd elements in the collection
and return only even elements. Please remember that index starts from zero.

Example: Linq - Where extension method in C#


IList<Student> studentList = new List<Student>() {
new Student() { StudentID = 1, StudentName = "John", Age = 18 } ,
new Student() { StudentID = 2, StudentName = "Steve", Age = 15 }
,
new Student() { StudentID = 3, StudentName = "Bill", Age =
25 } ,
new Student() { StudentID = 4, StudentName = "Ram" , Age = 20 } ,
new Student() { StudentID = 5, StudentName = "Ron" , Age = 19 }
};

var filteredResult = studentList.Where((s, i) => {


if(i % 2 == 0) // if it is even element
return true;

return false;
});

foreach (var std in filteredResult)


Console.WriteLine(std.StudentName);
 

Output:
John
Bill
Ron

Multiple Where clause

You can call the Where() extension method more than one time in a single LINQ query.

Example: Multiple where clause in Query Syntax C#


var filteredResult = from s in studentList
where s.Age > 12
where s.Age < 20
select s;
Example: Multiple where clause in Method Syntax C#
var filteredResult = studentList.Where(s => s.Age > 12).Where(s => s.Age
< 20);

Points to Remember :

1. Where is used for filtering the collection based on given criteria.


2. Where extension method has two overload methods. Use a second overload method to
know the index of current element in the collection.
3. Method Syntax requires the whole lambda expression in Where extension method
whereas Query syntax requires only expression body.
4. Multiple Where extension methods are valid in a single LINQ query.

Filtering Operator - OfType


The OfType operator filters the collection based on the ability to cast an element in a
collection to a specified type.

OfType in Query Syntax

Use OfType operator to filter the above collection based on each element's type

Example: OfType operator in C#


IList mixedList = new ArrayList();
mixedList.Add(0);
mixedList.Add("One");
mixedList.Add("Two");
mixedList.Add(3);
mixedList.Add(new Student() { StudentID = 1, StudentName = "Bill" });

var stringResult = from s in mixedList.OfType<string>()


select s;

var intResult = from s in mixedList.OfType<int>()


select s;
Example: OfType operator in VB.Net:
Dim stringResult = From s In mixedList.OfType(Of String)()

The above sample queries will return items whose type is string in the mixedList.
stringResult contains following elements after execution:

One
Two
0
3
Bill

OfType in Method Syntax

You can use OfType<TResult>() extension method in linq method syntax as shown below.

Example: OfType in C#
var stringResult = mixedList.OfType<string>();
Example: OfType in VB.Net
Dim stringResult = mixedList.OfType(Of String)

stringResult would contain following elements.

One
Two

Visit MSDN for more information on Filtering operators.

Points to Remember :

1. The Where operator filters the collection based on a predicate function.


2. The OfType operator filters the collection based on a given type
3. Where and OfType extension methods can be called multiple times in a single
LINQ query.

Sorting Operators: OrderBy &


OrderByDescending
A sorting operator arranges the elements of the collection in ascending or descending order.
LINQ includes following sorting operators.

Sorting Operator Description

Sorts the elements in the collection based on specified fields in ascending or


OrderBy
decending order.

Sorts the collection based on specified fields in descending order. Only valid
OrderByDescending
in method syntax.

ThenBy Only valid in method syntax. Used for second level sorting in ascending order.
Sorting Operator Description

Only valid in method syntax. Used for second level sorting in descending
ThenByDescending
order.

Reverse Only valid in method syntax. Sorts the collection in reverse order.

OrderBy
OrderBy sorts the values of a collection in ascending or descending order. It sorts the
collection in ascending order by default because ascending keyword is optional here. Use
descending keyword to sort collection in descending order.

Example: OrderBy in Query Syntax C#


IList<Student> studentList = new List<Student>() {
new Student() { StudentID = 1, StudentName = "John", Age = 18 } ,
new Student() { StudentID = 2, StudentName = "Steve", Age = 15 } ,
new Student() { StudentID = 3, StudentName = "Bill", Age = 25 } ,
new Student() { StudentID = 4, StudentName = "Ram" , Age = 20 } ,
new Student() { StudentID = 5, StudentName = "Ron" , Age = 19 }
};

var orderByResult = from s in studentList


orderby s.StudentName
select s;

var orderByDescendingResult = from s in studentList


orderby s.StudentName descending
select s;
Example: OrderBy in Query Syntax VB.Net
Dim orderByResult = From s In studentList
Order By s.StudentName
Select s

Dim orderByDescendingResult = From s In studentList


Order By s.StudentName Descending
Select s

orderByResult in the above example would contain following elements after execution:

Bill
John
Ram
Ron
Steve

orderByDescendingResult in the above example would contain following elements after


execution:
Steve
Ron
Ram
John
Bill

OrderBy in Method Syntax

OrderBy extension method has two overloads. First overload of OrderBy extension method
accepts the Func delegate type parameter. So you need to pass the lambda expression for
the field based on which you want to sort the collection.

The second overload method of OrderBy accepts object of IComparer along with Func
delegate type to use custom comparison for sorting.

OrderBy Overload Methods:


public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(this
IEnumerable<TSource> source,
Func<TSource, TKey> keySelector);

public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(this


IEnumerable<TSource> source,
Func<TSource, TKey> keySelector,
IComparer<TKey> comparer);

The following example sorts the studentList collection in ascending order of StudentName
using OrderBy extension method.

Example: OrderBy in Method Syntax C#


IList<Student> studentList = new List<Student>() {
new Student() { StudentID = 1, StudentName = "John", Age = 18 } ,
new Student() { StudentID = 2, StudentName = "Steve", Age = 15 } ,
new Student() { StudentID = 3, StudentName = "Bill", Age = 25 } ,
new Student() { StudentID = 4, StudentName = "Ram" , Age = 20 } ,
new Student() { StudentID = 5, StudentName = "Ron" , Age = 19 }
};

var studentsInAscOrder = studentList.OrderBy(s => s.StudentName);


Example: OrderBy in Method Syntax VB.Net
Dim studentsInAscOrder = studentList.OrderBy(Function(s) s.StudentName)
Note:

Method syntax does not allow the decending keyword to sorts the collection in decending order.
Use OrderByDecending() method for it.

OrderByDescending
OrderByDescending sorts the collection in descending order.

OrderByDescending is valid only with the Method syntax. It is not valid in query syntax
because the query syntax uses ascending and descending attributes as shown above.

Example: OrderByDescending C#
IList<Student> studentList = new List<Student>() {
new Student() { StudentID = 1, StudentName = "John", Age = 18 } ,
new Student() { StudentID = 2, StudentName = "Steve", Age = 15 } ,
new Student() { StudentID = 3, StudentName = "Bill", Age = 25 } ,
new Student() { StudentID = 4, StudentName = "Ram" , Age = 20 } ,
new Student() { StudentID = 5, StudentName = "Ron" , Age = 19 }
};

var studentsInDescOrder = studentList.OrderByDescending(s =>


s.StudentName);
Example: OrderByDescending VB.Net
Dim studentsInDescOrder = studentList.OrderByDescending(Function(s)
s.StudentName)

A result in the above example would contain following elements after execution.

Steve
Ron
Ram
John
Bill

Please note that OrderByDescending is not supported in query syntax. Use the decending
keyword instead.

Multiple Sorting

You can sort the collection on multiple fields seperated by comma. The given collection
would be first sorted based on the first field and then if value of first field would be the
same for two elements then it would use second field for sorting and so on.

Example: Multiple sorting in Query syntax C#


IList<Student> studentList = new List<Student>() {
new Student() { StudentID = 1, StudentName = "John", Age = 18 } ,
new Student() { StudentID = 2, StudentName = "Steve", Age = 15 } ,
new Student() { StudentID = 3, StudentName = "Bill", Age = 25 } ,
new Student() { StudentID = 4, StudentName = "Ram" , Age = 20 } ,
new Student() { StudentID = 5, StudentName = "Ron" , Age = 19 },
new Student() { StudentID = 6, StudentName = "Ram" , Age = 18 }
};

var orderByResult = from s in studentList


orderby s.StudentName, s.Age
select new { s.StudentName, s.Age };

In the above example, studentList collection includes two identical StudentNames, Ram. So
now, studentList would be first sorted based on StudentName and then by Age in ascending
order. So, orderByResult would contain following elements after execution

StudentName: Bill, Age: 25


StudentName: John, Age: 18
StudentName: Ram, Age: 18
StudentName: Ram, Age: 20
StudentName: Ron, Age: 19
StudentName: Steve, Age: 15  

Note:

Multiple sorting in method syntax works differently. Use ThenBy or ThenByDecending extension
methods for secondary sorting.

Points to Remember :

1. LINQ includes five sorting operators: OrderBy, OrderByDescending, ThenBy,


ThenByDescending and Reverse
2. LINQ query syntax does not support OrderByDescending, ThenBy, ThenByDescending and
Reverse. It only supports 'Order By' clause with 'ascending' and 'descending' sorting
direction.
3. LINQ query syntax supports multiple sorting fields seperated by comma whereas you have
to use ThenBy & ThenByDescending methods for secondary sorting.

Sorting Operators: ThenBy &


ThenByDescending
We have seen how to do sorting using multiple fields in query syntax in the previous
section.

Multiple sorting in method syntax is supported by using ThenBy and ThenByDescending


extension methods.

The OrderBy() method sorts the collection in ascending order based on specified field. Use
ThenBy() method after OrderBy to sort the collection on another field in ascending order.
Linq will first sort the collection based on primary field which is specified by OrderBy
method and then sort the resulted collection in ascending order again based on secondary
field specified by ThenBy method.
The same way, use ThenByDescending method to apply secondary sorting in descending
order.

The following example shows how to use ThenBy and ThenByDescending method for
second level sorting:

Example: ThenBy & ThenByDescending


IList<Student> studentList = new List<Student>() {
new Student() { StudentID = 1, StudentName = "John", Age = 18 } ,
new Student() { StudentID = 2, StudentName = "Steve", Age = 15 } ,
new Student() { StudentID = 3, StudentName = "Bill", Age = 25 } ,
new Student() { StudentID = 4, StudentName = "Ram" , Age = 20 } ,
new Student() { StudentID = 5, StudentName = "Ron" , Age = 19 },
new Student() { StudentID = 6, StudentName = "Ram" , Age = 18 }
};
var thenByResult = studentList.OrderBy(s => s.StudentName).ThenBy(s =>
s.Age);

var thenByDescResult = studentList.OrderBy(s =>


s.StudentName).ThenByDescending(s => s.Age);

As you can see in the above example, we first sort a studentList collection by StudentName
and then by Age. So now, thenByResult would contain follwoing elements after sorting:

StudentName: Bill, Age: 25


StudentName: John, Age: 18
StudentName: Ram, Age: 18
StudentName: Ram, Age: 20
StudentName: Ron, Age: 19
StudentName: Steve, Age: 15

thenByDescResult would contain following elements. Please notice that Ram with age 20
comes before Ram with age 18 because it has used ThenByDescending.

StudentName: Bill, Age: 25


StudentName: John, Age: 18
StudentName: Ram, Age: 20
StudentName: Ram, Age: 18
StudentName: Ron, Age: 19
StudentName: Steve, Age: 15

You can use ThenBy and ThenByDescending method same way in VB.Net as below:

Example: ThenBy & ThenByDescending VB.Net


Dim sortedResult = studentList.OrderBy(Function(s) s.StudentName)
.ThenBy(Function(s) s.Age)

Dim sortedResult = studentList.OrderBy(Function(s) s.StudentName)


.ThenByDescending(Function(s) s.Age)
Points to Remember :

1. OrderBy and ThenBy sorts collections in ascending order by default.


2. ThenBy or ThenByDescending is used for second level sorting in method syntax.
3. ThenByDescending method sorts the collection in decending order on another field.
4. ThenBy or ThenByDescending is NOT applicable in Query syntax.
5. Apply secondary sorting in query syntax by separating fields using comma.

Learn about grouping operators next.

Grouping Operators: GroupBy &


ToLookup
The grouping operators do the same thing as the GroupBy clause of SQL query. The
grouping operators create a group of elements based on the given key. This group is
contained in a special type of collection that implements an IGrouping<TKey,TSource>
interface where TKey is a key value, on which the group has been formed and TSource is
the collection of elements that matches with the grouping key value.

Grouping
Description
Operators

The GroupBy operator returns groups of elements based on some key value. Each
GroupBy
group is represented by IGrouping<TKey, TElement> object.

ToLookup is the same as GroupBy; the only difference is the execution of GroupBy
ToLookup
is deferred whereas ToLookup execution is immediate.

GroupBy

A LINQ query can end with a GroupBy or Select clause.

The GroupBy operator returns a group of elements from the given collection based on some
key value. Each group is represented by IGrouping<TKey, TElement> object. Also, the
GroupBy method has eight overload methods, so you can use appropriate extension method
based on your requirement in method syntax.

The result of GroupBy operators is a collection of groups. For example, GroupBy returns
IEnumerable<IGrouping<TKey,Student>> from the Student collection:
Return type of GroupBy()

GroupBy in Query Syntax

The following example creates a groups of students who have same age. Students of the
same age will be in the same collection and each grouped collection will have a key and
inner collection, where the key will be the age and the inner collection will include students
whose age is matched with a key.

Example: GroupBy in Query syntax C#


IList<Student> studentList = new List<Student>() {
new Student() { StudentID = 1, StudentName = "John", Age = 18 } ,
new Student() { StudentID = 2, StudentName = "Steve", Age = 21 }
,
new Student() { StudentID = 3, StudentName = "Bill", Age =
18 } ,
new Student() { StudentID = 4, StudentName = "Ram" , Age = 20 } ,
new Student() { StudentID = 5, StudentName = "Abram" , Age = 21 }
};

var groupedResult = from s in studentList


group s by s.Age;

//iterate each group


foreach (var ageGroup in groupedResult)
{
Console.WriteLine("Age Group: {0}", ageGroup .Key); //Each group has
a key

foreach(Student s in ageGroup) // Each group has inner collection


Console.WriteLine("Student Name: {0}", s.StudentName);
}
Output:
AgeGroup: 18
StudentName: John
StudentName: Bill
AgeGroup: 21
StudentName: Steve
StudentName: Abram
AgeGroup: 20
StudentName: Ram
As you can see in the above example, you can iterate the group using a 'foreach' loop,
where each group contains a key and inner collection. The following figure shows the result
in debug view.

Grouped collection with key and inner collection

Use "Into Group" with the 'Group By' clause in VB.Net as shown below.

Example: GroupBy clause in VB.Net


Dim groupQuery = From s In studentList
Group By s.Age Into Group

For Each group In groupQuery


Console.WriteLine("Age Group: {0}", group.Age) // Each group has key
property name

For Each student In group.Group // Each group has inner collection


Console.WriteLine("Student Name: {0}", student.StudentName)
Next
Next

Notice that each group will have a property name on which group is performed. In the
above example, we have used Age to form a group so each group will have "Age" property
name instead of "Key" as a property name.

Output:
AgeGroup: 18
StudentName: John
StudentName: Bill
AgeGroup: 21
StudentName: Steve
StudentName: Abram
AgeGroup: 20
StudentName: Ram

GroupBy in Method Syntax


The GroupBy() extension method works the same way in the method syntax. Specify the
lambda expression for key selector field name in GroupBy extension method.

Example: GroupBy in method syntax C#


IList<Student> studentList = new List<Student>() {
new Student() { StudentID = 1, StudentName = "John", Age = 18 } ,
new Student() { StudentID = 2, StudentName = "Steve", Age = 21 }
,
new Student() { StudentID = 3, StudentName = "Bill", Age =
18 } ,
new Student() { StudentID = 4, StudentName = "Ram" , Age = 20 } ,
new Student() { StudentID = 5, StudentName = "Abram" , Age = 21 }
};

var groupedResult = studentList.GroupBy(s => s.Age);

foreach (var ageGroup in groupedResult)


{
Console.WriteLine("Age Group: {0}", ageGroup.Key); //Each group has
a key

foreach(Student s in ageGroup) //Each group has a inner collection


Console.WriteLine("Student Name: {0}", s.StudentName);
}
Example: GroupBy in method syntax VB.Net
Dim groupQuery = studentList.GroupBy(Function(s) s.Age)

For Each ageGroup In groupQuery

Console.WriteLine("Age Group: {0}", ageGroup.Key) //Each group has a


key

For Each student In ageGroup.AsEnumerable() //Each group has a inner


collection
Console.WriteLine("Student Name: {0}", student.StudentName)
Next
Next
Output:
AgeGroup: 18
StudentName: John
StudentName: Bill
AgeGroup: 21
StudentName: Steve
StudentName: Abram
AgeGroup: 20
StudentName: Ram
ToLookup

ToLookup is the same as GroupBy; the only difference is GroupBy execution is deferred,
whereas ToLookup execution is immediate. Also, ToLookup is only applicable in Method
syntax. ToLookup is not supported in the query syntax.

Example: ToLookup in method syntax C#


IList<Student> studentList = new List<Student>() {
new Student() { StudentID = 1, StudentName = "John", Age = 18 } ,
new Student() { StudentID = 2, StudentName = "Steve", Age = 21 }
,
new Student() { StudentID = 3, StudentName = "Bill", Age =
18 } ,
new Student() { StudentID = 4, StudentName = "Ram" , Age = 20 } ,
new Student() { StudentID = 5, StudentName = "Abram" , Age = 21 }
};

var lookupResult = studentList.ToLookup(s => s.age);

foreach (var group in lookupResult)


{
Console.WriteLine("Age Group: {0}", group.Key); //Each group has a
key

foreach(Student s in group) //Each group has a inner collection


Console.WriteLine("Student Name: {0}", s.StudentName);
}

Example: ToLookup in method syntax VB.Net


Dim loopupResult = studentList.ToLookup(Function(s) s.Age)

Points to Remember :

1. GroupBy & ToLookup return a collection that has a key and an inner collection based on a
key field value.
2. The execution of GroupBy is deferred whereas that of ToLookup is immediate.
3. A LINQ query syntax can be end with the GroupBy or Select clause.

Joining Operator: Join


The joining operators joins the two sequences (collections) and produce a result.

Joining
Usage
Operators

Join The Join operator joins two sequences (collections) based on a key and returns a
Joining
Usage
Operators

resulted sequence.

The GroupJoin operator joins two sequences based on keys and returns groups of
GroupJoin
sequences. It is like Left Outer Join of SQL.

Join

The Join operator operates on two collections, inner collection & outer collection. It returns
a new collection that contains elements from both the collections which satisfies specified
expression. It is the same as inner join of SQL.

Join in Method Syntax

The Join extension method has two overloads as shown below.

Join Overload Methods:


public static IEnumerable<TResult> Join<TOuter, TInner, TKey,
TResult>(this IEnumerable<TOuter> outer,
IEnumerable<TInner> inner, Func<TOuter, TKey>
outerKeySelector,
Func<TInner, TKey> innerKeySelector,
Func<TOuter, TInner, TResult> resultSelector);

public static IEnumerable<TResult> Join<TOuter, TInner, TKey,


TResult>(this IEnumerable<TOuter> outer,
IEnumerable<TInner> inner,
Func<TOuter, TKey> outerKeySelector,
Func<TInner, TKey> innerKeySelector,
Func<TOuter, TInner, TResult> resultSelector,
IEqualityComparer<TKey> comparer);

As you can see in the first overload method takes five input parameters (except the first
'this' parameter): 1) outer 2) inner 3) outerKeySelector 4) innerKeySelector 5)
resultSelector.

Let's take a simple example. The following example joins two string collection and return
new collection that includes matching strings in both the collection.

Example: Join operator C#


IList<string> strList1 = new List<string>() {
"One",
"Two",
"Three",
"Four"
};
IList<string> strList2 = new List<string>() {
"One",
"Two",
"Five",
"Six"
};

var innerJoin = strList1.Join(strList2,


str1 => str1,
str2 => str2,
(str1, str2) => str1);
One
Two

Now, let's understand join metohod using following Student and Standard class where
Student class includes StandardID that matches with StandardID of Standard class.

Example Classes
public class Student{
public int StudentID { get; set; }
public string StudentName { get; set; }
public int StandardID { get; set; }
}

public class Standard{


public int StandardID { get; set; }
public string StandardName { get; set; }
}

The following example demonstrates LINQ Join query.

Example: Join Query C#


IList<Student> studentList = new List<Student>() {
new Student() { StudentID = 1, StudentName = "John", StandardID =1 },
new Student() { StudentID = 2, StudentName = "Moin", StandardID =1 },
new Student() { StudentID = 3, StudentName = "Bill", StandardID =2 },
new Student() { StudentID = 4, StudentName = "Ram" , StandardID =2 },
new Student() { StudentID = 5, StudentName = "Ron" }
};

IList<Standard> standardList = new List<Standard>() {


new Standard(){ StandardID = 1, StandardName="Standard 1"},
new Standard(){ StandardID = 2, StandardName="Standard 2"},
new Standard(){ StandardID = 3, StandardName="Standard 3"}
};

var innerJoin = studentList.Join(// outer sequence


standardList, // inner sequence
student => student.StudentID, //
outerKeySelector
standard => standard.StandardID, //
innerKeySelector
(student, standard) => new // result selector
{
StudentName =
student.StudentName,
StandardName =
standard.StandardName
});

The following image illustrate the parts of Join operator in the above example.

join operator

In the above example of join query, studentList is outer sequence because query starts from
it. First parameter in Join method is used to specify the inner sequence which is
standardList in the above example. Second and third parameter of Join method is used to
specify a field whose value should be match using lambda expression in order to include
element in the result. The key selector for the outer sequence student =>
student.StandardID indicates that take StandardID field of each elements of studentList
should be match with the key of inner sequence standard => standard.StandardID. If
value of both the key field is matched then include that element into result.

The last parameter in Join method is an expression to formulate the result. In the above
example, result selector includes StudentName and StandardName property of both the
sequence.

StandardID Key of both the sequences (collections) must match otherwise the item will not
be included in the result. For example, Ron is not associated with any standard so Ron is
not included in the result collection. innerJoinResult in the above example would contain
following elements after execution:

John - Standard 1
Moin - Standard 1
Bill - Standard 2
Ram - Standard 2

The following example demonstrates the Join operator in method syntax in VB.Net.
Example: Join operator VB.Net
Dim innerJoin = studentList.Join(standardList,
Function(s) s.StandardID,
Function(std) std.StandardID,
Function(s, std) New With
{
.StudentName = s.StudentName,
.StandardName = std.StandardName
});

Join in Query Syntax

Join operator in query syntax works slightly different than method syntax. It requires outer
sequence, inner sequence, key selector and result selector. 'on' keyword is used for key
selector where left side of 'equals' operator is outerKeySelector and right side of 'equals' is
innerKeySelector.

Syntax: Join in query syntax


from ... in outerSequence

join ... in innerSequence

on outerKey equals innerKey

select ...

The following example of Join operator in query syntax returns a collection of elements
from studentList and standardList if their Student.StandardID and
Standard.StandardID is match.

Example: Join operator in query syntax C#


IList<Student> studentList = new List<Student>() {
new Student() { StudentID = 1, StudentName = "John", Age = 13,
StandardID =1 },
new Student() { StudentID = 2, StudentName = "Moin", Age = 21,
StandardID =1 },
new Student() { StudentID = 3, StudentName = "Bill", Age = 18,
StandardID =2 },
new Student() { StudentID = 4, StudentName = "Ram" , Age = 20,
StandardID =2 },
new Student() { StudentID = 5, StudentName = "Ron" , Age = 15 }
};

IList<Standard> standardList = new List<Standard>() {


new Standard(){ StandardID = 1, StandardName="Standard 1"},
new Standard(){ StandardID = 2, StandardName="Standard 2"},
new Standard(){ StandardID = 3, StandardName="Standard 3"}
};

var innerJoin = from s in studentList // outer sequence


join st in standardList //inner sequence
on s.StandardID equals st.StandardID // key
selector
select new { // result selector
StudentName = s.StudentName,
StandardName = st.StandardName
};
Example: Join operator in query syntax VB.Net
Dim innerJoin = From s In studentList ' outer sequence
Join std In standardList ' inner sequence
On s.StandardID Equals std.StandardID ' key
selector
Select _ ' result selector
StudentName = s.StudentName,
StandardName = std.StandardName
Output:
John - Standard 1
Moin - Standard 1
Bill - Standard 2
Ram - Standard 2

Note:

Use the equals operator to match key selector in query syntax. == is not valid.

Points to Remember :

1. Join and GroupJoin are joining operators.


2. Join is like inner join of SQL. It returns a new collection that contains common elements
from two collections whosh keys matches.
3. Join operates on two sequences inner sequence and outer sequence and produces a result
sequence.
4. Join query syntax:
5. from... in outerSequence
6. join... in innerSequence
7. on outerKey equals innerKey
8. select ...

Joining Operator: GroupJoin


We have seen the Join operator in the previous section. The GroupJoin operator performs
the same task as Join operator except that GroupJoin returns a result in group based on
specified group key. The GroupJoin operator joins two sequences based on key and groups
the result by matching key and then returns the collection of grouped result and key.

GroupJoin requires same parameters as Join. GroupJoin has following two overload
methods:
GroupJoin Overload Methods:
public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey,
TResult>(this IEnumerable<TOuter> outer, IEnumerable<TInner> inner,
Func<TOuter, TKey> outerKeySelector, Func<TInner, TKey> innerKeySelector,
Func<TOuter, IEnumerable<TInner>, TResult> resultSelector);

public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey,


TResult>(this IEnumerable<TOuter> outer, IEnumerable<TInner> inner,
Func<TOuter, TKey> outerKeySelector, Func<TInner, TKey> innerKeySelector,
Func<TOuter, IEnumerable<TInner>, TResult> resultSelector,
IEqualityComparer<TKey> comparer);

As you can see in the first overload method takes five input parameters (except the first
'this' parameter): 1) outer 2) inner 3) outerKeySelector 4) innerKeySelector 5)
resultSelector. Please notice that resultSelector is of Func delegate type that has second
input parameter as IEnumerable type for inner sequence.

Now, let's understand GroupJoin using following Student and Standard class where Student
class includes StandardID that matches with StandardID of Standard class.

Example Classes
public class Student{
public int StudentID { get; set; }
public string StudentName { get; set; }
public int StandardID { get; set; }
}

public class Standard{


public int StandardID { get; set; }
public string StandardName { get; set; }
}

Consider the following GroupJoin query example.

Example: GroupJoin in Method syntax C#


IList<Student> studentList = new List<Student>() {
new Student() { StudentID = 1, StudentName = "John", StandardID =1 },
new Student() { StudentID = 2, StudentName = "Moin", StandardID =1 },
new Student() { StudentID = 3, StudentName = "Bill", StandardID =2 },
new Student() { StudentID = 4, StudentName = "Ram", StandardID =2 },
new Student() { StudentID = 5, StudentName = "Ron" }
};

IList<Standard> standardList = new List<Standard>() {


new Standard(){ StandardID = 1, StandardName="Standard 1"},
new Standard(){ StandardID = 2, StandardName="Standard 2"},
new Standard(){ StandardID = 3, StandardName="Standard 3"}
};

var groupJoin = standardList.GroupJoin(studentList, //inner sequence


std => std.StandardID, //outerKeySelector
s => s.StandardID, //innerKeySelector
(std, studentsGroup) => new //
resultSelector
{
Students = studentsGroup,
StandarFulldName = std.StandardName
});

foreach (var item in groupJoin)


{
Console.WriteLine(item.StandarFulldName );

foreach(var stud in item.Students)


Console.WriteLine(stud.StudentName);
}
Output:
Standard 1:
John,
Moin,
Standard 2:
Bill,
Ram,
Standard 3:

In the above example of GroupJoin query, standardList is the outer sequence, because the
query starts from it. The first parameter in GroupJoin method is to specify the inner
sequence, which is studentList in the above example. The second and third parameters of
the GroupJoin() method are to specify a field whose value should be matched using lambda
expression, in order to include element in the result. The key selector for the outer sequence
standard => standard.StandardID indicates that StandardID field of each elements in
standardList should be match with the key of inner sequence studentList student =>
student.StandardID. If value of both the key field is matched then include that element
into grouped collection studentsGroup where key would be StandardID.

The last parameter in Join method is an expression to formulate the result. In the above
example, result selector includes grouped collection studentGroup and StandardName.

The following image illustrate that inner sequence grouped into studentsGroup collection
for matching StandardID key and that grouped collection can be used to formulate the
result.
Grouping Operator - GroupJoin

Resultset would include an anonymous objects that has the Students and StandardFullName
properties. Students property will be a collection of Students whose StandardID matches
with Standard.StandardID.

GroupJoin Result in Debug View

You can access the result using a 'foreach' loop. Each element will have the
StandardFullName & Students property, where Students will be a collection.

Example: Access GroupJoin Result in C#


foreach (var item in groupJoinResult)
{
Console.WriteLine(item.StandarFulldName );

foreach(var stud in item.Students)


Console.WriteLine(stud.StudentName);
}

Following is an example of GroupJoin in VB.Net:


Example: GroupJoin in Method VB.Net
Dim groupJoin = standardList.GroupJoin( ' outer sequence
studentList, ' inner sequence
Function(s) s.StandardID, ' outerKeySelector
Function(stud) stud.StandardID, ' innerKeySelector
Function(s, studentGroup) New With { ' result
selector
.students = studentGroup,
.standardName = s.StandardName
})

For Each item In groupJoin

Console.WriteLine(item.standardName)

For Each std In item.students


Console.WriteLine( std.StudentName)
Next

Next
Output:
Standard 1:
John,
Moin,
Standard 2:
Bill,
Ram,
Standard 3:

GroupJoin in Query Syntax

GroupJoin operator in query syntax works slightly different than method syntax. It requires
an outer sequence, inner sequence, key selector and result selector. 'on' keyword is used for
key selector where the left side of 'equals' operator is the outerKeySelector and the right
side of 'equals' is the innerKeySelector. Use the into keyword to create the grouped
collection.

Syntax: GroupJoin in Query Syntax


from ... in outerSequence

join ... in innerSequence

on outerKey equals innerKey

into groupedCollection

select ...

The following example demonstrates the GroupJoin in query syntax.


Example: GroupJoin Query Syntax C#
IList<Student> studentList = new List<Student>() {
new Student() { StudentID = 1, StudentName = "John",
Age = 13, StandardID =1 },
new Student() { StudentID = 2, StudentName = "Moin",
Age = 21, StandardID =1 },
new Student() { StudentID = 3, StudentName = "Bill",
Age = 18, StandardID =2 },
new Student() { StudentID = 4, StudentName = "Ram" ,
Age = 20, StandardID =2 },
new Student() { StudentID = 5, StudentName = "Ron" ,
Age = 15 }
};

IList<Standard> standardList = new List<Standard>() {


new Standard(){ StandardID = 1,
StandardName="Standard 1"},
new Standard(){ StandardID = 2,
StandardName="Standard 2"},
new Standard(){ StandardID = 3,
StandardName="Standard 3"}
};

var groupJoin = from std in standardList


join s in studentList
on std.StandardID equals s.StandardID
into studentGroup
select new {
Students = studentGroup ,
StandardName = std.StandardName
};

foreach (var item in groupJoin)


{
Console.WriteLine(item.StandarFulldName );

foreach(var stud in item.Students)


Console.WriteLine(stud.StudentName);
}
Example: GroupJoin Query Syntax VB.Net
Dim groupJoin = From s In standardList
Group Join stud In studentList
On stud.StandardID Equals s.StandardID
Into Group _
Select _
StudentsGroup = Group,
StandardName = s.StandardName
Output:
Standard 1:
John,
Moin,
Standard 2:
Bill,
Ram,
Standard 3:

In the VB.Net, the InTo keyword will create a group of all students of same standard and
assign it to the Group keyword. So, use Group in the projection result.

Note:

Use of the equals operator to match key selector. == is not valid.

Projection Operators: Select, SelectMany


There are two projection operators available in LINQ. 1) Select 2) SelectMany

Select

The Select operator always returns an IEnumerable collection which contains elements
based on a transformation function. It is similar to the Select clause of SQL that produces a
flat result set.

Now, let's understand Select query operator using the following Student class.

public class Student{


public int StudentID { get; set; }
public string StudentName { get; set; }
public int Age { get; set; }
}

Select in Query Syntax

LINQ query syntax must end with a Select or GroupBy clause. The following example
demonstrates select operator that returns a string collection of StudentName.

Example: Select in Query Syntax C#


IList<Student> studentList = new List<Student>() {
new Student() { StudentID = 1, StudentName = "John" },
new Student() { StudentID = 2, StudentName = "Moin" },
new Student() { StudentID = 3, StudentName = "Bill" },
new Student() { StudentID = 4, StudentName = "Ram" },
new Student() { StudentID = 5, StudentName = "Ron" }
};

var selectResult = from s in studentList


select s.StudentName;
The select operator can be used to formulat the result as per our requirement. It can be used
to return a collection of custom class or anonymous type which includes properties as per
our need.

The following example of the select clause returns a collection of anonymous type
containing the Name and Age property.

Example: Select in Query Syntax C#


IList<Student> studentList = new List<Student>() {
new Student() { StudentID = 1, StudentName = "John", Age = 13 } ,
new Student() { StudentID = 2, StudentName = "Moin", Age = 21 } ,
new Student() { StudentID = 3, StudentName = "Bill", Age = 18 } ,
new Student() { StudentID = 4, StudentName = "Ram" , Age = 20 } ,
new Student() { StudentID = 5, StudentName = "Ron" , Age = 15 }
};

// returns collection of anonymous objects with Name and Age property


var selectResult = from s in studentList
select new { Name = "Mr. " + s.StudentName, Age =
s.Age };

// iterate selectResult
foreach (var item in selectResult)
Console.WriteLine("Student Name: {0}, Age: {1}", item.Name,
item.Age);
Example: Select in Query Syntax VB.Net
Dim selectResult = From s In studentList
Select New With {.Name = s.StudentName, .Age = s.Age}
Output:
Student Name: Mr. John, Age: 13
Student Name: Mr. Moin, Age: 21
Student Name: Mr. Bill, Age: 18
Student Name: Mr. Ram, Age: 20
Student Name: Mr. Ron, Age: 15

Select in Method Syntax

The Select operator is optional in method syntax. However, you can use it to shape the data.
In the following example, Select extension method returns a collection of anonymous
object with the Name and Age property:

Example: Select in Method Syntax C#


IList<Student> studentList = new List<Student>() {
new Student() { StudentID = 1, StudentName = "John", Age = 18 } ,
new Student() { StudentID = 2, StudentName = "Moin", Age = 21 } ,
new Student() { StudentID = 3, StudentName = "Bill", Age = 18 } ,
new Student() { StudentID = 4, StudentName = "Ram" , Age = 20 } ,
new Student() { StudentID = 5, StudentName = "Ron" , Age = 21 }
};
var selectResult = studentList.Select(s => new { Name = s.StudentName ,
Age = s.Age });

In the above example, selectResult would contain anonymous objects with Name and Age
property as shown below in the debug view.

Select clause returns an Anonymous objects

Example: Select in Method Syntax VB.Net


Dim selectResult = studentList.Select(Function(s) New With {.Name =
s.StudentName,
.Age =
s.Age})
Select Many

The SelectMany operator projects sequences of values that are based on a transform
function and then flattens them into one sequence.

Visit MSDN for more information on projection operators.

Quantifier Operators
The quantifier operators evaluate elements of the sequence on some condition and return a
boolean value to indicate that some or all elements satisfy the condition.

Operator Description

All Checks if all the elements in a sequence satisfies the specified condition

Any Checks if any of the elements in a sequence satisfies the specified condition

Contains Checks if the sequence contains a specific element


All

The All operator evalutes each elements in the given collection on a specified condition and
returns True if all the elements satisfy a condition.

Example: All operator C#


IList<Student> studentList = new List<Student>() {
new Student() { StudentID = 1, StudentName = "John", Age = 18 } ,
new Student() { StudentID = 2, StudentName = "Steve", Age = 15 }
,
new Student() { StudentID = 3, StudentName = "Bill", Age =
25 } ,
new Student() { StudentID = 4, StudentName = "Ram" , Age = 20 } ,
new Student() { StudentID = 5, StudentName = "Ron" , Age = 19 }
};

// checks whether all the students are teenagers


bool areAllStudentsTeenAger = studentList.All(s => s.Age > 12 && s.Age <
20);

Console.WriteLine(areAllStudentsTeenAger);
Example: All operator VB.Net
Dim areAllStudentsTeenAger = studentList.All(Function(s) s.Age > 12 And
s.Age < 20)
Output:
false

Any

Any checks whether any element satisfy given condition or not? In the following example,
Any operation is used to check whether any student is teen ager or not.

Example: Any operator C#


bool isAnyStudentTeenAger = studentList.Any(s => s.age > 12 && s.age <
20);
Example: Any operator VB.Net
Dim isAnyStudentTeenAger = studentList.Any(Function(s) s.Age > 12 And
s.Age < 20)
Output:
true

Note:

Quantifier operators are Not Supported with C# query syntax.

Learn about quanifier operator - Contains in the next section.


Quantifier Operator: Contains
The Contains operator checks whether a specified element exists in the collection or not
and returns a boolean.

The Contains() extension method has following two overloads. The first overload method
requires a value to check in the collection and the second overload method requires
additional parameter of IEqualityComparer type for custom equalality comparison.

Contains() Overloads:
public static bool Contains<TSource>(this IEnumerable<TSource> source,
TSource value);

public static bool Contains<TSource>(this IEnumerable<TSource> source,


TSource value,
IEqualityComparer<TSource> comparer);

As mentioned above, the Contains() extension method requires a value to check as a input
parameter. Type of a value must be same as type of generic collection. The following
example of Contains checks whether 10 exists in the collection or not. Please notice that
int is a type of generic collection.

Example: Contains operator C#


IList<int> intList = new List<int>() { 1, 2, 3, 4, 5 };
bool result = intList.Contains(10); // returns false
Example: Contains operator VB.Net
Dim intList As IList(Of Integer) = New List(Of Integer) From {1, 2, 3, 4,
5}
Dim result = intList.Contains(10) ' returns false

The above example works well with primitive data types. However, it will not work with a
custom class. Consider the following example:

Error:
IList<Student> studentList = new List<Student>() {
new Student() { StudentID = 1, StudentName = "John", Age = 18 } ,
new Student() { StudentID = 2, StudentName = "Steve", Age = 15 }
,
new Student() { StudentID = 3, StudentName = "Bill", Age =
25 } ,
new Student() { StudentID = 4, StudentName = "Ram" , Age = 20 } ,
new Student() { StudentID = 5, StudentName = "Ron" , Age = 19 }
};

Student std = new Student(){ StudentID =3, StudentName = "Bill"};


bool result = studentList.Contains(std); //returns false
As you can see in the above example, Contains returns false even if "Bill" exists in the
studentList. This is because the Contains extension method only compares reference of an
object but not the actual values of an object. So to compare values of the student object,
you need to create a class by implementing IEqualityComparer interface, that compares
values of two Student objects and returns boolean.

The following is a StudentComparer class that implements IEqualityComparer<Student>


interface to compare values of two Students objects:

Example: IEqualityComperer
class StudentComparer : IEqualityComparer<Student>
{
public bool Equals(Student x, Student y)
{
if (x.StudentID == y.StudentID &&
x.StudentName.ToLower() ==
y.StudentName.ToLower())
return true;

return false;
}

public int GetHashCode(Student obj)


{
return obj.GetHashCode();
}
}

Now, you can use the above StudentComparer class in second overload method of Contains
extension method that accepts second parameter of IEqualityComparer type, as below:

Example: Contains with Comparer class C#


IList<Student> studentList = new List<Student>() {
new Student() { StudentID = 1, StudentName = "John", Age = 18 } ,
new Student() { StudentID = 2, StudentName = "Steve", Age = 15 }
,
new Student() { StudentID = 3, StudentName = "Bill", Age =
25 } ,
new Student() { StudentID = 4, StudentName = "Ram" , Age = 20 } ,
new Student() { StudentID = 5, StudentName = "Ron" , Age = 19 }
};

Student std = new Student(){ StudentID =3, StudentName = "Bill"};


bool result = studentList.Contains(std, new StudentComparer()); //returns
true

So thus, you have to use comparer class in order to get corrent result from Contains
extension method for custom classes.

The following is a similar example in VB.Net:


Example: Contains with Comparer class VB.Net
public class Student
{
public int StudentID { get; set; }
public string StudentName { get; set; }
public int Age { get; set; }
}

Public Class StudentComparer Implements IEqualityComparer(Of Student)

Public Function Equals1(x As Student, y As Student) As Boolean


Implements IEqualityComparer(Of Student).Equals
If (x.StudentID = y.StudentID And x.StudentName.ToLower() =
y.StudentName.ToLower()) Then
Return True
End If

Return False
End Function

Public Function GetHashCode1(obj As Student) As Integer Implements


IEqualityComparer(Of Student).GetHashCode
Return obj.GetHashCode()
End Function
End Class

Sub Main
Dim studentList = New List(Of Student) From {
New Student() With {.StudentID = 1, .StudentName = "John", .Age =
18},
New Student() With {.StudentID = 2, .StudentName = "Steve", .Age
= 15},
New Student() With {.StudentID = 3, .StudentName = "Bill", .Age =
25},
New Student() With {.StudentID = 4, .StudentName = "Ram", .Age =
20},
New Student() With {.StudentID = 5, .StudentName = "Ron", .Age =
19}
}

Dim std As New Student With {.StudentID = 3, .StudentName = "Bill"}


Dim result = studentList.Contains(std, New StudentComparer()) '
returns true
End Sub
Note:
Quantifier operators are Not Supported with query syntax in C# or VB.Net.
Points to Remember :

1. All, Any & Contains are quantifier operators in LINQ.


2. All checks if all the elements in a sequence satisfies the specified condition.
3. Any check if any of the elements in a sequence satisfies the specified condition
4. Contains operator checks whether specified element exists in the collection or not.
5. Use custom class that derives IEqualityOperator with Contains to check for the
object in the collection.
6. All, Any & Contains are not supported in query syntax in C# or VB.Net.

Learn about aggregate operator next.

Aggregation Operators: Aggregate


The aggregation operators perform mathematical operations like Average, Aggregate,
Count, Max, Min and Sum, on the numeric property of the elements in the collection.

Method Description

Aggregate Performs a custom aggregation operation on the values in the collection.

Average calculates the average of the numeric items in the collection.

Count Counts the elements in a collection.

LongCount Counts the elements in a collection.

Max Finds the largest value in the collection.

Min Finds the smallest value in the collection.

Sum Calculates sum of the values in the collection.

Aggregate

The Aggregate method performs an accumulate operation. Aggregate extension method has
the following overload methods:

Aggregate() Overloads:
public static TSource Aggregate<TSource>(this IEnumerable<TSource>
source,
Func<TSource, TSource, TSource>
func);

public static TAccumulate Aggregate<TSource, TAccumulate>(this


IEnumerable<TSource> source,
TAccumulate seed,
Func<TAccumulate, TSource,
TAccumulate> func);

public static TResult Aggregate<TSource, TAccumulate, TResult>(this


IEnumerable<TSource> source,
TAccumulate seed,
Func<TAccumulate, TSource,
TAccumulate> func,
Func<TAccumulate, TResult>
resultSelector);

The following example demonstrates Aggregate method that returns comma seperated
elements of the string list.

Example: Aggregate in Method Syntax C#


IList<String> strList = new List<String>() { "One", "Two", "Three",
"Four", "Five"};

var commaSeperatedString = strList.Aggregate((s1, s2) => s1 + ", " + s2);

Console.WriteLine(commaSeperatedString);
Output:
One, Two, Three, Four, Five

In the above example, Aggregate extension method returns comma separated strings from
strList collection. The following image illustrates the whole aggregate operation performed
in the above example.

Aggregate extension method

As per the above figure, first item of strList "One" will be pass as s1 and rest of the items
will be passed as s2. The lambda expression (s1, s2) => s1 + ", " + s2 will be
treated like s1 = s1 + ", " + s1 where s1 will be accumulated for each item in the
collection. Thus, Aggregate method will return comma separated string.
Example: Aggregate in Method Syntax VB.Net
Dim strList As IList(Of String) = New List(Of String) From {
"One",
"Two",
"Three",
"Four",
"Five"
}

Dim commaSeparatedString = strList.Aggregate(Function(s1, s2) s1 + ", " +


s2)
Aggregate Method with Seed Value

The second overload method of Aggregate requires first parameter for seed value to
accumulate. Second parameter is Func type delegate:
TAccumulate Aggregate<TSource, TAccumulate>(TAccumulate seed,
Func<TAccumulate, TSource, TAccumulate> func); .

The following example uses string as a seed value in the Aggregate extension method.

Example: Aggregate with Seed Value C#


// Student collection
IList<Student> studentList = new List<Student>>() {
new Student() { StudentID = 1, StudentName = "John", Age = 13} ,
new Student() { StudentID = 2, StudentName = "Moin", Age =
21 } ,
new Student() { StudentID = 3, StudentName = "Bill", Age =
18 } ,
new Student() { StudentID = 4, StudentName = "Ram" , Age = 20} ,
new Student() { StudentID = 5, StudentName = "Ron" , Age = 15 }
};

string commaSeparatedStudentNames = studentList.Aggregate<Student,


string>(
"Student Names: ", // seed value
(str, s) => str += s.StudentName
+ "," );

Console.WriteLine(commaSeparatedStudentNames);
Example: Aggregate with Seed Value VB.Net
// Student collection
Dim studentList = New List(Of Student) From {
New Student() With {.StudentID = 1, .StudentName = "John", .Age =
13},
New Student() With {.StudentID = 2, .StudentName = "Moin", .Age =
21},
New Student() With {.StudentID = 3, .StudentName = "Bill", .Age =
18},
New Student() With {.StudentID = 4, .StudentName = "Ram", .Age =
20},
New Student() With {.StudentID = 5, .StudentName = "Ron", .Age =
15}
}
Dim commaSeparatedStudentNames = studentList.Aggregate(Of String)(
"Student Names: ",
Function(str, s) str + s.StudentName + ",")

Console.WriteLine(commaSeparatedStudentNames);
Output:
Student Names: John, Moin, Bill, Ram, Ron,

In the above example, the first parameter of the Aggregate method is the "Student Names: "
string that will be accumulated with all student names. The comma in the lambda
expression will be passed as a second parameter.

The following example use Aggregate operator to add the age of all the students.

Example: Aggregate with Seed Value C#


// Student collection
IList<Student> studentList = new List<Student>>() {
new Student() { StudentID = 1, StudentName = "John", Age = 13} ,
new Student() { StudentID = 2, StudentName = "Moin", Age =
21 } ,
new Student() { StudentID = 3, StudentName = "Bill", Age =
18 } ,
new Student() { StudentID = 4, StudentName = "Ram" , Age = 20} ,
new Student() { StudentID = 5, StudentName = "Ron" , Age = 15 }
};

int SumOfStudentsAge = studentList.Aggregate<Student, int>(0,


(totalAge, s) => totalAge
+= s.Age );
Aggregate Method with Result Selector

Now, let's see third overload method that required the third parameter of the Func delegate
expression for result selector, so that you can formulate the result.

Example: Aggregate with Result Selector C#


IList<Student> studentList = new List<Student>>() {
new Student() { StudentID = 1, StudentName = "John", Age = 13} ,
new Student() { StudentID = 2, StudentName = "Moin", Age =
21 } ,
new Student() { StudentID = 3, StudentName = "Bill", Age =
18 } ,
new Student() { StudentID = 4, StudentName = "Ram" , Age = 20} ,
new Student() { StudentID = 5, StudentName = "Ron" , Age = 15 }
};

string commaSeparatedStudentNames = studentList.Aggregate<Student,


string,string>(
String.Empty, // seed value
(str, s) => str +=
s.StudentName + ",", // returns result using seed value, String.Empty
goes to lambda expression as str
str =>
str.Substring(0,str.Length - 1 )); // result selector that removes last
comma

Console.WriteLine(commaSeparatedStudentNames);

In the above example, we have specified a lambda expression str =>


str.Substring(0,str.Length - 1 ) which will remove the last comma in the string
result. Below is the same example in VB.Net.

Example: Aggregate with Result Selector VB.Net


// Student collection
Dim studentList = New List(Of Student) From {
New Student() With {.StudentID = 1, .StudentName = "John", .Age =
13},
New Student() With {.StudentID = 2, .StudentName = "Moin", .Age =
21},
New Student() With {.StudentID = 3, .StudentName = "Bill", .Age =
18},
New Student() With {.StudentID = 4, .StudentName = "Ram", .Age =
20},
New Student() With {.StudentID = 5, .StudentName = "Ron", .Age =
15}
}

Dim commaSeparatedStudentNames = studentList.Aggregate(Of String, String)


(
String.Empty,
Function(str, s) str + s.StudentName + ",",
Function(str) str.Substring(0, str.Length - 1))

Console.WriteLine(commaSeparatedStudentNames);
Output:
John, Moin, Bill, Ram, Ron

Note:

Aggregate operator is Not Supported with query syntax in C# or VB.Net.

Learn about another aggregate operator - Average in the next section.

Aggregation Operator: Average


Average extension method calculates the average of the numeric items in the collection.
Average method returns nullable or non-nullable decimal, double or float value.
The following example demonstrate Agerage method that returns average value of all the
integers in the collection.

Example: Average Method C#


IList<int> intList = new List<int>>() { 10, 20, 30 };

var avg = intList.Average();

Console.WriteLine("Average: {0}", avg);

You can specify an int, decimal, double or float property of a class as a lambda expression
of which you want to get an average value. The following example demonstrates Average
method on the complex type.

Example: Average in Method Syntax C#


IList<Student> studentList = new List<Student>>() {
new Student() { StudentID = 1, StudentName = "John", Age = 13} ,
new Student() { StudentID = 2, StudentName = "Moin", Age =
21 } ,
new Student() { StudentID = 3, StudentName = "Bill", Age =
18 } ,
new Student() { StudentID = 4, StudentName = "Ram" , Age = 20} ,
new Student() { StudentID = 5, StudentName = "Ron" , Age = 15 }
};

var avgAge = studentList.Average(s => s.Age);

Console.WriteLine("Average Age of Student: {0}", avgAge);


Example: Average in Method Syntax VB.Net
Dim studentList = New List(Of Student) From {
New Student() With {.StudentID = 1, .StudentName = "John", .Age =
13},
New Student() With {.StudentID = 2, .StudentName = "Moin", .Age =
21},
New Student() With {.StudentID = 3, .StudentName = "Bill", .Age =
18},
New Student() With {.StudentID = 4, .StudentName = "Ram", .Age =
20},
New Student() With {.StudentID = 5, .StudentName = "Ron", .Age =
15}
}

Dim avgAge = studentList.Average(Function(s) s.Age)

Console.WriteLine("Average Age of Student: {0}", avgAge)


Output:
Average Age of Student: 17.4

The Average operator in query syntax is Not Supported in C#. However, it is supported in
VB.Net as shown below.
Example: Average in Query Syntax VB.Net
Dim studentList = New List(Of Student) From {
New Student() With {.StudentID = 1, .StudentName = "John", .Age =
13},
New Student() With {.StudentID = 2, .StudentName = "Moin", .Age =
21},
New Student() With {.StudentID = 3, .StudentName = "Bill", .Age =
18},
New Student() With {.StudentID = 4, .StudentName = "Ram", .Age =
20},
New Student() With {.StudentID = 5, .StudentName = "Ron", .Age =
15}
}

Dim avgAge = Aggregate st In studentList Into Average(st.Age)

Console.WriteLine("Average Age of Student: {0}", avgAge)


Output:
Average Age of Student: 17.4

Learn about another aggregate operator - Count in the next section.

Aggregation Operator: Count


The Count operator returns the number of elements in the collection or number of elements
that have satisfied the given condition.

The Count() extension method has the following two overloads:

Count() Overloads:
int Count<TSource>();

int Count<TSource>(Func<TSource, bool> predicate);

The first overload method of Count returns the number of elements in the specified
collection, whereas the second overload method returns the number of elements which have
satisfied the specified condition given as lambda expression/predicate function.

The following example demonstrates Count() on primitive collection.

Example: Count() - C#
IList<int> intList = new List<int>() { 10, 21, 30, 45, 50 };

var totalElements = intList.Count();


Console.WriteLine("Total Elements: {0}", totalElements);

var evenElements = intList.Count(i => i%2 == 0);

Console.WriteLine("Even Elements: {0}", evenElements);


Output:
Total Elements: 5
Even Elements: 3

The following example demonstrates Count() method on the complex type collection.

Example: Count() in C#
IList<Student> studentList = new List<Student>>() {
new Student() { StudentID = 1, StudentName = "John", Age = 13} ,
new Student() { StudentID = 2, StudentName = "Moin", Age =
21 } ,
new Student() { StudentID = 3, StudentName = "Bill", Age =
18 } ,
new Student() { StudentID = 4, StudentName = "Ram" , Age = 20} ,
new Student() { StudentID = 5, StudentName = "Mathew" , Age =
15 }
};

var totalStudents = studentList.Count();

Console.WriteLine("Total Students: {0}", totalStudents);

var adultStudents = studentList.Count(s => s.Age >= 18);

Console.WriteLine("Number of Adult Students: {0}", adultStudents );


Output:
Total Students: 5
Number of Adult Students: 3

Example: Count() in VB.Net


Dim studentList = New List(Of Student) From {
New Student() With {.StudentID = 1, .StudentName = "John", .Age =
13},
New Student() With {.StudentID = 2, .StudentName = "Moin", .Age =
21},
New Student() With {.StudentID = 3, .StudentName = "Bill", .Age =
18},
New Student() With {.StudentID = 4, .StudentName = "Ram", .Age =
20},
New Student() With {.StudentID = 5, .StudentName = "Ron", .Age =
15}
}

Dim totalStudents = studentList.Count()

Console.WriteLine("Total Students: {0}", totalStudents)


Output:
Total Students: 5

Note:

Count(predicate) extension method with predicate parameter is Not Supported in VB.Net.

Count Operator in Query Syntax


Example: Count operator in query syntax - VB.Net
// Student collection
Dim studentList = New List(Of Student) From {
New Student() With {.StudentID = 1, .StudentName = "John", .Age =
13},
New Student() With {.StudentID = 2, .StudentName = "Moin", .Age =
21},
New Student() With {.StudentID = 3, .StudentName = "Bill", .Age =
18},
New Student() With {.StudentID = 4, .StudentName = "Ram", .Age =
20},
New Student() With {.StudentID = 5, .StudentName = "Ron", .Age =
15}
}

Dim totalStudents = Aggregate st In studentList


Into Count(st.Age >= 18)

Console.WriteLine("Total Students: {0}", totalStudents)


Output:
Total Students: 3

C# Query Syntax doesn't support aggregation operators. However, you can wrap the query
into brackets and use an aggregation functions as shown below.

Example: Count operator in query syntax C#


var totalAge = (from s in studentList
select s.age).Count();

Learn about another aggregate operator - Max in the next section.

Aggregation Operator: Max


The Max operator returns the largest numeric element from a collection.

The following example demonstrates Max() on primitive collection.

Example: Max method C#


IList<int> intList = new List<int>() { 10, 21, 30, 45, 50, 87 };
var largest = intList.Max();

Console.WriteLine("Largest Element: {0}", largest);

var largestEvenElements = intList.Max(i => {


if(i%2 == 0)
return i;

return 0;
});

Console.WriteLine("Largest Even Element: {0}", largestEvenElements );


Output:
Largest Element: 87
Largest Even Element: 50

The following example demonstrates Max() method on the complex type collection.

Example: Max in Method Syntax C#


IList<Student> studentList = new List<Student>>() {
new Student() { StudentID = 1, StudentName = "John", Age = 13} ,
new Student() { StudentID = 2, StudentName = "Moin", Age =
21 } ,
new Student() { StudentID = 3, StudentName = "Bill", Age =
18 } ,
new Student() { StudentID = 4, StudentName = "Ram" , Age = 20} ,
new Student() { StudentID = 5, StudentName = "Ron" , Age = 15 }
};

var oldest = studentList.Max(s => s.Age);

Console.WriteLine("Oldest Student Age: {0}", oldest);


Example: Max in Method Syntax VB.Net
Dim studentList = New List(Of Student) From {
New Student() With {.StudentID = 1, .StudentName = "John", .Age =
13},
New Student() With {.StudentID = 2, .StudentName = "Moin", .Age =
21},
New Student() With {.StudentID = 3, .StudentName = "Bill", .Age =
18},
New Student() With {.StudentID = 4, .StudentName = "Ram", .Age =
20},
New Student() With {.StudentID = 5, .StudentName = "Ron", .Age =
15}
}

Dim oldest = studentList.Max(Function(s) s.Age)

Console.WriteLine("Oldest Student Age: {0}", oldest)


Output:
Oldest Student Ag: 21
Max returns a result of any data type. The following example shows how you can find a
student with the longest name in the collection:

Example: Max() in C#
public class Student : IComparable<Student>
{
public int StudentID { get; set; }
public string StudentName { get; set; }
public int Age { get; set; }
public int StandardID { get; set; }

public int CompareTo(Student other)


{
if (this.StudentName.Length >= other.StudentName.Length)
return 1;

return 0;
}
}

class Program
{
static void Main(string[] args)
{
// Student collection
IList<Student> studentList = new List<Student>>() {
new Student() { StudentID = 1, StudentName = "John", Age
= 13} ,
new Student() { StudentID = 2, StudentName = "Moin", Age
= 21 } ,
new Student() { StudentID = 3, StudentName = "Bill", Age
= 18 } ,
new Student() { StudentID = 4, StudentName = "Ram" , Age
= 20} ,
new Student() { StudentID = 5, StudentName = "Steve" ,
Age = 15 }
};

var studentWithLongName = studentList.Max();

Console.WriteLine("Student ID: {0}, Student Name: {1}",


.StudentID,
studentWithLongName.StudentName)
}
}
Output:
Student ID: 5, Student Name: Steve

Note:

You can use Min extension method/operator the same way as Max.
As per the above example, to find the student with the longest name, you need to
implement IComparable<T> interface and compare student names' length in CompareTo
method. So now, you can use Max() method which will use CompareTo method in order to
return appropriate result.

Max Operator in Query Syntax

Max operator is Not Supported in C# Query syntax. However, it is supported in VB.Net


query syntax as shown below.

Example: Max Operator in Query Syntax VB.Net


Dim studentList = New List(Of Student) From {
New Student() With {.StudentID = 1, .StudentName = "John", .Age =
13},
New Student() With {.StudentID = 2, .StudentName = "Moin", .Age =
21},
New Student() With {.StudentID = 3, .StudentName = "Bill", .Age =
18},
New Student() With {.StudentID = 4, .StudentName = "Ram", .Age =
20},
New Student() With {.StudentID = 5, .StudentName = "Ron", .Age =
15}
}

Dim maxAge = Aggregate st In studentList Into Max(st.Age)

Console.WriteLine("Maximum Age of Student: {0}", maxAge);


Output:
Maximum Age of Student: 21

Learn about another aggregate operator - Sum in the next section.

Aggregation Operator: Sum


The Sum() method calculates the sum of numeric items in the collection.

The following example demonstrates Sum() on primitive collection.

Example: LINQ Sum() C#


IList<int> intList = new List<int>() { 10, 21, 30, 45, 50, 87 };

var total = intList.Sum();

Console.WriteLine("Sum: {0}", total);


var sumOfEvenElements = intList.Sum(i => {
if(i%2 == 0)
return i;

return 0;
});

Console.WriteLine("Sum of Even Elements: {0}", sumOfEvenElements );


Output:
Sum: 243
Sum of Even Elements: 90

The following example calculates sum of all student's age and also number of adult
students in a student collection.

Example: LINQ Sum() - C#


IList<Student> studentList = new List<Student>>() {
new Student() { StudentID = 1, StudentName = "John", Age = 13} ,
new Student() { StudentID = 2, StudentName = "Moin", Age =
21 } ,
new Student() { StudentID = 3, StudentName = "Bill", Age =
18 } ,
new Student() { StudentID = 4, StudentName = "Ram" , Age = 20} ,
new Student() { StudentID = 5, StudentName = "Ron" , Age = 15 }
};

var sumOfAge = studentList.Sum(s => s.Age);

Console.WriteLine("Sum of all student's age: {0}", sumOfAge);

var numOfAdults = studentList.Sum(s => {

if(s.Age >= 18)


return 1;
else
return 0;
});

Console.WriteLine("Total Adult Students: {0}", numOfAdults);


Example: Sum in Method Syntax VB.NET
// Student collection
Dim studentList = New List(Of Student) From {
New Student() With {.StudentID = 1, .StudentName = "John", .Age =
13},
New Student() With {.StudentID = 2, .StudentName = "Moin", .Age =
21},
New Student() With {.StudentID = 3, .StudentName = "Bill", .Age =
18},
New Student() With {.StudentID = 4, .StudentName = "Ram", .Age =
20},
New Student() With {.StudentID = 5, .StudentName = "Ron", .Age =
15}
}
Dim sumOfAge = studentList.Sum(Function(s) s.Age)

Console.WriteLine("Total Age of Student: {0}", sumOfAge)

Dim numOfAdults = studentList.Sum(Function(s)


if(s.Age >= 18)
return 1
else
return 0
end if
end function)

Console.WriteLine("Total Adult Students: {0}", numOfAdults)


Output:
Total Age of Student: 87
Total Adult Students: 3

Sum operator in query syntax

Sum operator is Not Supported in C# Query syntax.

Example: Sum Operator in Query Syntax VB.Net


// Student collection
Dim studentList = New List(Of Student) From {
New Student() With {.StudentID = 1, .StudentName = "John", .Age =
13},
New Student() With {.StudentID = 2, .StudentName = "Moin", .Age =
21},
New Student() With {.StudentID = 3, .StudentName = "Bill", .Age =
18},
New Student() With {.StudentID = 4, .StudentName = "Ram", .Age =
20},
New Student() With {.StudentID = 5, .StudentName = "Ron", .Age =
15}
}

Dim totalAge = Aggregate st In studentList Into Sum(st.Age)

Console.WriteLine("Sum of all student's age: {0}", totalAge);


Output:
Sum of all student's age: 87

Element Operators: ElementAt,


ElementAtOrDefault
Element operators return a particular element from a sequence (collection).
The following table lists all the Element operators in LINQ.

Element Operators
Description
(Methods)

ElementAt Returns the element at a specified index in a collection

Returns the element at a specified index in a collection or a default value


ElementAtOrDefault
if the index is out of range.

Returns the first element of a collection, or the first element that satisfies
First
a condition.

Returns the first element of a collection, or the first element that satisfies
FirstOrDefault
a condition. Returns a default value if index is out of range.

Returns the last element of a collection, or the last element that satisfies
Last
a condition

Returns the last element of a collection, or the last element that satisfies
LastOrDefault
a condition. Returns a default value if no such element exists.

Returns the only element of a collection, or the only element that


Single
satisfies a condition.

Returns the only element of a collection, or the only element that


SingleOrDefault satisfies a condition. Returns a default value if no such element exists or
the collection does not contain exactly one element.

The ElementAt() method returns an element from the specified index from a given
collection. If the specified index is out of the range of a collection then it will throw an
Index out of range exception. Please note that index is a zero based index.

The ElementAtOrDefault() method also returns an element from the specified index from a
collaction and if the specified index is out of range of a collection then it will return a
default value of the data type instead of throwing an error.

The following example demonstrates ElementAt and ElementAtOrDefault method on


primitive collection.

Example: LINQ ElementAt() and ElementAtOrDefault() - C#


IList<int> intList = new List<int>() { 10, 21, 30, 45, 50, 87 };
IList<string> strList = new List<string>() { "One", "Two", null, "Four",
"Five" };

Console.WriteLine("1st Element in intList: {0}", intList.ElementAt(0));


Console.WriteLine("1st Element in strList: {0}", strList.ElementAt(0));
Console.WriteLine("2nd Element in intList: {0}", intList.ElementAt(1));
Console.WriteLine("2nd Element in strList: {0}", strList.ElementAt(1));

Console.WriteLine("3rd Element in intList: {0}",


intList.ElementAtOrDefault(2));
Console.WriteLine("3rd Element in strList: {0}",
strList.ElementAtOrDefault(2));

Console.WriteLine("10th Element in intList: {0} - default int value",


intList.ElementAtOrDefault(9));
Console.WriteLine("10th Element in strList: {0} - default string value
(null)",
strList.ElementAtOrDefault(9));

Console.WriteLine("intList.ElementAt(9) throws an exception: Index out of


range");
Console.WriteLine("------------------------------------------------------
-------");
Console.WriteLine(intList.ElementAt(9));
Output:
1st Element in intList: 10
1st Element in strList: One
2nd Element in intList: 21
2nd Element in strList:
3rd Element in intList: 30
3rd Element in strList: Three
10th Element in intList: 0 - default int value
10th Element in strList: - default string value (null)
intList.ElementAt(9) throws an exception: Index out of range
-------------------------------------------------------------
Run-time exception: Index was out of range....

As you can see in the above example, intList.ElementAtOrDefault(9) returns 0


(default value of int) because intList does not include 10th element. However
intList.ElementAt(9) throws "Index out of range" exception.The same way,
strList.ElementAtOrDefault(9) returns null which is default value of string type.
(console display empty space because it cannot display null)

Thus, it is advisable to use the ElementAtOrDefault extension method to eliminate the


possibility of a runtime exception.

Learn about another element operator First and FirstOrDefault in the next section.

Element Operators: First &


FirstOrDefault
The First and FirstOrDefault method returns an element from the zeroth index in the
collection i.e. the first element. Also, it returns an element that satisfies the specified
condition.

Element
Description
Operators

Returns the first element of a collection, or the first element that satisfies a
First
condition.

Returns the first element of a collection, or the first element that satisfies a
FirstOrDefault
condition. Returns a default value if index is out of range.

First and FirstOrDefault has two overload methods. The first overload method doesn't take
any input parameter and returns the first element in the collection. The second overload
method takes the lambda expression as predicate delegate to specify a condition and returns
the first element that satisfies the specified condition.

First() Á FirstOrDefault() Overloads:


public static TSource First<TSource>(this IEnumerable<TSource> source);

public static TSource First<TSource>(this IEnumerable<TSource> source,


Func<TSource, bool> predicate);

public static TSource FirstOrDefault<TSource>(this IEnumerable<TSource>


source);

public static TSource FirstOrDefault<TSource>(this IEnumerable<TSource>


source, Func<TSource, bool> predicate);

The First() method returns the first element of a collection, or the first element that satisfies
the specified condition using lambda expression or Func delegate. If a given collection is
empty or does not include any element that satisfied the condition then it will throw
InvalidOperation exception.

The FirstOrDefault() method does the same thing as First() method. The only difference is
that it returns default value of the data type of a collection if a collection is empty or doesn't
find any element that satisfies the condition.

The following example demonstrates First() method.

Example: LINQ First() - C#


IList<int> intList = new List<int>() { 7, 10, 21, 30, 45, 50, 87 };
IList<string> strList = new List<string>() { null, "Two", "Three",
"Four", "Five" };
IList<string> emptyList = new List<string>();

Console.WriteLine("1st Element in intList: {0}", intList.First());


Console.WriteLine("1st Even Element in intList: {0}", intList.First(i =>
i % 2 == 0));

Console.WriteLine("1st Element in strList: {0}", strList.First());

Console.WriteLine("emptyList.First() throws an
InvalidOperationException");
Console.WriteLine("------------------------------------------------------
-------");
Console.WriteLine(emptyList.First());
Output:
1st Element in intList: 7
1st Even Element in intList: 10
1st Element in strList:
emptyList.First() throws an InvalidOperationException
-------------------------------------------------------------
Run-time exception: Sequence contains no elements...

The following example demonstrates FirstOrDefault() method.

Example: LINQ FirstOrDefault() - C#


IList<int> intList = new List<int>() { 7, 10, 21, 30, 45, 50, 87 };
IList<string> strList = new List<string>() { null, "Two", "Three",
"Four", "Five" };
IList<string> emptyList = new List<string>();

Console.WriteLine("1st Element in intList: {0}",


intList.FirstOrDefault());
Console.WriteLine("1st Even Element in intList: {0}",
intList.FirstOrDefault(i => i % 2 ==
0));

Console.WriteLine("1st Element in strList: {0}",


strList.FirstOrDefault());

Console.WriteLine("1st Element in emptyList: {0}",


emptyList.FirstOrDefault());
Output:
1st Element in intList: 7
1st Even Element in intList: 10
1st Element in strList:
1st Element in emptyList:

Be careful while specifying condition in First() or FirstOrDefault(). First() will throw an


exception if a collection does not include any element that satisfies the specified condition
or includes null element.

If a collection includes null element then FirstOrDefault() throws an exception while


evaluting the specified condition. The following example demonstrates this.
Example: LINQ First() & FirstOrDefault() - C#
IList<int> intList = new List<int>() { 7, 10, 21, 30, 45, 50, 87 };
IList<string> strList = new List<string>() { null, "Two", "Three",
"Four", "Five" };

Console.WriteLine("1st Element which is greater than 250 in intList:


{0}",
intList.First( i > 250));

Console.WriteLine("1st Even Element in intList: {0}",


strList.FirstOrDefault(s =>
s.Contains("T")));
Output:
Run-time exception: Sequence contains no matching element

Element Operators : Last &


LastOrDefault
Element
Description
Operators

Returns the last element from a collection, or the last element that satisfies a
Last
condition

Returns the last element from a collection, or the last element that satisfies a
LastOrDefault
condition. Returns a default value if no such element exists.

Last and LastOrDefault has two overload methods. One overload method doesn't take any
input parameter and returns last element from the collection. Second overload method takes
a lambda expression to specify a condition and returns last element that satisfies the
specified condition.

Last() Á LastOrDefault() Overloads:


public static TSource Last<TSource>(this IEnumerable<TSource> source);

public static TSource Last<TSource>(this IEnumerable<TSource> source,


Func<TSource, bool> predicate);

public static TSource LastOrDefault<TSource>(this IEnumerable<TSource>


source);

public static TSource LastOrDefault<TSource>(this IEnumerable<TSource>


source, Func<TSource, bool> predicate);
The Last() method returns the last element from a collection, or the last element that
satisfies the specified condition using lambda expression or Func delegate. If a given
collection is empty or does not include any element that satisfied the condition then it will
throw InvalidOperation exception.

The LastOrDefault() method does the same thing as Last() method. The only difference is
that it returns default value of the data type of a collection if a collection is empty or doesn't
find any element that satisfies the condition.

The following example demonstrates Last() method.

Example: LINQ Last() - C#


IList<int> intList = new List<int>() { 7, 10, 21, 30, 45, 50, 87 };
IList<string> strList = new List<string>() { null, "Two", "Three",
"Four", "Five" };
IList<string> emptyList = new List<string>();

Console.WriteLine("Last Element in intList: {0}", intList.Last());

Console.WriteLine("Last Even Element in intList: {0}", intList.Last(i =>


i % 2 == 0));

Console.WriteLine("Last Element in strList: {0}", strList.Last());

Console.WriteLine("emptyList.Last() throws an
InvalidOperationException");
Console.WriteLine("------------------------------------------------------
-------");
Console.WriteLine(emptyList.Last());
Output:
Last Element in intList: 87
Last Even Element in intList: 50
Last Element in strList: Five
emptyList.Last() throws an InvalidOperationException
-------------------------------------------------------------
Run-time exception: Sequence contains no elements...

The following example demonstrates LastOrDefault() method.

Example: LINQ LastOrDefault() - C#


IList<int> intList = new List<int>() { 7, 10, 21, 30, 45, 50, 87 };
IList<string> strList = new List<string>() { null, "Two", "Three",
"Four", "Five" };
IList<string> emptyList = new List<string>();

Console.WriteLine("Last Element in intList: {0}",


intList.LastOrDefault());

Console.WriteLine("Last Even Element in intList: {0}",


intList.LastOrDefault(i => i % 2 == 0));
Console.WriteLine("Last Element in strList: {0}",
strList.LastOrDefault());

Console.WriteLine("Last Element in emptyList: {0}",


emptyList.LastOrDefault());
Output:
Last Element in intList: 7
Last Even Element in intList: 10
Last Element in strList:
Last Element in emptyList:

Be careful while specifying condition in Last() or LastOrDefault(). Last() will throw an


exception if a collection does not include any element that satisfies the specified condition
or includes null element.

If a collection includes null element then LastOrDefault() throws an exception while


evaluting the specified condition. The following example demonstrates this.

Example: LINQ Last() & LastOrDefault() - C#


IList<int> intList = new List<int>() { 7, 10, 21, 30, 45, 50, 87 };
IList<string> strList = new List<string>() { null, "Two", "Three",
"Four", "Five" };

Console.WriteLine("Last Element which is greater than 250 in intList:


{0}",
intList.Last(i => i > 250));

Console.WriteLine("Last Even Element in intList: {0}",


strList.LastOrDefault(s =>
s.Contains("T")));
Output:
Run-time exception: Sequence contains no matching element

Element Operators: Single &


SingleOrDefault
Element
Description
Operators
Returns the only element from a collection, or the only element that
Single satisfies a condition. If Single() found no elements or more than one
elements in the collection then throws InvalidOperationException.
SingleOrDefault The same as Single, except that it returns a default value of a specified
generic type, instead of throwing an exception if no element found for
Element
Description
Operators
the specified condition. However, it will thrown
InvalidOperationException if it found more than one element for the
specified condition in the collection.

Single and SingleOrDefault have two overload methods. The first overload method doesn't
take any input parameter and returns a single element in the collection. The second
overload method takes the lambda expression as a predicate delegate that specifies the
condition and returns a single element that satisfies the specified condition.

Single() Á SingleOrDefault() Overloads:


public static TSource Single<TSource>(this IEnumerable<TSource> source);

public static TSource Single<TSource>(this IEnumerable<TSource> source,


Func<TSource, bool> predicate);

public static TSource SingleOrDefault<TSource>(this IEnumerable<TSource>


source);

public static TSource SingleOrDefault<TSource>(this IEnumerable<TSource>


source, Func<TSource, bool> predicate);

Single() returns the only element from a collection, or the only element that satisfies the
specified condition. If a given collection includes no elements or more than one elements
then Single() throws InvalidOperationException.

The SingleOrDefault() method does the same thing as Single() method. The only difference
is that it returns default value of the data type of a collection if a collection is empty,
includes more than one element or finds no element or more than one element for the
specified condition.

Example: Single in method syntax C#


IList<int> oneElementList = new List<int>() { 7 };
IList<int> intList = new List<int>() { 7, 10, 21, 30, 45, 50, 87 };
IList<string> strList = new List<string>() { null, "Two", "Three",
"Four", "Five" };
IList<string> emptyList = new List<string>();

Console.WriteLine("The only element in oneElementList: {0}",


oneElementList.Single());
Console.WriteLine("The only element in oneElementList: {0}",
oneElementList.SingleOrDefault());

Console.WriteLine("Element in emptyList: {0}",


emptyList.SingleOrDefault());

Console.WriteLine("The only element which is less than 10 in intList:


{0}",
intList.Single(i => i < 10));
//Followings throw an exception
//Console.WriteLine("The only Element in intList: {0}",
intList.Single());
//Console.WriteLine("The only Element in intList: {0}",
intList.SingleOrDefault());
//Console.WriteLine("The only Element in emptyList: {0}",
emptyList.Single());
Output:
The only element in oneElementList: 7
The only element in oneElementList: 7
Element in emptyList: 0
The only element which is less than 10 in intList: 7

The following example code throws an exception because Single() or SingleOrDefault()


returns none or multiple elements for the specified condition.

C#: Single() and SingleOrDefault()


IList<int> oneElementList = new List<int>() { 7 };
IList<int> intList = new List<int>() { 7, 10, 21, 30, 45, 50, 87 };
IList<string> strList = new List<string>() { null, "Two", "Three",
"Four", "Five" };
IList<string> emptyList = new List<string>();

//following throws error because list contains more than one element
which is less than 100
Console.WriteLine("Element less than 100 in intList: {0}",
intList.Single(i => i < 100));

//following throws error because list contains more than one element
which is less than 100
Console.WriteLine("Element less than 100 in intList: {0}",
intList.SingleOrDefault(i => i <
100));

//following throws error because list contains more than one elements
Console.WriteLine("The only Element in intList: {0}", intList.Single());

//following throws error because list contains more than one elements
Console.WriteLine("The only Element in intList: {0}",
intList.SingleOrDefault());

//following throws error because list does not contains any element
Console.WriteLine("The only Element in emptyList: {0}",
emptyList.Single());

Points to Remember :

1. Single() expects one and only one element in the collection.


2. Single() throws an exception when it gets no element or more than one elements in
the collection.
3. If specified a condition in Single() and result contains no element or more than one
elements then it throws an exception.
4. SingleOrDefault() will return default value of a data type of generic collection if
there is no elements in a colection or for the specified condition.
5. SingleOrDefault() will throw an exception if there is more than one elements in a
colection or for the specified condition.

Equality Operator: SequenceEqual


There is only one equality operator: SequenceEqual. The SequenceEqual method checks
whether the number of elements, value of each element and order of elements in two
collections are equal or not.

If the collection contains elements of primitive data types then it compares the values and
number of elements, whereas collection with complex type elements, checks the references
of the objects. So, if the objects have the same reference then they considered as equal
otherwise they are considered not equal.

The following example demonstrates the SequenceEqual method with the collection of
primitive data types.

Example: SequenceEqual in Method Syntax C#


IList<string> strList1 = new List<string>(){"One", "Two", "Three",
"Four", "Three"};

IList<string> strList2 = new List<string>(){"One", "Two", "Three",


"Four", "Three"};

bool isEqual = strList1.SequenceEqual(strList2); // returns true


Console.WriteLine(isEqual);
Output:
true

If the order of elements are not the same then SequenceEqual() method returns false.

Example: SequenceEqual in Method Syntax C#


IList<string> strList1 = new List<string>(){"One", "Two", "Three",
"Four", "Three"};

IList<string> strList2 = new List<string>(){ "Two", "One", "Three",


"Four", "Three"};

bool isEqual = strList1.SequenceEqual(strList2); // returns false


Console.WriteLine(isEqual);
Output:
false
The SequenceEqual extension method checks the references of two objects to determine
whether two sequences are equal or not. This may give wrong result. Consider following
example:

Example: SequenceEqual in C#
Student std = new Student() { StudentID = 1, StudentName = "Bill" };

IList<Student> studentList1 = new List<Student>(){ std };

IList<Student> studentList2 = new List<Student>(){ std };

bool isEqual = studentList1.SequenceEqual(studentList2); // returns true

Student std1 = new Student() { StudentID = 1, StudentName = "Bill" };


Student std2 = new Student() { StudentID = 1, StudentName = "Bill" };

IList<Student> studentList3 = new List<Student>(){ std1};

IList<Student> studentList4 = new List<Student>(){ std2 };

isEqual = studentList3.SequenceEqual(studentList4);// returns false

In the above example, studentList1 and studentList2 contains the same student object, std.
So studentList1.SequenceEqual(studentList2) returns true. But, stdList1 and
stdList2 contains two seperate student object, std1 and std2. So now,
stdList1.SequenceEqual(stdList2) will return false even if std1 and std2 contain the
same value.

To compare the values of two collection of complex type (reference type or object), you
need to implement IEqualityComperar<T> interface as shown below.

Example: IEqualityComparer C#:


class StudentComparer : IEqualityComparer<Student>
{
public bool Equals(Student x, Student y)
{
if (x.StudentID == y.StudentID && x.StudentName.ToLower() ==
y.StudentName.ToLower())
return true;

return false;
}

public int GetHashCode(Student obj)


{
return obj.GetHashCode();
}
}

Now, you can use above StudentComparer class in SequenceEqual extension method as a
second parameter to compare the values:
Example: Compare object type elements using SequenceEqual C#
IList<Student> studentList1 = new List<Student>() {
new Student() { StudentID = 1, StudentName = "John", Age = 18 } ,
new Student() { StudentID = 2, StudentName = "Steve", Age = 15 }
,
new Student() { StudentID = 3, StudentName = "Bill", Age =
25 } ,
new Student() { StudentID = 4, StudentName = "Ram" , Age = 20 } ,
new Student() { StudentID = 5, StudentName = "Ron" , Age = 19 }
};

IList<Student> studentList2 = new List<Student>() {


new Student() { StudentID = 1, StudentName = "John", Age = 18 } ,
new Student() { StudentID = 2, StudentName = "Steve", Age = 15 }
,
new Student() { StudentID = 3, StudentName = "Bill", Age =
25 } ,
new Student() { StudentID = 4, StudentName = "Ram" , Age = 20 } ,
new Student() { StudentID = 5, StudentName = "Ron" , Age = 19 }
};
// following returns true
bool isEqual = studentList1.SequenceEqual(studentList2, new
StudentComparer());

Points to Remember :

1. The SequenceEqual method compares the number of items and their values for
primitive data types.
2. The SequenceEqual method compares the reference of objects for complex data
types.
3. Use IEqualityComparer class to compare two colection of complex type using
SequenceEqual method.

Concatenation Operator: Concat


The Concat() method appends two sequences of the same type and returns a new sequence
(collection).

Example: Concat in C#
IList<string> collection1 = new List<string>() { "One", "Two", "Three" };
IList<string> collection2 = new List<string>() { "Five", "Six"};

var collection3 = collection1.Concat(collection2);

foreach (string str in collection3)


Console.WriteLine(str);
Output:
One
Two
Three
Five
Six

Example: Concat in C#
IList<int> collection1 = new List<int>() { 1, 2, 3 };
IList<int> collection2 = new List<int>() { 4, 5, 6 };

var collection3 = collection1.Concat(collection2);

foreach (int i in collection3)


Console.WriteLine(i);
Output:
1
2
3
4
5
6

Concat operator is not supported in query syntax in C# or VB.Net.

Generation Operator: DefaultIfEmpty


The DefaultIfEmpty() method returns a new collection with the default value if the given
collection on which DefaultIfEmpty() is invoked is empty.

Another overload method of DefaultIfEmpty() takes a value parameter that should be


replaced with default value.

Consider the following example.

Example: DefaultIfEmpty C#
IList<string> emptyList = new List<string>();

var newList1 = emptyList.DefaultIfEmpty();


var newList2 = emptyList.DefaultIfEmpty("None");

Console.WriteLine("Count: {0}" , newList1.Count());


Console.WriteLine("Value: {0}" , newList1.ElementAt(0));

Console.WriteLine("Count: {0}" , newList2.Count());


Console.WriteLine("Value: {0}" , newList2.ElementAt(0));
Output:
Count: 1
Value:
Count: 1
Value: None

In the above example, emptyList.DefaultIfEmpty() returns a new string collection with


one element whose value is null because null is a default value of string. Another method
emptyList.DefaultIfEmpty("None") returns a string collection with one element whose
value is "None" instead of null.

The following example demonstrates calling DefaultIfEmpty on int collection.

Example: DefaultIfEmpty C#
IList<int> emptyList = new List<int>();

var newList1 = emptyList.DefaultIfEmpty();


var newList2 = emptyList.DefaultIfEmpty(100);

Console.WriteLine("Count: {0}" , newList1.Count());


Console.WriteLine("Value: {0}" , newList1.ElementAt(0));

Console.WriteLine("Count: {0}" , newList2.Count());


Console.WriteLine("Value: {0}" , newList2.ElementAt(0));
Output:
Count: 1
Value: 0
Count: 1
Value: 100

The following example demonstrates DefaultIfEmpty() method on complex type collection.

Example: DefaultIfEmpty C#:


IList<Student> emptyStudentList = new List<Student>();

var newStudentList1 = studentList.DefaultIfEmpty(new Student());

var newStudentList2 = studentList.DefaultIfEmpty(new Student(){


StudentID = 0,
StudentName = "" });

Console.WriteLine("Count: {0} ", newStudentList1.Count());


Console.WriteLine("Student ID: {0} ", newStudentList1.ElementAt(0));

Console.WriteLine("Count: {0} ", newStudentList2.Count());


Console.WriteLine("Student ID: {0} ",
newStudentList2.ElementAt(0).StudentID);
Output:
Count: 1
Student ID:
Count: 1
Student ID: 0

Generation Operators: Empty, Range,


Repeat
LINQ includes generation operators DefaultIfEmpty, Empty, Range & Repeat. The Empty,
Range & Repeat methods are not extension methods for IEnumerable or IQueryable but
they are simply static methods defined in a static class Enumerable.

Method Description

Empty Returns an empty collection

Generates collection of IEnumerable<T> type with specified number of elements with


Range
sequential values, starting from first element.

Generates a collection of IEnumerable<T> type with specified number of elements and


Repeat
each element contains same specified value.

Empty

The Empty() method is not an extension method of IEnumerable or IQueryable like other
LINQ methods. It is a static method included in Enumerable static class. So, you can call it
the same way as other static methods like Enumerable.Empty<TResult>(). The Empty()
method returns an empty collection of a specified type as shown below.

Example: Enumerable.Empty()
var emptyCollection1 = Enumerable.Empty<string>();
var emptyCollection2 = Enumerable.Empty<Student>();

Console.WriteLine("Count: {0} ", emptyCollection1.Count());


Console.WriteLine("Type: {0} ", emptyCollection1.GetType().Name );

Console.WriteLine("Count: {0} ",emptyCollection2.Count());


Console.WriteLine("Type: {0} ", emptyCollection2.GetType().Name );
Output:
Type: String[]
Count: 0
Type: Student[]
Count: 0
Range

The Range() method returns a collection of IEnumerable<T> type with specified number of
elements and sequential values starting from the first element.

Example: Enumerable.Range()
var intCollection = Enumerable.Range(10, 10);
Console.WriteLine("Total Count: {0} ", intCollection.Count());

for(int i = 0; i < intCollection.Count(); i++)


Console.WriteLine("Value at index {0} : {1}", i,
intCollection.ElementAt(i));
Output:
Total Count: 10
Value at index 0 : 10
Value at index 1 : 11
Value at index 2 : 12
Value at index 3 : 13
Value at index 4 : 14
Value at index 5 : 15
Value at index 6 : 16
Value at index 7 : 17
Value at index 8 : 18
Value at index 9 : 19

In the above example, Enumerable.Range(10, 10) creates collection with 10 integer


elements with the sequential values starting from 10. First parameter specifies the starting
value of elements and second parameter specifies the number of elements to create.

Repeat

The Repeat() method generates a collection of IEnumerable<T> type with specified number
of elements and each element contains same specified value.

Example: Repeat
var intCollection = Enumerable.Repeat<int>(10, 10);
Console.WriteLine("Total Count: {0} ", intCollection.Count());

for(int i = 0; i < intCollection.Count(); i++)


Console.WriteLine("Value at index {0} : {1}", i,
intCollection.ElementAt(i));
Output:
Total Count: 10
Value at index 0: 10
Value at index 1: 10
Value at index 2: 10
Value at index 3: 10
Value at index 4: 10
Value at index 5: 10
Value at index 6: 10
Value at index 7: 10
Value at index 8: 10
Value at index 9: 10

In the above example, Enumerable.Repeat<int>(10, 10) creates collection with 100


integer type elements with the repeated value of 10. First parameter specifies the values of
all the elements and second parameter specifies the number of elements to create.

Set Operator: Distinct


The following table lists all Set operators available in LINQ.

Set
Usage
Operators

Distinct Returns distinct values from a collection.

Returns the difference between two sequences, which means the elements of one
Except
collection that do not appear in the second collection.

Returns the intersection of two sequences, which means elements that appear in
Intersect
both the collections.

Returns unique elements from two sequences, which means unique elements that
Union
appear in either of the two sequences.

The following figure shows how each set operators works on the collections:
LINQ Set operators

Distinct

The Distinct extension method returns a new collection of unique elements from the given
collection.

Example: Distinct C#
IList<string> strList = new List<string>(){ "One", "Two", "Three", "Two",
"Three" };

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

var distinctList1 = strList.Distinct();

foreach(var str in distinctList1)


Console.WriteLine(str);

var distinctList2 = intList.Distinct();

foreach(var i in distinctList2)
Console.WriteLine(i);
Output:
One
Two
Three
1
2
3
4
5

The Distinct extension method doesn't compare values of complex type objects. You need
to implement IEqualityComparer<T> interface in order to compare the values of complex
types. In the following example, StudentComparer class implements
IEqualityComparer<Student> to compare Student< objects.

Example: Implement IEqualityComparer in C#


public class Student
{
public int StudentID { get; set; }
public string StudentName { get; set; }
public int Age { get; set; }
}

class StudentComparer : IEqualityComparer<Student>


{
public bool Equals(Student x, Student y)
{
if (x.StudentID == y.StudentID
&& x.StudentName.ToLower() == y.StudentName.ToLower())
return true;

return false;
}

public int GetHashCode(Student obj)


{
return obj.StudentID.GetHashCode();
}
}

Now, you can pass an object of the above StudentComparer class in the Distinct() method
as a parameter to compare the Student objects as shown below.

Example: Distinct in C#
IList<Student> studentList = new List<Student>() {
new Student() { StudentID = 1, StudentName = "John", Age = 18 } ,
new Student() { StudentID = 2, StudentName = "Steve", Age = 15 }
,
new Student() { StudentID = 3, StudentName = "Bill", Age =
25 } ,
new Student() { StudentID = 3, StudentName = "Bill", Age =
25 } ,
new Student() { StudentID = 3, StudentName = "Bill", Age =
25 } ,
new Student() { StudentID = 3, StudentName = "Bill", Age =
25 } ,
new Student() { StudentID = 5, StudentName = "Ron" , Age = 19 }
};
var distinctStudents = studentList.Distinct(new StudentComparer());

foreach(Student std in distinctStudents)


Console.WriteLine(std.StudentName);
Output:
John
Steve
Bill
Ron

Distinct operator in Query Syntax

The Distinct operator is Not Supported in C# Query syntax. However, you can use
Distinct method of query variable or wrap whole query into brackets and then call
Distinct().

Use the Distinct keyword in VB.Net query syntax:

Example: Distinct in query syntax VB.Net


Dim strList = New List(Of string) From {"One", "Three", "Two", "Two",
"One" }

Dim distinctStr = From s In strList _


Select s Distinct

Set Operator: Except


The Except() method requires two collections. It returns a new collection with elements
from the first collection which do not exist in the second collection (parameter collection).

Example: Except in method syntax C#


IList<string> strList1 = new List<string>(){"One", "Two", "Three",
"Four", "Five" };
IList<string> strList2 = new List<string>(){"Four", "Five", "Six",
"Seven", "Eight"};

var result = strList1.Except(strList2);

foreach(string str in result)


Console.WriteLine(str);
Output:
One
Two
Three
Except extension method doesn't return the correct result for the collection of complex
types. You need to implement IEqualityComparer interface in order to get the correct result
from Except method.

Implement IEqualityComparer interface for Student class as shown below:

Example: IEqualityComparer with Except method C#


public class Student
{
public int StudentID { get; set; }
public string StudentName { get; set; }
public int Age { get; set; }
}

class StudentComparer : IEqualityComparer<Student>


{
public bool Equals(Student x, Student y)
{
if (x.StudentID == y.StudentID && x.StudentName.ToLower() ==
y.StudentName.ToLower())
return true;

return false;
}

public int GetHashCode(Student obj)


{
return obj.StudentID.GetHashCode();
}
}

Now, you can pass above StudentComparer class in Except extension method in order to
get the correct result:

Example: Except() with object type C#


IList<Student> studentList1 = new List<Student>() {
new Student() { StudentID = 1, StudentName = "John", Age = 18 } ,
new Student() { StudentID = 2, StudentName = "Steve", Age = 15 }
,
new Student() { StudentID = 3, StudentName = "Bill", Age =
25 } ,
new Student() { StudentID = 5, StudentName = "Ron" , Age = 19 }
};

IList<Student> studentList2 = new List<Student>() {


new Student() { StudentID = 3, StudentName = "Bill", Age =
25 } ,
new Student() { StudentID = 5, StudentName = "Ron" , Age = 19 }
};

var resultedCol = studentList1.Except(studentList2,new


StudentComparer());

foreach(Student std in resultedCol)


Console.WriteLine(std.StudentName);
Output:
John
Steve

The Except operator is Not Supported in C# & VB.Net Query syntax. However, you can
use Distinct method on query variable or wrap whole query into brackets and then call
Except().

The following figure shows how each set operators works on the collections:

LINQ Set operators

Set Operator: Intersect


The Intersect extension method requires two collections. It returns a new collection that
includes common elements that exists in both the collection. Consider the following
example.

Example: Intersect in method syntax C#


IList<string> strList1 = new List<string>() { "One", "Two", "Three",
"Four", "Five" };
IList<string> strList2 = new List<string>() { "Four", "Five", "Six",
"Seven", "Eight"};

var result = strList1.Intersect(strList2);


foreach(string str in result)
Console.WriteLine(str);
Output:
Four
Five

The Intersect extension method doesn't return the correct result for the collection of
complex types. You need to implement IEqualityComparer interface in order to get the
correct result from Intersect method.

Implement IEqualityComparer interface for Student class as shown below:

Example: Use IEqualityComparer with Intersect in C#


public class Student
{
public int StudentID { get; set; }
public string StudentName { get; set; }
public int Age { get; set; }
}

class StudentComparer : IEqualityComparer<Student>


{
public bool Equals(Student x, Student y)
{
if (x.StudentID == y.StudentID &&
x.StudentName.ToLower() ==
y.StudentName.ToLower())
return true;

return false;
}

public int GetHashCode(Student obj)


{
return obj.StudentID.GetHashCode();
}
}

Now, you can pass above StudentComparer class in the Intersect extension method in order
to get the correct result:

Example: Intersect operator C#


IList<Student> studentList1 = new List<Student>() {
new Student() { StudentID = 1, StudentName = "John", Age = 18 } ,
new Student() { StudentID = 2, StudentName = "Steve", Age = 15 }
,
new Student() { StudentID = 3, StudentName = "Bill", Age =
25 } ,
new Student() { StudentID = 5, StudentName = "Ron" , Age = 19 }
};

IList<Student> studentList2 = new List<Student>() {


new Student() { StudentID = 3, StudentName = "Bill", Age =
25 } ,
new Student() { StudentID = 5, StudentName = "Ron" , Age = 19 }
};

var resultedCol = studentList1.Intersect(studentList2, new


StudentComparer());

foreach(Student std in resultedCol)


Console.WriteLine(std.StudentName);
Output:
Bill
Ron

The Intersect operator is Not Supported in C# & VB.Net Query syntax. However, you can
use the Intersect method on a query variable or wrap whole query into brackets and then
call Intersect().

The following figure shows how each set operators works on the collections:

LINQ Set operators

Set Operator: Union


The Union extension method requires two collections and returns a new collection that
includes distinct elements from both the collections. Consider the following example.
Example: Union() in C#
IList<string> strList1 = new List<string>() { "One", "Two", "three",
"Four" };
IList<string> strList2 = new List<string>() { "Two", "THREE", "Four",
"Five" };

var result = strList1.Union(strList2);

foreach(string str in result)


Console.WriteLine(str);
Output:
One
Two
three
THREE
Four
Five

The Union extension method doesn't return the correct result for the collection of complex
types. You need to implement IEqualityComparer interface in order to get the correct result
from Union method.

Implement IEqualityComparer interface for Student class as below:

Example: Union operator with IEqualityComparer:


public class Student
{
public int StudentID { get; set; }
public string StudentName { get; set; }
public int Age { get; set; }
}

class StudentComparer : IEqualityComparer<Student>


{
public bool Equals(Student x, Student y)
{
if (x.StudentID == y.StudentID && x.StudentName.ToLower() ==
y.StudentName.ToLower())
return true;

return false;
}

public int GetHashCode(Student obj)


{
return obj.StudentID.GetHashCode();
}
}

Now, you can pass above StudentComparer class in the Union extension method to get the
correct result:
Example: Union operator C#
IList<Student> studentList1 = new List<Student>() {
new Student() { StudentID = 1, StudentName = "John", Age = 18 } ,
new Student() { StudentID = 2, StudentName = "Steve", Age = 15 }
,
new Student() { StudentID = 3, StudentName = "Bill", Age =
25 } ,
new Student() { StudentID = 5, StudentName = "Ron" , Age = 19 }
};

IList<Student> studentList2 = new List<Student>() {


new Student() { StudentID = 3, StudentName = "Bill", Age =
25 } ,
new Student() { StudentID = 5, StudentName = "Ron" , Age = 19 }
};

var resultedCol = studentList1.Union(studentList2, new


StudentComparer());

foreach(Student std in resultedCol)


Console.WriteLine(std.StudentName);
Output:
John
Steve
Bill
Ron

Query Syntax

The Union operator is Not Supported in C# & VB.Net Query syntax. However, you can
use Union method on query variable or wrap whole query into brackets and then call
Union().

The following figure shows how each set operators works on the collections:
LINQ Set operators

Partitioning Operators: Skip & SkipWhile


Partitioning operators split the sequence (collection) into two parts and return one of the
parts.

Method Description

Skip Skips elements up to a specified position starting from the first element in a sequence.

Skips elements based on a condition until an element does not satisfy the condition. If
SkipWhile the first element itself doesn't satisfy the condition, it then skips 0 elements and
returns all the elements in the sequence.

Take Takes elements up to a specified position starting from the first element in a sequence.

Returns elements from the first element until an element does not satisfy the
TakeWhile condition. If the first element itself doesn't satisfy the condition then returns an empty
collection.

Skip

The Skip() method skips the specified number of element starting from first element and
returns rest of the elements.
Example: Skip() - C#
IList<string> strList = new List<string>(){ "One", "Two", "Three",
"Four", "Five" };

var newList = strList.Skip(2);

foreach(var str in newList)


Console.WriteLine(str);
Output:
Three
Four
Five

Skip Operator in Query Syntax

The Skip & SkipWhile operator is Not Supported in C# query syntax. However, you can
use Skip/SkipWhile method on a query variable or wrap whole query into brackets and then
call Skip/SkipWhile.

The following example demonstrates skip operator in query syntax - VB.NET

Example: Skip operator in VB.Net


Dim skipResult = From s In studentList
Skip 3
Select s
SkipWhile

As the name suggests, the SkipWhile() extension method in LINQ skip elements in the
collection till the specified condition is true. It returns a new collection that includes all the
remaining elements once the specified condition becomes false for any element.

The SkipWhile() method has two overload methods. One method accepts the predicate of
Func<TSource, bool> type and other overload method accepts the predicate
Func<TSource, int, bool> type that pass the index of an element.

In the following example, SkipWhile() method skips all elements till it finds a string whose
length is equal or more than 4 characters.

Example: SkipWhile in C#
IList<string> strList = new List<string>() {
"One",
"Two",
"Three",
"Four",
"Five",
"Six" };
var resultList = strList.SkipWhile(s => s.Length < 4);

foreach(string str in resultList)


Console.WriteLine(str);
Output:
Three
Four
Five
Six

In the above example, SkipWhile() skips first two elements because their length is less than
3 and finds third element whose length is equal or more than 4. Once it finds any element
whose length is equal or more than 4 characters then it will not skip any other elements
even if they are less than 4 characters.

Now, consider the following example where SkipWhile() does not skip any elements
because the specified condition is false for the first element.

Example: SkipWhile in C#
IList<string> strList = new List<string>() {
"Three",
"One",
"Two",
"Four",
"Five",
"Six" };

var resultList = strList.SkipWhile(s => s.Length < 4);

foreach(string str in resultList)


Console.WriteLine(str);
Output:
Three
One
Two
Four
Five
Six

The second overload of SkipWhile passes an index of each elements. Consider the
following example.

Example: SkipWhile with index in C#


IList<string> strList = new List<string>() {
"One",
"Two",
"Three",
"Four",
"Five",
"Six" };

var result = strList.SkipWhile((s, i) => s.Length > i);

foreach(string str in result)


Console.WriteLine(str);
Output:
Five
Six

In the above example, the lambda expression includes element and index of an elements as
a parameter. It skips all the elements till the length of a string element is greater than it's
index.

SkipWhile operator in Query Syntax

Skip & SkipWhile operator is NOT Supported in C# query syntax. However, you can use
Skip/SkipWhile method on a query variable or wrap whole query into brackets and then
call Skip/SkipWhile().

Example: SkipWhile method in VB.Net


Dim strList = New List(Of string) From {
"One",
"Two",
"Three",
"Four",
"Five",
"Six" }

Dim skipWhileResult = From s In studentList


Skip While s.Length < 4
Select s
Output:
Three
Four
Five
Six

Partitioning Operators: Take & TakeWhile


Partitioning operators split the sequence (collection) into two parts and returns one of the
parts.
The Take() extension method returns the specified number of elements starting from the
first element.

Example: Take() in C#
IList<string> strList = new List<string>(){ "One", "Two", "Three",
"Four", "Five" };

var newList = strList.Take(2);

foreach(var str in newList)


Console.WriteLine(str);
Output:
One
Two

Take & TakeWhile operator is Not Supported in C# query syntax. However, you can use
Take/TakeWhile method on query variable or wrap whole query into brackets and then call
Take/TakeWhile().

Example: Take Operator in Query Syntax VB.Net


Dim takeResult = From s In studentList
Take 3
Select s
TakeWhile

The TakeWhile() extension method returns elements from the given collection until the
specified condition is true. If the first element itself doesn't satisfy the condition then
returns an empty collection.

The TakeWhile method has two overload methods. One method accepts the predicate of
Func<TSource, bool> type and the other overload method accepts the predicate
Func<TSource, int, bool> type that passes the index of element.

In the following example, TakeWhile() method returns a new collection that includes all the
elements till it finds a string whose length less than 4 characters.

Example: TakeWhile in C#
IList<string> strList = new List<string>() {
"Three",
"Four",
"Five",
"Hundred" };

var result = strList.TakeWhile(s => s.Length > 4);

foreach(string str in result)


Console.WriteLine(str);
Output:
Three

In the above example, TakeWhile() includes only first element because second string
element does not satisfied the condition.

TakeWhile also passes an index of current element in predicate function. Following


example of TakeWhile method takes elements till length of string element is greater than
it's index

Example: TakeWhile in C#:


IList<string> strList = new List<string>() {
"One",
"Two",
"Three",
"Four",
"Five",
"Six" };

var resultList = strList.TakeWhile((s, i) => s.Length > i);

foreach(string str in resultList)


Console.WriteLine(str);
Output:
One
Two
Three
Four

Conversion Operators
The Conversion operators in LINQ are useful in converting the type of the elements in a
sequence (collection). There are three types of conversion operators: As operators
(AsEnumerable and AsQueryable), To operators (ToArray, ToDictionary, ToList and
ToLookup), and Casting operators (Cast and OfType).

The following table lists all the conversion operators.

Method Description

AsEnumerable Returns the input sequence as IEnumerable<t>

AsQueryable Converts IEnumerable to IQueryable, to simulate a remote query provider

Cast Coverts a non-generic collection to a generic collection (IEnumerable to


Method Description

IEnumerable<T>)

OfType Filters a collection based on a specified type

ToArray Converts a collection to an array

ToDictionary Puts elements into a Dictionary based on key selector function

ToList Converts collection to List

ToLookup Groups elements into an Lookup<TKey,TElement>

AsEnumerable & AsQueryable

The AsEnumerable and AsQueryable methods cast or convert a source object to


IEnumerable<T> or IQueryable<T> respectively.

Consider the following example: (courtesy: Jon Skeet)

Example: AsEnumerable & AsQueryable operator in C#:


class Program
{

static void ReportTypeProperties<T>(T obj)


{
Console.WriteLine("Compile-time type: {0}", typeof(T).Name);
Console.WriteLine("Actual type: {0}", obj.GetType().Name);
}

static void Main(string[] args)


{
Student[] studentArray = {
new Student() { StudentID = 1, StudentName = "John", Age
= 18 } ,
new Student() { StudentID = 2, StudentName = "Steve",
Age = 21 } ,
new Student() { StudentID = 3, StudentName = "Bill", Age
= 25 } ,
new Student() { StudentID = 4, StudentName = "Ram" , Age
= 20 } ,
new Student() { StudentID = 5, StudentName = "Ron" , Age
= 31 } ,
};

ReportTypeProperties( studentArray);
ReportTypeProperties(studentArray.AsEnumerable());
ReportTypeProperties(studentArray.AsQueryable());
}
}
Output:
Compile-time type: Student[]
Actual type: Student[]
Compile-time type: IEnumerable`1
Actual type: Student[]
Compile-time type: IQueryable`1
Actual type: EnumerableQuery`1

As you can see in the above example AsEnumerable and AsQueryable methods convert
compile time type to IEnumerable and IQueryable respectively

Visit stackoverflow for detail information on AsEnumerable and AsQueryable method.

Cast

Cast does the same thing as AsEnumerable<T>. It cast the source object into
IEnumerable<T>.

Example: Cast operator in C#


class Program
{

static void ReportTypeProperties<T>(T obj)


{
Console.WriteLine("Compile-time type: {0}", typeof(T).Name);
Console.WriteLine("Actual type: {0}", obj.GetType().Name);
}

static void Main(string[] args)


{
Student[] studentArray = {
new Student() { StudentID = 1, StudentName = "John", Age
= 18 } ,
new Student() { StudentID = 2, StudentName = "Steve",
Age = 21 } ,
new Student() { StudentID = 3, StudentName = "Bill", Age
= 25 } ,
new Student() { StudentID = 4, StudentName = "Ram" , Age
= 20 } ,
new Student() { StudentID = 5, StudentName = "Ron" , Age
= 31 } ,
};

ReportTypeProperties( studentArray);
ReportTypeProperties(studentArray.Cast<Student>());
}
}
Output:
Compile-time type: Student[]
Actual type: Student[]
Compile-time type: IEnumerable`1
Actual type: Student[]
Compile-time type: IEnumerable`1
Actual type: Student[]
Compile-time type: IEnumerable`1
Actual type: Student[]

studentArray.Cast<Student>() is the same as


(IEnumerable<Student>)studentArray but Cast<Student>() is more readable.

To Operators: ToArray(), ToList(), ToDictionary()

As the name suggests, ToArray(), ToList(), ToDictionary() method converts a source object
into an array, List or Dictionary respectively.

To operators force the execution of the query. It forces the remote query provider to
execute a query and get the result from the underlying data source e.g. SQL Server
database.

Example: ToArray & ToList in C#


IList<string> strList = new List<string>() {
"One",
"Two",
"Three",
"Four",
"Three"
};

string[] strArray = strList.ToArray<string>();// converts List to Array

IList<string> list = strArray.ToList<string>(); // converts array into


list

ToDictionary - Converts a Generic list to a generic dictionary:

Example: ToDictionary in C#:


IList<Student> studentList = new List<Student>() {
new Student() { StudentID = 1, StudentName = "John",
age = 18 } ,
new Student() { StudentID = 2, StudentName = "Steve",
age = 21 } ,
new Student() { StudentID = 3, StudentName = "Bill",
age = 18 } ,
new Student() { StudentID = 4, StudentName = "Ram" ,
age = 20 } ,
new Student() { StudentID = 5, StudentName = "Ron" ,
age = 21 }
};

//following converts list into dictionary where StudentId is a key


IDictionary<int, Student> studentDict =
studentList.ToDictionary<Student, int>(s
=> s.StudentID);

foreach(var key in studentDict.Keys)


Console.WriteLine("Key: {0}, Value: {1}",
key, (studentDict[key] as
Student).StudentName);
Output:
Key: 1, Value: John
Key: 2, Value: Steve
Key: 3, Value: Bill
Key: 4, Value: Ram
Key: 5, Value: Ron

The following figure shows how studentDict in the above example contains a key-value
pair, where key is a StudentID and the value is Student object.

LINQ-ToDictionary Operator

Expression in LINQ
We have learned that the lambda Expression can be assigned to the Func or Action type
delegates to process over in-memory collections. The .NET compiler converts the lambda
expression assigned to Func or Action type delegate into executable code at compile time.

LINQ introduced the new type called Expression that represents strongly typed lambda
expression. It means lambda expression can also be assigned to Expression<TDelegate>
type. The .NET compiler converts the lambda expression which is assigned to
Expression<TDelegate> into an Expression tree instead of executable code. This expression
tree is used by remote LINQ query providers as a data structure to build a runtime query
out of it (such as LINQ-to-SQL, EntityFramework or any other LINQ query provider that
implements IQueryable<T> interface).

The following figure illustrates differences when the lambda expression assigned to the
Func or Action delegate and the Expression in LINQ.
Expression and Func

We will learn Expression tree in the next section but first, let's see how to define and
invoke an Expression.

Define an Expression

Take the reference of System.Linq.Expressions namespace and use an


Expression<TDelegate> class to define an Expression. Expression<TDelegate> requires
delegate type Func or Action.

For example, you can assign lambda expression to the isTeenAger variable of Func type
delegate, as shown below:

Example: Define Func delegate for an expression in C#


public class Student
{
public int StudentID { get; set; }
public string StudentName { get; set; }
public int Age { get; set; }
}

Func<Student, bool> isTeenAger = s => s.Age > 12 && s.Age < 20;
Example: Define Func delegate for an expression in VB.Net
Dim isTeenAger As Func(Of Student, Boolean) = Function(s) s.Age > 12 And
s.Age < 20

And now, you can convert the above Func type delegate into an Expression by wrapping
Func delegate with Expresson, as below:

Example: Define Expression in C#


Expression<Func<Student, bool>> isTeenAgerExpr = s => s.age > 12 && s.age
< 20;
Example: Define Expression in VB.Net
Dim isTeenAgerExpr As Expression(Func(Of Student, Boolean)) =
Function(s) s.Age > 12 And s.Age
< 20
in the same way, you can also wrap an Action<t> type delegate with Expression if you
don't return a value from the delegate.

Example: Define Expression in C#


Expression<Action<Student>> printStudentName = s =>
Console.WriteLine(s.StudentName);
Example: Define Expression in VB.Net
Dim printStudentName As Expression(Action(Of Student) =
Function(s)
Console.WriteLine(s.StudentName);

Thus, you can define Expression<TDelegate> type. Now, let's see how to invoke delegate
wrapped by an Expression<TDelegate>.

Invoke an Expression

You can invoke the delegate wrapped by an Expression the same way as a delegate, but
first you need to compile it using the Compile() method. Compile() returns delegateof Func
or Action type so that you can invoke it like a delegate.

Example: Invoke Expression in C#


Expression<Func<Student, bool>> isTeenAgerExpr = s => s.age > 12 && s.age
< 20;

//compile Expression using Compile method to invoke it as Delegate


Func<Student, bool> isTeenAger = isTeenAgerExpr.Compile();

//Invoke
bool result = isTeenAger(new Student(){ StudentID = 1, StudentName =
"Steve", Age = 20});
Example: Invoke Expression in VB.Net
Dim isTeenAgerExpr As Expression(Of Func(Of Student, Boolean)) =
Function(s) s.Age >
12 And s.Age < 20

'compile Expression using Compile method to invoke it as Delegate


Dim isTeenAger As Func(Of Student, Boolean) = isTeenAgerExpr.Compile()

Dim result = isTeenAger(New Student() With { .StudentID = 1, .StudentName


= "Steve", .Age = 20})

Learn about the Expression tree in detail in the next section.

Expression Tree
You have learned about the Expression in the previous section. Now, let's learn about the
Expresion tree here.

Expression tree as name suggests is nothing but expressions arranged in a tree-like data
structure. Each node in an expression tree is an expression. For example, an expression tree
can be used to represent mathematical formula x < y where x, < and y will be represented
as an expression and arranged in the tree like structure.

Expression tree is an in-memory representation of a lambda expression. It holds the actual


elements of the query, not the result of the query.

The expression tree makes the structure of the lambda expression transparent and explicit.
You can interact with the data in the expression tree just as you can with any other data
structure.

For example, consider the following isTeenAgerExpr expression:

Example: Expression in C#
Expression<Func<Student, bool>> isTeenAgerExpr = s => s.age > 12 && s.age
< 20;

The compiler will translate the above expression into the following expression tree:

Example: Expression Tree in C#


Expression.Lambda<Func<Student, bool>>(
Expression.AndAlso(
Expression.GreaterThan(Expression.Property(pe,
"Age"), Expression.Constant(12, typeof(int))),
Expression.LessThan(Expression.Property(pe, "Age"),
Expression.Constant(20, typeof(int)))),
new[] { pe });

You can also build an expression tree manually. Let's see how to build an expression tree
for the following simple lambda expression:

Example: Func delegate in C#:


Func<Student, bool> isAdult = s => s.age >= 18;

This Func type delegate will be treated like the following method:

C#:
public bool function(Student s)
{
return s.Age > 18;
}
To create the expression tree, first of all, create a parameter expression where Student is the
type of the parameter and 's' is the name of the parameter as below:

Step 1: Create Parameter Expression in C#


ParameterExpression pe = Expression.Parameter(typeof(Student), "s");

Now, use Expression.Property() to create s.Age expression where s is the parameter and
Age is the property name of Student. (Expression is an abstract class that contains static
helper methods to create the Expression tree manually.)

Step 2: Create Property Expression in C#


MemberExpression me = Expression.Property(pe, "Age");

Now, create a constant expression for 18:

Step 3: Create Constant Expression in C#


ConstantExpression constant = Expression.Constant(18, typeof(int));

Till now, we have built expression trees for s.Age (member expression) and 18 (constant
expression). We now need to check whether a member expression is greater than a constant
expression or not. For that, use the Expression.GreaterThanOrEqual() method and pass the
member expression and constant expression as parameters:

Step 4: Create Binary Expression in C#


BinaryExpression body = Expression.GreaterThanOrEqual(me, constant);

Thus, we have built an expression tree for a lambda expression body s.Age >= 18. We now
need to join the parameter and body expressions. Use Expression.Lambda(body, parameters
array) to join the body and parameter part of the lambda expression s => s.age >= 18:

Step 5: Create Lambda Expression in C#


var isAdultExprTree = Expression.Lambda<Func<Student, bool>>(body, new[]
{ pe });

This way you can build an expression tree for simple Func delegates with a lambda
expression.

Example: Expression Tree in C#


ParameterExpression pe = Expression.Parameter(typeof(Student), "s");

MemberExpression me = Expression.Property(pe, "Age");

ConstantExpression constant = Expression.Constant(18, typeof(int));

BinaryExpression body = Expression.GreaterThanOrEqual(me, constant);


var ExpressionTree = Expression.Lambda<Func<Student, bool>>(body, new[] {
pe });

Console.WriteLine("Expression Tree: {0}", ExpressionTree);

Console.WriteLine("Expression Tree Body: {0}", ExpressionTree.Body);

Console.WriteLine("Number of Parameters in Expression Tree: {0}",


ExpressionTree.Parameters.Count);

Console.WriteLine("Parameters in Expression Tree: {0}",


ExpressionTree.Parameters[0]);
Example: Expression Tree in VB.Net
Dim pe As ParameterExpression = Expression.Parameter(GetType(Student),
"s")

Dim mexp As MemberExpression = Expression.Property(pe, "Age")

Dim constant As ConstantExpression = Expression.Constant(18,


GetType(Integer))

Dim body As BinaryExpression = Expression.GreaterThanOrEqual(mexp,


constant)

Dim ExpressionTree As Expression(Of Func(Of Student, Boolean)) =


Expression.Lambda(Of Func(Of Student, Boolean))(body, New
ParameterExpression() {pe})

Console.WriteLine("Expression Tree: {0}", ExpressionTree)

Console.WriteLine("Expression Tree Body: {0}", ExpressionTree.Body)

Console.WriteLine("Number of Parameters in Expression Tree: {0}",


ExpressionTree.Parameters.Count)

Console.WriteLine("Parameters in Expression Tree: {0}",


ExpressionTree.Parameters(0))
Output:
Expression Tree: s => (s.Age >= 18)
Expression Tree Body: (s.Age >= 18)
Number of Parameters in Expression Tree: 1
Parameters in Expression Tree: s

The following image illustrates the whole process of creating an expression tree:
Construct Expression Tree

Why Expression Tree?

We have seen in the previous section that the lambda expression assigned to Func<T>
compiles into executable code and the lambda expression assigned to
Expression<TDelegate> type compiles into Expression tree.

Executable code excutes in the same application domain to process over in-memory
collection. Enumerable static classes contain extension methods for in-memory collections
that implements IEnumerable<T> interface e.g. List<T>, Dictionary<T>, etc. The
Extension methods in an Enumerable class accept a predicate parameter of Func type
delegate. For example, the Where extension method accepts Func<TSource, bool>
predicate. It then compiles it into IL (Intermediate Language) to process over in-memory
collections that are in the same AppDomain.

The following image shows Where extension method in Enumerable class includes Func
delegate as a parameter:

Func delegate in Where


Func delegate is a raw executable code, so if you debug the code, you will find that the
Func delegate will be represented as opaque code. You cannot see its parameters, return
type and body:

Func delegate in debug mode

Func delegate is for in-memory collections because it will be processed in the same
AppDomain, but what about remote LINQ query providers like LINQ-to-SQL,
EntityFramework or other third party products that provides LINQ capabilities? How
would they parse lambda expression that has been compiled into raw executable code to
know about the parameters, return type of lambda expression and build runtime query to
process further? The answer is Expression tree.

Expression<TDelegate> is compiled into a data structure called an expression tree.

If you debug the code, Expression delegate will be represented as shown below:

Expression Tree in debug mode

Now you can see the difference between a normal delegate and an Expression. An
expression tree is transparent. You can retrieve a parameter, return type and body
expression information from the expression, as below:

Example: Expression Tree in C#


Expression<Func<Student, bool>> isTeenAgerExpr = s => s.Age > 12 && s.Age
< 20;

Console.WriteLine("Expression: {0}", isTeenAgerExpr );

Console.WriteLine("Expression Type: {0}", isTeenAgerExpr.NodeType);

var parameters = isTeenAgerExpr.Parameters;

foreach (var param in parameters)


{
Console.WriteLine("Parameter Name: {0}", param.Name);
Console.WriteLine("Parameter Type: {0}", param.Type.Name );
}
var bodyExpr = isTeenAgerExpr.Body as BinaryExpression;

Console.WriteLine("Left side of body expression: {0}", bodyExpr.Left);


Console.WriteLine("Binary Expression Type: {0}", bodyExpr.NodeType);
Console.WriteLine("Right side of body expression: {0}", bodyExpr.Right);
Console.WriteLine("Return Type: {0}", isTeenAgerExpr.ReturnType);
Output:
Expression: s => ((s.Age > 12) AndAlso (s.Age < 20))
Expression Type: Lambda
Parameter Name: s
Parameter Type: Student
Left side of body expression: (s.Age > 12)
Binary Expression Type: AndAlso
Right side of body expression: (s.Age < 20)
Return Type: System.Boolean

LINQ query for LINQ-to-SQL or Entity Framework is not executed in the same app
domain. For example, the following LINQ query for Entity Framework is never actually
executed inside your program:

Example: LINQ Query in C#


var query = from s in dbContext.Students
where s.Age >= 18
select s;

It is first translated into an SQL statement and then executed on the database server.

The code found in a query expression has to be translated into an SQL query that can be
sent to another process as a string. For LINQ-to-SQL or Entity Frameworks, that process
happens to be an SQL server database. It is obviously going to be much easier to translate a
data structure such as an expression tree into SQL than it is to translate raw IL or
executable code into SQL because, as you have seen, it is easy to retrieve information from
an expression.

Expression trees were created for the task of converting code such as a query expression
into a string that can be passed to some other process and executed there.

Queryable static class includes extension methods that accept a predicate parameter of
Expression type. This predicate expression will be converted into an Expression Tree and
then will be passed to the remote LINQ provider as a data structure so that the provider can
build an appropriate query from the expression tree and execute the query.
Expression Tree Process

Deferred Execution of LINQ Query


Deferred execution means that the evaluation of an expression is delayed until its realized
value is actually required. It greatly improves performance by avoiding unnecessary
execution.

Deferred execution is applicable on any in-memory collection as well as remote LINQ


providers like LINQ-to-SQL, LINQ-to-Entities, LINQ-to-XML, etc.

Let's understand deferred execution using the following example:

Deferred Execution

In the above example, you can see the query is materialized and executed when you iterate
using the foreach loop. This is called deferred execution. LINQ processes the studentList
collection when you actually access each object from the collection and do something with
it.

Deferred Execution returns the Latest Data

To check whether deferred execution returns the latest data each time, add one more teen
ager student after the foreach loop and check the teenager student list:

Deferred Execution

As you can see, the second foreach loop executes the query again and returns the latest
data. Deferred execution re-evaluates on each execution; this is called lazy evaluation.
This is one of the major advantages of deferred execution: it always gives you the latest
data.
Implementing Deferred Execution

You can implement deferred execution for your custom extension methods for
IEnumerable using the yield keyword of C#.

For example, you can implement custom extension method GetTeenAgerStudents for
IEnumerable that returns a list of all students who are teenagers.

Example: Implimenting Deferred Execution in C#


public static class EnumerableExtensionMethods
{
public static IEnumerable<Student> GetTeenAgerStudents(this
IEnumerable<Student> source)
{

foreach (Student std in source)


{
Console.WriteLine("Accessing student {0}", std.StudentName);

if (std.age > 12 && std.age < 20)


yield return std;
}
}
}

Notice that we print the student name on the console whenever GetTeenAgerStudents() gets
called.

You can now use this extension method as below:

C#:
IList<Student> studentList = new List<Student>() {
new Student() { StudentID = 1, StudentName = "John", age = 13
} ,
new Student() { StudentID = 2, StudentName = "Steve", age =
15 } ,
new Student() { StudentID = 3, StudentName = "Bill", age =
18 } ,
new Student() { StudentID = 4, StudentName = "Ram" , age = 12
} ,
new Student() { StudentID = 5, StudentName = "Ron" , age = 21
}
};

var teenAgerStudents = from s in studentList.GetTeenAgerStudents()


select s;

foreach (Student teenStudent in teenAgerStudents)


Console.WriteLine("Student Name: {0}", teenStudent.StudentName);
Output:
Accessing student John
Student Name: John
Accessing student Steve
Student Name: Steve
Accessing student Bill
Student Name: Bill
Accessing student Ram
Accessing student Ron

As you can see from the output, GetTeenAgerStudents() is getting called when you iterate
studentList using the foreach loop.

Deferred Execution

So, in this way you can create custom methods using the yield keyword to get the
advantage of deferred execution.

Immediate Execution of LINQ Query


Immediate execution is the reverse of deferred execution. It forces the LINQ query to
execute and gets the result immediately. The 'To' conversion operators execute the given
query and give the result immediately.

Method Syntax

In the following example, ToList() extension method executes the query immediately and
returns the result.

C#: Immediate Execution


IList<Student> teenAgerStudents =
studentList.Where(s => s.age > 12 && s.age <
20).ToList();
VB.Net:Immediate Execution
Dim teenAgerStudents As IList(Of Student) =
studentList.Where(Function(s) s.Age > 12 And s.Age <
20).ToList()

Query Syntax

C#:
var teenAgerStudents = from s in studentList
where s.age > 12 && s.age < 20
select s;

The above query will not execute immediately. You won't find any result as shown below:

Immediate Execution

Query Syntax doesn't support 'To' operators but can use ToList(), ToArray() or
ToDictionary() for immediate execution as below:

C#:
IList<Student> teenAgerStudents = (from s in studentList
where s.age > 12 && s.age < 20
select s).ToList();
VB.Net:
Dim teenAgerStudents As IList(Of Student) = (From s In studentList _
Where s.Age > 12 And s.Age < 20 _
Select s).ToList()

You can see the result in the teenAgerStudents collection, as below:

Immediate Execution

Further Reading

 Charlies' blog
 MSDN
let keyword
The 'let' keyword is useful in query syntax. It projects a new range variable, allows re-use
of the expression and makes the query more readable.

For example, you can compare string values and select the lowercase string value as shown
below:

Example: let in LINQ query - C#


IList<Student> studentList = new List<Student>() {
new Student() { StudentID = 1, StudentName = "John", Age = 18 } ,
new Student() { StudentID = 2, StudentName = "Steve", Age = 21 } ,
new Student() { StudentID = 3, StudentName = "Bill", Age = 18 } ,
new Student() { StudentID = 4, StudentName = "Ram" , Age = 20 } ,
new Student() { StudentID = 5, StudentName = "Ron" , Age = 21 }
};

var lowercaseStudentNames = from s in studentList


where s.StudentName.ToLower().StartsWith("r")
select s.StudentName.ToLower();

As you can see, the ToLower() method is used multiple times in the above query. The
following example use 'let' to introduce new variable 'lowercaseStudentName' that will be
then used in every where. Thus, let keyword to make the query more readable.

Example: let keyword in C#


var lowercaseStudentNames = from s in studentList
let lowercaseStudentName =
s.StudentName.ToLower()
where
lowercaseStudentName.StartsWith("r")
select lowercaseStudentName;

foreach (var name in lowercaseStudentNames)


Console.WriteLine(name);
Example: let keyword in VB.Net
Dim lowercaseStudentNames = From s In studentList
Let lowercaseStudentName =
s.StudentName.ToLower()
Where
lowercaseStudentName.StartsWith("r")
Select lowercaseStudentName;
Output:
ram
ron

into keyword
We have already used the 'into' keyword in grouping. You can also use the 'into' keyword to
continue a query after a select clause.

Example: into keyword in LINQ


var teenAgerStudents = from s in studentList
where s.age > 12 && s.age < 20
select s
into teenStudents
where teenStudents.StudentName.StartsWith("B")
select teenStudents;

In the above query, the 'into' keyword introduced a new range variable teenStudents, so the
first range variable s goes out of scope. You can write a further query after the into
keyword using a new range variable.

The 'into' keyword in VB.Net used for grouping purposes.

Example: into keyword in LINQ VB.Net


Dim groupQuery = From s In studentList
Group By s.Age Into Group

Sample LINQ Queries


In this section, you will learn some complex LINQ queries. We will use the following
Student and Standard collection for our queries.

Sample Collections:
IList<Student> studentList = new List<Student>() {
new Student() { StudentID = 1, StudentName = "John", Age = 18,
StandardID = 1 } ,
new Student() { StudentID = 2, StudentName = "Steve", Age = 21,
StandardID = 1 } ,
new Student() { StudentID = 3, StudentName = "Bill", Age = 18,
StandardID = 2 } ,
new Student() { StudentID = 4, StudentName = "Ram" , Age = 20,
StandardID = 2 } ,
new Student() { StudentID = 5, StudentName = "Ron" , Age = 21 }
};

IList<Standard> standardList = new List<Standard>() {


new Standard(){ StandardID = 1, StandardName="Standard 1"},
new Standard(){ StandardID = 2, StandardName="Standard 2"},
new Standard(){ StandardID = 3, StandardName="Standard 3"}
};
Multiple Select and where operator
Example: Multiple Select and where Operator
var studentNames = studentList.Where(s => s.Age > 18)
.Select(s => s)
.Where(st => st.StandardID > 0)
.Select(s => s.StudentName);
Output:
Steve
Ram

The following query returns Enumerable of anonymous object that has only StudentName
property:

Example: LINQ Query returns Collection of Anonymous Objects


var teenStudentsName = from s in studentList
where s.age > 12 && s.age < 20
select new { StudentName = s.StudentName };

teenStudentsName.ToList().ForEach(s => Console.WriteLine(s.StudentName));


Output:
John
Bill

Group By

The following query returns list students group by StandardID:

Example: LINQ GroupBy Query - C#


var studentsGroupByStandard = from s in studentList
group s by s.StandardID into sg
orderby sg.Key
select new { sg.Key, sg };

foreach (var group in studentsGroupByStandard)


{
Console.WriteLine("StandardID {0}:", group.Key);

group.sg.ToList().ForEach(st => Console.WriteLine(st.StudentName ));


}
Output:
StandardID 0:
Ron
StandardID 1:
John
Steve
StandardID 2:
Bill
Ram
The output includes Ron who doesn't have any StandardID. So Ron falls under StandardID
0.

To remove a student who doesn't have a StandardID, use a where operator before the group
operator:

Example: LINQ GroupBy Query - C#


var studentsGroupByStandard = from s in studentList
where s.StandardID > 0
group s by s.StandardID into sg
orderby sg.Key
select new { sg.Key, sg };
Output:
StandardID 1:
John
Steve
StandardID 2:
Bill
Ram

Left outer join

Use left outer join to display students under each standard. Display the standard name even
if there is no student assigned to that standard.

Example: LINQ Left Outer Join - C#


var studentsGroup = from stad in standardList
join s in studentList
on stad.StandardID equals s.StandardID
into sg
select new {
StandardName = stad.StandardName,
Students = sg
};

foreach (var group in studentsGroup)


{
Console.WriteLine(group.StandardName);

group.Students.ToList().ForEach(st =>
Console.WriteLine(st.StudentName));
}
Output:
Standard 1:
John
Steve
Standard 2:
Bill
Ram
Standard 3:

In the following example of group by query, we sort the group and select only
StudentName:

Example: LINQ Left Outer Join - C#


var studentsWithStandard = from stad in standardList
join s in studentList
on stad.StandardID equals s.StandardID
into sg
from std_grp in sg
orderby stad.StandardName,
std_grp.StudentName
select new {
StudentName =
std_grp.StudentName,
StandardName =
stad.StandardName
};

foreach (var group in studentsWithStandard)


{
Console.WriteLine("{0} is in {1}", group.StudentName,
group.StandardName);
}
Output:
John is in Standard 1
Steve is in Standard 1
Bill is in Standard 2
Ram is in Standard 2

Sorting

The following query returns list of students by ascending order of StandardID and Age.

Example: Sorting
var sortedStudents = from s in studentList
orderby s.StandardID, s.age
select new {
StudentName = s.StudentName,
Age = s.age,
StandardID = s.StandardID };

sortedStudents.ToList().ForEach(s => Console.WriteLine("Student Name:


{0}, Age: {1}, StandardID: {2}", s.StudentName, s.Age , s.StandardID));
Output:
Student Name: Ron, Age: 21, StandardID: 0
Student Name: John, Age: 18, StandardID: 1
Student Name: Steve, Age: 21, StandardID: 1
Student Name: Bill, Age: 18, StandardID: 2
Student Name: Ram, Age: 20, StandardID: 2

Inner Join
Example: LINQ Inner join - C#
var studentWithStandard = from s in studentList
join stad in standardList
on s.StandardID equals stad.StandardID
select new {
StudentName = s.StudentName,
StandardName = stad.StandardName
};

studentWithStandard.ToList().ForEach(s => Console.WriteLine("{0} is in


{1}", s.StudentName, s.StandardName ));
Output:
John is in Standard 1
Steve is in Standard 1
Bill is in Standard 2
Ram is in Standard 2

Nested Query
C#:
var nestedQueries = from s in studentList
where s.age > 18 && s.StandardID ==
(from std in standardList
where std.StandardName == "Standard 1"
select std.StandardID).FirstOrDefault()
select s;

nestedQueries.ToList().ForEach(s => Console.WriteLine(s.StudentName));


Output:
Steve

http://www.tutorialsteacher.com/linq/linq-useful-resources

You might also like