Вы находитесь на странице: 1из 529

C

#
Language Specification
Version 3.0
Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
Please send corrections, coents, and other feed!ac" to sharp#icrosoft.co
Notice
1999-2007 Microsoft Corporation. All rights reserved.
Microsoft, Windows, is!al "asic, is!al C#, and is!al C$$ are either registered trade%ar&s or trade%ar&s of Microsoft
Corporation in the '.(.A. and)or other co!ntries)regions.
*ther prod!ct and co%pan+ na%es %entioned herein %a+ ,e the trade%ar&s of their respective owners.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
Table of Contents
Table of Contents
1. Introduction..................................................................................................................................................... 1
1.1 Hello world.................................................................................................................................................. 1
1.2 Program structure........................................................................................................................................ 2
1.3 Types and variables..................................................................................................................................... 4
1.4 Epressions................................................................................................................................................. !
1." #tatements................................................................................................................................................... $
1.% Classes and ob&ects.................................................................................................................................... 14
1.%.1 'embers............................................................................................................................................. 1"
1.%.2 (ccessibility....................................................................................................................................... 1"
1.%.3 Type parameters.................................................................................................................................. 1%
1.%.4 )ase classes........................................................................................................................................ 1%
1.%." *ields.................................................................................................................................................. 1!
1.%.% 'et+ods.............................................................................................................................................. 1!
1.%.%.1 Parameters..................................................................................................................................... 1!
1.%.%.2 'et+od body and local variables...................................................................................................1$
1.%.%.3 #tatic and instance met+ods...........................................................................................................1$
1.%.%.4 ,irtual- override- and abstract met+ods.........................................................................................2.
1.%.%." 'et+od overloading...................................................................................................................... 23
1.%.! /t+er 0unction members...................................................................................................................... 23
1.%.!.1 Constructors.................................................................................................................................. 2"
1.%.!.2 Properties...................................................................................................................................... 2%
1.%.!.3 1ndeers......................................................................................................................................... 2%
1.%.!.4 Events............................................................................................................................................ 2!
1.%.!." /perators....................................................................................................................................... 2!
1.%.!.% 2estructors.................................................................................................................................... 23
1.! #tructs........................................................................................................................................................ 23
1.3 (rrays........................................................................................................................................................ 2$
1.$ 1nter0aces................................................................................................................................................... 31
1.1. Enums...................................................................................................................................................... 32
1.11 2elegates................................................................................................................................................. 34
1.12 (ttributes................................................................................................................................................. 3"
2. Lexical structure........................................................................................................................................... 37
2.1 Programs................................................................................................................................................... 3!
2.2 4rammars.................................................................................................................................................. 3!
2.2.1 4rammar notation............................................................................................................................... 3!
2.2.2 5eical grammar................................................................................................................................. 33
2.2.3 #yntactic grammar..............................................................................................................................33
2.3 5eical analysis......................................................................................................................................... 33
2.3.1 5ine terminators.................................................................................................................................. 3$
2.3.2 Comments........................................................................................................................................... 3$
2.3.3 6+ite space......................................................................................................................................... 41
2.4 To7ens....................................................................................................................................................... 41
2.4.1 8nicode c+aracter escape se9uences...................................................................................................41
2.4.2 1denti0iers............................................................................................................................................ 42
2.4.3 :eywords............................................................................................................................................ 44
2.4.4 5iterals................................................................................................................................................ 44
2.4.4.1 )oolean literals.............................................................................................................................. 44
2.4.4.2 1nteger literals................................................................................................................................ 4"
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. iii
C# Language Specification
2.4.4.3 ;eal literals.................................................................................................................................... 4%
2.4.4.4 C+aracter literals........................................................................................................................... 4%
2.4.4." #tring literals................................................................................................................................. 4!
2.4.4.% T+e null literal...............................................................................................................................4$
2.4." /perators and punctuators...................................................................................................................4$
2." Pre<processing directives...........................................................................................................................".
2.".1 Conditional compilation symbols........................................................................................................"1
2.".2 Pre<processing epressions................................................................................................................."1
2.".3 2eclaration directives......................................................................................................................... "2
2.".4 Conditional compilation directives....................................................................................................."3
2."." 2iagnostic directives...........................................................................................................................""
2.".% ;egion directives................................................................................................................................ "%
2.".! 5ine directives..................................................................................................................................... "%
2.".3 Pragma directives................................................................................................................................ "!
2.".3.1 Pragma warning............................................................................................................................."!
3. Basic concepts................................................................................................................................................ !
3.1 (pplication #tartup.................................................................................................................................... "$
3.2 (pplication termination.............................................................................................................................%.
3.3 2eclarations............................................................................................................................................... %.
3.4 'embers.................................................................................................................................................... %2
3.4.1 =amespace members........................................................................................................................... %3
3.4.2 #truct members................................................................................................................................... %3
3.4.3 Enumeration members........................................................................................................................%3
3.4.4 Class members.................................................................................................................................... %4
3.4." 1nter0ace members............................................................................................................................... %4
3.4.% (rray members................................................................................................................................... %4
3.4.! 2elegate members............................................................................................................................... %4
3." 'ember access.......................................................................................................................................... %4
3.".1 2eclared accessibility......................................................................................................................... %4
3.".2 (ccessibility domains.........................................................................................................................%"
3.".3 Protected access 0or instance members...............................................................................................%3
3.".4 (ccessibility constraints.....................................................................................................................%$
3.% #ignatures and overloading........................................................................................................................!.
3.! #copes....................................................................................................................................................... !1
3.!.1 =ame +iding........................................................................................................................................ !4
3.!.1.1 Hiding t+roug+ nesting.................................................................................................................. !4
3.!.1.2 Hiding t+roug+ in+eritance............................................................................................................!"
3.3 =amespace and type names.......................................................................................................................!%
3.3.1 *ully 9uali0ied names.......................................................................................................................... !3
3.$ (utomatic memory management...............................................................................................................!$
3.1. Eecution order....................................................................................................................................... 31
". T#pes.............................................................................................................................................................. $3
4.1 ,alue types................................................................................................................................................ 33
4.1.1 T+e #ystem.,alueType type...............................................................................................................34
4.1.2 2e0ault constructors............................................................................................................................ 34
4.1.3 #truct types......................................................................................................................................... 3"
4.1.4 #imple types........................................................................................................................................ 3"
4.1." 1ntegral types...................................................................................................................................... 3%
4.1.% *loating point types............................................................................................................................. 3!
i% Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
Table of Contents
4.1.! T+e decimal type.................................................................................................................................33
4.1.3 T+e bool type...................................................................................................................................... 3$
4.1.$ Enumeration types.............................................................................................................................. 3$
4.1.1. =ullable types................................................................................................................................... 3$
4.2 ;e0erence types......................................................................................................................................... $.
4.2.1 Class types.......................................................................................................................................... $.
4.2.2 T+e ob&ect type.................................................................................................................................... $1
4.2.3 T+e string type.................................................................................................................................... $1
4.2.4 1nter0ace types..................................................................................................................................... $1
4.2." (rray types.......................................................................................................................................... $1
4.2.% 2elegate types..................................................................................................................................... $1
4.3 )oing and unboing................................................................................................................................ $2
4.3.1 )oing conversions.............................................................................................................................$2
4.3.2 8nboing conversions.........................................................................................................................$3
4.4 Constructed types...................................................................................................................................... $4
4.4.1 Type arguments................................................................................................................................... $"
4.4.2 /pen and closed types.........................................................................................................................$"
4.4.3 )ound and unbound types...................................................................................................................$"
4.4.4 #atis0ying constraints..........................................................................................................................$%
4." Type parameters........................................................................................................................................ $!
4.% Epression tree types................................................................................................................................. $!
. &ariables........................................................................................................................................................ !!
".1 ,ariable categories.................................................................................................................................... $$
".1.1 #tatic variables.................................................................................................................................... $$
".1.2 1nstance variables................................................................................................................................ $$
".1.2.1 1nstance variables in classes........................................................................................................1..
".1.2.2 1nstance variables in structs.........................................................................................................1..
".1.3 (rray elements.................................................................................................................................. 1..
".1.4 ,alue parameters.............................................................................................................................. 1..
".1." ;e0erence parameters........................................................................................................................1..
".1.% /utput parameters............................................................................................................................. 1.1
".1.! 5ocal variables.................................................................................................................................. 1.1
".2 2e0ault values.......................................................................................................................................... 1.2
".3 2e0inite assignment................................................................................................................................. 1.2
".3.1 1nitially assigned variables................................................................................................................ 1.3
".3.2 1nitially unassigned variables............................................................................................................1.3
".3.3 Precise rules 0or determining de0inite assignment.............................................................................1.3
".3.3.1 4eneral rules 0or statements........................................................................................................1.4
".3.3.2 )loc7 statements- c+ec7ed- and unc+ec7ed statements................................................................1.4
".3.3.3 Epression statements.................................................................................................................1.4
".3.3.4 2eclaration statements.................................................................................................................1."
".3.3." 10 statements................................................................................................................................ 1."
".3.3.% #witc+ statements........................................................................................................................ 1."
".3.3.! 6+ile statements.........................................................................................................................1."
".3.3.3 2o statements.............................................................................................................................. 1.%
".3.3.$ *or statements.............................................................................................................................1.%
".3.3.1. )rea7- continue- and goto statements........................................................................................1.%
".3.3.11 T+row statements......................................................................................................................1.%
".3.3.12 ;eturn statements...................................................................................................................... 1.%
".3.3.13 Try<catc+ statements.................................................................................................................. 1.!
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. %
C# Language Specification
".3.3.14 Try<0inally statements................................................................................................................1.!
".3.3.1" Try<catc+<0inally statements......................................................................................................1.3
".3.3.1% *oreac+ statements.................................................................................................................... 1.3
".3.3.1! 8sing statements........................................................................................................................1.$
".3.3.13 5oc7 statements.........................................................................................................................1.$
".3.3.1$ >ield statements........................................................................................................................ 1.$
".3.3.2. 4eneral rules 0or simple epressions.........................................................................................1.$
".3.3.21 4eneral rules 0or epressions wit+ embedded epressions........................................................1.$
".3.3.22 1nvocation epressions and ob&ect creation epressions............................................................11.
".3.3.23 #imple assignment epressions.................................................................................................11.
".3.3.24 ?? epressions.........................................................................................................................111
".3.3.2" @@ epressions..............................................................................................................................111
".3.3.2% A epressions.............................................................................................................................. 112
".3.3.2! BB epressions............................................................................................................................ 113
".3.3.23 BC epressions............................................................................................................................ 113
".3.3.2$ (nonymous 0unctions................................................................................................................113
".4 ,ariable re0erences.................................................................................................................................. 114
"." (tomicity o0 variable re0erences..............................................................................................................114
'. Con%ersions................................................................................................................................................. 11
%.1 1mplicit conversions................................................................................................................................ 11"
%.1.1 1dentity conversion............................................................................................................................ 11"
%.1.2 1mplicit numeric conversions............................................................................................................11%
%.1.3 1mplicit enumeration conversions.....................................................................................................11%
%.1.4 1mplicit nullable conversions............................................................................................................11%
%.1." =ull literal conversions.....................................................................................................................11!
%.1.% 1mplicit re0erence conversions..........................................................................................................11!
%.1.! )oing conversions...........................................................................................................................11!
%.1.3 1mplicit constant epression conversions..........................................................................................113
%.1.$ 1mplicit conversions involving type parameters................................................................................113
%.1.1. 8ser<de0ined implicit conversions...................................................................................................113
%.1.11 (nonymous 0unction conversions and met+od group conversions..................................................113
%.2 Eplicit conversions................................................................................................................................ 11$
%.2.1 Eplicit numeric conversions............................................................................................................11$
%.2.2 Eplicit enumeration conversions.....................................................................................................121
%.2.3 Eplicit nullable conversions............................................................................................................121
%.2.4 Eplicit re0erence conversions..........................................................................................................121
%.2." 8nboing conversions.......................................................................................................................122
%.2.% Eplicit conversions involving type parameters................................................................................123
%.2.! 8ser<de0ined eplicit conversions.....................................................................................................123
%.3 #tandard conversions...............................................................................................................................124
%.3.1 #tandard implicit conversions...........................................................................................................124
%.3.2 #tandard eplicit conversions............................................................................................................124
%.4 8ser<de0ined conversions........................................................................................................................ 124
%.4.1 Permitted user<de0ined conversions..................................................................................................124
%.4.2 5i0ted conversion operators...............................................................................................................124
%.4.3 Evaluation o0 user<de0ined conversions............................................................................................12"
%.4.4 8ser<de0ined implicit conversions.....................................................................................................12%
%.4." 8ser<de0ined eplicit conversions.....................................................................................................12%
%." (nonymous 0unction conversions............................................................................................................12!
%.".1 Evaluation o0 anonymous 0unction conversions to delegate types....................................................12$
%i Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
Table of Contents
%.".2 Evaluation o0 anonymous 0unction conversions to epression tree types..........................................12$
%.".3 1mplementation eample................................................................................................................... 12$
%.% 'et+od group conversions...................................................................................................................... 132
7. (xpressions.................................................................................................................................................. 13
!.1 Epression classi0ications........................................................................................................................13"
!.1.1 ,alues o0 epressions........................................................................................................................ 13%
!.2 /perators................................................................................................................................................. 13%
!.2.1 /perator precedence and associativity..............................................................................................13!
!.2.2 /perator overloading........................................................................................................................133
!.2.3 8nary operator overload resolution...................................................................................................13$
!.2.4 )inary operator overload resolution..................................................................................................13$
!.2." Candidate user<de0ined operators......................................................................................................13$
!.2.% =umeric promotions......................................................................................................................... 14.
!.2.%.1 8nary numeric promotions..........................................................................................................14.
!.2.%.2 )inary numeric promotions.........................................................................................................14.
!.2.! 5i0ted operators................................................................................................................................. 141
!.3 'ember loo7up....................................................................................................................................... 142
!.3.1 )ase types......................................................................................................................................... 143
!.4 *unction members................................................................................................................................... 143
!.4.1 (rgument lists................................................................................................................................... 14%
!.4.2 Type in0erence.................................................................................................................................. 143
!.4.2.1 T+e 0irst p+ase.............................................................................................................................14$
!.4.2.2 T+e second p+ase.........................................................................................................................14$
!.4.2.3 1nput types................................................................................................................................... 1".
!.4.2.4 /utput types............................................................................................................................... 1".
!.4.2." 2ependence................................................................................................................................. 1".
!.4.2.% /utput type in0erences................................................................................................................. 1".
!.4.2.! Eplicit parameter type in0erences..............................................................................................1".
!.4.2.3 Eact in0erences..........................................................................................................................1".
!.4.2.$ 5ower<bound in0erences..............................................................................................................1".
!.4.2.1. *iing........................................................................................................................................ 1"1
!.4.2.11 1n0erred return type....................................................................................................................1"1
!.4.2.12 Type in0erence 0or conversion o0 met+od groups......................................................................1"2
!.4.2.13 *inding t+e best common type o0 a set o0 epressions...............................................................1"3
!.4.3 /verload resolution...........................................................................................................................1"3
!.4.3.1 (pplicable 0unction member.......................................................................................................1"3
!.4.3.2 )etter 0unction member...............................................................................................................1"4
!.4.3.3 )etter conversion 0rom epression..............................................................................................1""
!.4.3.4 )etter conversion 0rom type........................................................................................................1""
!.4.3." /verloading in generic classes....................................................................................................1"%
!.4.4 *unction member invocation.............................................................................................................1"%
!.4.4.1 1nvocations on boed instances...................................................................................................1"3
!." Primary epressions................................................................................................................................. 1"3
!.".1 5iterals.............................................................................................................................................. 1"$
!.".2 #imple names.................................................................................................................................... 1"$
!.".2.1 1nvariant meaning in bloc7s........................................................................................................1%.
!.".3 Parent+esiDed epressions.................................................................................................................1%1
!.".4 'ember access.................................................................................................................................. 1%1
!.".4.1 1dentical simple names and type names.......................................................................................1%3
!.".4.2 4rammar ambiguities.................................................................................................................. 1%4
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. %ii
C# Language Specification
!."." 1nvocation epressions...................................................................................................................... 1%4
!.".".1 'et+od invocations.....................................................................................................................1%"
!.".".2 Etension met+od invocations.....................................................................................................1%%
!.".".3 2elegate invocations................................................................................................................... 1%3
!.".% Element access.................................................................................................................................. 1%$
!.".%.1 (rray access................................................................................................................................ 1%$
!.".%.2 1ndeer access............................................................................................................................. 1%$
!.".! T+is access........................................................................................................................................ 1!.
!.".3 )ase access....................................................................................................................................... 1!1
!.".$ Post0i increment and decrement operators.......................................................................................1!1
!.".1. T+e new operator............................................................................................................................1!2
!.".1..1 /b&ect creation epressions.......................................................................................................1!3
!.".1..2 /b&ect initialiDers...................................................................................................................... 1!4
!.".1..3 Collection initialiDers.................................................................................................................1!%
!.".1..4 (rray creation epressions........................................................................................................1!!
!.".1.." 2elegate creation epressions....................................................................................................1!$
!.".1..% (nonymous ob&ect creation epressions....................................................................................13.
!.".11 T+e typeo0 operator.........................................................................................................................132
!.".12 T+e c+ec7ed and unc+ec7ed operators............................................................................................134
!.".13 2e0ault value epressions............................................................................................................... 13%
!.".14 (nonymous met+od epressions.....................................................................................................13%
!.% 8nary operators....................................................................................................................................... 13%
!.%.1 8nary plus operator...........................................................................................................................13!
!.%.2 8nary minus operator........................................................................................................................ 13!
!.%.3 5ogical negation operator................................................................................................................. 13!
!.%.4 )itwise complement operator............................................................................................................133
!.%." Pre0i increment and decrement operators........................................................................................133
!.%.% Cast epressions................................................................................................................................ 13$
!.! (rit+metic operators................................................................................................................................ 13$
!.!.1 'ultiplication operator..................................................................................................................... 1$.
!.!.2 2ivision operator.............................................................................................................................. 1$1
!.!.3 ;emainder operator........................................................................................................................... 1$2
!.!.4 (ddition operator.............................................................................................................................. 1$3
!.!." #ubtraction operator.......................................................................................................................... 1$"
!.3 #+i0t operators......................................................................................................................................... 1$%
!.$ ;elational and type<testing operators.......................................................................................................1$!
!.$.1 1nteger comparison operators............................................................................................................1$3
!.$.2 *loating<point comparison operators.................................................................................................1$$
!.$.3 2ecimal comparison operators..........................................................................................................2..
!.$.4 )oolean e9uality operators................................................................................................................2..
!.$." Enumeration comparison operators...................................................................................................2..
!.$.% ;e0erence type e9uality operators.....................................................................................................2..
!.$.! #tring e9uality operators...................................................................................................................2.2
!.$.3 2elegate e9uality operators...............................................................................................................2.2
!.$.$ E9uality operators and null...............................................................................................................2.3
!.$.1. T+e is operator................................................................................................................................ 2.3
!.$.11 T+e as operator................................................................................................................................ 2.4
!.1. 5ogical operators................................................................................................................................... 2."
!.1..1 1nteger logical operators.................................................................................................................. 2."
!.1..2 Enumeration logical operators........................................................................................................2."
!.1..3 )oolean logical operators................................................................................................................2.%
%iii Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
Table of Contents
!.1..4 =ullable boolean logical operators..................................................................................................2.%
!.11 Conditional logical operators................................................................................................................. 2.%
!.11.1 )oolean conditional logical operators.............................................................................................2.!
!.11.2 8ser<de0ined conditional logical operators......................................................................................2.!
!.12 T+e null coalescing operator.................................................................................................................. 2.3
!.13 Conditional operator.............................................................................................................................. 2.3
!.14 (nonymous 0unction epressions..........................................................................................................2.$
!.14.1 (nonymous 0unction signatures......................................................................................................211
!.14.2 (nonymous 0unction bodies............................................................................................................211
!.14.3 /verload resolution.........................................................................................................................212
!.14.4 /uter variables................................................................................................................................ 213
!.14.4.1 Captured outer variables............................................................................................................213
!.14.4.2 1nstantiation o0 local variables...................................................................................................214
!.14." Evaluation o0 anonymous 0unction epressions..............................................................................21%
!.1" Euery epressions................................................................................................................................. 21%
!.1".1 (mbiguities in 9uery epressions...................................................................................................213
!.1".2 Euery epression translation...........................................................................................................213
!.1".2.1 #elect and groupby clauses wit+ continuations..........................................................................213
!.1".2.2 Eplicit range variable types.....................................................................................................21$
!.1".2.3 2egenerate 9uery epressions...................................................................................................21$
!.1".2.4 *rom- let- w+ere- &oin and orderby clauses................................................................................22.
!.1".2." #elect clauses.............................................................................................................................223
!.1".2.% 4roupby clauses........................................................................................................................ 224
!.1".2.! Transparent identi0iers...............................................................................................................224
!.1".3 T+e 9uery epression pattern..........................................................................................................22%
!.1% (ssignment operators............................................................................................................................ 22!
!.1%.1 #imple assignment..........................................................................................................................22!
!.1%.2 Compound assignment.................................................................................................................... 22$
!.1%.3 Event assignment............................................................................................................................23.
!.1! Epression............................................................................................................................................. 23.
!.13 Constant epressions.............................................................................................................................231
!.1$ )oolean epressions.............................................................................................................................. 232
$. State)ents.................................................................................................................................................... 233
3.1 End points and reac+ability.....................................................................................................................233
3.2 )loc7s...................................................................................................................................................... 23"
3.2.1 #tatement lists................................................................................................................................... 23"
3.3 T+e empty statement................................................................................................................................ 23%
3.4 5abeled statements.................................................................................................................................. 23%
3." 2eclaration statements.............................................................................................................................23!
3.".1 5ocal variable declarations............................................................................................................... 23!
3.".2 5ocal constant declarations............................................................................................................... 23$
3.% Epression statements..............................................................................................................................23$
3.! #election statements................................................................................................................................ 23$
3.!.1 T+e i0 statement................................................................................................................................ 24.
3.!.2 T+e switc+ statement.........................................................................................................................24.
3.3 1teration statements.................................................................................................................................. 244
3.3.1 T+e w+ile statement..........................................................................................................................244
3.3.2 T+e do statement............................................................................................................................... 24"
3.3.3 T+e 0or statement..............................................................................................................................24"
3.3.4 T+e 0oreac+ statement....................................................................................................................... 24%
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. ix
C# Language Specification
3.$ Fump statements...................................................................................................................................... 24$
3.$.1 T+e brea7 statement..........................................................................................................................2".
3.$.2 T+e continue statement..................................................................................................................... 2"1
3.$.3 T+e goto statement............................................................................................................................2"1
3.$.4 T+e return statement.......................................................................................................................... 2"2
3.$." T+e t+row statement.......................................................................................................................... 2"3
3.1. T+e try statement................................................................................................................................... 2"4
3.11 T+e c+ec7ed and unc+ec7ed statements.................................................................................................2"!
3.12 T+e loc7 statement.................................................................................................................................2"!
3.13 T+e using statement...............................................................................................................................2"3
3.14 T+e yield statement................................................................................................................................2%.
!. Na)espaces.................................................................................................................................................. 2'2
$.1 Compilation units.................................................................................................................................... 2%2
$.2 =amespace declarations..........................................................................................................................2%2
$.3 Etern aliases........................................................................................................................................... 2%4
$.4 8sing directives....................................................................................................................................... 2%4
$.4.1 8sing alias directives........................................................................................................................ 2%"
$.4.2 8sing namespace directives..............................................................................................................2%!
$." =amespace members............................................................................................................................... 2%$
$.% Type declarations..................................................................................................................................... 2!.
$.! =amespace alias 9uali0iers...................................................................................................................... 2!.
$.!.1 8ni9ueness o0 aliases........................................................................................................................ 2!1
1*. Classes........................................................................................................................................................ 273
1..1 Class declarations.................................................................................................................................. 2!3
1..1.1 Class modi0iers................................................................................................................................ 2!3
1..1.1.1 (bstract classes.........................................................................................................................2!4
1..1.1.2 #ealed classes............................................................................................................................ 2!4
1..1.1.3 #tatic classes.............................................................................................................................. 2!"
1..1.2 Partial modi0ier............................................................................................................................... 2!"
1..1.3 Type parameters.............................................................................................................................. 2!%
1..1.4 Class base speci0ication...................................................................................................................2!%
1..1.4.1 )ase classes...............................................................................................................................2!%
1..1.4.2 1nter0ace implementations.........................................................................................................2!3
1..1." Type parameter constraints.............................................................................................................2!3
1..1.% Class body....................................................................................................................................... 232
1..2 Partial types........................................................................................................................................... 232
1..2.1 (ttributes........................................................................................................................................ 232
1..2.2 'odi0iers......................................................................................................................................... 233
1..2.3 Type parameters and constraints.....................................................................................................233
1..2.4 )ase class........................................................................................................................................ 234
1..2." )ase inter0aces................................................................................................................................ 234
1..2.% 'embers......................................................................................................................................... 234
1..2.! Partial met+ods................................................................................................................................ 23"
1..2.3 =ame binding.................................................................................................................................. 23!
1..3 Class members....................................................................................................................................... 233
1..3.1 T+e instance type ........................................................................................................................... 23$
1..3.2 'embers o0 constructed types.........................................................................................................2$.
1..3.3 1n+eritance...................................................................................................................................... 2$1
1..3.4 T+e new modi0ier............................................................................................................................2$1
x Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
Table of Contents
1..3." (ccess modi0iers.............................................................................................................................2$2
1..3.% Constituent types............................................................................................................................. 2$2
1..3.! #tatic and instance members...........................................................................................................2$2
1..3.3 =ested types.................................................................................................................................... 2$3
1..3.3.1 *ully 9uali0ied name..................................................................................................................2$3
1..3.3.2 2eclared accessibility................................................................................................................ 2$4
1..3.3.3 Hiding........................................................................................................................................ 2$4
1..3.3.4 t+is access.................................................................................................................................. 2$"
1..3.3." (ccess to private and protected members o0 t+e containing type..............................................2$%
1..3.3.% =ested types in generic classes..................................................................................................2$!
1..3.$ ;eserved member names.................................................................................................................2$!
1..3.$.1 'ember names reserved 0or properties......................................................................................2$3
1..3.$.2 'ember names reserved 0or events...........................................................................................2$$
1..3.$.3 'ember names reserved 0or indeers........................................................................................2$$
1..3.$.4 'ember names reserved 0or destructors....................................................................................2$$
1..4 Constants............................................................................................................................................... 2$$
1.." *ields..................................................................................................................................................... 3.1
1..".1 #tatic and instance 0ields.................................................................................................................3.2
1..".2 ;eadonly 0ields............................................................................................................................... 3.3
1..".2.1 8sing static readonly 0ields 0or constants..................................................................................3.3
1..".2.2 ,ersioning o0 constants and static readonly 0ields.....................................................................3.3
1..".3 ,olatile 0ields.................................................................................................................................. 3.4
1..".4 *ield initialiDation...........................................................................................................................3."
1.."." ,ariable initialiDers.........................................................................................................................3.%
1..".".1 #tatic 0ield initialiDation.............................................................................................................3.!
1..".".2 1nstance 0ield initialiDation........................................................................................................3.3
1..% 'et+ods................................................................................................................................................. 3.3
1..%.1 'et+od parameters.......................................................................................................................... 31.
1..%.1.1 ,alue parameters.......................................................................................................................311
1..%.1.2 ;e0erence parameters................................................................................................................311
1..%.1.3 /utput parameters..................................................................................................................... 312
1..%.1.4 Parameter arrays........................................................................................................................ 313
1..%.2 #tatic and instance met+ods............................................................................................................31%
1..%.3 ,irtual met+ods...............................................................................................................................31%
1..%.4 /verride met+ods............................................................................................................................ 313
1..%." #ealed met+ods............................................................................................................................... 32.
1..%.% (bstract met+ods............................................................................................................................321
1..%.! Eternal met+ods............................................................................................................................322
1..%.3 Partial met+ods................................................................................................................................ 323
1..%.$ Etension met+ods.......................................................................................................................... 323
1..%.1. 'et+od body................................................................................................................................. 324
1..%.11 'et+od overloading...................................................................................................................... 32"
1..! Properties............................................................................................................................................... 32"
1..!.1 #tatic and instance properties..........................................................................................................32%
1..!.2 (ccessors........................................................................................................................................ 32%
1..!.3 (utomatically implemented properties...........................................................................................332
1..!.4 (ccessibility.................................................................................................................................... 332
1..!." ,irtual- sealed- override- and abstract accessors.............................................................................334
1..3 Events.................................................................................................................................................... 33"
1..3.1 *ield<li7e events.............................................................................................................................. 33!
1..3.2 Event accessors............................................................................................................................... 33$
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. xi
C# Language Specification
1..3.3 #tatic and instance events................................................................................................................34.
1..3.4 ,irtual- sealed- override- and abstract accessors.............................................................................34.
1..$ 1ndeers................................................................................................................................................. 341
1..$.1 1ndeer overloading........................................................................................................................344
1..1. /perators............................................................................................................................................. 344
1..1..1 8nary operators.............................................................................................................................34%
1..1..2 )inary operators............................................................................................................................ 34!
1..1..3 Conversion operators....................................................................................................................34!
1..11 1nstance constructors...........................................................................................................................3".
1..11.1 Constructor initialiDers.................................................................................................................. 3"1
1..11.2 1nstance variable initialiDers..........................................................................................................3"2
1..11.3 Constructor eecution................................................................................................................... 3"2
1..11.4 2e0ault constructors...................................................................................................................... 3"4
1..11." Private constructors.......................................................................................................................3"4
1..11.% /ptional instance constructor parameters......................................................................................3""
1..12 #tatic constructors............................................................................................................................... 3""
1..13 2estructors........................................................................................................................................... 3"!
1..14 1terators................................................................................................................................................ 3"$
1..14.1 Enumerator inter0aces................................................................................................................... 3"$
1..14.2 Enumerable inter0aces................................................................................................................... 3"$
1..14.3 >ield type...................................................................................................................................... 3"$
1..14.4 Enumerator ob&ects....................................................................................................................... 3%.
1..14.4.1 T+e 'ove=et met+od............................................................................................................3%.
1..14.4.2 T+e Current property...............................................................................................................3%1
1..14.4.3 T+e 2ispose met+od................................................................................................................ 3%1
1..14." Enumerable ob&ects....................................................................................................................... 3%2
1..14.".1 T+e 4etEnumerator met+od....................................................................................................3%2
1..14.% 1mplementation eample...............................................................................................................3%2
11. Structs........................................................................................................................................................ 37*
11.1 #truct declarations................................................................................................................................. 3!.
11.1.1 #truct modi0iers...............................................................................................................................3!.
11.1.2 Partial modi0ier............................................................................................................................... 3!1
11.1.3 #truct inter0aces.............................................................................................................................. 3!1
11.1.4 #truct body...................................................................................................................................... 3!1
11.2 #truct members...................................................................................................................................... 3!1
11.3 Class and struct di00erences...................................................................................................................3!1
11.3.1 ,alue semantics..............................................................................................................................3!2
11.3.2 1n+eritance...................................................................................................................................... 3!3
11.3.3 (ssignment..................................................................................................................................... 3!3
11.3.4 2e0ault values................................................................................................................................. 3!3
11.3." )oing and unboing...................................................................................................................... 3!4
11.3.% 'eaning o0 t+is............................................................................................................................... 3!%
11.3.! *ield initialiDers.............................................................................................................................. 3!%
11.3.3 Constructors.................................................................................................................................... 3!%
11.3.$ 2estructors...................................................................................................................................... 3!!
11.3.1. #tatic constructors.........................................................................................................................3!!
11.4 #truct eamples..................................................................................................................................... 3!!
11.4.1 2atabase integer type...................................................................................................................... 3!!
11.4.2 2atabase boolean type....................................................................................................................3!$
12. +rra#s........................................................................................................................................................ 3$3
xii Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
Table of Contents
12.1 (rray types............................................................................................................................................ 333
12.1.1 T+e #ystem.(rray type...................................................................................................................334
12.1.2 (rrays and t+e generic 15ist inter0ace.............................................................................................334
12.2 (rray creation........................................................................................................................................ 334
12.3 (rray element access.............................................................................................................................33"
12.4 (rray members...................................................................................................................................... 33"
12." (rray covariance................................................................................................................................... 33"
12.% (rray initialiDers.................................................................................................................................... 33"
13. Interfaces................................................................................................................................................... 3$!
13.1 1nter0ace declarations.............................................................................................................................33$
13.1.1 1nter0ace modi0iers.......................................................................................................................... 33$
13.1.2 Partial modi0ier............................................................................................................................... 33$
13.1.3 )ase inter0aces................................................................................................................................ 3$.
13.1.4 1nter0ace body................................................................................................................................. 3$.
13.2 1nter0ace members................................................................................................................................. 3$.
13.2.1 1nter0ace met+ods............................................................................................................................ 3$2
13.2.2 1nter0ace properties......................................................................................................................... 3$2
13.2.3 1nter0ace events............................................................................................................................... 3$2
13.2.4 1nter0ace indeers............................................................................................................................ 3$2
13.2." 1nter0ace member access................................................................................................................. 3$3
13.3 *ully 9uali0ied inter0ace member names................................................................................................3$4
13.4 1nter0ace implementations.....................................................................................................................3$"
13.4.1 Eplicit inter0ace member implementations....................................................................................3$%
13.4.2 8ni9ueness o0 implemented inter0aces............................................................................................3$3
13.4.3 1mplementation o0 generic met+ods................................................................................................3$$
13.4.4 1nter0ace mapping........................................................................................................................... 4..
13.4." 1nter0ace implementation in+eritance..............................................................................................4.3
13.4.% 1nter0ace re<implementation............................................................................................................4.4
13.4.! (bstract classes and inter0aces........................................................................................................4.%
1". (nu)s........................................................................................................................................................ "*7
14.1 Enum declarations................................................................................................................................. 4.!
14.2 Enum modi0iers..................................................................................................................................... 4.!
14.3 Enum members...................................................................................................................................... 4.3
14.4 T+e #ystem.Enum type..........................................................................................................................41.
14." Enum values and operations.................................................................................................................. 41.
1. ,elegates.................................................................................................................................................... "11
1".1 2elegate declarations.............................................................................................................................411
1".2 2elegate compatibility........................................................................................................................... 413
1".3 2elegate instantiation............................................................................................................................ 413
1".4 2elegate invocation...............................................................................................................................414
1'. (xceptions.................................................................................................................................................. "17
1%.1 Causes o0 eceptions.............................................................................................................................41!
1%.2 T+e #ystem.Eception class.................................................................................................................. 41!
1%.3 How eceptions are +andled.................................................................................................................. 41!
1%.4 Common Eception Classes.................................................................................................................. 413
17. +ttributes................................................................................................................................................... "21
1!.1 (ttribute classes..................................................................................................................................... 421
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. xiii
C# Language Specification
1!.1.1 (ttribute usage................................................................................................................................ 421
1!.1.2 Positional and named parameters....................................................................................................422
1!.1.3 (ttribute parameter types................................................................................................................ 423
1!.2 (ttribute speci0ication...........................................................................................................................424
1!.3 (ttribute instances................................................................................................................................. 42$
1!.3.1 Compilation o0 an attribute.............................................................................................................42$
1!.3.2 ;un<time retrieval o0 an attribute instance......................................................................................42$
1!.4 ;eserved attributes................................................................................................................................ 43.
1!.4.1 T+e (ttribute8sage attribute...........................................................................................................43.
1!.4.2 T+e Conditional attribute................................................................................................................43.
1!.4.2.1 Conditional met+ods..................................................................................................................431
1!.4.2.2 Conditional attribute classes......................................................................................................433
1!.4.3 T+e /bsolete attribute.....................................................................................................................434
1!." (ttributes 0or 1nteroperation..................................................................................................................43"
1!.".1 1nteroperation wit+ C/' and 6in32 components..........................................................................43"
1!.".2 1nteroperation wit+ ot+er .=ET languages......................................................................................43"
1!.".2.1 T+e 1ndeer=ame attribute........................................................................................................43"
1$. -nsafe code................................................................................................................................................ "37
13.1 8nsa0e contets..................................................................................................................................... 43!
13.2 Pointer types.......................................................................................................................................... 44.
13.3 *ied and moveable variables................................................................................................................442
13.4 Pointer conversions............................................................................................................................... 443
13." Pointers in epressions.......................................................................................................................... 444
13.".1 Pointer indirection...........................................................................................................................444
13.".2 Pointer member access....................................................................................................................444
13.".3 Pointer element access....................................................................................................................44"
13.".4 T+e address<o0 operator...................................................................................................................44%
13."." Pointer increment and decrement....................................................................................................44!
13.".% Pointer arit+metic............................................................................................................................ 44!
13.".! Pointer comparison......................................................................................................................... 443
13.".3 T+e siDeo0 operator.......................................................................................................................... 443
13.% T+e 0ied statement............................................................................................................................... 44$
13.! *ied siDe bu00ers.................................................................................................................................. 4"3
13.!.1 *ied siDe bu00er declarations.........................................................................................................4"3
13.!.2 *ied siDe bu00ers in epressions.....................................................................................................4"4
13.!.3 2e0inite assignment c+ec7ing.........................................................................................................4""
13.3 #tac7 allocation..................................................................................................................................... 4"%
13.$ 2ynamic memory allocation..................................................................................................................4"!
+. ,ocu)entation co))ents.......................................................................................................................... "!
(.1 1ntroduction............................................................................................................................................ 4"$
(.2 ;ecommended tags................................................................................................................................. 4%.
(.2.1 GcH................................................................................................................................................... 4%1
(.2.2 GcodeH............................................................................................................................................. 4%1
(.2.3 GeampleH....................................................................................................................................... 4%2
(.2.4 GeceptionH..................................................................................................................................... 4%2
(.2." GincludeH......................................................................................................................................... 4%3
(.2.% GlistH................................................................................................................................................ 4%4
(.2.! GparaH.............................................................................................................................................. 4%"
(.2.3 GparamH........................................................................................................................................... 4%"
xi% Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
Table of Contents
(.2.$ Gparamre0H....................................................................................................................................... 4%%
(.2.1. GpermissionH.................................................................................................................................. 4%%
(.2.11 GsummaryH.................................................................................................................................... 4%!
(.2.12 GreturnsH........................................................................................................................................ 4%!
(.2.13 GseeH.............................................................................................................................................. 4%!
(.2.14 GseealsoH....................................................................................................................................... 4%3
(.2.1" GsummaryH.................................................................................................................................... 4%3
(.2.1% GvalueH.......................................................................................................................................... 4%$
(.2.1! GtypeparamH.................................................................................................................................. 4%$
(.2.13 Gtypeparamre0H..............................................................................................................................4%$
(.3 Processing t+e documentation 0ile..........................................................................................................4!.
(.3.1 12 string 0ormat................................................................................................................................ 4!.
(.3.2 12 string eamples........................................................................................................................... 4!1
(.4 (n eample............................................................................................................................................. 4!"
(.4.1 C# source code................................................................................................................................. 4!"
(.4.2 ;esulting I'5................................................................................................................................ 4!3
B. .ra))ar.................................................................................................................................................... "$2
).1 5eical grammar..................................................................................................................................... 432
).1.1 5ine terminators............................................................................................................................... 432
).1.2 Comments........................................................................................................................................ 432
).1.3 6+ite space...................................................................................................................................... 433
).1.4 To7ens.............................................................................................................................................. 433
).1." 8nicode c+aracter escape se9uences................................................................................................433
).1.% 1denti0iers......................................................................................................................................... 434
).1.! :eywords......................................................................................................................................... 43"
).1.3 5iterals............................................................................................................................................. 43"
).1.$ /perators and punctuators................................................................................................................ 43!
).1.1. Pre<processing directives................................................................................................................43!
).2 #yntactic grammar.................................................................................................................................. 4$.
).2.1 )asic concepts.................................................................................................................................. 4$.
).2.2 Types................................................................................................................................................ 4$.
).2.3 ,ariables.......................................................................................................................................... 4$1
).2.4 Epressions...................................................................................................................................... 4$2
).2." #tatements........................................................................................................................................ 4$3
).2.% =amespaces...................................................................................................................................... ".2
).2.! Classes.............................................................................................................................................. ".3
).2.3 #tructs.............................................................................................................................................. "1.
).2.$ (rrays............................................................................................................................................... "1.
).2.1. 1nter0aces........................................................................................................................................ "11
).2.11 Enums............................................................................................................................................ "12
).2.12 2elegates........................................................................................................................................ "12
).2.13 (ttributes........................................................................................................................................ "13
).3 4rammar etensions 0or unsa0e code......................................................................................................"14
C. /eferences................................................................................................................................................... 1!
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. x%
C0apter 1 Introduction
1. Introduction
C# Jpronounced K#ee #+arpLM is a simple- modern- ob&ect<oriented- and type<sa0e programming language. C#
+as its roots in t+e C 0amily o0 languages and will be immediately 0amiliar to C- CNN- and Fava programmers.
C# is standardiDed by EC'( 1nternational as t+e $CMA-%%& standard and by 1#/O1EC as t+e '()*'$C 2%270
standard. 'icroso0tPs C# compiler 0or t+e .=ET *ramewor7 is a con0orming implementation o0 bot+ o0 t+ese
standards.
C# is an ob&ect<oriented language- but C# 0urt+er includes support 0or coponent-oriented programming.
Contemporary so0tware design increasingly relies on so0tware components in t+e 0orm o0 sel0<contained and
sel0<describing pac7ages o0 0unctionality. :ey to suc+ components is t+at t+ey present a programming model
wit+ properties- met+ods- and eventsQ t+ey +ave attributes t+at provide declarative in0ormation about t+e
componentQ and t+ey incorporate t+eir own documentation. C# provides language constructs to directly support
t+ese concepts- ma7ing C# a very natural language in w+ic+ to create and use so0tware components.
#everal C# 0eatures aid in t+e construction o0 robust and durable applicationsC +ar!age collection automatically
reclaims memory occupied by unused ob&ectsQ e,ception handling provides a structured and etensible
approac+ to error detection and recoveryQ and t+e type-safe design o0 t+e language ma7es it impossible to read
0rom uninitialiDed variables- to inde arrays beyond t+eir bounds- or to per0orm unc+ec7ed type casts.
C# +as a -nified type syste. (ll C# types- including primitive types suc+ as int and double- in+erit 0rom a
single root object type. T+us- all types s+are a set o0 common operations- and values o0 any type can be stored-
transported- and operated upon in a consistent manner. *urt+ermore- C# supports bot+ user<de0ined re0erence
types and value types- allowing dynamic allocation o0 ob&ects as well as in<line storage o0 lig+tweig+t structures.
To ensure t+at C# programs and libraries can evolve over time in a compatible manner- muc+ emp+asis +as been
placed on versioning in C#Ps design. 'any programming languages pay little attention to t+is issue- and- as a
result- programs written in t+ose languages brea7 more o0ten t+an necessary w+en newer versions o0 dependent
libraries are introduced. (spects o0 C#Ps design t+at were directly in0luenced by versioning considerations
include t+e separate virtual and override modi0iers- t+e rules 0or met+od overload resolution- and support
0or eplicit inter0ace member declarations.
T+e rest o0 t+is c+apter describes t+e essential 0eatures o0 t+e C# language. (lt+oug+ later c+apters describe
rules and eceptions in a detail<oriented and sometimes mat+ematical manner- t+is c+apter strives 0or clarity and
brevity at t+e epense o0 completeness. T+e intent is to provide t+e reader wit+ an introduction to t+e language
t+at will 0acilitate t+e writing o0 early programs and t+e reading o0 later c+apters.
1.1 Hello world
T+e KHello- 6orldL program is traditionally used to introduce a programming language. Here it is in C#C
using System;
class Hello
{
static void Main() {
Console.WriteLine("Hello World");
!
!
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 1
C# Language Specification
C# source 0iles typically +ave t+e 0ile etension .cs. (ssuming t+at t+e KHello- 6orldL program is stored in t+e
0ile "ello.cs- t+e program can be compiled wit+ t+e 'icroso0t C# compiler using t+e command line
csc "ello.cs
w+ic+ produces an eecutable assembly named "ello.e#e. T+e output produced by t+is application w+en it is
run is
Hello World
T+e KHello- 6orldL program starts wit+ a using directive t+at re0erences t+e System namespace. =amespaces
provide a +ierarc+ical means o0 organiDing C# programs and libraries. =amespaces contain types and ot+er
namespacesR0or eample- t+e System namespace contains a number o0 types- suc+ as t+e Console class
re0erenced in t+e program- and a number o0 ot+er namespaces- suc+ as $% and Collections. ( using
directive t+at re0erences a given namespace enables un9uali0ied use o0 t+e types t+at are members o0 t+at
namespace. )ecause o0 t+e using directive- t+e program can use Console.WriteLine as s+ort+and 0or
System.Console.WriteLine.
T+e Hello class declared by t+e KHello- 6orldL program +as a single member- t+e met+od named Main. T+e
Main met+od is declared wit+ t+e static modi0ier. 6+ile instance met+ods can re0erence a particular
enclosing ob&ect instance using t+e 7eyword t"is- static met+ods operate wit+out re0erence to a particular
ob&ect. )y convention- a static met+od named Main serves as t+e entry point o0 a program.
T+e output o0 t+e program is produced by t+e WriteLine met+od o0 t+e Console class in t+e System
namespace. T+is class is provided by t+e .=ET *ramewor7 class libraries- w+ic+- by de0ault- are automatically
re0erenced by t+e 'icroso0t C# compiler. =ote t+at C# itsel0 does not +ave a separate runtime library. 1nstead-
t+e .=ET *ramewor7 is t+e runtime library o0 C#.
1.2 Progra structure
T+e 7ey organiDational concepts in C# are progras- naespaces- types- e!ers- and asse!lies. C#
programs consist o0 one or more source 0iles. Programs declare types- w+ic+ contain members and can be
organiDed into namespaces. Classes and inter0aces are eamples o0 types. *ields- met+ods- properties- and events
are eamples o0 members. 6+en C# programs are compiled- t+ey are p+ysically pac7aged into assemblies.
(ssemblies typically +ave t+e 0ile etension .e#e or .dll- depending on w+et+er t+ey implement applications
or li!raries.
T+e eample
using System;
names&ace 'cme.Collections
{
&ublic class Stac(
{
)ntry to&;
&ublic void *us"(object data) {
to& + ne, )ntry(to& data);
!
&ublic object *o&() {
i- (to& ++ null) t"ro, ne, $nvalid%&eration)#ce&tion();
object result + to&.data;
to& + to&.ne#t;
return result;
!
2 Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
class )ntry
{
&ublic )ntry ne#t;
&ublic object data;
&ublic )ntry()ntry ne#t object data) {
t"is.ne#t + ne#t;
t"is.data + data;
!
!
!
!
declares a class named Stac( in a namespace called 'cme.Collections. T+e 0ully 9uali0ied name o0 t+is
class is 'cme.Collections.Stac(. T+e class contains several membersC a 0ield named to&- two met+ods
named *us" and *o&- and a nested class named )ntry. T+e )ntry class 0urt+er contains t+ree membersC a
0ield named ne#t- a 0ield named data- and a constructor. (ssuming t+at t+e source code o0 t+e eample is
stored in t+e 0ile acme.cs- t+e command line
csc .t/library acme.cs
compiles t+e eample as a library Jcode wit+out a Main entry pointM and produces an assembly named
acme.dll.
(ssemblies contain eecutable code in t+e 0orm o0 'nterediate .ang-age J15M instructions- and symbolic
in0ormation in t+e 0orm o0 etadata. )e0ore it is eecuted- t+e 15 code in an assembly is automatically
converted to processor<speci0ic code by t+e Fust<1n<Time JF1TM compiler o0 .=ET Common 5anguage ;untime.
)ecause an assembly is a sel0<describing unit o0 0unctionality containing bot+ code and metadata- t+ere is no
need 0or 0include directives and +eader 0iles in C#. T+e public types and members contained in a particular
assembly are made available in a C# program simply by re0erencing t+at assembly w+en compiling t+e program.
*or eample- t+is program uses t+e 'cme.Collections.Stac( class 0rom t+e acme.dll assemblyC
using System;
using 'cme.Collections;
class 1est
{
static void Main() {
Stac( s + ne, Stac(();
s.*us"(2);
s.*us"(23);
s.*us"(233);
Console.WriteLine(s.*o&());
Console.WriteLine(s.*o&());
Console.WriteLine(s.*o&());
!
!
10 t+e program is stored in t+e 0ile test.cs- w+en test.cs is compiled- t+e acme.dll assembly can be
re0erenced using t+e compilerPs .r optionC
csc .r/acme.dll test.cs
T+is creates an eecutable assembly named test.e#e- w+ic+- w+en run- produces t+e outputC
233
23
2
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 3
C# Language Specification
C# permits t+e source tet o0 a program to be stored in several source 0iles. 6+en a multi<0ile C# program is
compiled- all o0 t+e source 0iles are processed toget+er- and t+e source 0iles can 0reely re0erence eac+ ot+erR
conceptually- it is as i0 all t+e source 0iles were concatenated into one large 0ile be0ore being processed. *orward
declarations are never needed in C# because- wit+ very 0ew eceptions- declaration order is insigni0icant. C#
does not limit a source 0ile to declaring only one public type nor does it re9uire t+e name o0 t+e source 0ile to
matc+ a type declared in t+e source 0ile.
1.3 T!pes and "ariables
T+ere are two 7inds o0 types in C#C val-e types and reference types. ,ariables o0 value types directly contain
t+eir data w+ereas variables o0 re0erence types store re0erences to t+eir data- t+e latter being 7nown as ob&ects.
6it+ re0erence types- it is possible 0or two variables to re0erence t+e same ob&ect and t+us possible 0or
operations on one variable to a00ect t+e ob&ect re0erenced by t+e ot+er variable. 6it+ value types- t+e variables
eac+ +ave t+eir own copy o0 t+e data- and it is not possible 0or operations on one to a00ect t+e ot+er Jecept in
t+e case o0 re- and out parameter variablesM.
C#Ps value types are 0urt+er divided into siple types- en- types- str-ct types- and n-lla!le types- and C#Ps
re0erence types are 0urt+er divided into class types- interface types- array types- and delegate types.
T+e 0ollowing table provides an overview o0 C#Ps type system.
Categor# ,escription
,alue
types
#imple types #igned integralC sbyte- s"ort- int- long
8nsigned integralC byte- us"ort- uint- ulong
8nicode c+aractersC c"ar
1EEE 0loating pointC -loat- double
Hig+<precision decimalC decimal
)ooleanC bool
Enum types 8ser<de0ined types o0 t+e 0orm enum ) {...!
#truct types 8ser<de0ined types o0 t+e 0orm struct S {...!
=ullable types Etensions o0 all ot+er value types wit+ a null value
;e0erence
types
Class types 8ltimate base class o0 all ot+er typesC object
8nicode stringsC string
8ser<de0ined types o0 t+e 0orm class C {...!
1nter0ace types 8ser<de0ined types o0 t+e 0orm inter-ace $ {...!
(rray types #ingle< and multi<dimensional- 0or eample- int45 and
int45
2elegate types 8ser<de0ined types o0 t+e 0orm e.g. delegate int 6(...)
T+e eig+t integral types provide support 0or 3<bit- 1%<bit- 32<bit- and %4<bit values in signed or unsigned 0orm.
T+e two 0loating point types- -loat and double- are represented using t+e 32<bit single<precision and %4<bit
double<precision 1EEE !"4 0ormats.
" Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
T+e decimal type is a 123<bit data type suitable 0or 0inancial and monetary calculations.
C#Ps bool type is used to represent boolean valuesRvalues t+at are eit+er true or -alse.
C+aracter and string processing in C# uses 8nicode encoding. T+e c"ar type represents a 8T*<1% code unit-
and t+e string type represents a se9uence o0 8T*<1% code units.
T+e 0ollowing table summariDes C#Ps numeric types.
Categor# Bits T#pe /ange12recision
#igned
integral
3
sbyte
S123...12!
1%
s"ort
S32-!%3...32-!%!
32
int
S2-14!-433-%43...2-14!-433-%4!
%4
long
S$-223-3!2-.3%-3"4-!!"-3.3...$-223-3!2-.3%-3"4-!!"-3.!
8nsigned
integral
3
byte
....2""
1%
us"ort
....%"-"3"
32
uint
....4-2$4-$%!-2$"
%4
ulong
....13-44%-!44-.!3-!.$-""1-%1"
*loating
point
32
-loat
1." T 1.
U4"
to 3.4 T 1.
33
- !<digit precision
%4
double
".. T 1.
U324
to 1.! T 1.
3.3
- 1"<digit precision
2ecimal 123
decimal
1.. T 1.
U23
to !.$ T 1.
23
- 23<digit precision
C# programs use type declarations to create new types. ( type declaration speci0ies t+e name and t+e members
o0 t+e new type. *ive o0 C#Ps categories o0 types are user<de0inableC class types- struct types- inter0ace types-
enum types- and delegate types.
( class type de0ines a data structure t+at contains data members J0ieldsM and 0unction members Jmet+ods-
properties- and ot+ersM. Class types support single in+eritance and polymorp+ism- mec+anisms w+ereby derived
classes can etend and specialiDe base classes.
( struct type is similar to a class type in t+at it represents a structure wit+ data members and 0unction members.
However- unli7e classes- structs are value types and do not re9uire +eap allocation. #truct types do not support
user<speci0ied in+eritance- and all struct types implicitly in+erit 0rom type object.
(n inter0ace type de0ines a contract as a named set o0 public 0unction members. ( class or struct t+at
implements an inter0ace must provide implementations o0 t+e inter0acePs 0unction members. (n inter0ace may
in+erit 0rom multiple base inter0aces- and a class or struct may implement multiple inter0aces.
( delegate type represents re0erences to met+ods wit+ a particular parameter list and return type. 2elegates
ma7e it possible to treat met+ods as entities t+at can be assigned to variables and passed as parameters.
2elegates are similar to t+e concept o0 0unction pointers 0ound in some ot+er languages- but unli7e 0unction
pointers- delegates are ob&ect<oriented and type<sa0e.
Class- struct- inter0ace and delegate types all support generics- w+ereby t+ey can be parameteriDed wit+ ot+er
types.
(n enum type is a distinct type wit+ named constants. Every enum type +as an underlying type- w+ic+ must be
one o0 t+e eig+t integral types. T+e set o0 values o0 an enum type is t+e same as t+e set o0 values o0 t+e
underlying type.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C# Language Specification
C# supports single< and multi<dimensional arrays o0 any type. 8nli7e t+e types listed above- array types do not
+ave to be declared be0ore t+ey can be used. 1nstead- array types are constructed by 0ollowing a type name wit+
s9uare brac7ets. *or eample- int45 is a single<dimensional array o0 int- int45 is a two<dimensional array
o0 int- and int4545 is a single<dimensional array o0 single<dimensional arrays o0 int.
=ullable types also do not +ave to be declared be0ore t+ey can be used. *or eac+ non<nullable value type 1 t+ere
is a corresponding nullable type 17- w+ic+ can +old an additional value null. *or instance- int7 is a type t+at
can +old any 32 bit integer or t+e value null.
C#Ps type system is uni0ied suc+ t+at a value o0 any type can be treated as an ob&ect. Every type in C# directly or
indirectly derives 0rom t+e object class type- and object is t+e ultimate base class o0 all types. ,alues o0
re0erence types are treated as ob&ects simply by viewing t+e values as type object. ,alues o0 value types are
treated as ob&ects by per0orming !o,ing and -n!o,ing operations. 1n t+e 0ollowing eample- an int value is
converted to object and bac7 again to int.
using System;
class 1est
{
static void Main() {
int i + 289;
object o + i; .. :o#ing
int j + (int)o; .. ;nbo#ing
!
!
6+en a value o0 a value type is converted to type object- an ob&ect instance- also called a Kbo-L is allocated to
+old t+e value- and t+e value is copied into t+at bo. Conversely- w+en an object re0erence is cast to a value
type- a c+ec7 is made t+at t+e re0erenced ob&ect is a bo o0 t+e correct value type- and- i0 t+e c+ec7 succeeds- t+e
value in t+e bo is copied out.
C#Ps uni0ied type system e00ectively means t+at value types can become ob&ects Kon demand.L )ecause o0 t+e
uni0ication- general<purpose libraries t+at use type object can be used wit+ bot+ re0erence types and value
types.
T+ere are several 7inds o0 varia!les in C#- including 0ields- array elements- local variables- and parameters.
,ariables represent storage locations- and every variable +as a type t+at determines w+at values can be stored in
t+e variable- as s+own by t+e 0ollowing table.
' Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
T#pe of &ariable 2ossible Contents
=on<nullable value
type
( value o0 t+at eact type
=ullable value type ( null value or a value o0 t+at eact type
object
( null re0erence- a re0erence to an ob&ect o0 any re0erence type- or a
re0erence to a boed value o0 any value type
Class type ( null re0erence- a re0erence to an instance o0 t+at class type- or a
re0erence to an instance o0 a class derived 0rom t+at class type
1nter0ace type ( null re0erence- a re0erence to an instance o0 a class type t+at
implements t+at inter0ace type- or a re0erence to a boed value o0 a value
type t+at implements t+at inter0ace type
(rray type ( null re0erence- a re0erence to an instance o0 t+at array type- or a
re0erence to an instance o0 a compatible array type
2elegate type ( null re0erence or a re0erence to an instance o0 t+at delegate type
1.# $%pressions
$,pressions are constructed 0rom operands and operators. T+e operators o0 an epression indicate w+ic+
operations to apply to t+e operands. Eamples o0 operators include <- =- >- .- and ne,. Eamples o0 operands
include literals- 0ields- local variables- and epressions.
6+en an epression contains multiple operators- t+e precedence o0 t+e operators controls t+e order in w+ic+ t+e
individual operators are evaluated. *or eample- t+e epression # < y > ? is evaluated as # < (y > ?) because
t+e > operator +as +ig+er precedence t+an t+e < operator.
'ost operators can be overloaded. /perator overloading permits user<de0ined operator implementations to be
speci0ied 0or operations w+ere one or bot+ o0 t+e operands are o0 a user<de0ined class or struct type.
T+e 0ollowing table summariDes C#Ps operators- listing t+e operator categories in order o0 precedence 0rom
+ig+est to lowest. /perators in t+e same category +ave e9ual precedence.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 7
C# Language Specification
Categor# (xpression ,escription
Primary
#.m
'ember access
#(...)
'et+od and delegate invocation
#4...5
(rray and indeer access
#<<
Post<increment
#==
Post<decrement
ne, 1(...)
/b&ect and delegate creation
ne, 1(...){...!
/b&ect creation wit+ initialiDer
ne, {...!
(nonymous ob&ect initialiDer
ne, 14...5
(rray creation
ty&eo-(1)
/btain System.1y&e ob&ect 0or 1
c"ec(ed(#)
Evaluate epression in c+ec7ed contet
unc"ec(ed(#)
Evaluate epression in unc+ec7ed contet
de-ault(1)
/btain de0ault value o0 type 1
delegate {...!
(nonymous 0unction Janonymous met+odM
8nary
<#
1dentity
=#
=egation
@#
5ogical negation
A#
)itwise negation
<<#
Pre<increment
==#
Pre<decrement
(1)#
Eplicitly convert # to type 1
'ultiplicative
# > y
'ultiplication
# . y
2ivision
# B y
;emainder
(dditive
# < y
(ddition- string concatenation- delegate combination
# C y
#ubtraction- delegate removal
$ Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
#+i0t
# DD y
#+i0t le0t
# EE y
#+i0t rig+t
;elational and
type testing
# D y
5ess t+an
# E y
4reater t+an
# D+ y
5ess t+an or e9ual
# E+ y
4reater t+an or e9ual
# is 1
;eturn true i0 # is a 1- -alse ot+erwise
# as 1
;eturn # typed as 1- or null i0 # is not a 1
E9uality
# ++ y
E9ual
# @+ y
=ot e9ual
5ogical (=2
# F y
1nteger bitwise (=2- boolean logical (=2
5ogical I/;
# G y
1nteger bitwise I/;- boolean logical I/;
5ogical /;
# H y
1nteger bitwise /;- boolean logical /;
Conditional (=2
# FF y
Evaluates y only i0 # is true
Conditional /;
# HH y
Evaluates y only i0 # is -alse
=ull coalescing
I 77 y
Evaluates to y i0 # is null- to # ot+erwise
Conditional
# 7 y / ?
Evaluates y i0 # is true- ? i0 # is -alse
(ssignment or
anonymous
0unction
# + y
(ssignment
# op+ y Compound assignmentQ supported operators are
>+ .+ B+ <+ =+ DD+ EE+ F+ G+ H+
(1 #) +E y
(nonymous 0unction Jlambda epressionM
1.& Stateents
T+e actions o0 a program are epressed using stateents. C# supports several di00erent 7inds o0 statements- a
number o0 w+ic+ are de0ined in terms o0 embedded statements.
( !loc" permits multiple statements to be written in contets w+ere a single statement is allowed. ( bloc7
consists o0 a list o0 statements written between t+e delimiters { and !.
/eclaration stateents are used to declare local variables and constants.
$,pression stateents are used to evaluate epressions. Epressions t+at can be used as statements include
met+od invocations- ob&ect allocations using t+e ne, operator- assignments using + and t+e compound
assignment operators- and increment and decrement operations using t+e << and == operators.
(election stateents are used to select one o0 a number o0 possible statements 0or eecution based on t+e value
o0 some epression. 1n t+is group are t+e i- and s,itc" statements.
'teration stateents are used to repeatedly eecute an embedded statement. 1n t+is group are t+e ,"ile- do-
-or- and -oreac" statements.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. !
C# Language Specification
0-p stateents are used to trans0er control. 1n t+is group are t+e brea(- continue- goto- t"ro,- return-
and yield statements.
T+e try...catc" statement is used to catc+ eceptions t+at occur during eecution o0 a bloc7- and t+e
try...-inally statement is used to speci0y 0inaliDation code t+at is always eecuted- w+et+er an eception
occurred or not.
T+e c"ec(ed and unc"ec(ed statements are used to control t+e over0low c+ec7ing contet 0or integral<type
arit+metic operations and conversions.
T+e loc( statement is used to obtain t+e mutual<eclusion loc7 0or a given ob&ect- eecute a statement- and t+en
release t+e loc7.
T+e using statement is used to obtain a resource- eecute a statement- and t+en dispose o0 t+at resource.
T+e 0ollowing table lists C#Ps statements and provides an eample 0or eac+ one.
State)ent (xa)ple
5ocal variable
declaration
static void Main() {
int a;
int b + 8 c + 9;
a + 2;
Console.WriteLine(a < b < c);
!
5ocal constant
declaration
static void Main() {
const -loat &i + 9.2J2KL8M-;
const int r + 8K;
Console.WriteLine(&i > r > r);
!
Epression statement
static void Main() {
int i;
i + 289; .. )#&ression statement
Console.WriteLine(i); .. )#&ression statement
i<<; .. )#&ression statement
Console.WriteLine(i); .. )#&ression statement
!
i- statement
static void Main(string45 args) {
i- (args.Lengt" ++ 3) {
Console.WriteLine("No arguments");
!
else {
Console.WriteLine("%ne or more arguments");
!
!
1* Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
s,itc" statement
static void Main(string45 args) {
int n + args.Lengt";
s,itc" (n) {
case 3/
Console.WriteLine("No arguments");
brea(;
case 2/
Console.WriteLine("%ne argument");
brea(;
de-ault/
Console.WriteLine("{3! arguments" n);
brea(;
!
!
!
,"ile statement
static void Main(string45 args) {
int i + 3;
,"ile (i D args.Lengt") {
Console.WriteLine(args4i5);
i<<;
!
!
do statement
static void Main() {
string s;
do {
s + Console.OeadLine();
i- (s @+ null) Console.WriteLine(s);
! ,"ile (s @+ null);
!
-or statement
static void Main(string45 args) {
-or (int i + 3; i D args.Lengt"; i<<) {
Console.WriteLine(args4i5);
!
!
-oreac" statement
static void Main(string45 args) {
-oreac" (string s in args) {
Console.WriteLine(s);
!
!
brea( statement
static void Main() {
,"ile (true) {
string s + Console.OeadLine();
i- (s ++ null) brea(;
Console.WriteLine(s);
!
!
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 11
C# Language Specification
continue statement
static void Main(string45 args) {
-or (int i + 3; i D args.Lengt"; i<<) {
i- (args4i5.StartsWit"(".")) continue;
Console.WriteLine(args4i5);
!
!
12 Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
goto statement
static void Main(string45 args) {
int i + 3;
goto c"ec(;
loo&/
Console.WriteLine(args4i<<5);
c"ec(/
i- (i D args.Lengt") goto loo&;
!
return statement
static int 'dd(int a int b) {
return a < b;
!
static void Main() {
Console.WriteLine('dd(2 8));
return;
!
yield statement
static $)numerableDintE Oange(int -rom int to) {
-or (int i + -rom; i D to; i<<) {
yield return i;
!
yield brea(;
!
static void Main() {
-oreac" (int # in Oange(=2323)) {
Console.WriteLine(#);
!
!
t"ro, and try
statements
static double 6ivide(double # double y) {
i- (y ++ 3) t"ro, ne, 6ivide:yPero)#ce&tion();
return # . y;
!
static void Main(string45 args) {
try {
i- (args.Lengt" @+ 8) {
t"ro, ne, )#ce&tion("1,o numbers reQuired");
!
double # + double.*arse(args435);
double y + double.*arse(args425);
Console.WriteLine(6ivide(# y));
!
catc" ()#ce&tion e) {
Console.WriteLine(e.Message);
!
-inally {
Console.WriteLine(RSood bye@T);
!
!
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 13
C# Language Specification
c"ec(ed and
unc"ec(ed
statements
static void Main() {
int i + int.Ma#Ualue;
c"ec(ed {
Console.WriteLine(i < 2); .. )#ce&tion
!
unc"ec(ed {
Console.WriteLine(i < 2); .. %ver-lo,
!
!
loc( statement
class 'ccount
{
decimal balance;
&ublic void Wit"dra,(decimal amount) {
loc( (t"is) {
i- (amount E balance) {
t"ro, ne, )#ce&tion("$nsu--icient -unds");
!
balance =+ amount;
!
!
!
using statement
static void Main() {
using (1e#tWriter , + Vile.Create1e#t("test.t#t")) {
,.WriteLine("Line one");
,.WriteLine("Line t,o");
,.WriteLine("Line t"ree");
!
!
1.' Classes and ob(ects
Classes are t+e most 0undamental o0 C#Ps types. ( class is a data structure t+at combines state J0ieldsM and
actions Jmet+ods and ot+er 0unction membersM in a single unit. ( class provides a de0inition 0or dynamically
created instances o0 t+e class- also 7nown as o!1ects. Classes support inheritance and polyorphis-
mec+anisms w+ereby derived classes can etend and specialiDe !ase classes.
=ew classes are created using class declarations. ( class declaration starts wit+ a +eader t+at speci0ies t+e
attributes and modi0iers o0 t+e class- t+e name o0 t+e class- t+e base class Ji0 givenM- and t+e inter0aces
implemented by t+e class. T+e +eader is 0ollowed by t+e class body- w+ic+ consists o0 a list o0 member
declarations written between t+e delimiters { and !.
T+e 0ollowing is a declaration o0 a simple class named *ointC
&ublic class *oint
{
&ublic int # y;
&ublic *oint(int # int y) {
t"is.# + #;
t"is.y + y;
!
!
1" Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
1nstances o0 classes are created using t+e ne, operator- w+ic+ allocates memory 0or a new instance- invo7es a
constructor to initialiDe t+e instance- and returns a re0erence to t+e instance. T+e 0ollowing statements create two
*oint ob&ects and store re0erences to t+ose ob&ects in two variablesC
*oint &2 + ne, *oint(3 3);
*oint &8 + ne, *oint(23 83);
T+e memory occupied by an ob&ect is automatically reclaimed w+en t+e ob&ect is no longer in use. 1t is neit+er
necessary nor possible to eplicitly deallocate ob&ects in C#.
1.'.1 )ebers
T+e members o0 a class are eit+er static e!ers or instance e!ers. #tatic members belong to classes- and
instance members belong to ob&ects Jinstances o0 classesM.
T+e 0ollowing table provides an overview o0 t+e 7inds o0 members a class can contain.
3e)ber ,escription
Constants Constant values associated wit+ t+e class
*ields ,ariables o0 t+e class
'et+ods Computations and actions t+at can be per0ormed by t+e class
Properties (ctions associated wit+ reading and writing named properties o0 t+e class
1ndeers (ctions associated wit+ indeing instances o0 t+e class li7e an array
Events =oti0ications t+at can be generated by t+e class
/perators Conversions and epression operators supported by t+e class
Constructors (ctions re9uired to initialiDe instances o0 t+e class or t+e class itsel0
2estructors (ctions to per0orm be0ore instances o0 t+e class are permanently discarded
Types =ested types declared by t+e class
1.'.2 *ccessibilit!
Eac+ member o0 a class +as an associated accessibility- w+ic+ controls t+e regions o0 program tet t+at are able
to access t+e member. T+ere are 0ive possible 0orms o0 accessibility. T+ese are summariDed in t+e 0ollowing
table.
+ccessibilit# 3eaning
&ublic
(ccess not limited
&rotected
(ccess limited to t+is class or classes derived 0rom t+is class
internal
(ccess limited to t+is program
&rotected internal
(ccess limited to t+is program or classes derived 0rom t+is class
&rivate
(ccess limited to t+is class
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 1
C# Language Specification
1.'.3 T!pe paraeters
( class de0inition may speci0y a set o0 type parameters by 0ollowing t+e class name wit+ angle brac7ets
enclosing a list o0 type parameter names. T+e type parameters can t+e be used in t+e body o0 t+e class
declarations to de0ine t+e members o0 t+e class. 1n t+e 0ollowing eample- t+e type parameters o0 *air are
1Virst and 1SecondC
&ublic class *airD1Virst1SecondE
{
&ublic 1Virst Virst;
&ublic 1Second Second;
!
( class type t+at is declared to ta7e type parameters is called a generic class type. #truct- inter0ace and delegate
types can also be generic.
6+en t+e generic class is used- type arguments must be provided 0or eac+ o0 t+e type parametersC
*airDintstringE &air + ne, *airDintstringE { Virst + 2 Second + Rt,oT !;
int i + &air.Virst; .. 1Virst is int
string s + &air.Second; .. 1Second is string
( generic type wit+ type arguments provided- li7e *airDintstringE above- is called a constructed type.
1.'.# +ase classes
( class declaration may speci0y a base class by 0ollowing t+e class name and type parameters wit+ a colon and
t+e name o0 t+e base class. /mitting a base class speci0ication is t+e same as deriving 0rom type object. 1n t+e
0ollowing eample- t+e base class o0 *oint96 is *oint- and t+e base class o0 *oint is objectC
&ublic class *oint
{
&ublic int # y;
&ublic *oint(int # int y) {
t"is.# + #;
t"is.y + y;
!
!
&ublic class *oint96/ *oint
{
&ublic int ?;
&ublic *oint96(int # int y int ?)/ base(# y) {
t"is.? + ?;
!
!
( class in+erits t+e members o0 its base class. 1n+eritance means t+at a class implicitly contains all members o0
its base class- ecept 0or t+e constructors o0 t+e base class. ( derived class can add new members to t+ose it
in+erits- but it cannot remove t+e de0inition o0 an in+erited member. 1n t+e previous eample- *oint96 in+erits
t+e # and y 0ields 0rom *oint- and every *oint96 instance contains t+ree 0ields- #- y- and ?.
(n implicit conversion eists 0rom a class type to any o0 its base class types. T+ere0ore- a variable o0 a class
type can re0erence an instance o0 t+at class or an instance o0 any derived class. *or eample- given t+e previous
class declarations- a variable o0 type *oint can re0erence eit+er a *oint or a *oint96C
*oint a + ne, *oint(23 83);
*oint b + ne, *oint96(23 83 93);
1' Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
1.'.& ,ields
( 0ield is a variable t+at is associated wit+ a class or wit+ an instance o0 a class.
( 0ield declared wit+ t+e static modi0ier de0ines a static field. ( static 0ield identi0ies eactly one storage
location. =o matter +ow many instances o0 a class are created- t+ere is only ever one copy o0 a static 0ield.
( 0ield declared wit+out t+e static modi0ier de0ines an instance field. Every instance o0 a class contains a
separate copy o0 all t+e instance 0ields o0 t+at class.
1n t+e 0ollowing eample- eac+ instance o0 t+e Color class +as a separate copy o0 t+e r- g- and b instance 0ields-
but t+ere is only one copy o0 t+e :lac(- W"ite- Oed- Sreen- and :lue static 0ieldsC
&ublic class Color
{
&ublic static readonly Color :lac( + ne, Color(3 3 3);
&ublic static readonly Color W"ite + ne, Color(8KK 8KK 8KK);
&ublic static readonly Color Oed + ne, Color(8KK 3 3);
&ublic static readonly Color Sreen + ne, Color(3 8KK 3);
&ublic static readonly Color :lue + ne, Color(3 3 8KK);
&rivate byte r g b;
&ublic Color(byte r byte g byte b) {
t"is.r + r;
t"is.g + g;
t"is.b + b;
!
!
(s s+own in t+e previous eample- read-only fields may be declared wit+ a readonly modi0ier. (ssignment to
a readonly 0ield can only occur as part o0 t+e 0ieldPs declaration or in a constructor in t+e same class.
1.'.' )et-ods
( ethod is a member t+at implements a computation or action t+at can be per0ormed by an ob&ect or class.
(tatic ethods are accessed t+roug+ t+e class. 'nstance ethods are accessed t+roug+ instances o0 t+e class.
'et+ods +ave a Jpossibly emptyM list o0 paraeters- w+ic+ represent values or variable re0erences passed to t+e
met+od- and a ret-rn type- w+ic+ speci0ies t+e type o0 t+e value computed and returned by t+e met+od. (
met+odPs return type is void i0 it does not return a value.
5i7e types- met+ods may also +ave a set o0 type parameters- 0or w+ic+ type arguments must be speci0ied w+en
t+e met+od is called. 8nli7e types- t+e type arguments can o0ten be in0erred 0rom t+e arguments o0 a met+od call
and need not be eplicitly given.
T+e signat-re o0 a met+od must be uni9ue in t+e class in w+ic+ t+e met+od is declared. T+e signature o0 a
met+od consists o0 t+e name o0 t+e met+od- t+e number o0 type parameters and t+e number- modi0iers- and types
o0 its parameters. T+e signature o0 a met+od does not include t+e return type.
1.6.6.1 Parameters
Parameters are used to pass values or variable re0erences to met+ods. T+e parameters o0 a met+od get t+eir
actual values 0rom t+e arg-ents t+at are speci0ied w+en t+e met+od is invo7ed. T+ere are 0our 7inds o0
parametersC value parameters- re0erence parameters- output parameters- and parameter arrays.
( val-e paraeter is used 0or input parameter passing. ( value parameter corresponds to a local variable t+at
gets its initial value 0rom t+e argument t+at was passed 0or t+e parameter. 'odi0ications to a value parameter do
not a00ect t+e argument t+at was passed 0or t+e parameter.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 17
C# Language Specification
( reference paraeter is used 0or bot+ input and output parameter passing. T+e argument passed 0or a re0erence
parameter must be a variable- and during eecution o0 t+e met+od- t+e re0erence parameter represents t+e same
storage location as t+e argument variable. ( re0erence parameter is declared wit+ t+e re- modi0ier. T+e
0ollowing eample s+ows t+e use o0 re- parameters.
using System;
class 1est
{
static void S,a&(re- int # re- int y) {
int tem& + #;
# + y;
y + tem&;
!
static void Main() {
int i + 2 j + 8;
S,a&(re- i re- j);
Console.WriteLine("{3! {2!" i j); .. %ut&uts "8 2"
!
!
(n o-tp-t paraeter is used 0or output parameter passing. (n output parameter is similar to a re0erence
parameter ecept t+at t+e initial value o0 t+e caller<provided argument is unimportant. (n output parameter is
declared wit+ t+e out modi0ier. T+e 0ollowing eample s+ows t+e use o0 out parameters.
using System;
class 1est
{
static void 6ivide(int # int y out int result out int remainder) {
result + # . y;
remainder + # B y;
!
static void Main() {
int res rem;
6ivide(23 9 out res out rem);
Console.WriteLine("{3! {2!" res rem); .. %ut&uts "9 2"
!
!
( paraeter array permits a variable number o0 arguments to be passed to a met+od. ( parameter array is
declared wit+ t+e &arams modi0ier. /nly t+e last parameter o0 a met+od can be a parameter array- and t+e type
o0 a parameter array must be a single<dimensional array type. T+e Write and WriteLine met+ods o0 t+e
System.Console class are good eamples o0 parameter array usage. T+ey are declared as 0ollows.
&ublic class Console
{
&ublic static void Write(string -mt &arams object45 args) {...!
&ublic static void WriteLine(string -mt &arams object45 args) {...!
...
!
6it+in a met+od t+at uses a parameter array- t+e parameter array be+aves eactly li7e a regular parameter o0 an
array type. However- in an invocation o0 a met+od wit+ a parameter array- it is possible to pass eit+er a single
argument o0 t+e parameter array type or any number o0 arguments o0 t+e element type o0 t+e parameter array. 1n
t+e latter case- an array instance is automatically created and initialiDed wit+ t+e given arguments. T+is eample
1$ Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
Console.WriteLine("#+{3! y+{2! ?+{8!" # y ?);
is e9uivalent to writing t+e 0ollowing.
string s + "#+{3! y+{2! ?+{8!";
object45 args + ne, object495;
args435 + #;
args425 + y;
args485 + ?;
Console.WriteLine(s args);
1.6.6.2 Method body and local variables
( met+odPs body speci0ies t+e statements to eecute w+en t+e met+od is invo7ed.
( met+od body can declare variables t+at are speci0ic to t+e invocation o0 t+e met+od. #uc+ variables are called
local varia!les. ( local variable declaration speci0ies a type name- a variable name- and possibly an initial
value. T+e 0ollowing eample declares a local variable i wit+ an initial value o0 Dero and a local variable j wit+
no initial value.
using System;
class SQuares
{
static void Main() {
int i + 3;
int j;
,"ile (i D 23) {
j + i > i;
Console.WriteLine("{3! # {3! + {2!" i j);
i + i < 2;
!
!
!
C# re9uires a local variable to be definitely assigned be0ore its value can be obtained. *or eample- i0 t+e
declaration o0 t+e previous i did not include an initial value- t+e compiler would report an error 0or t+e
subse9uent usages o0 i because i would not be de0initely assigned at t+ose points in t+e program.
( met+od can use return statements to return control to its caller. 1n a met+od returning void- return
statements cannot speci0y an epression. 1n a met+od returning non<void- return statements must include an
epression t+at computes t+e return value.
1.6.6.3 Static and instance methods
( met+od declared wit+ a static modi0ier is a static ethod. ( static met+od does not operate on a speci0ic
instance and can only directly access static members.
( met+od declared wit+out a static modi0ier is an instance ethod. (n instance met+od operates on a
speci0ic instance and can access bot+ static and instance members. T+e instance on w+ic+ an instance met+od
was invo7ed can be eplicitly accessed as t"is. 1t is an error to re0er to t"is in a static met+od.
T+e 0ollowing )ntity class +as bot+ static and instance members.
class )ntity
{
static int ne#tSerialNo;
int serialNo;
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 1!
C# Language Specification
&ublic )ntity() {
serialNo + ne#tSerialNo<<;
!
&ublic int SetSerialNo() {
return serialNo;
!
&ublic static int SetNe#tSerialNo() {
return ne#tSerialNo;
!
&ublic static void SetNe#tSerialNo(int value) {
ne#tSerialNo + value;
!
!
Eac+ )ntity instance contains a serial number Jand presumably some ot+er in0ormation t+at is not s+own
+ereM. T+e )ntity constructor Jw+ic+ is li7e an instance met+odM initialiDes t+e new instance wit+ t+e net
available serial number. )ecause t+e constructor is an instance member- it is permitted to access bot+ t+e
serialNo instance 0ield and t+e ne#tSerialNo static 0ield.
T+e SetNe#tSerialNo and SetNe#tSerialNo static met+ods can access t+e ne#tSerialNo static 0ield- but
it would be an error 0or t+em to directly access t+e serialNo instance 0ield.
T+e 0ollowing eample s+ows t+e use o0 t+e )ntity class.
using System;
class 1est
{
static void Main() {
)ntity.SetNe#tSerialNo(2333);
)ntity e2 + ne, )ntity();
)ntity e8 + ne, )ntity();
Console.WriteLine(e2.SetSerialNo()); .. %ut&uts "2333"
Console.WriteLine(e8.SetSerialNo()); .. %ut&uts "2332"
Console.WriteLine()ntity.SetNe#tSerialNo()); .. %ut&uts "2338"
!
!
=ote t+at t+e SetNe#tSerialNo and SetNe#tSerialNo static met+ods are invo7ed on t+e class w+ereas t+e
SetSerialNo instance met+od is invo7ed on instances o0 t+e class.
1.6.6.4 Virtual, override, and abstract methods
6+en an instance met+od declaration includes a virtual modi0ier- t+e met+od is said to be a virt-al ethod.
6+en no virtual modi0ier is present- t+e met+od is said to be a non-virt-al ethod.
6+en a virtual met+od is invo7ed- t+e r-ntie type o0 t+e instance 0or w+ic+ t+at invocation ta7es place
determines t+e actual met+od implementation to invo7e. 1n a nonvirtual met+od invocation- t+e copile-tie
type o0 t+e instance is t+e determining 0actor.
( virtual met+od can be overridden in a derived class. 6+en an instance met+od declaration includes an
override modi0ier- t+e met+od overrides an in+erited virtual met+od wit+ t+e same signature. 6+ereas a
virtual met+od declaration introd!ces a new met+od- an override met+od declaration speciali-es an eisting
in+erited virtual met+od by providing a new implementation o0 t+at met+od.
2* Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
(n a!stract met+od is a virtual met+od wit+ no implementation. (n abstract met+od is declared wit+ t+e
abstract modi0ier and is permitted only in a class t+at is also declared abstract. (n abstract met+od must
be overridden in every non<abstract derived class.
T+e 0ollowing eample declares an abstract class- )#&ression- w+ic+ represents an epression tree node- and
t+ree derived classes- Constant- UariableOe-erence- and %&eration- w+ic+ implement epression tree
nodes 0or constants- variable re0erences- and arit+metic operations. JT+is is similar to- but not to be con0used
wit+ t+e epression tree types introduced in section V4.%M.
using System;
using System.Collections;
&ublic abstract class )#&ression
{
&ublic abstract double )valuate(Has"table vars);
!
&ublic class Constant/ )#&ression
{
double value;
&ublic Constant(double value) {
t"is.value + value;
!
&ublic override double )valuate(Has"table vars) {
return value;
!
!
&ublic class UariableOe-erence/ )#&ression
{
string name;
&ublic UariableOe-erence(string name) {
t"is.name + name;
!
&ublic override double )valuate(Has"table vars) {
object value + vars4name5;
i- (value ++ null) {
t"ro, ne, )#ce&tion(";n(no,n variable/ " < name);
!
return Convert.1o6ouble(value);
!
!
&ublic class %&eration/ )#&ression
{
)#&ression le-t;
c"ar o&;
)#&ression rig"t;
&ublic %&eration()#&ression le-t c"ar o& )#&ression rig"t) {
t"is.le-t + le-t;
t"is.o& + o&;
t"is.rig"t + rig"t;
!
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 21
C# Language Specification
&ublic override double )valuate(Has"table vars) {
double # + le-t.)valuate(vars);
double y + rig"t.)valuate(vars);
s,itc" (o&) {
case W<W/ return # < y;
case W=W/ return # = y;
case W>W/ return # > y;
case W.W/ return # . y;
!
t"ro, ne, )#ce&tion(";n(no,n o&erator");
!
!
T+e previous 0our classes can be used to model arit+metic epressions. *or eample- using instances o0 t+ese
classes- t+e epression # < 9 can be represented as 0ollows.
)#&ression e + ne, %&eration(
ne, UariableOe-erence("#")
W<W
ne, Constant(9));
T+e )valuate met+od o0 an )#&ression instance is invo7ed to evaluate t+e given epression and produce a
double value. T+e met+od ta7es as an argument a Has"table t+at contains variable names Jas 7eys o0 t+e
entriesM and values Jas values o0 t+e entriesM. T+e )valuate met+od is a virtual abstract met+od- meaning t+at
non<abstract derived classes must override it to provide an actual implementation.
( ConstantPs implementation o0 )valuate simply returns t+e stored constant. ( UariableOe-erencePs
implementation loo7s up t+e variable name in t+e +as+table and returns t+e resulting value. (n %&erationPs
implementation 0irst evaluates t+e le0t and rig+t operands Jby recursively invo7ing t+eir )valuate met+odsM
and t+en per0orms t+e given arit+metic operation.
T+e 0ollowing program uses t+e )#&ression classes to evaluate t+e epression # > (y < 8) 0or di00erent values
o0 # and y.
using System;
using System.Collections;
class 1est
{
static void Main() {
)#&ression e + ne, %&eration(
ne, UariableOe-erence("#")
W>W
ne, %&eration(
ne, UariableOe-erence("y")
W<W
ne, Constant(8)
)
);
Has"table vars + ne, Has"table();
vars4"#"5 + 9;
vars4"y"5 + K;
Console.WriteLine(e.)valuate(vars)); .. %ut&uts "82"
22 Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
vars4"#"5 + 2.K;
vars4"y"5 + L;
Console.WriteLine(e.)valuate(vars)); .. %ut&uts "2X.K"
!
!
1.6.6.5 Method overloading
'et+od overloading permits multiple met+ods in t+e same class to +ave t+e same name as long as t+ey +ave
uni9ue signatures. 6+en compiling an invocation o0 an overloaded met+od- t+e compiler uses overload
resol-tion to determine t+e speci0ic met+od to invo7e. /verload resolution 0inds t+e one met+od t+at best
matc+es t+e arguments or reports an error i0 no single best matc+ can be 0ound. T+e 0ollowing eample s+ows
overload resolution in e00ect. T+e comment 0or eac+ invocation in t+e Main met+od s+ows w+ic+ met+od is
actually invo7ed.
class 1est
{
static void V() {
Console.WriteLine("V()");
!
static void V(object #) {
Console.WriteLine("V(object)");
!
static void V(int #) {
Console.WriteLine("V(int)");
!
static void V(double #) {
Console.WriteLine("V(double)");
!
static void VD1E(1 #) {
Console.WriteLine("VD1E(1)");
!
static void V(double # double y) {
Console.WriteLine("V(double double)");
!
static void Main() {
V(); .. $nvo(es V()
V(2); .. $nvo(es V(int)
V(2.3); .. $nvo(es V(double)
V("abc"); .. $nvo(es V(object)
V((double)2); .. $nvo(es V(double)
V((object)2); .. $nvo(es V(object)
VDintE(2); .. $nvo(es VD1E(1)
V(2 2); .. $nvo(es V(double double) !
!
(s s+own by t+e eample- a particular met+od can always be selected by eplicitly casting t+e arguments to t+e
eact parameter types andOor eplicitly supplying type arguments.
1.'.. /t-er function ebers
'embers t+at contain eecutable code are collectively 7nown as t+e f-nction e!ers o0 a class. T+e
preceding section describes met+ods- w+ic+ are t+e primary 7ind o0 0unction members. T+is section describes
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 23
C# Language Specification
t+e ot+er 7inds o0 0unction members supported by C#C constructors- properties- indeers- events- operators- and
destructors.
T+e 0ollowing table s+ows a generic class called ListD1E- w+ic+ implements a growable list o0 ob&ects. T+e
class contains several eamples o0 t+e most common 7inds o0 0unction members.
&ublic class ListD1E
{
const int de-aultCa&acity + J;
Constant
145 items;
int count;
*ields
&ublic List()/ t"is(de-aultCa&acity) {!
&ublic List(int ca&acity) {
items + ne, 14ca&acity5;
!
Constructors
&ublic int Count {
get { return count; !
!
&ublic int Ca&acity {
get {
return items.Lengt";
!
set {
i- (value D count) value + count;
i- (value @+ items.Lengt") {
145 ne,$tems + ne, 14value5;
'rray.Co&y(items 3 ne,$tems 3 count);
items + ne,$tems;
!
!
!
Properties
2" Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
&ublic 1 t"is4int inde#5 {
get {
return items4inde#5;
!
set {
items4inde#5 + value;
%nC"anged();
!
!
1ndeer
&ublic void 'dd(1 item) {
i- (count ++ Ca&acity) Ca&acity + count > 8;
items4count5 + item;
count<<;
%nC"anged();
!
&rotected virtual void %nC"anged() {
i- (C"anged @+ null) C"anged(t"is )vent'rgs.)m&ty);
!
&ublic override bool )Quals(object ot"er) {
return )Quals(t"is ot"er as ListD1E);
!
static bool )Quals(ListD1E a ListD1E b) {
i- (a ++ null) return b ++ null;
i- (b ++ null HH a.count @+ b.count) return -alse;
-or (int i + 3; i D a.count; i<<) {
i- (@object.)Quals(a.items4i5 b.items4i5)) {
return -alse;
!
!
return true;
!
'et+ods
&ublic event )ventHandler C"anged;
Event
&ublic static bool o&erator ++(ListD1E a ListD1E b) {
return )Quals(a b);
!
&ublic static bool o&erator @+(ListD1E a ListD1E b) {
return @)Quals(a b);
!
/perators
!
1.6..1 !onstructors
C# supports bot+ instance and static constructors. (n instance constr-ctor is a member t+at implements t+e
actions re9uired to initialiDe an instance o0 a class. ( static constr-ctor is a member t+at implements t+e actions
re9uired to initialiDe a class itsel0 w+en it is 0irst loaded.
( constructor is declared li7e a met+od wit+ no return type and t+e same name as t+e containing class. 10 a
constructor declaration includes a static modi0ier- it declares a static constructor. /t+erwise- it declares an
instance constructor.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 2
C# Language Specification
1nstance constructors can be overloaded. *or eample- t+e ListD1E class declares two instance constructors-
one wit+ no parameters and one t+at ta7es an int parameter. 1nstance constructors are invo7ed using t+e ne,
operator. T+e 0ollowing statements allocate two ListDstringE instances using eac+ o0 t+e constructors o0 t+e
List class.
ListDstringE list2 + ne, ListDstringE();
ListDstringE list8 + ne, ListDstringE(23);
8nli7e ot+er members- instance constructors are not in+erited- and a class +as no instance constructors ot+er
t+an t+ose actually declared in t+e class. 10 no instance constructor is supplied 0or a class- t+en an empty one
wit+ no parameters is automatically provided.
1.6..2 Pro"erties
Properties are a natural etension o0 0ields. )ot+ are named members wit+ associated types- and t+e synta 0or
accessing 0ields and properties is t+e same. However- unli7e 0ields- properties do not denote storage locations.
1nstead- properties +ave accessors t+at speci0y t+e statements to be eecuted w+en t+eir values are read or
written.
( property is declared li7e a 0ield- ecept t+at t+e declaration ends wit+ a get accessor andOor a set accessor
written between t+e delimiters { and ! instead o0 ending in a semicolon. ( property t+at +as bot+ a get accessor
and a set accessor is a read-2rite property- a property t+at +as only a get accessor is a read-only property- and
a property t+at +as only a set accessor is a 2rite-only property.
( get accessor corresponds to a parameterless met+od wit+ a return value o0 t+e property type. Ecept as t+e
target o0 an assignment- w+en a property is re0erenced in an epression- t+e get accessor o0 t+e property is
invo7ed to compute t+e value o0 t+e property.
( set accessor corresponds to a met+od wit+ a single parameter named value and no return type. 6+en a
property is re0erenced as t+e target o0 an assignment or as t+e operand o0 << or ==- t+e set accessor is invo7ed
wit+ an argument t+at provides t+e new value.
T+e ListD1E class declares two properties- Count and Ca&acity- w+ic+ are read<only and read<write-
respectively. T+e 0ollowing is an eample o0 use o0 t+ese properties.
ListDstringE names + ne, ListDstringE();
names.Ca&acity + 233; .. $nvo(es set accessor
int i + names.Count; .. $nvo(es get accessor
int j + names.Ca&acity; .. $nvo(es get accessor
#imilar to 0ields and met+ods- C# supports bot+ instance properties and static properties. #tatic properties are
declared wit+ t+e static modi0ier- and instance properties are declared wit+out it.
T+e accessorJsM o0 a property can be virtual. 6+en a property declaration includes a virtual- abstract- or
override modi0ier- it applies to t+e accessorJsM o0 t+e property.
1.6..3 #nde$ers
(n inde,er is a member t+at enables ob&ects to be indeed in t+e same way as an array. (n indeer is declared
li7e a property ecept t+at t+e name o0 t+e member is t"is 0ollowed by a parameter list written between t+e
delimiters 4 and 5. T+e parameters are available in t+e accessorJsM o0 t+e indeer. #imilar to properties- indeers
can be read<write- read<only- and write<only- and t+e accessorJsM o0 an indeer can be virtual.
T+e List class declares a single read<write indeer t+at ta7es an int parameter. T+e indeer ma7es it possible
to inde List instances wit+ int values. *or eample
2' Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
ListDstringE names + ne, ListDstringE();
names.'dd("Li?");
names.'dd("Mart"a");
names.'dd(":et"");
-or (int i + 3; i D names.Count; i<<) {
string s + names4i5;
names4i5 + s.1o;&&er();
!
1ndeers can be overloaded- meaning t+at a class can declare multiple indeers as long as t+e number or types o0
t+eir parameters di00er.
1.6..4 %vents
(n event is a member t+at enables a class or ob&ect to provide noti0ications. (n event is declared li7e a 0ield
ecept t+at t+e declaration includes an event 7eyword and t+e type must be a delegate type.
6it+in a class t+at declares an event member- t+e event be+aves &ust li7e a 0ield o0 a delegate type Jprovided t+e
event is not abstract and does not declare accessorsM. T+e 0ield stores a re0erence to a delegate t+at represents t+e
event +andlers t+at +ave been added to t+e event. 10 no event +andles are present- t+e 0ield is null.
T+e ListD1E class declares a single event member called C"anged- w+ic+ indicates t+at a new item +as been
added to t+e list. T+e C"anged event is raised by t+e %nC"anged virtual met+od- w+ic+ 0irst c+ec7s w+et+er
t+e event is null Jmeaning t+at no +andlers are presentM. T+e notion o0 raising an event is precisely e9uivalent
to invo7ing t+e delegate represented by t+e eventRt+us- t+ere are no special language constructs 0or raising
events.
Clients react to events t+roug+ event handlers. Event +andlers are attac+ed using t+e <+ operator and removed
using t+e =+ operator. T+e 0ollowing eample attac+es an event +andler to t+e C"anged event o0 a
ListDstringE.
using System;
class 1est
{
static int c"angeCount;
static void ListC"anged(object sender )vent'rgs e) {
c"angeCount<<;
!
static void Main() {
ListDstringE names + ne, ListDstringE();
names.C"anged <+ ne, )ventHandler(ListC"anged);
names.'dd("Li?");
names.'dd("Mart"a");
names.'dd(":et"");
Console.WriteLine(c"angeCount); .. %ut&uts "9"
!
!
*or advanced scenarios w+ere control o0 t+e underlying storage o0 an event is desired- an event declaration can
eplicitly provide add and remove accessors- w+ic+ are somew+at similar to t+e set accessor o0 a property.
1.6..5 &"erators
(n operator is a member t+at de0ines t+e meaning o0 applying a particular epression operator to instances o0 a
class. T+ree 7inds o0 operators can be de0inedC unary operators- binary operators- and conversion operators. (ll
operators must be declared as &ublic and static.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 27
C# Language Specification
T+e ListD1E class declares two operators- o&erator ++ and o&erator @+- and t+us gives new meaning to
epressions t+at apply t+ose operators to List instances. #peci0ically- t+e operators de0ine e9uality o0 two
ListD1E instances as comparing eac+ o0 t+e contained ob&ects using t+eir )Quals met+ods. T+e 0ollowing
eample uses t+e ++ operator to compare two ListDintE instances.
using System;
class 1est
{
static void Main() {
ListDintE a + ne, ListDintE();
a.'dd(2);
a.'dd(8);
ListDintE b + ne, ListDintE();
b.'dd(2);
b.'dd(8);
Console.WriteLine(a ++ b); .. %ut&uts "1rue"
b.'dd(9);
Console.WriteLine(a ++ b); .. %ut&uts "Valse"
!
!
T+e 0irst Console.WriteLine outputs 1rue because t+e two lists contain t+e same number o0 ob&ects wit+ t+e
same values in t+e same order. Had ListD1E not de0ined o&erator ++- t+e 0irst Console.WriteLine would
+ave output Valse because a and b re0erence di00erent ListDintE instances.
1.6..6 'estructors
( destr-ctor is a member t+at implements t+e actions re9uired to destruct an instance o0 a class. 2estructors
cannot +ave parameters- t+ey cannot +ave accessibility modi0iers- and t+ey cannot be invo7ed eplicitly. T+e
destructor 0or an instance is invo7ed automatically during garbage collection.
T+e garbage collector is allowed wide latitude in deciding w+en to collect ob&ects and run destructors.
#peci0ically- t+e timing o0 destructor invocations is not deterministic- and destructors may be eecuted on any
t+read. *or t+ese and ot+er reasons- classes s+ould implement destructors only w+en no ot+er solutions are
0easible.
T+e using statement provides a better approac+ to ob&ect destruction.
1.. Structs
5i7e classes- str-cts are data structures t+at can contain data members and 0unction members- but unli7e classes-
structs are value types and do not re9uire +eap allocation. ( variable o0 a struct type directly stores t+e data o0
t+e struct- w+ereas a variable o0 a class type stores a re0erence to a dynamically allocated ob&ect. #truct types do
not support user<speci0ied in+eritance- and all struct types implicitly in+erit 0rom type object.
#tructs are particularly use0ul 0or small data structures t+at +ave value semantics. Comple numbers- points in a
coordinate system- or 7ey<value pairs in a dictionary are all good eamples o0 structs. T+e use o0 structs rat+er
t+an classes 0or small data structures can ma7e a large di00erence in t+e number o0 memory allocations an
application per0orms. *or eample- t+e 0ollowing program creates and initialiDes an array o0 1.. points. 6it+
*oint implemented as a class- 1.1 separate ob&ects are instantiatedRone 0or t+e array and one eac+ 0or t+e 1..
elements.
class *oint
{
&ublic int # y;
2$ Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
&ublic *oint(int # int y) {
t"is.# + #;
t"is.y + y;
!
!
class 1est
{
static void Main() {
*oint45 &oints + ne, *oint42335;
-or (int i + 3; i D 233; i<<) &oints4i5 + ne, *oint(i i);
!
!
(n alternative is to ma7e *oint a struct.
struct *oint
{
&ublic int # y;
&ublic *oint(int # int y) {
t"is.# + #;
t"is.y + y;
!
!
=ow- only one ob&ect is instantiatedRt+e one 0or t+e arrayRand t+e *oint instances are stored in<line in t+e
array.
#truct constructors are invo7ed wit+ t+e ne, operator- but t+at does not imply t+at memory is being allocated.
1nstead o0 dynamically allocating an ob&ect and returning a re0erence to it- a struct constructor simply returns t+e
struct value itsel0 Jtypically in a temporary location on t+e stac7M- and t+is value is t+en copied as necessary.
6it+ classes- it is possible 0or two variables to re0erence t+e same ob&ect and t+us possible 0or operations on one
variable to a00ect t+e ob&ect re0erenced by t+e ot+er variable. 6it+ structs- t+e variables eac+ +ave t+eir own
copy o0 t+e data- and it is not possible 0or operations on one to a00ect t+e ot+er. *or eample- t+e output
produced by t+e 0ollowing code 0ragment depends on w+et+er *oint is a class or a struct.
*oint a + ne, *oint(23 23);
*oint b + a;
a.# + 83;
Console.WriteLine(b.#);
10 *oint is a class- t+e output is 83 because a and b re0erence t+e same ob&ect. 10 *oint is a struct- t+e output is
23 because t+e assignment o0 a to b creates a copy o0 t+e value- and t+is copy is una00ected by t+e subse9uent
assignment to a.#.
T+e previous eample +ig+lig+ts two o0 t+e limitations o0 structs. *irst- copying an entire struct is typically less
e00icient t+an copying an ob&ect re0erence- so assignment and value parameter passing can be more epensive
wit+ structs t+an wit+ re0erence types. #econd- ecept 0or re- and out parameters- it is not possible to create
re0erences to structs- w+ic+ rules out t+eir usage in a number o0 situations.
1.0 *rra!s
(n array is a data structure t+at contains a number o0 variables t+at are accessed t+roug+ computed indices. T+e
variables contained in an array- also called t+e eleents o0 t+e array- are all o0 t+e same type- and t+is type is
called t+e eleent type o0 t+e array.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 2!
C# Language Specification
(rray types are re0erence types- and t+e declaration o0 an array variable simply sets aside space 0or a re0erence
to an array instance. (ctual array instances are created dynamically at runtime using t+e ne, operator. T+e ne,
operation speci0ies t+e length o0 t+e new array instance- w+ic+ is t+en 0ied 0or t+e li0etime o0 t+e instance. T+e
indices o0 t+e elements o0 an array range 0rom 3 to Lengt" = 2. T+e ne, operator automatically initialiDes t+e
elements o0 an array to t+eir de0ault value- w+ic+- 0or eample- is Dero 0or all numeric types and null 0or all
re0erence types.
T+e 0ollowing eample creates an array o0 int elements- initialiDes t+e array- and prints out t+e contents o0 t+e
array.
using System;
class 1est
{
static void Main() {
int45 a + ne, int4235;
-or (int i + 3; i D a.Lengt"; i<<) {
a4i5 + i > i;
!
-or (int i + 3; i D a.Lengt"; i<<) {
Console.WriteLine("a4{3!5 + {2!" i a4i5);
!
!
!
T+is eample creates and operates on a single-diensional array. C# also supports -lti-diensional arrays.
T+e number o0 dimensions o0 an array type- also 7nown as t+e ran" o0 t+e array type- is one plus t+e number o0
commas written between t+e s9uare brac7ets o0 t+e array type. T+e 0ollowing eample allocates a one<
dimensional- a two<dimensional- and a t+ree<dimensional array.
int45 a2 + ne, int4235;
int45 a8 + ne, int423 K5;
int45 a9 + ne, int423 K 85;
T+e a2 array contains 1. elements- t+e a8 array contains ". J1. T "M elements- and t+e a9 array contains 1..
J1. T " T 2M elements.
T+e element type o0 an array can be any type- including an array type. (n array wit+ elements o0 an array type is
sometimes called a 1agged array because t+e lengt+s o0 t+e element arrays do not all +ave to be t+e same. T+e
0ollowing eample allocates an array o0 arrays o0 intC
int4545 a + ne, int49545;
a435 + ne, int4235;
a425 + ne, int4K5;
a485 + ne, int4835;
T+e 0irst line creates an array wit+ t+ree elements- eac+ o0 type int45 and eac+ wit+ an initial value o0 null.
T+e subse9uent lines t+en initialiDe t+e t+ree elements wit+ re0erences to individual array instances o0 varying
lengt+s.
T+e ne, operator permits t+e initial values o0 t+e array elements to be speci0ied using an array initiali3er- w+ic+
is a list o0 epressions written between t+e delimiters { and !. T+e 0ollowing eample allocates and initialiDes an
int45 wit+ t+ree elements.
int45 a + ne, int45 {2 8 9!;
=ote t+at t+e lengt+ o0 t+e array is in0erred 0rom t+e number o0 epressions between { and !. 5ocal variable and
0ield declarations can be s+ortened 0urt+er suc+ t+at t+e array type does not +ave to be restated.
3* Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
int45 a + {2 8 9!;
)ot+ o0 t+e previous eamples are e9uivalent to t+e 0ollowingC
int45 t + ne, int495;
t435 + 2;
t425 + 8;
t485 + 9;
int45 a + t;
1.1 Interfaces
(n interface de0ines a contract t+at can be implemented by classes and structs. (n inter0ace can contain
met+ods- properties- events- and indeers. (n inter0aces does not provide implementations o0 t+e members it
de0inesRit merely speci0ies t+e members t+at must be supplied by classes or structs t+at implement t+e
inter0ace.
1nter0aces may employ -ltiple inheritance. 1n t+e 0ollowing eample- t+e inter0ace $Combo:o# in+erits 0rom
bot+ $1e#t:o# and $List:o#.
inter-ace $Control
{
void *aint();
!
inter-ace $1e#t:o#/ $Control
{
void Set1e#t(string te#t);
!
inter-ace $List:o#/ $Control
{
void Set$tems(string45 items);
!
inter-ace $Combo:o#/ $1e#t:o# $List:o# {!
Classes and structs can implement multiple inter0aces. 1n t+e 0ollowing eample- t+e class )dit:o# implements
bot+ $Control and $6ata:ound.
inter-ace $6ata:ound
{
void :ind(:inder b);
!
&ublic class )dit:o#/ $Control $6ata:ound
{
&ublic void *aint() {...!
&ublic void :ind(:inder b) {...!
!
6+en a class or struct implements a particular inter0ace- instances o0 t+at class or struct can be implicitly
converted to t+at inter0ace type. *or eample
)dit:o# edit:o# + ne, )dit:o#();
$Control control + edit:o#;
$6ata:ound data:ound + edit:o#;
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 31
C# Language Specification
1n cases w+ere an instance is not statically 7nown to implement a particular inter0ace- dynamic type casts can be
used. *or eample- t+e 0ollowing statements use dynamic type casts to obtain an ob&ectPs $Control and
$6ata:ound inter0ace implementations. )ecause t+e actual type o0 t+e ob&ect is )dit:o#- t+e casts succeed.
object obj + ne, )dit:o#();
$Control control + ($Control)obj;
$6ata:ound data:ound + ($6ata:ound)obj;
1n t+e previous )dit:o# class- t+e *aint met+od 0rom t+e $Control inter0ace and t+e :ind met+od 0rom t+e
$6ata:ound inter0ace are implemented using &ublic members. C# also supports e,plicit interface e!er
ipleentations- using w+ic+ t+e class or struct can avoid ma7ing t+e members &ublic. (n eplicit inter0ace
member implementation is written using t+e 0ully 9uali0ied inter0ace member name. *or eample- t+e )dit:o#
class could implement t+e $Control.*aint and $6ata:ound.:ind met+ods using eplicit inter0ace member
implementations as 0ollows.
&ublic class )dit:o#/ $Control $6ata:ound
{
void $Control.*aint() {...!
void $6ata:ound.:ind(:inder b) {...!
!
Eplicit inter0ace members can only be accessed via t+e inter0ace type. *or eample- t+e implementation o0
$Control.*aint provided by t+e previous )dit:o# class can only be invo7ed by 0irst converting t+e
)dit:o# re0erence to t+e $Control inter0ace type.
)dit:o# edit:o# + ne, )dit:o#();
edit:o#.*aint(); .. )rror no suc" met"od
$Control control + edit:o#;
control.*aint(); .. %(
1.10 $nus
(n en- type is a distinct value type wit+ a set o0 named constants. T+e 0ollowing eample declares and uses
an enum type named Color wit+ t+ree constant values- Oed- Sreen- and :lue.
using System;
enum Color
{
Oed
Sreen
:lue
!
32 Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
class 1est
{
static void *rintColor(Color color) {
s,itc" (color) {
case Color.Oed/
Console.WriteLine("Oed");
brea(;
case Color.Sreen/
Console.WriteLine("Sreen");
brea(;
case Color.:lue/
Console.WriteLine(":lue");
brea(;
de-ault/
Console.WriteLine(";n(no,n color");
brea(;
!
!
static void Main() {
Color c + Color.Oed;
*rintColor(c);
*rintColor(Color.:lue);
!
!
Eac+ enum type +as a corresponding integral type called t+e -nderlying type o0 t+e enum type. (n enum type
t+at does not eplicitly declare an underlying type +as an underlying type o0 int. (n enum typePs storage
0ormat and range o0 possible values are determined by its underlying type. T+e set o0 values t+at an enum type
can ta7e on is not limited by its enum members. 1n particular- any value o0 t+e underlying type o0 an enum can
be cast to t+e enum type and is a distinct valid value o0 t+at enum type.
T+e 0ollowing eample declares an enum type named 'lignment wit+ an underlying type o0 sbyte.
enum 'lignment/ sbyte
{
Le-t + =2
Center + 3
Oig"t + 2
!
(s s+own by t+e previous eample- an enum member declaration can include a constant epression t+at
speci0ies t+e value o0 t+e member. T+e constant value 0or eac+ enum member must be in t+e range o0 t+e
underlying type o0 t+e enum. 6+en an enum member declaration does not eplicitly speci0y a value- t+e
member is given t+e value Dero Ji0 it is t+e 0irst member in t+e enum typeM or t+e value o0 t+e tetually preceding
enum member plus one.
Enum values can be converted to integral values and vice versa using type casts. *or eample
int i + (int)Color.:lue; .. int i + 8;
Color c + (Color)8; .. Color c + Color.:lue;
T+e de0ault value o0 any enum type is t+e integral value Dero converted to t+e enum type. 1n cases w+ere
variables are automatically initialiDed to a de0ault value- t+is is t+e value given to variables o0 enum types. 1n
order 0or t+e de0ault value o0 an enum type to be easily available- t+e literal 3 implicitly converts to any enum
type. T+us- t+e 0ollowing is permitted.
Color c + 3;
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 33
C# Language Specification
1.11 2elegates
( delegate type represents re0erences to met+ods wit+ a particular parameter list and return type. 2elegates
ma7e it possible to treat met+ods as entities t+at can be assigned to variables and passed as parameters.
2elegates are similar to t+e concept o0 0unction pointers 0ound in some ot+er languages- but unli7e 0unction
pointers- delegates are ob&ect<oriented and type<sa0e.
T+e 0ollowing eample declares and uses a delegate type named Vunction.
using System;
delegate double Vunction(double #);
class Multi&lier
{
double -actor;
&ublic Multi&lier(double -actor) {
t"is.-actor + -actor;
!
&ublic double Multi&ly(double #) {
return # > -actor;
!
!
class 1est
{
static double SQuare(double #) {
return # > #;
!
static double45 '&&ly(double45 a Vunction -) {
double45 result + ne, double4a.Lengt"5;
-or (int i + 3; i D a.Lengt"; i<<) result4i5 + -(a4i5);
return result;
!
static void Main() {
double45 a + {3.3 3.K 2.3!;
double45 sQuares + '&&ly(a SQuare);
double45 sines + '&&ly(a Mat".Sin);
Multi&lier m + ne, Multi&lier(8.3);
double45 doubles + '&&ly(a m.Multi&ly);
!
!
(n instance o0 t+e Vunction delegate type can re0erence any met+od t+at ta7es a double argument and returns
a double value. T+e '&&ly met+od applies a given Vunction to t+e elements o0 a double45- returning a
double45 wit+ t+e results. 1n t+e Main met+od- '&&ly is used to apply t+ree di00erent 0unctions to a
double45.
( delegate can re0erence eit+er a static met+od Jsuc+ as SQuare or Mat".Sin in t+e previous eampleM or an
instance met+od Jsuc+ as m.Multi&ly in t+e previous eampleM. ( delegate t+at re0erences an instance met+od
also re0erences a particular ob&ect- and w+en t+e instance met+od is invo7ed t+roug+ t+e delegate- t+at ob&ect
becomes t"is in t+e invocation.
3" Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
2elegates can also be created using anonymous 0unctions- w+ic+ are Kinline met+odsL t+at are created on t+e
0ly. (nonymous 0unctions can see t+e local variables o0 t+e sourrounding met+ods. T+us- t+e multiplier eample
above can be written more easily wit+out using a Multi&lier classC
double45 doubles + '&&ly(a (double #) +E # > 8.3);
(n interesting and use0ul property o0 a delegate is t+at it does not 7now or care about t+e class o0 t+e met+od it
re0erencesQ all t+at matters is t+at t+e re0erenced met+od +as t+e same parameters and return type as t+e delegate.
1.12 *ttributes
Types- members- and ot+er entities in a C# program support modi0iers t+at control certain aspects o0 t+eir
be+avior. *or eample- t+e accessibility o0 a met+od is controlled using t+e &ublic- &rotected- internal-
and &rivate modi0iers. C# generaliDes t+is capability suc+ t+at user<de0ined types o0 declarative in0ormation
can be attac+ed to program entities and retrieved at runtime. Programs speci0y t+is additional declarative
in0ormation by de0ining and using attri!-tes.
T+e 0ollowing eample declares a Hel&'ttribute attribute t+at can be placed on program entities to provide
lin7s to t+eir associated documentation.
using System;
&ublic class Hel&'ttribute/ 'ttribute
{
string url;
string to&ic;
&ublic Hel&'ttribute(string url) {
t"is.url + url;
!
&ublic string ;rl {
get { return url; !
!
&ublic string 1o&ic {
get { return to&ic; !
set { to&ic + value; !
!
!
(ll attribute classes derive 0rom t+e System.'ttribute base class provided by t+e .=ET *ramewor7.
(ttributes can be applied by giving t+eir name- along wit+ any arguments- inside s9uare brac7ets &ust be0ore t+e
associated declaration. 10 an attributePs name ends in 'ttribute- t+at part o0 t+e name can be omitted w+en t+e
attribute is re0erenced. *or eample- t+e Hel&'ttribute attribute can be used as 0ollows.
4Hel&(""tt&/..msdn.microso-t.com.....MyClass."tm")5
&ublic class Widget
{
4Hel&(""tt&/..msdn.microso-t.com.....MyClass."tm" 1o&ic + "6is&lay")5
&ublic void 6is&lay(string te#t) {!
!
T+is eample attac+es a Hel&'ttribute to t+e Widget class and anot+er Hel&'ttribute to t+e 6is&lay
met+od in t+e class. T+e public constructors o0 an attribute class control t+e in0ormation t+at must be provided
w+en t+e attribute is attac+ed to a program entity. (dditional in0ormation can be provided by re0erencing public
read<write properties o0 t+e attribute class Jsuc+ as t+e re0erence to t+e 1o&ic property previouslyM.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 3
C# Language Specification
T+e 0ollowing eample s+ows +ow attribute in0ormation 0or a given program entity can be retrieved at runtime
using re0lection.
using System;
using System.Oe-lection;
class 1est
{
static void S"o,Hel&(Member$n-o member) {
Hel&'ttribute a + 'ttribute.SetCustom'ttribute(member
ty&eo-(Hel&'ttribute)) as Hel&'ttribute;
i- (a ++ null) {
Console.WriteLine("No "el& -or {3!" member);
!
else {
Console.WriteLine("Hel& -or {3!/" member);
Console.WriteLine(" ;rl+{3! 1o&ic+{2!" a.;rl a.1o&ic);
!
!
static void Main() {
S"o,Hel&(ty&eo-(Widget));
S"o,Hel&(ty&eo-(Widget).SetMet"od("6is&lay"));
!
!
6+en a particular attribute is re9uested t+roug+ re0lection- t+e constructor 0or t+e attribute class is invo7ed wit+
t+e in0ormation provided in t+e program source- and t+e resulting attribute instance is returned. 10 additional
in0ormation was provided t+roug+ properties- t+ose properties are set to t+e given values be0ore t+e attribute
instance is returned.
3' Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
2. Le%ical structure
2.1 Progras
( C# progra consists o0 one or more so-rce files- 7nown 0ormally as copilation -nits JV$.1M. ( source 0ile
is an ordered se9uence o0 8nicode c+aracters. #ource 0iles typically +ave a one<to<one correspondence wit+ 0iles
in a 0ile system- but t+is correspondence is not re9uired. *or maimal portability- it is recommended t+at 0iles in
a 0ile system be encoded wit+ t+e 8T*<3 encoding.
Conceptually spea7ing- a program is compiled using t+ree stepsC
1. Trans0ormation- w+ic+ converts a 0ile 0rom a particular c+aracter repertoire and encoding sc+eme into a
se9uence o0 8nicode c+aracters.
2. 5eical analysis- w+ic+ translates a stream o0 8nicode input c+aracters into a stream o0 to7ens.
3. #yntactic analysis- w+ic+ translates t+e stream o0 to7ens into eecutable code.
2.2 3raars
T+is speci0ication presents t+e synta o0 t+e C# programming language using two grammars. T+e le,ical
graar JV2.2.2M de0ines +ow 8nicode c+aracters are combined to 0orm line terminators- w+ite space-
comments- to7ens- and pre<processing directives. T+e syntactic graar JV2.2.3M de0ines +ow t+e to7ens
resulting 0rom t+e leical grammar are combined to 0orm C# programs.
2.2.1 3raar notation
T+e leical and syntactic grammars are presented using graar prod-ctions. Eac+ grammar production
de0ines a non<terminal symbol and t+e possible epansions o0 t+at non<terminal symbol into se9uences o0 non<
terminal or terminal symbols. 1n grammar productions- non-ter%inal symbols are s+own in italic type- and
terminal symbols are s+own in a 0ied<widt+ 0ont.
T+e 0irst line o0 a grammar production is t+e name o0 t+e non<terminal symbol being de0ined- 0ollowed by a
colon. Eac+ successive indented line contains a possible epansion o0 t+e non<terminal given as a se9uence o0
non<terminal or terminal symbols. *or eample- t+e productionC
while-state%ent.
while ( ,oolean-e/pression ) e%,edded-state%ent
de0ines a while-state%ent to consist o0 t+e to7en ,"ile- 0ollowed by t+e to7en K(L- 0ollowed by a ,oolean-
e/pression- 0ollowed by t+e to7en K)L- 0ollowed by an e%,edded-state%ent.
6+en t+ere is more t+an one possible epansion o0 a non<terminal symbol- t+e alternatives are listed on separate
lines. *or eample- t+e productionC
state%ent-list.
state%ent
state%ent-list state%ent
de0ines a state%ent-list to eit+er consist o0 a state%ent or consist o0 a state%ent-list 0ollowed by a state%ent. 1n
ot+er words- t+e de0inition is recursive and speci0ies t+at a statement list consists o0 one or more statements.
( subscripted su00i KoptL is used to indicate an optional symbol. T+e productionC
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 37
C# Language Specification
,loc&.
{ state%ent-listopt }
is s+ort+and 0orC
,loc&.
{ }
{ state%ent-list }
and de0ines a ,loc& to consist o0 an optional state%ent-list enclosed in K{L and K!L to7ens.
(lternatives are normally listed on separate lines- t+oug+ in cases w+ere t+ere are many alternatives- t+e p+rase
Kone o0L may precede a list o0 epansions given on a single line. T+is is simply s+ort+and 0or listing eac+ o0 t+e
alternatives on a separate line. *or eample- t+e productionC
real-t+pe-s!ffi/. one of
F f D d M m
is s+ort+and 0orC
real-t+pe-s!ffi/.
F
f
D
d
M
m
2.2.2 Le%ical graar
T+e leical grammar o0 C# is presented in V2.3- V2.4- and V2.". T+e terminal symbols o0 t+e leical grammar are
t+e c+aracters o0 t+e 8nicode c+aracter set- and t+e leical grammar speci0ies +ow c+aracters are combined to
0orm to7ens JV2.4M- w+ite space JV2.3.3M- comments JV2.3.2M- and pre<processing directives JV2."M.
Every source 0ile in a C# program must con0orm to t+e inp!t production o0 t+e leical grammar JV2.3M.
2.2.3 S!ntactic graar
T+e syntactic grammar o0 C# is presented in t+e c+apters and appendices t+at 0ollow t+is c+apter. T+e terminal
symbols o0 t+e syntactic grammar are t+e to7ens de0ined by t+e leical grammar- and t+e syntactic grammar
speci0ies +ow to7ens are combined to 0orm C# programs.
Every source 0ile in a C# program must con0orm to t+e co%pilation-!nit production o0 t+e syntactic grammar
JV$.1M.
2.3 Le%ical anal!sis
T+e inp!t production de0ines t+e leical structure o0 a C# source 0ile. Eac+ source 0ile in a C# program must
con0orm to t+is leical grammar production.
inp!t.
inp!t-sectionopt
inp!t-section.
inp!t-section-part
inp!t-section inp!t-section-part
3$ Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
inp!t-section-part.
inp!t-ele%entsopt new-line
pp-directive
inp!t-ele%ents.
inp!t-ele%ent
inp!t-ele%ents inp!t-ele%ent
inp!t-ele%ent.
whitespace
co%%ent
to&en
*ive basic elements ma7e up t+e leical structure o0 a C# source 0ileC 5ine terminators JV2.3.1M- w+ite space
JV2.3.3M- comments JV2.3.2M- to7ens JV2.4M- and pre<processing directives JV2."M. /0 t+ese basic elements- only
to7ens are signi0icant in t+e syntactic grammar o0 a C# program JV2.2.3M.
T+e leical processing o0 a C# source 0ile consists o0 reducing t+e 0ile into a se9uence o0 to7ens w+ic+ becomes
t+e input to t+e syntactic analysis. 5ine terminators- w+ite space- and comments can serve to separate to7ens-
and pre<processing directives can cause sections o0 t+e source 0ile to be s7ipped- but ot+erwise t+ese leical
elements +ave no impact on t+e syntactic structure o0 a C# program.
6+en several leical grammar productions matc+ a se9uence o0 c+aracters in a source 0ile- t+e leical
processing always 0orms t+e longest possible leical element. *or eample- t+e c+aracter se9uence .. is
processed as t+e beginning o0 a single<line comment because t+at leical element is longer t+an a single . to7en.
2.3.1 Line terinators
5ine terminators divide t+e c+aracters o0 a C# source 0ile into lines.
new-line.
Carriage ret!rn character 0U+000D1
2ine feed character 0U+000A1
Carriage ret!rn character 0U+000D1 followed ,+ line feed character 0U+000A1
3e/t line character 0U+00851
2ine separator character 0U+20281
4aragraph separator character 0U+20291
*or compatibility wit+ source code editing tools t+at add end<o0<0ile mar7ers- and to enable a source 0ile to be
viewed as a se9uence o0 properly terminated lines- t+e 0ollowing trans0ormations are applied- in order- to every
source 0ile in a C# programC
10 t+e last c+aracter o0 t+e source 0ile is a Control<W c+aracter J;<332'M- t+is c+aracter is deleted.
( carriage<return c+aracter J;<3336M is added to t+e end o0 t+e source 0ile i0 t+at source 0ile is non<empty
and i0 t+e last c+aracter o0 t+e source 0ile is not a carriage return J;<3336M- a line 0eed J;<333'M- a line
separator J;<838YM- or a paragrap+ separator J;<838LM.
2.3.2 Coents
Two 0orms o0 comments are supportedC single<line comments and delimited comments. (ingle-line coents
start wit+ t+e c+aracters .. and etend to t+e end o0 t+e source line. /eliited coents start wit+ t+e
c+aracters .> and end wit+ t+e c+aracters >.. 2elimited comments may span multiple lines.
co%%ent.
single-line-co%%ent
deli%ited-co%%ent
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 3!
C# Language Specification
single-line-co%%ent.
// inp!t-charactersopt
inp!t-characters.
inp!t-character
inp!t-characters inp!t-character
inp!t-character.
An+ 'nicode character e/cept a new-line-character
new-line-character.
Carriage ret!rn character 0U+000D1
2ine feed character 0U+000A1
3e/t line character 0U+00851
2ine separator character 0U+20281
4aragraph separator character 0U+20291
deli%ited-co%%ent.
/* deli%ited-co%%ent-te/topt asteris&s /
deli%ited-co%%ent-te/t.
deli%ited-co%%ent-section
deli%ited-co%%ent-te/t deli%ited-co%%ent-section
deli%ited-co%%ent-section.
/
asteris&sopt not-slash-or-asteris&
asteris&s.
*
asteris&s *
not-slash-or-asteris&.
An+ 'nicode character e/cept / or *
Comments do not nest. T+e c+aracter se9uences .> and >. +ave no special meaning wit+in a .. comment- and
t+e c+aracter se9uences .. and .> +ave no special meaning wit+in a delimited comment.
Comments are not processed wit+in c+aracter and string literals.
T+e eample
.> Hello ,orld &rogram
1"is &rogram ,rites R"ello ,orldT to t"e console
>.
class Hello
{
static void Main() {
System.Console.WriteLine(""ello ,orld");
!
!
includes a delimited comment.
T+e eample
"* Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
.. Hello ,orld &rogram
.. 1"is &rogram ,rites R"ello ,orldT to t"e console
..
class Hello .. any name ,ill do -or t"is class
{
static void Main() { .. t"is met"od must be named "Main"
System.Console.WriteLine(""ello ,orld");
!
!
s+ows several single<line comments.
2.3.3 4-ite space
6+ite space is de0ined as any c+aracter wit+ 8nicode class Ws Jw+ic+ includes t+e space c+aracterM as well as
t+e +oriDontal tab c+aracter- t+e vertical tab c+aracter- and t+e 0orm 0eed c+aracter.
whitespace.
An+ character with 'nicode class 5s
6ori-ontal ta, character 0U+00091
ertical ta, character 0U+000B1
7or% feed character 0U+000C1
2.# To5ens
T+ere are several 7inds o0 to7ensC identi0iers- 7eywords- literals- operators- and punctuators. 6+ite space and
comments are not to7ens- t+oug+ t+ey act as separators 0or to7ens.
to&en.
identifier
&e+word
integer-literal
real-literal
character-literal
string-literal
operator-or-p!nct!ator
2.#.1 6nicode c-aracter escape se7uences
( 8nicode c+aracter escape se9uence represents a 8nicode c+aracter. 8nicode c+aracter escape se9uences are
processed in identi0iers JV2.4.2M- c+aracter literals JV2.4.4.4M- and regular string literals JV2.4.4."M. ( 8nicode
c+aracter escape is not processed in any ot+er location J0or eample- to 0orm an operator- punctuator- or
7eywordM.
!nicode-escape-se8!ence.
\u he/-digit he/-digit he/-digit he/-digit
\U he/-digit he/-digit he/-digit he/-digit he/-digit he/-digit he/-digit he/-digit
( 8nicode escape se9uence represents t+e single 8nicode c+aracter 0ormed by t+e +eadecimal number
0ollowing t+e KZuL or KZ;L c+aracters. #ince C# uses a 1%<bit encoding o0 8nicode code points in c+aracters and
string values- a 8nicode c+aracter in t+e range 8N1.... to 8N1.**** is not permitted in a c+aracter literal and
is represented using a 8nicode surrogate pair in a string literal. 8nicode c+aracters wit+ code points above
.1.**** are not supported.
'ultiple translations are not per0ormed. *or instance- t+e string literal KZu33KCu33KCL is e9uivalent to
KZu33KCL rat+er t+an KZL. T+e 8nicode value Zu33KC is t+e c+aracter KZL.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. "1
C# Language Specification
T+e eample
class Class2
{
static void 1est(bool Zu33XX) {
c"ar c + WZu33XXW;
i- (Zu33XX)
System.Console.WriteLine(c.1oString());
!
!
s+ows several uses o0 Zu33XX- w+ic+ is t+e escape se9uence 0or t+e letter K-L. T+e program is e9uivalent to
class Class2
{
static void 1est(bool -) {
c"ar c + W-W;
i- (-)
System.Console.WriteLine(c.1oString());
!
!
2.#.2 Identifiers
T+e rules 0or identi0iers given in t+is section correspond eactly to t+ose recommended by t+e 8nicode #tandard
(nne 1"- ecept t+at underscore is allowed as an initial c+aracter Jas is traditional in t+e C programming
languageM- 8nicode escape se9uences are permitted in identi0iers- and t+e KXL c+aracter is allowed as a pre0i to
enable 7eywords to be used as identi0iers.
identifier.
availa,le-identifier
@ identifier-or-&e+word
availa,le-identifier.
An identifier-or-&e+word that is not a &e+word
identifier-or-&e+word.
identifier-start-character identifier-part-charactersopt
identifier-start-character.
letter-character
0the !nderscore character U+005F1
identifier-part-characters.
identifier-part-character
identifier-part-characters identifier-part-character
identifier-part-character.
letter-character
deci%al-digit-character
connecting-character
co%,ining-character
for%atting-character
letter-character.
A 'nicode character of classes 2!, 2l, 2t, 2%, 2o, or 3l
A !nicode-escape-se8!ence representing a character of classes 2!, 2l, 2t, 2%, 2o, or 3l
"2 Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
co%,ining-character.
A 'nicode character of classes Mn or Mc
A !nicode-escape-se8!ence representing a character of classes Mn or Mc
deci%al-digit-character.
A 'nicode character of the class 3d
A !nicode-escape-se8!ence representing a character of the class 3d
connecting-character.
A 'nicode character of the class 4c
A !nicode-escape-se8!ence representing a character of the class 4c
for%atting-character.
A 'nicode character of the class Cf
A !nicode-escape-se8!ence representing a character of the class Cf
*or in0ormation on t+e 8nicode c+aracter classes mentioned above- see 9he 'nicode (tandard- ersion :.0-
section 4.".
Eamples o0 valid identi0iers include Kidenti-ier2L- K[identi-ier8L- and K\i-L.
(n identi0ier in a con0orming program must be in t+e canonical 0ormat de0ined by 8nicode =ormaliDation *orm
C- as de0ined by 8nicode #tandard (nne 1". T+e be+avior w+en encountering an identi0ier not in
=ormaliDation *orm C is implementation<de0inedQ +owever- a diagnostic is not re9uired.
T+e pre0i K\L enables t+e use o0 7eywords as identi0iers- w+ic+ is use0ul w+en inter0acing wit+ ot+er
programming languages. T+e c+aracter \ is not actually part o0 t+e identi0ier- so t+e identi0ier mig+t be seen in
ot+er languages as a normal identi0ier- wit+out t+e pre0i. (n identi0ier wit+ an \ pre0i is called a ver!ati
identifier. 8se o0 t+e \ pre0i 0or identi0iers t+at are not 7eywords is permitted- but strongly discouraged as a
matter o0 style.
T+e eampleC
class \class
{
&ublic static void \static(bool \bool) {
i- (\bool)
System.Console.WriteLine("true");
else
System.Console.WriteLine("-alse");
!
!
class Class2
{
static void M() {
clZu33X2ss.stZu33X2tic(true);
!
!
de0ines a class named KclassL wit+ a static met+od named KstaticL t+at ta7es a parameter named KboolL.
=ote t+at since 8nicode escapes are not permitted in 7eywords- t+e to7en KclZu33X2ssL is an identi0ier- and is
t+e same identi0ier as K\classL.
Two identi0iers are considered t+e same i0 t+ey are identical a0ter t+e 0ollowing trans0ormations are applied- in
orderC
T+e pre0i K\L- i0 used- is removed.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. "3
C# Language Specification
Eac+ !nicode-escape-se8!ence is trans0ormed into its corresponding 8nicode c+aracter.
(ny for%atting-characters are removed.
1denti0iers containing two consecutive underscore c+aracters J;<33KVM are reserved 0or use by t+e
implementation. *or eample- an implementation mig+t provide etended 7eywords t+at begin wit+ two
underscores.
2.#.3 8e!words
( "ey2ord is an identi0ier<li7e se9uence o0 c+aracters t+at is reserved- and cannot be used as an identi0ier ecept
w+en pre0aced by t+e \ c+aracter.
&e+word. one of
!"#$%!&$ !# "!#e "''l "%e!(
")$e &!#e &!$&h &h!% &he&(ed
&l!## &'*#$ &'*$i*ue de&im!l def!ul$
dele+!$e d' d'u"le el#e e*um
e,e*$ e-.li&i$ e-$e%* f!l#e fi*!ll)
fi-ed fl'!$ f'% f'%e!&h +'$'
if im.li&i$ i* i*$ i*$e%f!&e
i*$e%*!l i# l'&( l'*+ *!me#.!&e
*ew *ull '"/e&$ '.e%!$'% 'u$
',e%%ide .!%!m# .%i,!$e .%'$e&$ed .u"li&
%e!d'*l) %ef %e$u%* #")$e #e!led
#h'%$ #i0e'f #$!&(!ll'& #$!$i& #$%i*+
#$%u&$ #wi$&h $hi# $h%'w $%ue
$%) $).e'f ui*$ ul'*+ u*&he&(ed
u*#!fe u#h'%$ u#i*+ ,i%$u!l ,'id
,'l!$ile while
1n some places in t+e grammar- speci0ic identi0iers +ave special meaning- but are not 7eywords. *or eample-
wit+in a property declaration- t+e KgetL and KsetL identi0iers +ave special meaning JV1..!.2M. (n identi0ier
ot+er t+an get or set is never permitted in t+ese locations- so t+is use does not con0lict wit+ a use o0 t+ese
words as identi0iers.
2.#.# Literals
( literal is a source code representation o0 a value.
literal.
,oolean-literal
integer-literal
real-literal
character-literal
string-literal
n!ll-literal
2.4.4.1 (oolean literals
T+ere are two boolean literal valuesC true and -alse.
,oolean-literal.
$%ue
f!l#e
"" Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
T+e type o0 a ,oolean-literal is bool.
2.4.4.2 #nteger literals
1nteger literals are used to write values o0 types int- uint- long- and ulong. 1nteger literals +ave two possible
0ormsC decimal and +eadecimal.
integer-literal.
deci%al-integer-literal
he/adeci%al-integer-literal
deci%al-integer-literal.
deci%al-digits integer-t+pe-s!ffi/opt
deci%al-digits.
deci%al-digit
deci%al-digits deci%al-digit
deci%al-digit. one of
0 1 2 2 3 5 4 5 8 9
integer-t+pe-s!ffi/. one of
U u 6 l U6 Ul u6 ul 6U 6u lU lu
he/adeci%al-integer-literal.
0- he/-digits integer-t+pe-s!ffi/opt
07 he/-digits integer-t+pe-s!ffi/opt
he/-digits.
he/-digit
he/-digits he/-digit
he/-digit. one of
0 1 2 2 3 5 4 5 8 9 A B C D 8 F ! " & d e f
T+e type o0 an integer literal is determined as 0ollowsC
10 t+e literal +as no su00i- it +as t+e 0irst o0 t+ese types in w+ic+ its value can be representedC int- uint-
long- ulong.
10 t+e literal is su00ied by ; or u- it +as t+e 0irst o0 t+ese types in w+ic+ its value can be representedC uint-
ulong.
10 t+e literal is su00ied by L or l- it +as t+e 0irst o0 t+ese types in w+ic+ its value can be representedC long-
ulong.
10 t+e literal is su00ied by ;L- ;l- uL- ul- L;- Lu- l;- or lu- it is o0 type ulong.
10 t+e value represented by an integer literal is outside t+e range o0 t+e ulong type- a compile<time error occurs.
(s a matter o0 style- it is suggested t+at KLL be used instead o0 KlL w+en writing literals o0 type long- since it is
easy to con0use t+e letter KlL wit+ t+e digit K2L.
To permit t+e smallest possible int and long values to be written as decimal integer literals- t+e 0ollowing two
rules eistC
6+en a deci%al-integer-literal wit+ t+e value 214!433%43 J2
31
M and no integer-t+pe-s!ffi/ appears as t+e
to7en immediately 0ollowing a unary minus operator to7en JV!.%.2M- t+e result is a constant o0 type int wit+
t+e value U214!433%43 JU2
31
M. 1n all ot+er situations- suc+ a deci%al-integer-literal is o0 type uint.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. "
C# Language Specification
6+en a deci%al-integer-literal wit+ t+e value $2233!2.3%3"4!!"3.3 J2
%3
M and no integer-t+pe-s!ffi/ or t+e
integer-t+pe-s!ffi/ L or l appears as t+e to7en immediately 0ollowing a unary minus operator to7en JV!.%.2M-
t+e result is a constant o0 type long wit+ t+e value U$2233!2.3%3"4!!"3.3 JU2
%3
M. 1n all ot+er situations-
suc+ a deci%al-integer-literal is o0 type ulong.
2.4.4.3 )eal literals
;eal literals are used to write values o0 types -loat- double- and decimal.
real-literal.
deci%al-digits 9 deci%al-digits e/ponent-partopt real-t+pe-s!ffi/opt
9 deci%al-digits e/ponent-partopt real-t+pe-s!ffi/opt
deci%al-digits e/ponent-part real-t+pe-s!ffi/opt
deci%al-digits real-t+pe-s!ffi/
e/ponent-part.
e signopt deci%al-digits
8 signopt deci%al-digits
sign. one of
+ :
real-t+pe-s!ffi/. one of
F f D d M m
10 no real-t+pe-s!ffi/ is speci0ied- t+e type o0 t+e real literal is double. /t+erwise- t+e real type su00i
determines t+e type o0 t+e real literal- as 0ollowsC
( real literal su00ied by V or - is o0 type -loat. *or eample- t+e literals 2-- 2.K-- 2e23-- and 289.JKXV
are all o0 type -loat.
( real literal su00ied by 6 or d is o0 type double. *or eample- t+e literals 2d- 2.Kd- 2e23d- and
289.JKX6 are all o0 type double.
( real literal su00ied by M or m is o0 type decimal. *or eample- t+e literals 2m- 2.Km- 2e23m- and
289.JKXM are all o0 type decimal. T+is literal is converted to a decimal value by ta7ing t+e eact value-
and- i0 necessary- rounding to t+e nearest representable value using ban7erYs rounding JV4.1.!M. (ny scale
apparent in t+e literal is preserved unless t+e value is rounded or t+e value is Dero Jin w+ic+ latter case t+e
sign and scale will be .M. Hence- t+e literal 8.L33m will be parsed to 0orm t+e decimal wit+ sign 3-
coe00icient 8L33- and scale 9.
10 t+e speci0ied literal cannot be represented in t+e indicated type- a compile<time error occurs.
T+e value o0 a real literal o0 type -loat or double is determined by using t+e 1EEE Kround to nearestL mode.
=ote t+at in a real literal- decimal digits are always re9uired a0ter t+e decimal point. *or eample- 2.9V is a real
literal but 2.V is not.
2.4.4.4 !haracter literals
( c+aracter literal represents a single c+aracter- and usually consists o0 a c+aracter in 9uotes- as in WaW.
character-literal.
; character ;
"' Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
character.
single-character
si%ple-escape-se8!ence
he/adeci%al-escape-se8!ence
!nicode-escape-se8!ence
single-character.
An+ character e/cept ; 0U+00251, \ 0U+005C1, and new-line-character
si%ple-escape-se8!ence. one of
\; \< \\ \0 \! \" \f \* \% \$ \,
he/adeci%al-escape-se8!ence.
\- he/-digit he/-digitopt he/-digitopt he/-digitopt
( c+aracter t+at 0ollows a bac7slas+ c+aracter JZM in a character must be one o0 t+e 0ollowing c+aractersC W- "-
Z- 3- a- b- -- n- r- t- u- ;- #- v. /t+erwise- a compile<time error occurs.
( +eadecimal escape se9uence represents a single 8nicode c+aracter- wit+ t+e value 0ormed by t+e
+eadecimal number 0ollowing KZ#L.
10 t+e value represented by a c+aracter literal is greater t+an ;<VVVV- a compile<time error occurs.
( 8nicode c+aracter escape se9uence JV2.4.1M in a c+aracter literal must be in t+e range ;<3333 to ;<VVVV.
( simple escape se9uence represents a 8nicode c+aracter encoding- as described in t+e table below.
(scape
se4uence
C0aracter
na)e
-nicode
encoding
ZW
#ingle 9uote
3#338M
Z"
2ouble 9uote
3#3388
ZZ
)ac7slas+
3#33KC
Z3
=ull
3#3333
Za
(lert
3#333M
Zb
)ac7space
3#333Y
Z-
*orm 0eed
3#333C
Zn
=ew line
3#333'
Zr
Carriage return
3#3336
Zt
HoriDontal tab
3#333L
Zv
,ertical tab
3#333:
T+e type o0 a character-literal is c"ar.
2.4.4.5 String literals
C# supports two 0orms o0 string literalsC reg-lar string literals and ver!ati string literals.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. "7
C# Language Specification
( regular string literal consists o0 Dero or more c+aracters enclosed in double 9uotes- as in ""ello"- and may
include bot+ simple escape se9uences Jsuc+ as Zt 0or t+e tab c+aracterM- and +eadecimal and 8nicode escape
se9uences.
( verbatim string literal consists o0 an \ c+aracter 0ollowed by a double<9uote c+aracter- Dero or more
c+aracters- and a closing double<9uote c+aracter. ( simple eample is \""ello". 1n a verbatim string literal-
t+e c+aracters between t+e delimiters are interpreted verbatim- t+e only eception being a 8!ote-escape-
se8!ence. 1n particular- simple escape se9uences- and +eadecimal and 8nicode escape se9uences are not
processed in verbatim string literals. ( verbatim string literal may span multiple lines.
string-literal.
reg!lar-string-literal
ver,ati%-string-literal
reg!lar-string-literal.
< reg!lar-string-literal-charactersopt <
reg!lar-string-literal-characters.
reg!lar-string-literal-character
reg!lar-string-literal-characters reg!lar-string-literal-character
reg!lar-string-literal-character.
single-reg!lar-string-literal-character
si%ple-escape-se8!ence
he/adeci%al-escape-se8!ence
!nicode-escape-se8!ence
single-reg!lar-string-literal-character.
An+ character e/cept < 0U+00221, \ 0U+005C1, and new-line-character
ver,ati%-string-literal.
@< ver,ati% -string-literal-charactersopt <
ver,ati%-string-literal-characters.
ver,ati%-string-literal-character
ver,ati%-string-literal-characters ver,ati%-string-literal-character
ver,ati%-string-literal-character.
single-ver,ati%-string-literal-character
8!ote-escape-se8!ence
single-ver,ati%-string-literal-character.
An+ character e/cept <
8!ote-escape-se8!ence.
<<
( c+aracter t+at 0ollows a bac7slas+ c+aracter JZM in a reg!lar-string-literal-character must be one o0 t+e
0ollowing c+aractersC W- "- Z- 3- a- b- -- n- r- t- u- ;- #- v. /t+erwise- a compile<time error occurs.
T+e eample
string a + ""ello ,orld"; .. "ello ,orld
string b + \""ello ,orld"; .. "ello ,orld
string c + ""ello Zt ,orld"; .. "ello ,orld
string d + \""ello Zt ,orld"; .. "ello Zt ,orld
string e + "]oe said Z"HelloZ" to me"; .. ]oe said "Hello" to me
string - + \"]oe said ""Hello"" to me"; .. ]oe said "Hello" to me
"$ Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
string g + "ZZZZserverZZs"areZZ-ile.t#t"; .. ZZserverZs"areZ-ile.t#t
string " + \"ZZserverZs"areZ-ile.t#t"; .. ZZserverZs"areZ-ile.t#t
string i + "oneZrZnt,oZrZnt"ree";
string j + \"one
t,o
t"ree";
s+ows a variety o0 string literals. T+e last string literal- j- is a verbatim string literal t+at spans multiple lines.
T+e c+aracters between t+e 9uotation mar7s- including w+ite space suc+ as new line c+aracters- are preserved
verbatim.
#ince a +eadecimal escape se9uence can +ave a variable number o0 +e digits- t+e string literal "Z#289"
contains a single c+aracter wit+ +e value 123. To create a string containing t+e c+aracter wit+ +e value 12
0ollowed by t+e c+aracter 3- one could write "Z#33289" or "Z#28" < "9" instead.
T+e type o0 a string-literal is string.
Eac+ string literal does not necessarily result in a new string instance. 6+en two or more string literals t+at are
e9uivalent according to t+e string e9uality operator JV!.$.!M appear in t+e same program- t+ese string literals
re0er to t+e same string instance. *or instance- t+e output produced by
class 1est
{
static void Main() {
object a + ""ello";
object b + ""ello";
System.Console.WriteLine(a ++ b);
!
!
is 1rue because t+e two literals re0er to t+e same string instance.
2.4.4.6 *he null literal
n!ll-literal.
*ull
T+e n!ll-literal can be implicitly converted to a re0erence type or nullable type.
2.#.& /perators and punctuators
T+ere are several 7inds o0 operators and punctuators. /perators are used in epressions to describe operations
involving one or more operands. *or eample- t+e epression a < b uses t+e < operator to add t+e two operands
a and b. Punctuators are 0or grouping and separating.
operator-or-p!nct!ator. one of
{ } = > ( ) 9 ? @ A
+ : * / B C D E F G
H I J K KK @@ ++ :: CC DD
:J HH FH IH JH +H :H *H /H BH
CH DH EH II IIH HJ
right-shift.
J;J
right-shift-assign%ent.
J;JH
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. "!
C# Language Specification
T+e vertical bar in t+e right-shift and right-shift-assign%ent productions are used to indicate t+at- unli7e ot+er
productions in t+e syntactic grammar- no c+aracters o0 any 7ind Jnot even w+itespaceM are allowed between t+e
to7ens. T+ese productions are treated specially in order to enable t+e correct +andling o0 t+pe-para%eter-lists
JV1..1.3M.
2.& Pre9processing directi"es
T+e pre<processing directives provide t+e ability to conditionally s7ip sections o0 source 0iles- to report error and
warning conditions- and to delineate distinct regions o0 source code. T+e term Kpre<processing directivesL is
used only 0or consistency wit+ t+e C and CNN programming languages. 1n C#- t+ere is no separate pre<
processing stepQ pre<processing directives are processed as part o0 t+e leical analysis p+ase.
pp-directive.
pp-declaration
pp-conditional
pp-line
pp-diagnostic
pp-region
pp-prag%a
T+e 0ollowing pre<processing directives are availableC
0de-ine and 0unde-- w+ic+ are used to de0ine and unde0ine- respectively- conditional compilation
symbols JV2.".3M.
0i-- 0eli-- 0else- and 0endi-- w+ic+ are used to conditionally s7ip sections o0 source code JV2.".4M.
0line- w+ic+ is used to control line numbers emitted 0or errors and warnings JV2.".!M.
0error and 0,arning- w+ic+ are used to issue errors and warnings- respectively JV2."."M.
0region and 0endregion- w+ic+ are used to eplicitly mar7 sections o0 source code JV2.".%M.
0&ragma- w+ic+ is used to speci0y optional contetual in0ormation to t+e compiler JV2.".3M.
( pre<processing directive always occupies a separate line o0 source code and always begins wit+ a 0 c+aracter
and a pre<processing directive name. 6+ite space may occur be0ore t+e 0 c+aracter and between t+e 0 c+aracter
and t+e directive name.
( source line containing a 0de-ine- 0unde-- 0i-- 0eli-- 0else- 0endi-- or 0line directive may end wit+ a
single<line comment. 2elimited comments Jt+e .> >. style o0 commentsM are not permitted on source lines
containing pre<processing directives.
Pre<processing directives are not to7ens and are not part o0 t+e syntactic grammar o0 C#. However- pre<
processing directives can be used to include or eclude se9uences o0 to7ens and can in t+at way a00ect t+e
meaning o0 a C# program. *or eample- w+en compiled- t+e programC
0de-ine '
0unde- :
class C
{
0i- '
void V() {!
0else
void S() {!
0endi-
* Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
0i- :
void H() {!
0else
void $() {!
0endi-
!
results in t+e eact same se9uence o0 to7ens as t+e programC
class C
{
void V() {!
void $() {!
!
T+us- w+ereas leically- t+e two programs are 9uite di00erent- syntactically- t+ey are identical.
2.&.1 Conditional copilation s!bols
T+e conditional compilation 0unctionality provided by t+e 0i-- 0eli-- 0else- and 0endi- directives is
controlled t+roug+ pre<processing epressions JV2.".2M and conditional compilation symbols.
conditional-s+%,ol.
An+ identifier-or-&e+word e/cept $%ue or f!l#e
( conditional compilation symbol +as two possible statesC defined or -ndefined. (t t+e beginning o0 t+e leical
processing o0 a source 0ile- a conditional compilation symbol is unde0ined unless it +as been eplicitly de0ined
by an eternal mec+anism Jsuc+ as a command<line compiler optionM. 6+en a 0de-ine directive is processed-
t+e conditional compilation symbol named in t+at directive becomes de0ined in t+at source 0ile. T+e symbol
remains de0ined until an 0unde- directive 0or t+at same symbol is processed- or until t+e end o0 t+e source 0ile
is reac+ed. (n implication o0 t+is is t+at 0de-ine and 0unde- directives in one source 0ile +ave no e00ect on
ot+er source 0iles in t+e same program.
6+en re0erenced in a pre<processing epression- a de0ined conditional compilation symbol +as t+e boolean
value true- and an unde0ined conditional compilation symbol +as t+e boolean value -alse. T+ere is no
re9uirement t+at conditional compilation symbols be eplicitly declared be0ore t+ey are re0erenced in pre<
processing epressions. 1nstead- undeclared symbols are simply unde0ined and t+us +ave t+e value -alse.
T+e name space 0or conditional compilation symbols is distinct and separate 0rom all ot+er named entities in a
C# program. Conditional compilation symbols can only be re0erenced in 0de-ine and 0unde- directives and in
pre<processing epressions.
2.&.2 Pre9processing e%pressions
Pre<processing epressions can occur in 0i- and 0eli- directives. T+e operators @- ++- @+- FF and HH are
permitted in pre<processing epressions- and parent+eses may be used 0or grouping.
pp-e/pression.
whitespaceopt pp-or-e/pression whitespaceopt
pp-or-e/pression.
pp-and-e/pression
pp-or-e/pression whitespaceopt DD whitespaceopt pp-and-e/pression
pp-and-e/pression.
pp-e8!alit+-e/pression
pp-and-e/pression whitespaceopt CC whitespaceopt pp-e8!alit+-e/pression
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 1
C# Language Specification
pp-e8!alit+-e/pression.
pp-!nar+-e/pression
pp-e8!alit+-e/pression whitespaceopt HH whitespaceopt pp-!nar+-e/pression
pp-e8!alit+-e/pression whitespaceopt FH whitespaceopt pp-!nar+-e/pression
pp-!nar+-e/pression.
pp-pri%ar+-e/pression
F whitespaceopt pp-!nar+-e/pression
pp-pri%ar+-e/pression.
$%ue
f!l#e
conditional-s+%,ol
( whitespaceopt pp-e/pression whitespaceopt )
6+en re0erenced in a pre<processing epression- a de0ined conditional compilation symbol +as t+e boolean
value true- and an unde0ined conditional compilation symbol +as t+e boolean value -alse.
Evaluation o0 a pre<processing epression always yields a boolean value. T+e rules o0 evaluation 0or a pre<
processing epression are t+e same as t+ose 0or a constant epression JV!.13M- ecept t+at t+e only user<de0ined
entities t+at can be re0erenced are conditional compilation symbols.
2.&.3 2eclaration directi"es
T+e declaration directives are used to de0ine or unde0ine conditional compilation symbols.
pp-declaration.
whitespaceopt L whitespaceopt defi*e whitespace conditional-s+%,ol pp-new-line
whitespaceopt L whitespaceopt u*def whitespace conditional-s+%,ol pp-new-line
pp-new-line.
whitespaceopt single-line-co%%entopt new-line
T+e processing o0 a 0de-ine directive causes t+e given conditional compilation symbol to become de0ined-
starting wit+ t+e source line t+at 0ollows t+e directive. 5i7ewise- t+e processing o0 an 0unde- directive causes
t+e given conditional compilation symbol to become unde0ined- starting wit+ t+e source line t+at 0ollows t+e
directive.
(ny 0de-ine and 0unde- directives in a source 0ile must occur be0ore t+e 0irst to&en JV2.4M in t+e source 0ileQ
ot+erwise a compile<time error occurs. 1n intuitive terms- 0de-ine and 0unde- directives must precede any
Kreal codeL in t+e source 0ile.
T+e eampleC
0de-ine )nter&rise
0i- *ro-essional HH )nter&rise
0de-ine 'dvanced
0endi-
names&ace Megacor&.6ata
{
0i- 'dvanced
class *ivot1able {...!
0endi-
!
is valid because t+e 0de-ine directives precede t+e 0irst to7en Jt+e names&ace 7eywordM in t+e source 0ile.
T+e 0ollowing eample results in a compile<time error because a 0de-ine 0ollows real codeC
2 Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
0de-ine '
names&ace N
{
0de-ine :
0i- :
class Class2 {!
0endi-
!
( 0de-ine may de0ine a conditional compilation symbol t+at is already de0ined- wit+out t+ere being any
intervening 0unde- 0or t+at symbol. T+e eample below de0ines a conditional compilation symbol ' and t+en
de0ines it again.
0de-ine '
0de-ine '
( 0unde- may Kunde0ineL a conditional compilation symbol t+at is not de0ined. T+e eample below de0ines a
conditional compilation symbol ' and t+en unde0ines it twiceQ alt+oug+ t+e second 0unde- +as no e00ect- it is
still valid.
0de-ine '
0unde- '
0unde- '
2.&.# Conditional copilation directi"es
T+e conditional compilation directives are used to conditionally include or eclude portions o0 a source 0ile.
pp-conditional.
pp-if-section pp-elif-sectionsopt pp-else-sectionopt pp-endif
pp-if-section.
whitespaceopt L whitespaceopt if whitespace pp-e/pression pp-new-line conditional-
sectionopt
pp-elif-sections.
pp-elif-section
pp-elif-sections pp-elif-section
pp-elif-section.
whitespace
opt
L whitespace
opt
elif whitespace pp-e/pression pp-new-line conditional-
sectionopt
pp-else-section.
whitespaceopt L whitespaceopt el#e pp-new-line conditional-sectionopt
pp-endif.
whitespaceopt L whitespaceopt e*dif pp-new-line
conditional-section.
inp!t-section
s&ipped-section
s&ipped-section.
s&ipped-section-part
s&ipped-section s&ipped-section-part
s&ipped-section-part.
s&ipped-charactersopt new-line
pp-directive
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 3
C# Language Specification
s&ipped-characters.
whitespaceopt not-n!%,er-sign inp!t-charactersopt
not-n!%,er-sign.
An+ inp!t-character e/cept L
(s indicated by t+e synta- conditional compilation directives must be written as sets consisting o0- in order- an
0i- directive- Dero or more 0eli- directives- Dero or one 0else directive- and an 0endi- directive. )etween
t+e directives are conditional sections o0 source code. Eac+ section is controlled by t+e immediately preceding
directive. ( conditional section may itsel0 contain nested conditional compilation directives provided t+ese
directives 0orm complete sets.
( pp-conditional selects at most one o0 t+e contained conditional-sections 0or normal leical processingC
T+e pp-e/pressions o0 t+e 0i- and 0eli- directives are evaluated in order until one yields true. 10 an
epression yields true- t+e conditional-section o0 t+e corresponding directive is selected.
10 all pp-e/pressions yield -alse- and i0 an 0else directive is present- t+e conditional-section o0 t+e 0else
directive is selected.
/t+erwise- no conditional-section is selected.
T+e selected conditional-section- i0 any- is processed as a normal inp!t-sectionC t+e source code contained in t+e
section must ad+ere to t+e leical grammarQ to7ens are generated 0rom t+e source code in t+e sectionQ and pre<
processing directives in t+e section +ave t+e prescribed e00ects.
T+e remaining conditional-sections- i0 any- are processed as s&ipped-sectionsC ecept 0or pre<processing
directives- t+e source code in t+e section need not ad+ere to t+e leical grammarQ no to7ens are generated 0rom
t+e source code in t+e sectionQ and pre<processing directives in t+e section must be leically correct but are not
ot+erwise processed. 6it+in a conditional-section t+at is being processed as a s&ipped-section- any nested
conditional-sections Jcontained in nested 0i-...0endi- and 0region...0endregion constructsM are also
processed as s&ipped-sections.
T+e 0ollowing eample illustrates +ow conditional compilation directives can nestC
0de-ine 6ebug .. 6ebugging on
0unde- 1race .. 1racing o--
class *urc"ase1ransaction
{
void Commit() {
0i- 6ebug
C"ec(Consistency();
0i- 1race
Write1oLog(t"is.1oString());
0endi-
0endi-
CommitHel&er();
!
!
Ecept 0or pre<processing directives- s7ipped source code is not sub&ect to leical analysis. *or eample- t+e
0ollowing is valid despite t+e unterminated comment in t+e 0else sectionC
0de-ine 6ebug .. 6ebugging on
" Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
class *urc"ase1ransaction
{
void Commit() {
0i- 6ebug
C"ec(Consistency();
0else
.> 6o somet"ing else
0endi-
!
!
=ote- +owever- t+at pre<processing directives are re9uired to be leically correct even in s7ipped sections o0
source code.
Pre<processing directives are not processed w+en t+ey appear inside multi<line input elements. *or eample- t+e
programC
class Hello
{
static void Main() {
System.Console.WriteLine(\""ello
0i- 6ebug
,orld
0else
Nebras(a
0endi-
");
!
!
results in t+e outputC
"ello
0i- 6ebug
,orld
0else
Nebras(a
0endi-
1n peculiar cases- t+e set o0 pre<processing directives t+at is processed mig+t depend on t+e evaluation o0 t+e pp-
e/pression. T+e eampleC
0i- I
.>
0else
.> >. class ^ { !
0endi-
always produces t+e same to7en stream Jclass ^ { !M- regardless o0 w+et+er or not I is de0ined. 10 I is de0ined-
t+e only processed directives are 0i- and 0endi-- due to t+e multi<line comment. 10 I is unde0ined- t+en t+ree
directives J0i-- 0else- 0endi-M are part o0 t+e directive set.
2.&.& 2iagnostic directi"es
T+e diagnostic directives are used to eplicitly generate error and warning messages t+at are reported in t+e
same way as ot+er compile<time errors and warnings.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C# Language Specification
pp-diagnostic.
whitespaceopt L whitespaceopt e%%'% pp-%essage
whitespaceopt L whitespaceopt w!%*i*+ pp-%essage
pp-%essage.
new-line
whitespace inp!t-charactersopt new-line
T+e eampleC
0,arning Code revie, needed be-ore c"ec(=in
0i- 6ebug FF Oetail
0error ' build canWt be bot" debug and retail
0endi-
class 1est {...!
always produces a warning JKCode review needed be0ore c+ec7<inLM- and produces a compile<time error JK(
build canPt be bot+ debug and retailLM i0 t+e conditional symbols 6ebug and Oetail are bot+ de0ined. =ote t+at
a pp-%essage can contain arbitrary tetQ speci0ically- it need not contain well<0ormed to7ens- as s+own by t+e
single 9uote in t+e word can_t.
2.&.' :egion directi"es
T+e region directives are used to eplicitly mar7 regions o0 source code.
pp-region.
pp-start-region conditional-sectionopt pp-end-region
pp-start-region.
whitespaceopt L whitespaceopt %e+i'* pp-%essage
pp-end-region.
whitespaceopt L whitespaceopt e*d%e+i'* pp-%essage
=o semantic meaning is attac+ed to a regionQ regions are intended 0or use by t+e programmer or by automated
tools to mar7 a section o0 source code. T+e message speci0ied in a 0region or 0endregion directive li7ewise
+as no semantic meaningQ it merely serves to identi0y t+e region. 'atc+ing 0region and 0endregion
directives may +ave di00erent pp-%essages.
T+e leical processing o0 a regionC
0region
...
0endregion
corresponds eactly to t+e leical processing o0 a conditional compilation directive o0 t+e 0ormC
0i- true
...
0endi-
2.&.. Line directi"es
5ine directives may be used to alter t+e line numbers and source 0ile names t+at are reported by t+e compiler in
output suc+ as warnings and errors.
5ine directives are most commonly used in meta<programming tools t+at generate C# source code 0rom some
ot+er tet input.
' Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
pp-line.
whitespaceopt L whitespaceopt li*e whitespace line-indicator pp-new-line
line-indicator.
deci%al-digits whitespace file-na%e
deci%al-digits
def!ul$
hidde*
file-na%e.
< file-na%e-characters <
file-na%e-characters.
file-na%e-character
file-na%e-characters file-na%e-character
file-na%e-character.
An+ inp!t-character e/cept <
6+en no 0line directives are present- t+e compiler reports true line numbers and source 0ile names in its
output. 6+en processing a 0line directive t+at includes a line-indicator t+at is not de-ault- t+e compiler
treats t+e line after t+e directive as +aving t+e given line number Jand 0ile name- i0 speci0iedM.
( 0line de-ault directive reverses t+e e00ect o0 all preceding #line directives. T+e compiler reports true line
in0ormation 0or subse9uent lines- precisely as i0 no 0line directives +ad been processed.
( 0line "idden directive +as no e00ect on t+e 0ile and line numbers reported in error messages- but does
a00ect source level debugging. 6+en debugging- all lines between a 0line "idden directive and t+e
subse9uent 0line directive Jt+at is not 0line "iddenM +ave no line number in0ormation. 6+en stepping
t+roug+ code in t+e debugger- t+ese lines will be s7ipped entirely.
=ote t+at a file-na%e di00ers 0rom a regular string literal in t+at escape c+aracters are not processedQ t+e ZZP
c+aracter simply designates an ordinary bac7slas+ c+aracter wit+in a file-na%e.
2.&.0 Praga directi"es
T+e 0&ragma preprocessing directive is used to speci0y optional contetual in0ormation to t+e compiler. T+e
in0ormation supplied in a 0&ragma directive will never c+ange program semantics.
pp-prag%a.
whitespaceopt L whitespaceopt .%!+m! whitespace prag%a-,od+ pp-new-line
prag%a-,od+.
prag%a-warning-,od+
C# provides 0&ragma directives to control compiler warnings. *uture versions o0 t+e language may include
additional 0&ragma directives. To ensure interoperability wit+ ot+er C# compilers- t+e 'icroso0t C# compiler
does not issue compilation errors 0or un7nown 0&ragma directivesQ suc+ directives do +owever generate
warnings.
2.5.+.1 Pragma ,arning
T+e 0&ragma ,arning directive is used to disable or restore all or a particular set o0 warning messages during
compilation o0 t+e subse9uent program tet.
prag%a-warning-,od+.
w!%*i*+ whitespace warning-action
w!%*i*+ whitespace warning-action whitespace warning-list
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 7
C# Language Specification
warning-action.
di#!"le
%e#$'%e
warning-list.
deci%al-digits
warning-list whitespaceopt ? whitespaceopt deci%al-digits
( 0&ragma ,arning directive t+at omits t+e warning list a00ects all warnings. ( 0&ragma ,arning directive
t+e includes a warning list a00ects only t+ose warnings t+at are speci0ied in t+e list.
( 0&ragma ,arning disable directive disables all or t+e given set o0 warnings.
( 0&ragma ,arning restore directive restores all or t+e given set o0 warnings to t+e state t+at was in e00ect
at t+e beginning o0 t+e compilation unit. =ote t+at i0 a particular warning was disabled eternally- a 0&ragma
,arning restore Jw+et+er 0or all or t+e speci0ic warningM will not re<enable t+at warning.
T+e 0ollowing eample s+ows use o0 0&ragma ,arning to temporarily disable t+e warning reported w+en
obsoleted members are re0erenced- using t+e warning number 0rom t+e 'icroso0t C# compiler.
using System;
class *rogram
{
4%bsolete5
static void Voo() {!
static void Main() {
0&ragma ,arning disable X28
Voo();
0&ragma ,arning restore X28
!
!
$ Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
3. +asic concepts
3.1 *pplication Startup
(n assembly t+at +as an entry point is called an application. 6+en an application is run- a new application
doain is created. #everal di00erent instantiations o0 an application may eist on t+e same mac+ine at t+e same
time- and eac+ +as its own application domain.
(n application domain enables application isolation by acting as a container 0or application state. (n application
domain acts as a container and boundary 0or t+e types de0ined in t+e application and t+e class libraries it uses.
Types loaded into one application domain are distinct 0rom t+e same type loaded into anot+er application
domain- and instances o0 ob&ects are not directly s+ared between application domains. *or instance- eac+
application domain +as its own copy o0 static variables 0or t+ese types- and a static constructor 0or a type is run
at most once per application domain. 1mplementations are 0ree to provide implementation<speci0ic policy or
mec+anisms 0or t+e creation and destruction o0 application domains.
Application start-p occurs w+en t+e eecution environment calls a designated met+od- w+ic+ is re0erred to as
t+e applicationYs entry point. T+is entry point met+od is always named Main- and can +ave one o0 t+e 0ollowing
signaturesC
static void Main() {...!
static void Main(string45 args) {...!
static int Main() {...!
static int Main(string45 args) {...!
(s s+own- t+e entry point may optionally return an int value. T+is return value is used in application
termination JV3.2M.
T+e entry point may optionally +ave one 0ormal parameter. T+e parameter may +ave any name- but t+e type o0
t+e parameter must be string45. 10 t+e 0ormal parameter is present- t+e eecution environment creates and
passes a string45 argument containing t+e command<line arguments t+at were speci0ied w+en t+e application
was started. T+e string45 argument is never null- but it may +ave a lengt+ o0 Dero i0 no command<line
arguments were speci0ied.
#ince C# supports met+od overloading- a class or struct may contain multiple de0initions o0 some met+od-
provided eac+ +as a di00erent signature. However- wit+in a single program- no class or struct may contain more
t+an one met+od called Main w+ose de0inition 9uali0ies it to be used as an application entry point. /t+er
overloaded versions o0 Main are permitted- +owever- provided t+ey +ave more t+an one parameter- or t+eir only
parameter is ot+er t+an type string45.
(n application can be made up o0 multiple classes or structs. 1t is possible 0or more t+an one o0 t+ese classes or
structs to contain a met+od called Main w+ose de0inition 9uali0ies it to be used as an application entry point. 1n
suc+ cases- an eternal mec+anism Jsuc+ as a command<line compiler optionM must be used to select one o0
t+ese Main met+ods as t+e entry point.
1n C#- every met+od must be de0ined as a member o0 a class or struct. /rdinarily- t+e declared accessibility
JV3.".1M o0 a met+od is determined by t+e access modi0iers JV1..3."M speci0ied in its declaration- and similarly
t+e declared accessibility o0 a type is determined by t+e access modi0iers speci0ied in its declaration. 1n order 0or
a given met+od o0 a given type to be callable- bot+ t+e type and t+e member must be accessible. However- t+e
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. !
C# Language Specification
application entry point is a special case. #peci0ically- t+e eecution environment can access t+e applicationYs
entry point regardless o0 its declared accessibility and regardless o0 t+e declared accessibility o0 its enclosing
type declarations.
T+e application entry point met+od may not be in a generic class declaration.
1n all ot+er respects- entry point met+ods be+ave li7e t+ose t+at are not entry points.
3.2 *pplication terination
Application terination returns control to t+e eecution environment.
10 t+e return type o0 t+e applicationPs entry point met+od is int- t+e value returned serves as t+e applicationYs
terination stat-s code. T+e purpose o0 t+is code is to allow communication o0 success or 0ailure to t+e
eecution environment.
10 t+e return type o0 t+e entry point met+od is void- reac+ing t+e rig+t brace J!M w+ic+ terminates t+at met+od-
or eecuting a return statement t+at +as no epression- results in a termination status code o0 3.
Prior to an applicationPs termination- destructors 0or all o0 its ob&ects t+at +ave not yet been garbage collected
are called- unless suc+ cleanup +as been suppressed Jby a call to t+e library met+od SC.Su&&ressVinali?e-
0or eampleM.
3.3 2eclarations
2eclarations in a C# program de0ine t+e constituent elements o0 t+e program. C# programs are organiDed using
namespaces JV$M- w+ic+ can contain type declarations and nested namespace declarations. Type declarations
JV$.%M are used to de0ine classes JV1.M- structs JV1..14M- inter0aces JV13M- enums JV14M- and delegates JV1"M. T+e
7inds o0 members permitted in a type declaration depend on t+e 0orm o0 t+e type declaration. *or instance- class
declarations can contain declarations 0or constants JV1..4M- 0ields JV1.."M- met+ods JV1..%M- properties JV1..!M-
events JV1..3M- indeers JV1..$M- operators JV1..1.M- instance constructors JV1..11M- static constructors JV1..12M-
destructors JV1..13M- and nested typesJV1..3.3M.
( declaration de0ines a name in t+e declaration space to w+ic+ t+e declaration belongs. Ecept 0or overloaded
members JV3.%M- it is a compile<time error to +ave two or more declarations t+at introduce members wit+ t+e
same name in a declaration space. 1t is never possible 0or a declaration space to contain di00erent 7inds o0
members wit+ t+e same name. *or eample- a declaration space can never contain a 0ield and a met+od by t+e
same name.
T+ere are several di00erent types o0 declaration spaces- as described in t+e 0ollowing.
6it+in all source 0iles o0 a program- na%espace-%e%,er-declarations wit+ no enclosing na%espace-
declaration are members o0 a single combined declaration space called t+e glo!al declaration space.
6it+in all source 0iles o0 a program- na%espace-%e%,er-declarations wit+in na%espace-declarations t+at
+ave t+e same 0ully 9uali0ied namespace name are members o0 a single combined declaration space.
Eac+ class- struct- or inter0ace declaration creates a new declaration space. =ames are introduced into t+is
declaration space t+roug+ class-%e%,er-declarations- str!ct-%e%,er-declarations- interface-%e%,er-
declarations- or t+pe-para%eters. Ecept 0or overloaded instance constructor declarations and static
constructor declarations- a class or struct cannot contain a member declaration wit+ t+e same name as t+e
class or struct. ( class- struct- or inter0ace permits t+e declaration o0 overloaded met+ods and indeers.
*urt+ermore- a class or struct permits t+e declaration o0 overloaded instance constructors and operators. *or
eample- a class- struct- or inter0ace may contain multiple met+od declarations wit+ t+e same name-
provided t+ese met+od declarations di00er in t+eir signature JV3.%M. =ote t+at base classes do not contribute
to t+e declaration space o0 a class- and base inter0aces do not contribute to t+e declaration space o0 an
'* Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
inter0ace. T+us- a derived class or inter0ace is allowed to declare a member wit+ t+e same name as an
in+erited member. #uc+ a member is said to hide t+e in+erited member.
Eac+ delegate declaration creates a new declaration space. =ames are introduced into t+is declaration space
t+roug+ t+pe-para%eters.
Eac+ enumeration declaration creates a new declaration space. =ames are introduced into t+is declaration
space t+roug+ en!%-%e%,er-declarations.
Eac+ ,loc& or switch-,loc& - as well as a for- foreach and !sing statement- creates a declaration space 0or
local variables and local constants called t+e local varia!le declaration space. =ames are introduced into
t+is declaration space t+roug+ local-varia,le-declarations and local-constant-declarations. 10 a bloc7 is t+e
body o0 an instance constructor- met+od- or operator declaration- a get or set accessor 0or an indeer
declaration- or an anonymous 0unction- t+e parameters declared in t+at construct are members o0 t+e bloc7Ps
local variable declaration space. #imilarly- any epression t+at occurs as t+e body o0 an anonymous 0unction
in t+e 0orm o0 a la%,da-e/pression creates a declaration space w+ic+ contains t+e parameters o0 t+e
anonymous 0unction. 1t is an error 0or two members o0 a local variable declaration space to +ave t+e same
name. 1t is an error 0or t+e local variable declaration space o0 a bloc7 and a nested local variable declaration
space to contain elements wit+ t+e same name. T+us- wit+in a nested declaration space it is not possible to
declare a local variable or constant wit+ t+e same name as a local variable or constant in an enclosing
declaration space. 1t is possible 0or two declaration spaces to contain elements wit+ t+e same name as long
as neit+er declaration space contains t+e ot+er.
Eac+ ,loc& or switch-,loc& creates a separate declaration space 0or labels. =ames are introduced into t+is
declaration space t+roug+ la,eled-state%ents- and t+e names are re0erenced t+roug+ goto-state%ents. T+e
la!el declaration space o0 a bloc7 includes any nested bloc7s. T+us- wit+in a nested bloc7 it is not possible
to declare a label wit+ t+e same name as a label in an enclosing bloc7.
T+e tetual order in w+ic+ names are declared is generally o0 no signi0icance. 1n particular- tetual order is not
signi0icant 0or t+e declaration and use o0 namespaces- constants- met+ods- properties- events- indeers-
operators- instance constructors- destructors- static constructors- and types. 2eclaration order is signi0icant in t+e
0ollowing waysC
2eclaration order 0or 0ield declarations and local variable declarations determines t+e order in w+ic+ t+eir
initialiDers Ji0 anyM are eecuted.
5ocal variables must be de0ined be0ore t+ey are used JV3.!M.
2eclaration order 0or enum member declarations JV14.3M is signi0icant w+en constant-e/pression values are
omitted.
T+e declaration space o0 a namespace is Kopen endedL- and two namespace declarations wit+ t+e same 0ully
9uali0ied name contribute to t+e same declaration space. *or eample
names&ace Megacor&.6ata
{
class Customer
{
...
!
!
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. '1
C# Language Specification
names&ace Megacor&.6ata
{
class %rder
{
...
!
!
T+e two namespace declarations above contribute to t+e same declaration space- in t+is case declaring two
classes wit+ t+e 0ully 9uali0ied names Megacor&.6ata.Customer and Megacor&.6ata.%rder. )ecause t+e
two declarations contribute to t+e same declaration space- it would +ave caused a compile<time error i0 eac+
contained a declaration o0 a class wit+ t+e same name.
(s speci0ied above- t+e declaration space o0 a bloc7 includes any nested bloc7s. T+us- in t+e 0ollowing eample-
t+e V and S met+ods result in a compile<time error because t+e name i is declared in t+e outer bloc7 and cannot
be redeclared in t+e inner bloc7. However- t+e H and $ met+ods are valid since t+e two iPs are declared in
separate non<nested bloc7s.
class '
{
void V() {
int i + 3;
i- (true) {
int i + 2;
!
!
void S() {
i- (true) {
int i + 3;
!
int i + 2;
!
void H() {
i- (true) {
int i + 3;
!
i- (true) {
int i + 2;
!
!
void $() {
-or (int i + 3; i D 23; i<<)
H();
-or (int i + 3; i D 23; i<<)
H();
!
!
3.# )ebers
=amespaces and types +ave e!ers. T+e members o0 an entity are generally available t+roug+ t+e use o0 a
9uali0ied name t+at starts wit+ a re0erence to t+e entity- 0ollowed by a K.L to7en- 0ollowed by t+e name o0 t+e
member.
'2 Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
'embers o0 a type are eit+er declared in t+e type declaration or inherited 0rom t+e base class o0 t+e type. 6+en
a type in+erits 0rom a base class- all members o0 t+e base class- ecept instance constructors- destructors and
static constructors- become members o0 t+e derived type. T+e declared accessibility o0 a base class member does
not control w+et+er t+e member is in+eritedRin+eritance etends to any member t+at isnPt an instance
constructor- static constructor- or destructor. However- an in+erited member may not be accessible in a derived
type- eit+er because o0 its declared accessibility JV3.".1M or because it is +idden by a declaration in t+e type itsel0
JV3.!.1.2M.
3.#.1 ;aespace ebers
=amespaces and types t+at +ave no enclosing namespace are members o0 t+e glo!al naespace. T+is
corresponds directly to t+e names declared in t+e global declaration space.
=amespaces and types declared wit+in a namespace are members o0 t+at namespace. T+is corresponds directly
to t+e names declared in t+e declaration space o0 t+e namespace.
=amespaces +ave no access restrictions. 1t is not possible to declare private- protected- or internal namespaces-
and namespace names are always publicly accessible.
3.#.2 Struct ebers
T+e members o0 a struct are t+e members declared in t+e struct and t+e members in+erited 0rom t+e structPs
direct base class System.Ualue1y&e and t+e indirect base class object.
T+e members o0 a simple type correspond directly to t+e members o0 t+e struct type aliased by t+e simple typeC
T+e members o0 sbyte are t+e members o0 t+e System.S:yte struct.
T+e members o0 byte are t+e members o0 t+e System.:yte struct.
T+e members o0 s"ort are t+e members o0 t+e System.$nt2X struct.
T+e members o0 us"ort are t+e members o0 t+e System.;$nt2X struct.
T+e members o0 int are t+e members o0 t+e System.$nt98 struct.
T+e members o0 uint are t+e members o0 t+e System.;$nt98 struct.
T+e members o0 long are t+e members o0 t+e System.$ntXJ struct.
T+e members o0 ulong are t+e members o0 t+e System.;$ntXJ struct.
T+e members o0 c"ar are t+e members o0 t+e System.C"ar struct.
T+e members o0 -loat are t+e members o0 t+e System.Single struct.
T+e members o0 double are t+e members o0 t+e System.6ouble struct.
T+e members o0 decimal are t+e members o0 t+e System.6ecimal struct.
T+e members o0 bool are t+e members o0 t+e System.:oolean struct.
3.#.3 $nueration ebers
T+e members o0 an enumeration are t+e constants declared in t+e enumeration and t+e members in+erited 0rom
t+e enumerationPs direct base class System.)num and t+e indirect base classes System.Ualue1y&e and
object.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. '3
C# Language Specification
3.#.# Class ebers
T+e members o0 a class are t+e members declared in t+e class and t+e members in+erited 0rom t+e base class
Jecept 0or class object w+ic+ +as no base classM. T+e members in+erited 0rom t+e base class include t+e
constants- 0ields- met+ods- properties- events- indeers- operators- and types o0 t+e base class- but not t+e
instance constructors- destructors and static constructors o0 t+e base class. )ase class members are in+erited
wit+out regard to t+eir accessibility.
( class declaration may contain declarations o0 constants- 0ields- met+ods- properties- events- indeers-
operators- instance constructors- destructors- static constructors and types.
T+e members o0 object and string correspond directly to t+e members o0 t+e class types t+ey aliasC
T+e members o0 object are t+e members o0 t+e System.%bject class.
T+e members o0 string are t+e members o0 t+e System.String class.
3.#.& Interface ebers
T+e members o0 an inter0ace are t+e members declared in t+e inter0ace and in all base inter0aces o0 t+e inter0ace.
T+e members in class object are not- strictly spea7ing- members o0 any inter0ace JV13.2M. However- t+e
members in class object are available via member loo7up in any inter0ace type JV!.3M.
3.#.' *rra! ebers
T+e members o0 an array are t+e members in+erited 0rom class System.'rray.
3.#.. 2elegate ebers
T+e members o0 a delegate are t+e members in+erited 0rom class System.6elegate.
3.& )eber access
2eclarations o0 members allow control over member access. T+e accessibility o0 a member is establis+ed by t+e
declared accessibility JV3.".1M o0 t+e member combined wit+ t+e accessibility o0 t+e immediately containing
type- i0 any.
6+en access to a particular member is allowed- t+e member is said to be accessi!le. Conversely- w+en access to
a particular member is disallowed- t+e member is said to be inaccessi!le. (ccess to a member is permitted w+en
t+e tetual location in w+ic+ t+e access ta7es place is included in t+e accessibility domain JV3.".2M o0 t+e
member.
3.&.1 2eclared accessibilit!
T+e declared accessi!ility o0 a member can be one o0 t+e 0ollowingC
Public- w+ic+ is selected by including a &ublic modi0ier in t+e member declaration. T+e intuitive meaning
o0 &ublic is Kaccess not limitedL.
Protected- w+ic+ is selected by including a &rotected modi0ier in t+e member declaration. T+e intuitive
meaning o0 &rotected is Kaccess limited to t+e containing class or types derived 0rom t+e containing
classL.
1nternal- w+ic+ is selected by including an internal modi0ier in t+e member declaration. T+e intuitive
meaning o0 internal is Kaccess limited to t+is programL.
'" Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
Protected internal Jmeaning protected or internalM- w+ic+ is selected by including bot+ a &rotected and an
internal modi0ier in t+e member declaration. T+e intuitive meaning o0 &rotected internal is Kaccess
limited to t+is program or types derived 0rom t+e containing classL.
Private- w+ic+ is selected by including a &rivate modi0ier in t+e member declaration. T+e intuitive
meaning o0 &rivate is Kaccess limited to t+e containing typeL.
2epending on t+e contet in w+ic+ a member declaration ta7es place- only certain types o0 declared accessibility
are permitted. *urt+ermore- w+en a member declaration does not include any access modi0iers- t+e contet in
w+ic+ t+e declaration ta7es place determines t+e de0ault declared accessibility.
=amespaces implicitly +ave &ublic declared accessibility. =o access modi0iers are allowed on namespace
declarations.
Types declared in compilation units or namespaces can +ave &ublic or internal declared accessibility
and de0ault to internal declared accessibility.
Class members can +ave any o0 t+e 0ive 7inds o0 declared accessibility and de0ault to &rivate declared
accessibility. J=ote t+at a type declared as a member o0 a class can +ave any o0 t+e 0ive 7inds o0 declared
accessibility- w+ereas a type declared as a member o0 a namespace can +ave only &ublic or internal
declared accessibility.M
#truct members can +ave &ublic- internal- or &rivate declared accessibility and de0ault to &rivate
declared accessibility because structs are implicitly sealed. #truct members introduced in a struct Jt+at is-
not in+erited by t+at structM cannot +ave &rotected or &rotected internal declared accessibility.
J=ote t+at a type declared as a member o0 a struct can +ave &ublic- internal- or &rivate declared
accessibility- w+ereas a type declared as a member o0 a namespace can +ave only &ublic or internal
declared accessibility.M
1nter0ace members implicitly +ave &ublic declared accessibility. =o access modi0iers are allowed on
inter0ace member declarations.
Enumeration members implicitly +ave &ublic declared accessibility. =o access modi0iers are allowed on
enumeration member declarations.
3.&.2 *ccessibilit! doains
T+e accessi!ility doain o0 a member consists o0 t+e Jpossibly dis&ointM sections o0 program tet in w+ic+
access to t+e member is permitted. *or purposes o0 de0ining t+e accessibility domain o0 a member- a member is
said to be top-level i0 it is not declared wit+in a type- and a member is said to be nested i0 it is declared wit+in
anot+er type. *urt+ermore- t+e progra te,t o0 a program is de0ined as all program tet contained in all source
0iles o0 t+e program- and t+e program tet o0 a type is de0ined as all program tet contained between t+e opening
and closing K{L and K!L to7ens in t+e class-,od+- str!ct-,od+- interface-,od+- or en!%-,od+ o0 t+e type
Jincluding- possibly- types t+at are nested wit+in t+e typeM.
T+e accessibility domain o0 a prede0ined type Jsuc+ as object- int- or doubleM is unlimited.
T+e accessibility domain o0 a top<level unbound type 1 JV4.4.3M t+at is declared in a program * is de0ined as
0ollowsC
10 t+e declared accessibility o0 1 is &ublic- t+e accessibility domain o0 1 is t+e program tet o0 * and any
program t+at re0erences *.
10 t+e declared accessibility o0 1 is internal- t+e accessibility domain o0 1 is t+e program tet o0 *.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. '
C# Language Specification
*rom t+ese de0initions it 0ollows t+at t+e accessibility domain o0 a top<level unbound type is always at least t+e
program tet o0 t+e program in w+ic+ t+at type is declared.
T+e accessibility domain 0or a constructed type 1D'
2
...'
N
E is t+e intersection o0 t+e accessibility domain o0
t+e unbound generic type 1 and t+e accessibility domains o0 t+e type arguments '
2
...'
N
.
T+e accessibility domain o0 a nested member M declared in a type 1 wit+in a program * is de0ined as 0ollows
Jnoting t+at M itsel0 may possibly be a typeMC
10 t+e declared accessibility o0 M is &ublic- t+e accessibility domain o0 M is t+e accessibility domain o0 1.
10 t+e declared accessibility o0 M is &rotected internal- let 6 be t+e union o0 t+e program tet o0 * and
t+e program tet o0 any type derived 0rom 1- w+ic+ is declared outside *. T+e accessibility domain o0 M is
t+e intersection o0 t+e accessibility domain o0 1 wit+ 6.
10 t+e declared accessibility o0 M is &rotected- let 6 be t+e union o0 t+e program tet o0 1 and t+e program
tet o0 any type derived 0rom 1. T+e accessibility domain o0 M is t+e intersection o0 t+e accessibility domain
o0 1 wit+ 6.
10 t+e declared accessibility o0 M is internal- t+e accessibility domain o0 M is t+e intersection o0 t+e
accessibility domain o0 1 wit+ t+e program tet o0 *.
10 t+e declared accessibility o0 M is &rivate- t+e accessibility domain o0 M is t+e program tet o0 1.
*rom t+ese de0initions it 0ollows t+at t+e accessibility domain o0 a nested member is always at least t+e program
tet o0 t+e type in w+ic+ t+e member is declared. *urt+ermore- it 0ollows t+at t+e accessibility domain o0 a
member is never more inclusive t+an t+e accessibility domain o0 t+e type in w+ic+ t+e member is declared.
1n intuitive terms- w+en a type or member M is accessed- t+e 0ollowing steps are evaluated to ensure t+at t+e
access is permittedC
*irst- i0 M is declared wit+in a type Jas opposed to a compilation unit or a namespaceM- a compile<time error
occurs i0 t+at type is not accessible.
T+en- i0 M is &ublic- t+e access is permitted.
/t+erwise- i0 M is &rotected internal- t+e access is permitted i0 it occurs wit+in t+e program in w+ic+ M
is declared- or i0 it occurs wit+in a class derived 0rom t+e class in w+ic+ M is declared and ta7es place
t+roug+ t+e derived class type JV3.".3M.
/t+erwise- i0 M is &rotected- t+e access is permitted i0 it occurs wit+in t+e class in w+ic+ M is declared- or
i0 it occurs wit+in a class derived 0rom t+e class in w+ic+ M is declared and ta7es place t+roug+ t+e derived
class type JV3.".3M.
/t+erwise- i0 M is internal- t+e access is permitted i0 it occurs wit+in t+e program in w+ic+ M is declared.
/t+erwise- i0 M is &rivate- t+e access is permitted i0 it occurs wit+in t+e type in w+ic+ M is declared.
/t+erwise- t+e type or member is inaccessible- and a compile<time error occurs.
1n t+e eample
&ublic class '
{
&ublic static int I;
internal static int `;
&rivate static int P;
!
'' Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
internal class :
{
&ublic static int I;
internal static int `;
&rivate static int P;
&ublic class C
{
&ublic static int I;
internal static int `;
&rivate static int P;
!
&rivate class 6
{
&ublic static int I;
internal static int `;
&rivate static int P;
!
!
t+e classes and members +ave t+e 0ollowing accessibility domainsC
T+e accessibility domain o0 ' and '.I is unlimited.
T+e accessibility domain o0 '.`- :- :.I- :.`- :.C- :.C.I- and :.C.` is t+e program tet o0 t+e containing
program.
T+e accessibility domain o0 '.P is t+e program tet o0 '.
T+e accessibility domain o0 :.P and :.6 is t+e program tet o0 :- including t+e program tet o0 :.C and
:.6.
T+e accessibility domain o0 :.C.P is t+e program tet o0 :.C.
T+e accessibility domain o0 :.6.I and :.6.` is t+e program tet o0 :- including t+e program tet o0 :.C
and :.6.
T+e accessibility domain o0 :.6.P is t+e program tet o0 :.6.
(s t+e eample illustrates- t+e accessibility domain o0 a member is never larger t+an t+at o0 a containing type.
*or eample- even t+oug+ all I members +ave public declared accessibility- all but '.I +ave accessibility
domains t+at are constrained by a containing type.
(s described in V3.4- all members o0 a base class- ecept 0or instance constructors- destructors and static
constructors- are in+erited by derived types. T+is includes even private members o0 a base class. However- t+e
accessibility domain o0 a private member includes only t+e program tet o0 t+e type in w+ic+ t+e member is
declared. 1n t+e eample
class '
{
int #;
static void V(: b) {
b.# + 2; .. %(
!
!
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. '7
C# Language Specification
class :/ '
{
static void V(: b) {
b.# + 2; .. )rror # not accessible
!
!
t+e : class in+erits t+e private member # 0rom t+e ' class. )ecause t+e member is private- it is only accessible
wit+in t+e class-,od+ o0 '. T+us- t+e access to b.# succeeds in t+e '.V met+od- but 0ails in t+e :.V met+od.
3.&.3 Protected access for instance ebers
6+en a &rotected instance member is accessed outside t+e program tet o0 t+e class in w+ic+ it is declared-
and w+en a &rotected internal instance member is accessed outside t+e program tet o0 t+e program in
w+ic+ it is declared- t+e access must ta7e place wit+in a class declaration t+at derives 0rom t+e class in w+ic+ it
is declared. *urt+ermore- t+e access is re9uired to ta7e place thro!gh an instance o0 t+at derived class type or a
class type constructed 0rom it. T+is restriction prevents one derived class 0rom accessing protected members o0
ot+er derived classes- even w+en t+e members are in+erited 0rom t+e same base class.
5et : be a base class t+at declares a protected instance member M- and let 6 be a class t+at derives 0rom :.
6it+in t+e class-,od+ o0 6- access to M can ta7e one o0 t+e 0ollowing 0ormsC
(n un9uali0ied t+pe-na%e or pri%ar+-e/pression o0 t+e 0orm M.
( pri%ar+-e/pression o0 t+e 0orm ).M- provided t+e type o0 ) is 1 or a class derived 0rom 1- w+ere 1 is t+e
class type 6- or a class type constructed 0rom 6
( pri%ar+-e/pression o0 t+e 0orm base.M.
1n addition to t+ese 0orms o0 access- a derived class can access a protected instance constructor o0 a base class in
a constr!ctor-initiali-er JV1..11.1M.
1n t+e eample
&ublic class '
{
&rotected int #;
static void V(' a : b) {
a.# + 2; .. %(
b.# + 2; .. %(
!
!
&ublic class :/ '
{
static void V(' a : b) {
a.# + 2; .. )rror must access t"roug" instance o- :
b.# + 2; .. %(
!
!
wit+in '- it is possible to access # t+roug+ instances o0 bot+ ' and :- since in eit+er case t+e access ta7es place
thro!gh an instance o0 ' or a class derived 0rom '. However- wit+in :- it is not possible to access # t+roug+ an
instance o0 '- since ' does not derive 0rom :.
1n t+e eample
'$ Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
class CD1E
{
&rotected 1 #;
!
class 6D1E/ CD1E
{
static void V() {
6D1E dt + ne, 6D1E();
6DintE di + ne, 6DintE();
6DstringE ds + ne, 6DstringE();
dt.# + de-ault(1);
di.# + 289;
ds.# + "test";
!
!
t+e t+ree assignments to # are permitted because t+ey all ta7e place t+roug+ instances o0 class types constructed
0rom t+e generic type.
3.&.# *ccessibilit! constraints
#everal constructs in t+e C# language re9uire a type to be at least as accessi!le as a member or anot+er type. (
type 1 is said to be at least as accessible as a member or type M i0 t+e accessibility domain o0 1 is a superset o0
t+e accessibility domain o0 M. 1n ot+er words- 1 is at least as accessible as M i0 1 is accessible in all contets in
w+ic+ M is accessible.
T+e 0ollowing accessibility constraints eistC
T+e direct base class o0 a class type must be at least as accessible as t+e class type itsel0.
T+e eplicit base inter0aces o0 an inter0ace type must be at least as accessible as t+e inter0ace type itsel0.
T+e return type and parameter types o0 a delegate type must be at least as accessible as t+e delegate type
itsel0.
T+e type o0 a constant must be at least as accessible as t+e constant itsel0.
T+e type o0 a 0ield must be at least as accessible as t+e 0ield itsel0.
T+e return type and parameter types o0 a met+od must be at least as accessible as t+e met+od itsel0.
T+e type o0 a property must be at least as accessible as t+e property itsel0.
T+e type o0 an event must be at least as accessible as t+e event itsel0.
T+e type and parameter types o0 an indeer must be at least as accessible as t+e indeer itsel0.
T+e return type and parameter types o0 an operator must be at least as accessible as t+e operator itsel0.
T+e parameter types o0 an instance constructor must be at least as accessible as t+e instance constructor
itsel0.
1n t+e eample
class ' {...!
&ublic class :/ ' {...!
t+e : class results in a compile<time error because ' is not at least as accessible as :.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. '!
C# Language Specification
5i7ewise- in t+e eample
class ' {...!
&ublic class :
{
' V() {...!
internal ' S() {...!
&ublic ' H() {...!
!
t+e H met+od in : results in a compile<time error because t+e return type ' is not at least as accessible as t+e
met+od.
3.' Signatures and o"erloading
'et+ods- instance constructors- indeers- and operators are c+aracteriDed by t+eir signat-resC
T+e signature o0 a met+od consists o0 t+e name o0 t+e met+od- t+e number o0 type parameters and t+e type
and 7ind Jvalue- re0erence- or outputM o0 eac+ o0 its 0ormal parameters- considered in t+e order le0t to rig+t.
*or t+ese purposes- any type parameter o0 t+e met+od t+at occurs in t+e type o0 a 0ormal parameter is
identi0ied not by its name- but by its ordinal position in t+e type argument list o0 t+e met+od. T+e signature
o0 a met+od speci0ically does not include t+e return type- t+e &arams modi0ier t+at may be speci0ied 0or t+e
rig+t<most parameter- nor t+e optional type parameter constraints.
T+e signature o0 an instance constructor consists o0 t+e type and 7ind Jvalue- re0erence- or outputM o0 eac+ o0
its 0ormal parameters- considered in t+e order le0t to rig+t. T+e signature o0 an instance constructor
speci0ically does not include t+e &arams modi0ier t+at may be speci0ied 0or t+e rig+t<most parameter.
T+e signature o0 an indeer consists o0 t+e type o0 eac+ o0 its 0ormal parameters- considered in t+e order le0t
to rig+t. T+e signature o0 an indeer speci0ically does not include t+e element type- nor does it include t+e
&arams modi0ier t+at may be speci0ied 0or t+e rig+t<most parameter.
T+e signature o0 an operator consists o0 t+e name o0 t+e operator and t+e type o0 eac+ o0 its 0ormal
parameters- considered in t+e order le0t to rig+t. T+e signature o0 an operator speci0ically does not include
t+e result type.
#ignatures are t+e enabling mec+anism 0or overloading o0 members in classes- structs- and inter0acesC
/verloading o0 met+ods permits a class- struct- or inter0ace to declare multiple met+ods wit+ t+e same name-
provided t+eir signatures are uni9ue wit+in t+at class- struct- or inter0ace.
/verloading o0 instance constructors permits a class or struct to declare multiple instance constructors-
provided t+eir signatures are uni9ue wit+in t+at class or struct.
/verloading o0 indeers permits a class- struct- or inter0ace to declare multiple indeers- provided t+eir
signatures are uni9ue wit+in t+at class- struct- or inter0ace.
/verloading o0 operators permits a class or struct to declare multiple operators wit+ t+e same name-
provided t+eir signatures are uni9ue wit+in t+at class or struct.
(lt+oug+ out and re- parameter modi0iers are considered part o0 a signature- members declared in a single
type cannot di00er in signature solely by re- and out. ( compile<time error occurs i0 two members are declared
in t+e same type wit+ signatures t+at would be t+e same i0 all parameters in bot+ met+ods wit+ out modi0iers
were c+anged to re- modi0iers. *or ot+er purposes o0 signature matc+ing Je.g.- +iding or overridingM- re- and
out are considered part o0 t+e signature and do not matc+ eac+ ot+er. JT+is restriction is to allow C# programs
7* Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
to be easily translated to run on t+e Common 5anguage 1n0rastructure JC51M- w+ic+ does not provide a way to
de0ine met+ods t+at di00er solely in re- and out.M
T+e 0ollowing eample s+ows a set o0 overloaded met+od declarations along wit+ t+eir signatures.
inter-ace $1est
{
void V(); .. V()
void V(int #); .. V(int)
void V(re- int #); .. V(re- int)
void V(out int #); .. V(out int) error
void V(int # int y); .. V(int int)
int V(string s); .. V(string)
int V(int #); .. V(int) error
void V(string45 a); .. V(string45)
void V(&arams string45 a); .. V(string45) error
!
=ote t+at any re- and out parameter modi0iers JV1..%.1M are part o0 a signature. T+us- V(int) and V(re-
int) are uni9ue signatures. However- V(re- int) and V(out int) cannot be declared wit+in t+e same
inter0ace because t+eir signatures di00er solely by re- and out. (lso- note t+at t+e return type and t+e &arams
modi0ier are not part o0 a signature- so it is not possible to overload solely based on return type or on t+e
inclusion or eclusion o0 t+e &arams modi0ier. (s suc+- t+e declarations o0 t+e met+ods V(int) and V(&arams
string45) identi0ied above result in a compile<time error.
3.. Scopes
T+e scope o0 a name is t+e region o0 program tet wit+in w+ic+ it is possible to re0er to t+e entity declared by
t+e name wit+out 9uali0ication o0 t+e name. #copes can be nested- and an inner scope may redeclare t+e
meaning o0 a name 0rom an outer scope Jt+is does not- +owever- remove t+e restriction imposed by V3.3 t+at
wit+in a nested bloc7 it is not possible to declare a local variable wit+ t+e same name as a local variable in an
enclosing bloc7M. T+e name 0rom t+e outer scope is t+en said to be hidden in t+e region o0 program tet covered
by t+e inner scope- and access to t+e outer name is only possible by 9uali0ying t+e name.
T+e scope o0 a namespace member declared by a na%espace-%e%,er-declaration JV$."M wit+ no enclosing
na%espace-declaration is t+e entire program tet.
T+e scope o0 a namespace member declared by a na%espace-%e%,er-declaration wit+in a na%espace-
declaration w+ose 0ully 9uali0ied name is N is t+e na%espace-,od+ o0 every na%espace-declaration w+ose
0ully 9uali0ied name is N or starts wit+ N- 0ollowed by a period.
T+e scope o0 name de0ined by an e/tern-alias-directive etends over t+e !sing-directives- glo,al-attri,!tes
and na%espace-%e%,er-declarations o0 its immediately containing compilation unit or namespace body.
(n e/tern-alias-directive does not contribute any new members to t+e underlying declaration space. 1n ot+er
words- an e/tern-alias-directive is not transitive- but- rat+er- a00ects only t+e compilation unit or namespace
body in w+ic+ it occurs.
T+e scope o0 a name de0ined or imported by a !sing-directive JV$.4M etends over t+e na%espace-%e%,er-
declarations o0 t+e co%pilation-!nit or na%espace-,od+ in w+ic+ t+e !sing-directive occurs. ( !sing-
directive may ma7e Dero or more namespace or type names available wit+in a particular co%pilation-!nit or
na%espace-,od+- but does not contribute any new members to t+e underlying declaration space. 1n ot+er
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 71
C# Language Specification
words- a !sing-directive is not transitive but rat+er a00ects only t+e co%pilation-!nit or na%espace-,od+ in
w+ic+ it occurs.
T+e scope o0 a type parameter declared by a t+pe-para%eter-list on a class-declaration JV1..1M is t+e class-
,ase- t+pe-para%eter-constraints-cla!ses- and class-,od+ o0 t+at class-declaration.
T+e scope o0 a type parameter declared by a t+pe-para%eter-list on a str!ct-declaration JV11.1M is t+e
str!ct-interfaces- t+pe-para%eter-constraints-cla!ses- and str!ct-,od+ o0 t+at str!ct-declaration.
T+e scope o0 a type parameter declared by a t+pe-para%eter-list on an interface-declaration JV13.1M is t+e
interface-,ase- t+pe-para%eter-constraints-cla!ses- and interface-,od+ o0 t+at interface-declaration.
T+e scope o0 a type parameter declared by a t+pe-para%eter-list on a delegate-declaration JV1".1M is t+e
ret!rn-t+pe- for%al-para%eter-list- and t+pe-para%eter-constraints-cla!ses o0 t+at delegate-declaration.
T+e scope o0 a member declared by a class-%e%,er-declaration JV1..1.%M is t+e class-,od+ in w+ic+ t+e
declaration occurs. 1n addition- t+e scope o0 a class member etends to t+e class-,od+ o0 t+ose derived
classes t+at are included in t+e accessibility domain JV3.".2M o0 t+e member.
T+e scope o0 a member declared by a str!ct-%e%,er-declaration JV11.2M is t+e str!ct-,od+ in w+ic+ t+e
declaration occurs.
T+e scope o0 a member declared by an en!%-%e%,er-declaration JV14.3M is t+e en!%-,od+ in w+ic+ t+e
declaration occurs.
T+e scope o0 a parameter declared in a %ethod-declaration JV1..%M is t+e %ethod-,od+ o0 t+at %ethod-
declaration.
T+e scope o0 a parameter declared in an inde/er-declaration JV1..$M is t+e accessor-declarations o0 t+at
inde/er-declaration.
T+e scope o0 a parameter declared in an operator-declaration JV1..1.M is t+e ,loc& o0 t+at operator-
declaration.
T+e scope o0 a parameter declared in a constr!ctor-declaration JV1..11M is t+e constr!ctor-initiali-er and
,loc& o0 t+at constr!ctor-declaration.
T+e scope o0 a parameter declared in a la%,da-e/pression JVM is t+e la%,da-e/pression-,od+ o0 t+at
la%,da-e/pression
T+e scope o0 a parameter declared in an anon+%o!s-%ethod-e/pression JVM is t+e ,loc& o0 t+at anon+%o!s-
%ethod-e/pression.
T+e scope o0 a label declared in a la,eled-state%ent JV3.4M is t+e ,loc& in w+ic+ t+e declaration occurs.
T+e scope o0 a local variable declared in a local-varia,le-declaration JV3.".1M is t+e bloc7 in w+ic+ t+e
declaration occurs.
T+e scope o0 a local variable declared in a switch-,loc& o0 a s,itc" statement JV3.!.2M is t+e switch-,loc&.
T+e scope o0 a local variable declared in a for-initiali-er o0 a -or statement JV3.3.3M is t+e for-initiali-er- t+e
for-condition- t+e for-iterator- and t+e contained state%ent o0 t+e -or statement.
T+e scope o0 a local constant declared in a local-constant-declaration JV3.".2M is t+e bloc7 in w+ic+ t+e
declaration occurs. 1t is a compile<time error to re0er to a local constant in a tetual position t+at precedes its
constant-declarator.
72 Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
T+e scope o0 a variable declared as part o0 a foreach-state%ent- !sing-state%ent- loc&-state%ent or 8!er+-
e/pression is determined by t+e epansion o0 t+e given construct.
6it+in t+e scope o0 a namespace- class- struct- or enumeration member it is possible to re0er to t+e member in a
tetual position t+at precedes t+e declaration o0 t+e member. *or eample
class '
{
void V() {
i + 2;
!
int i + 3;
!
Here- it is valid 0or V to re0er to i be0ore it is declared.
6it+in t+e scope o0 a local variable- it is a compile<time error to re0er to t+e local variable in a tetual position
t+at precedes t+e local-varia,le-declarator o0 t+e local variable. *or eample
class '
{
int i + 3;
void V() {
i + 2; .. )rror use &recedes declaration
int i;
i + 8;
!
void S() {
int j + (j + 2); .. Ualid
!
void H() {
int a + 2 b + <<a; .. Ualid
!
!
1n t+e V met+od above- t+e 0irst assignment to i speci0ically does not re0er to t+e 0ield declared in t+e outer
scope. ;at+er- it re0ers to t+e local variable and it results in a compile<time error because it tetually precedes
t+e declaration o0 t+e variable. 1n t+e S met+od- t+e use o0 j in t+e initialiDer 0or t+e declaration o0 j is valid
because t+e use does not precede t+e local-varia,le-declarator. 1n t+e H met+od- a subse9uent local-varia,le-
declarator correctly re0ers to a local variable declared in an earlier local-varia,le-declarator wit+in t+e same
local-varia,le-declaration.
T+e scoping rules 0or local variables are designed to guarantee t+at t+e meaning o0 a name used in an epression
contet is always t+e same wit+in a bloc7. 10 t+e scope o0 a local variable were to etend only 0rom its
declaration to t+e end o0 t+e bloc7- t+en in t+e eample above- t+e 0irst assignment would assign to t+e instance
variable and t+e second assignment would assign to t+e local variable- possibly leading to compile<time errors i0
t+e statements o0 t+e bloc7 were later to be rearranged.
T+e meaning o0 a name wit+in a bloc7 may di00er based on t+e contet in w+ic+ t+e name is used. 1n t+e
eample
using System;
class ' {!
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 73
C# Language Specification
class 1est
{
static void Main() {
string ' + ""ello ,orld";
string s + '; .. e#&ression conte#t
1y&e t + ty&eo-('); .. ty&e conte#t
Console.WriteLine(s); .. ,rites ""ello ,orld"
Console.WriteLine(t); .. ,rites "'"
!
!
t+e name ' is used in an epression contet to re0er to t+e local variable ' and in a type contet to re0er to t+e
class '.
3...1 ;ae -iding
T+e scope o0 an entity typically encompasses more program tet t+an t+e declaration space o0 t+e entity. 1n
particular- t+e scope o0 an entity may include declarations t+at introduce new declaration spaces containing
entities o0 t+e same name. #uc+ declarations cause t+e original entity to become hidden. Conversely- an entity is
said to be visi!le w+en it is not +idden.
=ame +iding occurs w+en scopes overlap t+roug+ nesting and w+en scopes overlap t+roug+ in+eritance. T+e
c+aracteristics o0 t+e two types o0 +iding are described in t+e 0ollowing sections.
3..1.1 -iding through nesting
=ame +iding t+roug+ nesting can occur as a result o0 nesting namespaces or types wit+in namespaces- as a result
o0 nesting types wit+in classes or structs- and as a result o0 parameter and local variable declarations.
1n t+e eample
class '
{
int i + 3;
void V() {
int i + 2;
!
void S() {
i + 2;
!
!
wit+in t+e V met+od- t+e instance variable i is +idden by t+e local variable i- but wit+in t+e S met+od- i still
re0ers to t+e instance variable.
6+en a name in an inner scope +ides a name in an outer scope- it +ides all overloaded occurrences o0 t+at name.
1n t+e eample
class %uter
{
static void V(int i) {!
static void V(string s) {!
7" Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
class $nner
{
void S() {
V(2); .. $nvo(es %uter.$nner.V
V("Hello"); .. )rror
!
static void V(long l) {!
!
!
t+e call V(2) invo7es t+e V declared in $nner because all outer occurrences o0 V are +idden by t+e inner
declaration. *or t+e same reason- t+e call V("Hello") results in a compile<time error.
3..1.2 -iding through inheritance
=ame +iding t+roug+ in+eritance occurs w+en classes or structs redeclare names t+at were in+erited 0rom base
classes. T+is type o0 name +iding ta7es one o0 t+e 0ollowing 0ormsC
( constant- 0ield- property- event- or type introduced in a class or struct +ides all base class members wit+
t+e same name.
( met+od introduced in a class or struct +ides all non<met+od base class members wit+ t+e same name- and
all base class met+ods wit+ t+e same signature Jmet+od name and parameter count- modi0iers- and typesM.
(n indeer introduced in a class or struct +ides all base class indeers wit+ t+e same signature Jparameter
count and typesM.
T+e rules governing operator declarations JV1..1.M ma7e it impossible 0or a derived class to declare an operator
wit+ t+e same signature as an operator in a base class. T+us- operators never +ide one anot+er.
Contrary to +iding a name 0rom an outer scope- +iding an accessible name 0rom an in+erited scope causes a
warning to be reported. 1n t+e eample
class :ase
{
&ublic void V() {!
!
class 6erived/ :ase
{
&ublic void V() {! .. Warning "iding an in"erited name
!
t+e declaration o0 V in 6erived causes a warning to be reported. Hiding an in+erited name is speci0ically not an
error- since t+at would preclude separate evolution o0 base classes. *or eample- t+e above situation mig+t +ave
come about because a later version o0 :ase introduced an V met+od t+at wasnPt present in an earlier version o0
t+e class. Had t+e above situation been an error- t+en an+ c+ange made to a base class in a separately versioned
class library could potentially cause derived classes to become invalid.
T+e warning caused by +iding an in+erited name can be eliminated t+roug+ use o0 t+e ne, modi0ierC
class :ase
{
&ublic void V() {!
!
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 7
C# Language Specification
class 6erived/ :ase
{
ne, &ublic void V() {!
!
T+e ne, modi0ier indicates t+at t+e V in 6erived is KnewL- and t+at it is indeed intended to +ide t+e in+erited
member.
( declaration o0 a new member +ides an in+erited member only wit+in t+e scope o0 t+e new member.
class :ase
{
&ublic static void V() {!
!
class 6erived/ :ase
{
ne, &rivate static void V() {! .. Hides :ase.V in 6erived only
!
class More6erived/ 6erived
{
static void S() { V(); ! .. $nvo(es :ase.V
!
1n t+e eample above- t+e declaration o0 V in 6erived +ides t+e V t+at was in+erited 0rom :ase- but since t+e
new V in 6erived +as private access- its scope does not etend to More6erived. T+us- t+e call V() in
More6erived.S is valid and will invo7e :ase.V.
3.0 ;aespace and t!pe naes
#everal contets in a C# program re9uire a na%espace-na%e or a t+pe-na%e to be speci0ied.
na%espace-na%e.
na%espace-or-t+pe-na%e
t+pe-na%e.
na%espace-or-t+pe-na%e
na%espace-or-t+pe-na%e.
identifier t+pe-arg!%ent-listopt
na%espace-or-t+pe-na%e 9 identifier t+pe-arg!%ent-listop
8!alified-alias-%e%,er
( na%espace-na%e is a na%espace-or-t+pe-na%e t+at re0ers to a namespace. *ollowing resolution as described
below- t+e na%espace-or-t+pe-na%e o0 a na%espace-na%e must re0er to a namespace- or ot+erwise a compile<
time error occurs. =o type arguments JV4.4.1M can be present in a na%espace-na%e Jonly types can +ave type
argumentsM.
( t+pe-na%e is a na%espace-or-t+pe-na%e t+at re0ers to a type. *ollowing resolution as described below- t+e
na%espace-or-t+pe-na%e o0 a t+pe-na%e must re0er to a type- or ot+erwise a compile<time error occurs.
10 t+e na%espace-or-t+pe-na%e is a 9uali0ied<alias<member its meaning is as described in V$.!. /t+erwise- a
na%espace-or-t+pe-na%e +as one o0 0our 0ormsC
$
$D'
2
... '
a
E
N.$
7' Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
N.$D'
2
... '
a
E
w+ere $ is a single identi0ier- N is a na%espace-or-t+pe-na%e and D'
2
... '
a
E is an optional t+pe-arg!%ent-list.
6+en no t+pe-arg!%ent-list is speci0ied- consider a to be Dero.
T+e meaning o0 a na%espace-or-t+pe-na%e is determined as 0ollowsC
10 t+e na%espace-or-t+pe-na%e is o0 t+e 0orm $ or o0 t+e 0orm $D'
2
... '
a
EC
o 10 a is Dero and t+e na%espace-or-t+pe-na%e appears wit+in t+e body o0 a generic met+od declaration
JV1..%M and i0 t+at declaration includes a type parameter JV1..1.3M wit+ name $- t+en t+e na%espace-or-
t+pe-na%e re0ers to t+at type parameter.
o /t+erwise- i0 t+e na%espace-or-t+pe-na%e appears wit+in t+e body o0 a type declaration- t+en 0or eac+
instance type 1 JV1..3.1M- starting wit+ t+e instance type o0 t+at type declaration and continuing wit+ t+e
instance type o0 eac+ enclosing class or struct declaration Ji0 anyMC
10 a is Dero and t+e declaration o0 1 includes a type parameter wit+ name $- t+en t+e na%espace-or-
t+pe-na%e re0ers to t+at type parameter.
/t+erwise- i0 1 or any o0 its base types contain a nested accessible type +aving name $ and a type
parameters- t+en t+e na%espace-or-t+pe-na%e re0ers to t+at type constructed wit+ t+e given type
arguments. 10 t+ere is more t+an one suc+ type- t+e type declared wit+in t+e more derived type is
selected. =ote t+at non<type members Jconstants- 0ields- met+ods- properties- indeers- operators-
instance constructors- destructors- and static constructorsM and type members wit+ a di00erent
number o0 type parameters are ignored w+en determining t+e meaning o0 t+e na%espace-or-t+pe-
na%e.
o 10 t+e previous steps w+ere unsuccess0ul t+en- 0or eac+ namespace N- starting wit+ t+e namespace in
w+ic+ t+e na%espace-or-t+pe-na%e occurs- continuing wit+ eac+ enclosing namespace Ji0 anyM- and
ending wit+ t+e global namespace- t+e 0ollowing steps are evaluated until an entity is locatedC
10 a is Dero and $ is t+e name o0 a namespace in N- t+enC
o 10 t+e location w+ere t+e na%espace-or-t+pe-na%e occurs is enclosed by a namespace
declaration 0or N and t+e namespace declaration contains an e/tern-alias-directive or !sing-
alias-directive t+at associates t+e name $ wit+ a namespace or type- t+en t+e na%espace-or-
t+pe-na%e is ambiguous and a compile<time error occurs.
o /t+erwise- t+e na%espace-or-t+pe-na%e re0ers to t+e namespace named $ in N.
/t+erwise- i0 N contains an accessible type +aving name $ and a type parameters- t+enC
o 10 a is Dero and t+e location w+ere t+e na%espace-or-t+pe-na%e occurs is enclosed by a
namespace declaration 0or N and t+e namespace declaration contains an e/tern-alias-directive or
!sing-alias-directive t+at associates t+e name $ wit+ a namespace or type- t+en t+e na%espace-
or-t+pe-na%e is ambiguous and a compile<time error occurs.
o /t+erwise- t+e na%espace-or-t+pe-na%e re0ers to t+e type constructed wit+ t+e given type
arguments.
/t+erwise- i0 t+e location w+ere t+e na%espace-or-t+pe-na%e occurs is enclosed by a namespace
declaration 0or NC
o 10 a is Dero and t+e namespace declaration contains an e/tern-alias-directive or !sing-alias-
directive t+at associates t+e name $ wit+ an imported namespace or type- t+en t+e na%espace-
or-t+pe-na%e re0ers to t+at namespace or type.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 77
C# Language Specification
o /t+erwise- i0 t+e namespaces imported by t+e !sing-na%espace-directives o0 t+e namespace
declaration contain eactly one type +aving name $ and a type parameters- t+en t+e na%espace-
or-t+pe-na%e re0ers to t+at type constructed wit+ t+e given type arguments.
o /t+erwise- i0 t+e namespaces imported by t+e !sing-na%espace-directives o0 t+e namespace
declaration contain more t+an one type +aving name $ and a type parameters- t+en t+e
na%espace-or-t+pe-na%e is ambiguous and an error occurs.
o /t+erwise- t+e na%espace-or-t+pe-na%e is unde0ined and a compile<time error occurs.
/t+erwise- t+e na%espace-or-t+pe-na%e is o0 t+e 0orm N.$ or o0 t+e 0orm N.$D'
2
... '
a
E. N is 0irst
resolved as a na%espace-or-t+pe-na%e. 10 t+e resolution o0 N is not success0ul- a compile<time error occurs.
/t+erwise- N.$ or N.$D'
2
... '
a
E is resolved as 0ollowsC
o 10 a is Dero and N re0ers to a namespace and N contains a nested namespace wit+ name $- t+en t+e
na%espace-or-t+pe-na%e re0ers to t+at nested namespace.
o /t+erwise- i0 N re0ers to a namespace and N contains an accessible type +aving name $ and a type
parameters- t+en t+e na%espace-or-t+pe-na%e re0ers to t+at type constructed wit+ t+e given type
arguments.
o /t+erwise- i0 N re0ers to a Jpossibly constructedM class or struct type and N contains a nested accessible
type +aving name $ and a type parameters- t+en t+e na%espace-or-t+pe-na%e re0ers to t+at type
constructed wit+ t+e given type arguments. 10 t+ere is more t+an one suc+ type- t+e type declared wit+in
t+e more derived type is selected.
o /t+erwise- N.$ is an invalid na%espace-or-t+pe-na%e- and a compile<time error occurs.
( na%espace-or-t+pe-na%e is permitted to re0erence a static class JV1..1.1.3M only i0
T+e na%espace-or-t+pe-na%e is t+e 1 in a na%espace-or-t+pe-na%e o0 t+e 0orm 1.$- or
T+e na%espace-or-t+pe-na%e is t+e 1 in a t+peof-e/pression JV!.".11M o0 t+e 0orm ty&eo-(1).
3.0.1 ,ull! 7ualified naes
Every namespace and type +as a f-lly 4-alified nae- w+ic+ uni9uely identi0ies t+e namespace or type amongst
all ot+ers. T+e 0ully 9uali0ied name o0 a namespace or type N is determined as 0ollowsC
10 N is a member o0 t+e global namespace- its 0ully 9uali0ied name is N.
/t+erwise- its 0ully 9uali0ied name is S.N- w+ere S is t+e 0ully 9uali0ied name o0 t+e namespace or type in
w+ic+ N is declared.
1n ot+er words- t+e 0ully 9uali0ied name o0 N is t+e complete +ierarc+ical pat+ o0 identi0iers t+at lead to N-
starting 0rom t+e global namespace. )ecause every member o0 a namespace or type must +ave a uni9ue name- it
0ollows t+at t+e 0ully 9uali0ied name o0 a namespace or type is always uni9ue.
T+e eample below s+ows several namespace and type declarations along wit+ t+eir associated 0ully 9uali0ied
names.
class ' {! .. '
names&ace I .. I
{
class : .. I.:
{
class C {! .. I.:.C
!
7$ Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
names&ace ` .. I.`
{
class 6 {! .. I.`.6
!
!
names&ace I.` .. I.`
{
class ) {! .. I.`.)
!
3.1 *utoatic eor! anageent
C# employs automatic memory management- w+ic+ 0rees developers 0rom manually allocating and 0reeing t+e
memory occupied by ob&ects. (utomatic memory management policies are implemented by a gar!age collector.
T+e memory management li0e cycle o0 an ob&ect is as 0ollowsC
1. 6+en t+e ob&ect is created- memory is allocated 0or it- t+e constructor is run- and t+e ob&ect is considered
live.
2. 10 t+e ob&ect- or any part o0 it- cannot be accessed by any possible continuation o0 eecution- ot+er t+an t+e
running o0 destructors- t+e ob&ect is considered no longer in use- and it becomes eligible 0or destruction. T+e
C# compiler and t+e garbage collector may c+oose to analyDe code to determine w+ic+ re0erences to an
ob&ect may be used in t+e 0uture. *or instance- i0 a local variable t+at is in scope is t+e only eisting
re0erence to an ob&ect- but t+at local variable is never re0erred to in any possible continuation o0 eecution
0rom t+e current eecution point in t+e procedure- t+e garbage collector may Jbut is not re9uired toM treat t+e
ob&ect as no longer in use.
3. /nce t+e ob&ect is eligible 0or destruction- at some unspeci0ied later time t+e destructor JV1..13M Ji0 anyM 0or
t+e ob&ect is run. 8nless overridden by eplicit calls- t+e destructor 0or t+e ob&ect is run once only.
4. /nce t+e destructor 0or an ob&ect is run- i0 t+at ob&ect- or any part o0 it- cannot be accessed by any possible
continuation o0 eecution- including t+e running o0 destructors- t+e ob&ect is considered inaccessible and t+e
ob&ect becomes eligible 0or collection.
". *inally- at some time a0ter t+e ob&ect becomes eligible 0or collection- t+e garbage collector 0rees t+e memory
associated wit+ t+at ob&ect.
T+e garbage collector maintains in0ormation about ob&ect usage- and uses t+is in0ormation to ma7e memory
management decisions- suc+ as w+ere in memory to locate a newly created ob&ect- w+en to relocate an ob&ect-
and w+en an ob&ect is no longer in use or inaccessible.
5i7e ot+er languages t+at assume t+e eistence o0 a garbage collector- C# is designed so t+at t+e garbage
collector may implement a wide range o0 memory management policies. *or instance- C# does not re9uire t+at
destructors be run or t+at ob&ects be collected as soon as t+ey are eligible- or t+at destructors be run in any
particular order- or on any particular t+read.
T+e be+avior o0 t+e garbage collector can be controlled- to some degree- via static met+ods on t+e class
System.SC. T+is class can be used to re9uest a collection to occur- destructors to be run Jor not runM- and so
0ort+.
#ince t+e garbage collector is allowed wide latitude in deciding w+en to collect ob&ects and run destructors- a
con0orming implementation may produce output t+at di00ers 0rom t+at s+own by t+e 0ollowing code. T+e
program
using System;
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 7!
C# Language Specification
class '
{
A'() {
Console.WriteLine("6estruct instance o- '");
!
!
class :
{
object Oe-;
&ublic :(object o) {
Oe- + o;
!
A:() {
Console.WriteLine("6estruct instance o- :");
!
!
class 1est
{
static void Main() {
: b + ne, :(ne, '());
b + null;
SC.Collect();
SC.WaitVor*endingVinali?ers();
!
!
creates an instance o0 class ' and an instance o0 class :. T+ese ob&ects become eligible 0or garbage collection
w+en t+e variable b is assigned t+e value null- since a0ter t+is time it is impossible 0or any user<written code to
access t+em. T+e output could be eit+er
6estruct instance o- '
6estruct instance o- :
or
6estruct instance o- :
6estruct instance o- '
because t+e language imposes no constraints on t+e order in w+ic+ ob&ects are garbage collected.
1n subtle cases- t+e distinction between Keligible 0or destructionL and Keligible 0or collectionL can be important.
*or eample-
using System;
class '
{
A'() {
Console.WriteLine("6estruct instance o- '");
!
&ublic void V() {
Console.WriteLine("'.V");
1est.Oe-' + t"is;
!
!
$* Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
class :
{
&ublic ' Oe-;
A:() {
Console.WriteLine("6estruct instance o- :");
Oe-.V();
!
!
class 1est
{
&ublic static ' Oe-';
&ublic static : Oe-:;
static void Main() {
Oe-: + ne, :();
Oe-' + ne, '();
Oe-:.Oe- + Oe-';
Oe-: + null;
Oe-' + null;
.. ' and : no, eligible -or destruction
SC.Collect();
SC.WaitVor*endingVinali?ers();
.. : no, eligible -or collection but ' is not
i- (Oe-' @+ null)
Console.WriteLine("Oe-' is not null");
!
!
1n t+e above program- i0 t+e garbage collector c+ooses to run t+e destructor o0 ' be0ore t+e destructor o0 :- t+en
t+e output o0 t+is program mig+t beC
6estruct instance o- '
6estruct instance o- :
'.V
Oe-' is not null
=ote t+at alt+oug+ t+e instance o0 ' was not in use and 'Ps destructor was run- it is still possible 0or met+ods o0
' Jin t+is case- VM to be called 0rom anot+er destructor. (lso- note t+at running o0 a destructor may cause an
ob&ect to become usable 0rom t+e mainline program again. 1n t+is case- t+e running o0 :Ps destructor caused an
instance o0 ' t+at was previously not in use to become accessible 0rom t+e live re0erence 1est.Oe-'. (0ter t+e
call to WaitVor*endingVinali?ers- t+e instance o0 : is eligible 0or collection- but t+e instance o0 ' is not-
because o0 t+e re0erence 1est.Oe-'.
To avoid con0usion and unepected be+avior- it is generally a good idea 0or destructors to only per0orm cleanup
on data stored in t+eir ob&ectYs own 0ields- and not to per0orm any actions on re0erenced ob&ects or static 0ields.
(n alternative to using destructors is to let a class implement t+e System.$6is&osable inter0ace. T+is allows
t+e client o0 t+e ob&ect to determine w+en to release t+e resources o0 t+e ob&ect- typically by accessing t+e ob&ect
as a resource in a using statement JV3.13M.
3.10 $%ecution order
Eecution o0 a C# program proceeds suc+ t+at t+e side e00ects o0 eac+ eecuting t+read are preserved at critical
eecution points. ( side effect is de0ined as a read or write o0 a volatile 0ield- a write to a non<volatile variable- a
write to an eternal resource- and t+e t+rowing o0 an eception. T+e critical eecution points at w+ic+ t+e order
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. $1
C# Language Specification
o0 t+ese side e00ects must be preserved are re0erences to volatile 0ields JV1..".3M- loc( statements JV3.12M- and
t+read creation and termination. T+e eecution environment is 0ree to c+ange t+e order o0 eecution o0 a C#
program- sub&ect to t+e 0ollowing constraintsC
2ata dependence is preserved wit+in a t+read o0 eecution. T+at is- t+e value o0 eac+ variable is computed
as i0 all statements in t+e t+read were eecuted in original program order.
1nitialiDation ordering rules are preserved JV1..".4 and V1.."."M.
T+e ordering o0 side e00ects is preserved wit+ respect to volatile reads and writes JV1..".3M. (dditionally- t+e
eecution environment need not evaluate part o0 an epression i0 it can deduce t+at t+at epressionPs value is
not used and t+at no needed side e00ects are produced Jincluding any caused by calling a met+od or
accessing a volatile 0ieldM. 6+en program eecution is interrupted by an async+ronous event Jsuc+ as an
eception t+rown by anot+er t+readM- it is not guaranteed t+at t+e observable side e00ects are visible in t+e
original program order.
$2 Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
#. T!pes
T+e types o0 t+e C# language are divided into two main categoriesC 5al-e types and reference types. )ot+ value
types and re0erence types may be generic types- w+ic+ ta7e one or more type parameters. Type parameters can
designate bot+ value types and re0erence types.
t+pe.
val!e-t+pe
reference-t+pe
t+pe-para%eter
( t+ird category o0 types- pointers- is available only in unsa0e code. T+is is discussed 0urt+er in V13.2.
,alue types di00er 0rom re0erence types in t+at variables o0 t+e value types directly contain t+eir data- w+ereas
variables o0 t+e re0erence types store references to t+eir data- t+e latter being 7nown as o!1ects. 6it+ re0erence
types- it is possible 0or two variables to re0erence t+e same ob&ect- and t+us possible 0or operations on one
variable to a00ect t+e ob&ect re0erenced by t+e ot+er variable. 6it+ value types- t+e variables eac+ +ave t+eir own
copy o0 t+e data- and it is not possible 0or operations on one to a00ect t+e ot+er.
C#Ps type system is uni0ied suc+ t+at a val!e of an+ t+pe can ,e treated as an o,<ect. Every type in C# directly
or indirectly derives 0rom t+e object class type- and object is t+e ultimate base class o0 all types. ,alues o0
re0erence types are treated as ob&ects simply by viewing t+e values as type object. ,alues o0 value types are
treated as ob&ects by per0orming boing and unboing operations JV4.3M.
#.1 Value t!pes
( value type is eit+er a struct type or an enumeration type. C# provides a set o0 prede0ined struct types called
t+e siple types. T+e simple types are identi0ied t+roug+ reserved words.
val!e-t+pe.
str!ct-t+pe
en!%-t+pe
str!ct-t+pe.
t+pe-na%e
si%ple-t+pe
n!lla,le-t+pe
si%ple-t+pe.
n!%eric-t+pe
"''l
n!%eric-t+pe.
integral-t+pe
floating-point-t+pe
de&im!l
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. $3
C# Language Specification
integral-t+pe.
#")$e
")$e
#h'%$
u#h'%$
i*$
ui*$
l'*+
ul'*+
&h!%
floating-point-t+pe.
fl'!$
d'u"le
n!lla,le-t+pe.
non-n!lla,le-val!e-t+pe K
non-n!lla,le-val!e-t+pe.
t+pe
en!%-t+pe.
t+pe-na%e
8nli7e a variable o0 a re0erence type- a variable o0 a value type can contain t+e value null only i0 t+e value type
is a nullable type. *or every non<nullable value type t+ere is a corresponding nullable value type denoting t+e
same set o0 values plus t+e value null.
(ssignment to a variable o0 a value type creates a cop+ o0 t+e value being assigned. T+is di00ers 0rom
assignment to a variable o0 a re0erence type- w+ic+ copies t+e re0erence but not t+e ob&ect identi0ied by t+e
re0erence.
#.1.1 T-e S!ste.ValueT!pe t!pe
(ll value types implicitly in+erit 0rom t+e class System.Ualue1y&e- w+ic+- in turn- in+erits 0rom class
object. 1t is not possible 0or any type to derive 0rom a value type- and value types are t+us implicitly sealed
JV1..1.1.2M.
=ote t+at System.Ualue1y&e is not itsel0 a val!e-t+pe. ;at+er- it is a class-t+pe 0rom w+ic+ all val!e-t+pes are
automatically derived.
#.1.2 2efault constructors
(ll value types implicitly declare a public parameterless instance constructor called t+e defa-lt constr-ctor. T+e
de0ault constructor returns a Dero<initialiDed instance 7nown as t+e defa-lt val-e 0or t+e value typeC
*or all si%ple-t+pes- t+e de0ault value is t+e value produced by a bit pattern o0 all DerosC
o *or sbyte- byte- s"ort- us"ort- int- uint- long- and ulong- t+e de0ault value is 3.
o *or c"ar- t+e de0ault value is WZ#3333W.
o *or -loat- t+e de0ault value is 3.3-.
o *or double- t+e de0ault value is 3.3d.
o *or decimal- t+e de0ault value is 3.3m.
o *or bool- t+e de0ault value is -alse.
$" Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
*or an en!%-t+pe )- t+e de0ault value is 3- converted to t+e type ).
*or a str!ct-t+pe- t+e de0ault value is t+e value produced by setting all value type 0ields to t+eir de0ault value
and all re0erence type 0ields to null.
*or a n!lla,le-t+pe t+e de0ault value is an instance 0or w+ic+ t+e HasUalue property is 0alse and t+e Ualue
property is unde0ined. T+e de0ault value is also 7nown as t+e n-ll val-e o0 t+e nullable type.
5i7e any ot+er instance constructor- t+e de0ault constructor o0 a value type is invo7ed using t+e ne, operator.
*or e00iciency reasons- t+is re9uirement is not intended to actually +ave t+e implementation generate a
constructor call. 1n t+e eample below- variables i and j are bot+ initialiDed to Dero.
class '
{
void V() {
int i + 3;
int j + ne, int();
!
!
)ecause every value type implicitly +as a public parameterless instance constructor- it is not possible 0or a struct
type to contain an eplicit declaration o0 a parameterless constructor. ( struct type is +owever permitted to
declare parameteriDed instance constructors JV11.3.3M.
#.1.3 Struct t!pes
( struct type is a value type t+at can declare constants- 0ields- met+ods- properties- indeers- operators- instance
constructors- static constructors- and nested types. T+e declaration o0 struct types is described in V11.1.
#.1.# Siple t!pes
C# provides a set o0 prede0ined struct types called t+e siple types. T+e simple types are identi0ied t+roug+
reserved words- but t+ese reserved words are simply aliases 0or prede0ined struct types in t+e System
namespace- as described in t+e table below.
/eser%ed 5ord +liased t#pe
sbyte System.S:yte
byte System.:yte
s"ort System.$nt2X
us"ort System.;$nt2X
int System.$nt98
uint System.;$nt98
long System.$ntXJ
ulong System.;$ntXJ
c"ar System.C"ar
-loat System.Single
double System.6ouble
bool System.:oolean
decimal System.6ecimal
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. $
C# Language Specification
)ecause a simple type aliases a struct type- every simple type +as members. *or eample- int +as t+e members
declared in System.$nt98 and t+e members in+erited 0rom System.%bject- and t+e 0ollowing statements are
permittedC
int i + int.Ma#Ualue; .. System.$nt98.Ma#Ualue constant
string s + i.1oString(); .. System.$nt98.1oString() instance met"od
string t + 289.1oString(); .. System.$nt98.1oString() instance met"od
T+e simple types di00er 0rom ot+er struct types in t+at t+ey permit certain additional operationsC
'ost simple types permit values to be created by writing literals JV2.4.4M. *or eample- 289 is a literal o0
type int and WaW is a literal o0 type c"ar. C# ma7es no provision 0or literals o0 struct types in general- and
non<de0ault values o0 ot+er struct types are ultimately always created t+roug+ instance constructors o0 t+ose
struct types.
6+en t+e operands o0 an epression are all simple type constants- it is possible 0or t+e compiler to evaluate
t+e epression at compile<time. #uc+ an epression is 7nown as a constant-e/pression JV!.13M. Epressions
involving operators de0ined by ot+er struct types are not considered to be constant epressions.
T+roug+ const declarations it is possible to declare constants o0 t+e simple types JV1..4M. 1t is not possible
to +ave constants o0 ot+er struct types- but a similar e00ect is provided by static readonly 0ields.
Conversions involving simple types can participate in evaluation o0 conversion operators de0ined by ot+er
struct types- but a user<de0ined conversion operator can never participate in evaluation o0 anot+er user<
de0ined operator JV%.4.3M.
#.1.& Integral t!pes
C# supports nine integral typesC sbyte- byte- s"ort- us"ort- int- uint- long- ulong- and c"ar. T+e
integral types +ave t+e 0ollowing siDes and ranges o0 valuesC
T+e sbyte type represents signed 3<bit integers wit+ values between S123 and 12!.
T+e byte type represents unsigned 3<bit integers wit+ values between . and 2"".
T+e s"ort type represents signed 1%<bit integers wit+ values between S32!%3 and 32!%!.
T+e us"ort type represents unsigned 1%<bit integers wit+ values between . and %""3".
T+e int type represents signed 32<bit integers wit+ values between S214!433%43 and 214!433%4!.
T+e uint type represents unsigned 32<bit integers wit+ values between . and 42$4$%!2$".
T+e long type represents signed %4<bit integers wit+ values between S$2233!2.3%3"4!!"3.3 and
$2233!2.3%3"4!!"3.!.
T+e ulong type represents unsigned %4<bit integers wit+ values between . and 1344%!44.!3!.$""1%1".
T+e c"ar type represents unsigned 1%<bit integers wit+ values between . and %""3". T+e set o0 possible
values 0or t+e c"ar type corresponds to t+e 8nicode c+aracter set. (lt+oug+ c"ar +as t+e same
representation as us"ort- not all operations permitted on one type are permitted on t+e ot+er.
T+e integral<type unary and binary operators always operate wit+ signed 32<bit precision- unsigned 32<bit
precision- signed %4<bit precision- or unsigned %4<bit precisionC
$' Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
*or t+e unary < and [ operators- t+e operand is converted to type 1- w+ere 1 is t+e 0irst o0 int- uint- long-
and ulong t+at can 0ully represent all possible values o0 t+e operand. T+e operation is t+en per0ormed using
t+e precision o0 type 1- and t+e type o0 t+e result is 1.
*or t+e unary C operator- t+e operand is converted to type 1- w+ere 1 is t+e 0irst o0 int and long t+at can
0ully represent all possible values o0 t+e operand. T+e operation is t+en per0ormed using t+e precision o0
type 1- and t+e type o0 t+e result is 1. T+e unary C operator cannot be applied to operands o0 type ulong.
*or t+e binary <- C- >- .- B- F- G- H- ++- @+- E- D- E+- and D+ operators- t+e operands are converted to type 1-
w+ere 1 is t+e 0irst o0 int- uint- long- and ulong t+at can 0ully represent all possible values o0 bot+
operands. T+e operation is t+en per0ormed using t+e precision o0 type 1- and t+e type o0 t+e result is 1 Jor
bool 0or t+e relational operatorsM. 1t is not permitted 0or one operand to be o0 type long and t+e ot+er to be
o0 type ulong wit+ t+e binary operators.
*or t+e binary DD and EE operators- t+e le0t operand is converted to type 1- w+ere 1 is t+e 0irst o0 int-
uint- long- and ulong t+at can 0ully represent all possible values o0 t+e operand. T+e operation is t+en
per0ormed using t+e precision o0 type 1- and t+e type o0 t+e result is 1.
T+e c"ar type is classi0ied as an integral type- but it di00ers 0rom t+e ot+er integral types in two waysC
T+ere are no implicit conversions 0rom ot+er types to t+e c"ar type. 1n particular- even t+oug+ t+e sbyte-
byte- and us"ort types +ave ranges o0 values t+at are 0ully representable using t+e c"ar type- implicit
conversions 0rom sbyte- byte- or us"ort to c"ar do not eist.
Constants o0 t+e c"ar type must be written as character-literals or as integer-literals in combination wit+ a
cast to type c"ar. *or eample- (c"ar)23 is t+e same as WZ#333'W.
T+e c"ec(ed and unc"ec(ed operators and statements are used to control over0low c+ec7ing 0or integral<type
arit+metic operations and conversions JV!.".12M. 1n a c"ec(ed contet- an over0low produces a compile<time
error or causes a System.%ver-lo,)#ce&tion to be t+rown. 1n an unc"ec(ed contet- over0lows are
ignored and any +ig+<order bits t+at do not 0it in t+e destination type are discarded.
#.1.' ,loating point t!pes
C# supports two 0loating point typesC -loat and double. T+e -loat and double types are represented using
t+e 32<bit single<precision and %4<bit double<precision 1EEE !"4 0ormats- w+ic+ provide t+e 0ollowing sets o0
valuesC
Positive Dero and negative Dero. 1n most situations- positive Dero and negative Dero be+ave identically as t+e
simple value Dero- but certain operations distinguis+ between t+e two JV!.!.2M.
Positive in0inity and negative in0inity. 1n0inities are produced by suc+ operations as dividing a non<Dero
number by Dero. *or eample- 2.3 . 3.3 yields positive in0inity- and C2.3 . 3.3 yields negative in0inity.
T+e 6ot-a-6-!er value- o0ten abbreviated =a=. =a=s are produced by invalid 0loating<point operations-
suc+ as dividing Dero by Dero.
T+e 0inite set o0 non<Dero values o0 t+e 0orm s T % T 2
e
- w+ere s is 1 or U1- and % and e are determined by
t+e particular 0loating<point typeC *or -loat- . G % G 2
24
and U14$ \ e \ 1.4- and 0or double- . G % G 2
"3

and U1.!" \ e \ $!.. 2enormaliDed 0loating<point numbers are considered valid non<Dero values.
T+e -loat type can represent values ranging 0rom approimately 1." T 1.
U4"
to 3.4 T 1.
33
wit+ a precision o0 !
digits.
T+e double type can represent values ranging 0rom approimately ".. T 1.
U324
to 1.! T 1.
3.3
wit+ a precision o0
1"<1% digits.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. $7
C# Language Specification
10 one o0 t+e operands o0 a binary operator is o0 a 0loating<point type- t+en t+e ot+er operand must be o0 an
integral type or a 0loating<point type- and t+e operation is evaluated as 0ollowsC
10 one o0 t+e operands is o0 an integral type- t+en t+at operand is converted to t+e 0loating<point type o0 t+e
ot+er operand.
T+en- i0 eit+er o0 t+e operands is o0 type double- t+e ot+er operand is converted to double- t+e operation is
per0ormed using at least double range and precision- and t+e type o0 t+e result is double Jor bool 0or t+e
relational operatorsM.
/t+erwise- t+e operation is per0ormed using at least -loat range and precision- and t+e type o0 t+e result is
-loat Jor bool 0or t+e relational operatorsM.
T+e 0loating<point operators- including t+e assignment operators- never produce eceptions. 1nstead- in
eceptional situations- 0loating<point operations produce Dero- in0inity- or =a=- as described belowC
10 t+e result o0 a 0loating<point operation is too small 0or t+e destination 0ormat- t+e result o0 t+e operation
becomes positive Dero or negative Dero.
10 t+e result o0 a 0loating<point operation is too large 0or t+e destination 0ormat- t+e result o0 t+e operation
becomes positive in0inity or negative in0inity.
10 a 0loating<point operation is invalid- t+e result o0 t+e operation becomes =a=.
10 one or bot+ operands o0 a 0loating<point operation is =a=- t+e result o0 t+e operation becomes =a=.
*loating<point operations may be per0ormed wit+ +ig+er precision t+an t+e result type o0 t+e operation. *or
eample- some +ardware arc+itectures support an KetendedL or Klong doubleL 0loating<point type wit+ greater
range and precision t+an t+e double type- and implicitly per0orm all 0loating<point operations using t+is +ig+er
precision type. /nly at ecessive cost in per0ormance can suc+ +ardware arc+itectures be made to per0orm
0loating<point operations wit+ less precision- and rat+er t+an re9uire an implementation to 0or0eit bot+
per0ormance and precision- C# allows a +ig+er precision type to be used 0or all 0loating<point operations. /t+er
t+an delivering more precise results- t+is rarely +as any measurable e00ects. However- in epressions o0 t+e 0orm
# > y . ?- w+ere t+e multiplication produces a result t+at is outside t+e double range- but t+e subse9uent
division brings t+e temporary result bac7 into t+e double range- t+e 0act t+at t+e epression is evaluated in a
+ig+er range 0ormat may cause a 0inite result to be produced instead o0 an in0inity.
#.1.. T-e decial t!pe
T+e decimal type is a 123<bit data type suitable 0or 0inancial and monetary calculations. T+e decimal type
can represent values ranging 0rom 1.. T 1.
U23
to approimately !.$ T 1.
23
wit+ 23<2$ signi0icant digits.
T+e 0inite set o0 values o0 type decimal are o0 t+e 0orm JS1M
s
T c T 1.
<e
- w+ere t+e sign s is . or 1- t+e
coe00icient c is given by . \ c G 2
$%
- and t+e scale e is suc+ t+at . \ e \ 23.T+e decimal type does not support
signed Deros- in0inities- or =a=Ys. ( decimal is represented as a $%<bit integer scaled by a power o0 ten. *or
decimals wit+ an absolute value less t+an 2.3m- t+e value is eact to t+e 23
t+
decimal place- but no 0urt+er. *or
decimals wit+ an absolute value greater t+an or e9ual to 2.3m- t+e value is eact to 23 or 2$ digits. Contrary to
t+e -loat and double data types- decimal 0ractional numbers suc+ as ..1 can be represented eactly in t+e
decimal representation. 1n t+e -loat and double representations- suc+ numbers are o0ten in0inite 0ractions-
ma7ing t+ose representations more prone to round<o00 errors.
10 one o0 t+e operands o0 a binary operator is o0 type decimal- t+en t+e ot+er operand must be o0 an integral
type or o0 type decimal. 10 an integral type operand is present- it is converted to decimal be0ore t+e operation
is per0ormed.
$$ Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
T+e result o0 an operation on values o0 type decimal is t+at w+ic+ would result 0rom calculating an eact result
Jpreserving scale- as de0ined 0or eac+ operatorM and t+en rounding to 0it t+e representation. ;esults are rounded
to t+e nearest representable value- and- w+en a result is e9ually close to two representable values- to t+e value
t+at +as an even number in t+e least signi0icant digit position Jt+is is 7nown as Kban7erPs roundingLM. ( Dero
result always +as a sign o0 . and a scale o0 ..
10 a decimal arit+metic operation produces a value less t+an or e9ual to " T 1.
<2$
in absolute value- t+e result o0
t+e operation becomes Dero. 10 a decimal arit+metic operation produces a result t+at is too large 0or t+e
decimal 0ormat- a System.%ver-lo,)#ce&tion is t+rown.
T+e decimal type +as greater precision but smaller range t+an t+e 0loating<point types. T+us- conversions 0rom
t+e 0loating<point types to decimal mig+t produce over0low eceptions- and conversions 0rom decimal to t+e
0loating<point types mig+t cause loss o0 precision. *or t+ese reasons- no implicit conversions eist between t+e
0loating<point types and decimal- and wit+out eplicit casts- it is not possible to mi 0loating<point and
decimal operands in t+e same epression.
#.1.0 T-e bool t!pe
T+e bool type represents boolean logical 9uantities. T+e possible values o0 type bool are true and -alse.
=o standard conversions eist between bool and ot+er types. 1n particular- t+e bool type is distinct and
separate 0rom t+e integral types- and a bool value cannot be used in place o0 an integral value- and vice versa.
1n t+e C and CNN languages- a Dero integral or 0loating<point value- or a null pointer can be converted to t+e
boolean value -alse- and a non<Dero integral or 0loating<point value- or a non<null pointer can be converted to
t+e boolean value true. 1n C#- suc+ conversions are accomplis+ed by eplicitly comparing an integral or
0loating<point value to Dero- or by eplicitly comparing an ob&ect re0erence to null.
#.1.1 $nueration t!pes
(n enumeration type is a distinct type wit+ named constants. Every enumeration type +as an underlying type-
w+ic+ must be byte- sbyte- s"ort- us"ort- int- uint- long or ulong. T+e set o0 values o0 t+e enumeration
type is t+e same as t+e set o0 values o0 t+e underlying type. ,alues o0 t+e enumeration type are not restricted to
t+e values o0 t+e named constants. Enumeration types are de0ined t+roug+ enumeration declarations JV14.1M.
#.1.10 ;ullable t!pes
( nullable type can represent all values o0 its -nderlying type plus an additional null value. ( nullable type is
written 17- w+ere 1 is t+e underlying type. T+is synta is s+ort+and 0or System.NullableD1E- and t+e two
0orms can be used interc+angeably.
( non-n-lla!le val-e type conversely is any value type ot+er t+an System.NullableD1E and its s+ort+and 17
J0or any 1)- plus any type parameter t+at is constrained to be a non<nullable value type Jt+at is- any type
parameter wit+ a struct constraintM. T+e System.NullableD1E type speci0ies t+e value type constraint 0or 1
(V1..1.")- w+ic+ means t+at t+e underlying type o0 a nullable type can be any non<nullable value type. T+e
underlying type o0 a nullable type cannot be a nullable type or a re0erence type. *or eample- int77 and
string7 are invalid types.
(n instance o0 a nullable type 17 +as two public read<only propertiesC
( HasUalue property o0 type bool
( Ualue property o0 type 1
(n instance 0or w+ic+ HasUalue is true is said to be non<null. ( non<null instance contains a 7nown value and
Ualue returns t+at value.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. $!
C# Language Specification
(n instance 0or w+ic+ HasUalue is 0alse is said to be null. ( null instance +as an unde0ined value. (ttempting
to read t+e Ualue o0 a null instance causes a System.$nvalid%&eration)#ce&tion to be t+rown. T+e
process o0 accessing t+e Ualue property o0 a nullable instance is re0erred to as -n2rapping.
1n addition to t+e de0ault constructor- every nullable type 17 +as a public constructor t+at ta7es a single
argument o0 type 1. 4iven a value # o0 type 1- a constructor invocation o0 t+e 0orm
ne, 17(#)
creates a non<null instance o0 17 0or w+ic+ t+e Ualue property is #. T+e process o0 creating a non<null instance
o0 a nullable type 0or a given value is re0erred to as 2rapping.
1mplicit conversions are available 0rom t+e null literal to 17 JV%.1."M and 0rom 1 to 17 JV%.1.4M.
#.2 :eference t!pes
( re0erence type is a class type- an inter0ace type- an array type- or a delegate type.
reference-t+pe.
class-t+pe
interface-t+pe
arra+-t+pe
delegate-t+pe
class-t+pe.
t+pe-na%e
'"/e&$
#$%i*+
interface-t+pe.
t+pe-na%e
arra+-t+pe.
non-arra+-t+pe ran&-specifiers
non-arra+-t+pe.
t+pe
ran&-specifiers.
ran&-specifier
ran&-specifiers ran&-specifier
ran&-specifier.
= di%-separatorsopt >
di%-separators.
?
di%-separators ?
delegate-t+pe.
t+pe-na%e
( re0erence type value is a re0erence to an instance o0 t+e type- t+e latter 7nown as an o!1ect. T+e special value
null is compatible wit+ all re0erence types and indicates t+e absence o0 an instance.
#.2.1 Class t!pes
( class type de0ines a data structure t+at contains data members Jconstants and 0ieldsM- 0unction members
Jmet+ods- properties- events- indeers- operators- instance constructors- destructors and static constructorsM- and
!* Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
nested types. Class types support in+eritance- a mec+anism w+ereby derived classes can etend and specialiDe
base classes. 1nstances o0 class types are created using o,<ect-creation-e/pressions JV!.".1..1M.
Class types are described in V1..
Certain prede0ined class types +ave special meaning in t+e C# language- as described in t+e table below.
Class t#pe ,escription
System.%bject
T+e ultimate base class o0 all ot+er types. #ee V4.2.2.
System.String
T+e string type o0 t+e C# language. #ee V4.2.3.
System.Ualue1y&e
T+e base class o0 all value types. #ee V4.1.1.
System.)num
T+e base class o0 all enum types. #ee V14.
System.'rray
T+e base class o0 all array types. #ee V12.
System.6elegate
T+e base class o0 all delegate types. #ee V1".
System.)#ce&tion
T+e base class o0 all eception types. #ee V1%.
#.2.2 T-e ob(ect t!pe
T+e object class type is t+e ultimate base class o0 all ot+er types. Every type in C# directly or indirectly
derives 0rom t+e object class type.
T+e 7eyword object is simply an alias 0or t+e prede0ined class System.%bject.
#.2.3 T-e string t!pe
T+e string type is a sealed class type t+at in+erits directly 0rom object. 1nstances o0 t+e string class
represent 8nicode c+aracter strings.
,alues o0 t+e string type can be written as string literals JV2.4.4."M.
T+e 7eyword string is simply an alias 0or t+e prede0ined class System.String.
#.2.# Interface t!pes
(n inter0ace de0ines a contract. ( class or struct t+at implements an inter0ace must ad+ere to its contract. (n
inter0ace may in+erit 0rom multiple base inter0aces- and a class or struct may implement multiple inter0aces.
1nter0ace types are described in V13.
#.2.& *rra! t!pes
(n array is a data structure t+at contains Dero or more variables w+ic+ are accessed t+roug+ computed indices.
T+e variables contained in an array- also called t+e elements o0 t+e array- are all o0 t+e same type- and t+is type
is called t+e element type o0 t+e array.
(rray types are described in V12.
#.2.' 2elegate t!pes
( delegate is a data structure t+at re0ers to one or more met+ods. *or instance met+ods- it also re0ers to t+eir
corresponding ob&ect instances.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. !1
C# Language Specification
T+e closest e9uivalent o0 a delegate in C or CNN is a 0unction pointer- but w+ereas a 0unction pointer can only
re0erence static 0unctions- a delegate can re0erence bot+ static and instance met+ods. 1n t+e latter case- t+e
delegate stores not only a re0erence to t+e met+odPs entry point- but also a re0erence to t+e ob&ect instance on
w+ic+ to invo7e t+e met+od.
2elegate types are described in V1".
#.3 +o%ing and unbo%ing
T+e concept o0 boing and unboing is central to C#Ps type system. 1t provides a bridge between val!e-t+pes
and reference-t+pes by permitting any value o0 a val!e-t+pe to be converted to and 0rom type object. )oing
and unboing enables a uni0ied view o0 t+e type system w+erein a value o0 any type can ultimately be treated as
an ob&ect.
#.3.1 +o%ing con"ersions
( boing conversion permits a val!e-t+pe to be implicitly converted to a reference-t+pe. T+e 0ollowing boing
conversions eistC
*rom any val!e-t+pe to t+e type object.
*rom any val!e-t+pe to t+e type System.Ualue1y&e.
*rom any non-n!lla,le-val!e-t+pe to any interface-t+pe implemented by t+e val!e-t+pe.
*rom any n!lla,le-t+pe to any interface-t+pe implemented by t+e underlying type o0 t+e n!lla,le-t+pe.
*rom any en!%-t+pe to t+e type System.)num.
*rom any n!lla,le-t+pe wit+ an underlying en!%-t+pe to t+e type System.)num.
=ote t+at an implicit conversion 0rom a type parameter will be eecuted as a boing conversion i0 at runtime
it ends up converting 0rom a value type to a re0erence type JV%.1.$M.
)oing a value o0 a non-n!lla,le-val!e-t+pe consists o0 allocating an ob&ect instance and copying t+e non-
n!lla,le-val!e-t+pe value into t+at instance.
)oing a value o0 a n!lla,le-t+pe produces a null re0erence i0 it is t+e null value JHasUalue is -alseM- or t+e
result o0 unwrapping and boing t+e underlying value ot+erwise.
T+e actual process o0 boing a value o0 a non-n!lla,le-val!e-t+pe is best eplained by imagining t+e eistence
o0 a generic !o,ing class- w+ic+ be+aves as i0 it were declared as 0ollowsC
sealed class :o#D1E/ System.Ualue1y&e
{
1 value;
&ublic :o#(1 t) {
value + t;
!
!
)oing o0 a value v o0 type 1 now consists o0 eecuting t+e epression ne, :o#D1E(v)- and returning t+e
resulting instance as a value o0 type object. T+us- t+e statements
int i + 289;
object bo# + i;
conceptually correspond to
!2 Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
int i + 289;
object bo# + ne, :o#DintE(i);
( boing class li7e :o#D1E above doesnPt actually eist and t+e dynamic type o0 a boed value isnPt actually a
class type. 1nstead- a boed value o0 type 1 +as t+e dynamic type 1- and a dynamic type c+ec7 using t+e is
operator can simply re0erence type 1. *or eample-
int i + 289;
object bo# + i;
i- (bo# is int) {
Console.Write(":o# contains an int");
!
will output t+e string K:o# contains an intL on t+e console.
( boing conversion implies %a&ing a cop+ o0 t+e value being boed. T+is is di00erent 0rom a conversion o0 a
reference-t+pe to type object- in w+ic+ t+e value continues to re0erence t+e same instance and simply is
regarded as t+e less derived type object. *or eample- given t+e declaration
struct *oint
{
&ublic int # y;
&ublic *oint(int # int y) {
t"is.# + #;
t"is.y + y;
!
!
t+e 0ollowing statements
*oint & + ne, *oint(23 23);
object bo# + &;
&.# + 83;
Console.Write(((*oint)bo#).#);
will output t+e value 1. on t+e console because t+e implicit boing operation t+at occurs in t+e assignment o0 &
to bo# causes t+e value o0 & to be copied. Had *oint been declared a class instead- t+e value 2. would be
output because & and bo# would re0erence t+e same instance.
#.3.2 6nbo%ing con"ersions
(n unboing conversion permits a reference-t+pe to be eplicitly converted to a val!e-t+pe. T+e 0ollowing
unboing conversions eistC
*rom t+e type object to any val!e-t+pe.
*rom t+e type System.Ualue1y&e to any val!e-t+pe.
*rom any interface-t+pe to any non-n!lla,le-val!e-t+pe t+at implements t+e interface-t+pe.
*rom any interface-t+pe to any n!lla,le-t+pe w+ose underlying type implements t+e interface-t+pe.
*rom t+e type System.)num to any en!%-t+pe.
*rom t+e type System.)num to any n!lla,le-t+pe wit+ an underlying en!%-t+pe.
=ote t+at an eplicit conversion to a type parameter will be eecuted as an unboing conversion i0 at
runtime it ends up converting 0rom a re0erence type to a value type JV%.2.%M.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. !3
C# Language Specification
(n unboing operation to a non-n!lla,le-val!e-t+pe consists o0 0irst c+ec7ing t+at t+e ob&ect instance is a boed
value o0 t+e given non-n!lla,le-val!e-t+pe- and t+en copying t+e value out o0 t+e instance.
8nboing to a n!lla,le-t+pe produces t+e null value o0 t+e n!lla,le-t+pe i0 t+e source operand is null- or t+e
wrapped result o0 unboing t+e ob&ect instance to t+e underlying type o0 t+e n!lla,le-t+pe ot+erwise.
;e0erring to t+e imaginary boing class described in t+e previous section- an unboing conversion o0 an ob&ect
bo# to a val!e-t+pe 1 consists o0 eecuting t+e epression ((:o#D1E)bo#).value. T+us- t+e statements
object bo# + 289;
int i + (int)bo#;
conceptually correspond to
object bo# + ne, :o#DintE(289);
int i + ((:o#DintE)bo#).value;
*or an unboing conversion to a given non-n!lla,le-val!e-t+pe to succeed at run<time- t+e value o0 t+e source
operand must be a re0erence to a boed value o0 t+at non-n!lla,le-val!e-t+pe. 10 t+e source operand is null- a
System.NullOe-erence)#ce&tion is t+rown. 10 t+e source operand is a re0erence to an incompatible ob&ect-
a System.$nvalidCast)#ce&tion is t+rown.
*or an unboing conversion to a given n!lla,le-t+pe to succeed at run<time- t+e value o0 t+e source operand
must be eit+er null or a re0erence to a boed value o0 t+e underlying non-n!lla,le-val!e-t+pe o0 t+e n!lla,le-
t+pe. 10 t+e source operand is a re0erence to an incompatible ob&ect- a System.$nvalidCast)#ce&tion is
t+rown.
#.# Constructed t!pes
( generic type declaration- by itsel0- denotes an -n!o-nd generic type t+at is used as a KblueprintL to 0orm
many di00erent types- by way o0 applying type arg-ents. T+e type arguments are written wit+in angle brac7ets
JD and EM immediately 0ollowing t+e name o0 t+e generic type. ( type t+at includes at least one type argument is
called a constr-cted type. ( constructed type can be used in most places in t+e language in w+ic+ a type name
can appear. (n unbound generic type can only be used wit+in a t+peof-e/pression JV!.".11M.
Constructed types can also be used in epressions as simple names JV!.".2M or w+en accessing a member
JV!.".4M.
6+en a na%espace-or-t+pe-na%e is evaluated- only generic types wit+ t+e correct number o0 type parameters
are considered. T+us- it is possible to use t+e same identi0ier to identi0y di00erent types- as long as t+e types +ave
di00erent numbers o0 type parameters. T+is is use0ul w+en miing generic and non<generic classes in t+e same
programC
names&ace Widgets
{
class ^ueue {...!
class ^ueueD1)lementE {...!
!
names&ace My'&&lication
{
using Widgets;
class I
{
^ueue Q2; .. Non=generic Widgets.^ueue
^ueueDintE Q8; .. Seneric Widgets.^ueue
!
!
!" Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
( t+pe-na%e mig+t identi0y a constructed type even t+oug+ it doesnPt speci0y type parameters directly. T+is can
occur w+ere a type is nested wit+in a generic class declaration- and t+e instance type o0 t+e containing
declaration is implicitly used 0or name loo7up JV1..3.3.%MC
class %uterD1E
{
&ublic class $nner {...!
&ublic $nner i; .. 1y&e o- i is %uterD1E.$nner
!
1n unsa0e code- a constructed type cannot be used as an !n%anaged-t+pe JV13.2M.
#.#.1 T!pe arguents
Eac+ argument in a type argument list is simply a t+pe.
t+pe-arg!%ent-list.
I t+pe-arg!%ents J
t+pe-arg!%ents.
t+pe-arg!%ent
t+pe-arg!%ents ? t+pe-arg!%ent
t+pe-arg!%ent.
t+pe
1n unsa0e code JV13M- a t+pe-arg!%ent may not be a pointer type. Eac+ type argument must satis0y any
constraints on t+e corresponding type parameter JV1..1."M.
#.#.2 /pen and closed t!pes
(ll types can be classi0ied as eit+er open types or closed types. (n open type is a type t+at involves type
parameters. 'ore speci0icallyC
( type parameter de0ines an open type.
(n array type is an open type i0 and only i0 its element type is an open type.
( constructed type is an open type i0 and only i0 one or more o0 its type arguments is an open type. (
constructed nested type is an open type i0 and only i0 one or more o0 its type arguments or t+e type
arguments o0 its containing typeJsM is an open type.
( closed type is a type t+at is not an open type.
(t run<time- all o0 t+e code wit+in a generic type declaration is eecuted in t+e contet o0 a closed constructed
type t+at was created by applying type arguments to t+e generic declaration. Eac+ type parameter wit+in t+e
generic type is bound to a particular run<time type. T+e run<time processing o0 all statements and epressions
always occurs wit+ closed types- and open types occur only during compile<time processing.
Eac+ closed constructed type +as its own set o0 static variables- w+ic+ are not s+ared wit+ any ot+er closed
constructed types. #ince an open type does not eist at run<time- t+ere are no static variables associated wit+ an
open type. Two closed constructed types are t+e same type i0 t+ey are constructed 0rom t+e same unbound
generic type- and t+eir corresponding type arguments are t+e same type.
#.#.3 +ound and unbound t!pes
T+e term -n!o-nd type re0ers to a non<generic type or an unbound generic type. T+e term !o-nd type re0ers to a
non<generic type or a constructed type.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. !
C# Language Specification
(n unbound type re0ers to t+e entity declared by a type declaration. (n unbound generic type is not itsel0 a type-
and cannot be used as t+e type o0 a variable- argument or return value- or as a base type. T+e only construct in
w+ic+ an unbound generic type can be re0erenced is t+e ty&eo- epression JV!.".11M.
#.#.# Satisf!ing constraints
6+enever a constructed type or generic met+od is re0erenced- t+e supplied type arguments are c+ec7ed against
t+e type parameter constraints declared on t+e generic type or met+od JV1..1."M. *or eac+ ,"ere clause- t+e
type argument ' t+at corresponds to t+e named type parameter is c+ec7ed against eac+ constraint as 0ollowsC
10 t+e constraint is a class type- an inter0ace type- or a type parameter- let C represent t+at constraint wit+ t+e
supplied type arguments substituted 0or any type parameters t+at appear in t+e constraint. To satis0y t+e
constraint- it must be t+e case t+at type ' is convertible to type C by one o0 t+e 0ollowingC
o (n identity conversion JV%.1.1M
o (n implicit re0erence conversion JV%.1.%M
o ( boing conversion JV%.1.!M- provided t+at type ( is a non<nullable value type.
o (n implicit re0erence- boing or type parameter conversion 0rom a type parameter ' to C.
10 t+e constraint is t+e re0erence type constraint JclassM- t+e type ' must satis0y one o0 t+e 0ollowingC
o ' is an inter0ace type- class type- delegate type or array type. =ote t+at System.Ualue1y&e and
System.)num are re0erence types t+at satis0y t+is constraint.
o ' is a type parameter t+at is 7nown to be a re0erence type JV1..1."M.
10 t+e constraint is t+e value type constraint JstructM- t+e type ' must satis0y one o0 t+e 0ollowingC
o ' is a struct type or enum type- but not a nullable type. =ote t+at System.Ualue1y&e and
System.)num are re0erence types t+at do not satis0y t+is constraint.
o ' is a type parameter +aving t+e value type constraint JV1..1."M.
10 t+e constraint is t+e constructor constraint ne,()- t+e type ' must not be abstract and must +ave a
public parameterless constructor. T+is is satis0ied i0 one o0 t+e 0ollowing is trueC
o ' is a value type- since all value types +ave a public de0ault constructor JV4.1.2M.
o ' is a type parameter +aving t+e constructor constraint JV1..1."M.
o ' is a type parameter +aving t+e value type constraint JV1..1."M.
o ' is a class t+at is not abstract and contains an eplicitly declared &ublic constructor wit+ no
parameters.
o ' is not abstract and +as a de0ault constructor JV1..11.4M.
( compile<time error occurs i0 one or more o0 a type parameterPs constraints are not satis0ied by t+e given type
arguments.
#ince type parameters are not in+erited- constraints are never in+erited eit+er. 1n t+e eample below- 6 needs to
speci0y t+e constraint on its type parameter 1 so t+at 1 satis0ies t+e constraint imposed by t+e base class :D1E.
1n contrast- class ) need not speci0y a constraint- because ListD1E implements $)numerable 0or any 1.
class :D1E ,"ere 1/ $)numerable {...!
class 6D1E/ :D1E ,"ere 1/ $)numerable {...!
!' Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
class )D1E/ :DListD1EE {...!
#.& T!pe paraeters
( type parameter is an identi0ier designating a value type or re0erence type t+at t+e parameter is bound to at run<
time.
t+pe-para%eter.
identifier
#ince a type parameter can be instantiated wit+ many di00erent actual type arguments- type parameters +ave
slig+tly di00erent operations and restrictions t+an ot+er types. T+ese includeC
( type parameter cannot be used directly to declare a base class JV1..2.4M or inter0ace JV13.1.3M.
T+e rules 0or member loo7up on type parameters depend on t+e constraints- i0 any- applied to t+e type
parameter. T+ey are detailed in V!.3.
T+e available conversions 0or a type parameter depend on t+e constraints- i0 any- applied to t+e type
parameter. T+ey are detailed in V%.1.$ and V%.2.%.
T+e literal null cannot be converted to a type given by a type parameter- ecept i0 t+e type parameter is
7nown to be a re0erence type JV%.1.$M. However- a de-ault epression JV!.".13M can be used instead. 1n
addition- a value wit+ a type given by a type parameter can be compared wit+ null using ++ and @+
JV!.$.%M unless t+e type parameter +as t+e value type constraint.
( ne, epression JV!.".1..1M can only be used wit+ a type parameter i0 t+e type parameter is constrained by
a constr!ctor-constraint or t+e value type constraint JV1..1."M.
( type parameter cannot be used anyw+ere wit+in an attribute.
( type parameter cannot be used in a member access JV!.".4M or type name JV3.3M to identi0y a static
member or a nested type.
1n unsa0e code- a type parameter cannot be used as an !n%anaged-t+pe JV13.2M.
(s a type- type parameters are purely a compile<time construct. (t run<time- eac+ type parameter is bound to a
run<time type t+at was speci0ied by supplying a type argument to t+e generic type declaration. T+us- t+e type o0
a variable declared wit+ a type parameter will- at run<time- be a closed constructed type JV4.4.2M. T+e run<time
eecution o0 all statements and epressions involving type parameters uses t+e actual type t+at was supplied as
t+e type argument 0or t+at parameter.
#.' $%pression tree t!pes
$,pression trees permit anonymous 0unctions to be represented as data structures instead o0 eecutable code.
Epression trees are values o0 e,pression tree types o0 t+e 0orm
System.LinQ.)#&ressions.)#&ressionD6E- w+ere 6 is any delegate type. *or t+e remainder o0 t+is
speci0ication we will re0er to t+ese types using t+e s+ort+and )#&ressionD6E.
10 a conversion eists 0rom an anonymous 0unction to a delegate type 6- a conversion also eists to t+e
epression tree type )#&ressionD6E. 6+ereas t+e conversion o0 an anonymous 0unction to a delegate type
generates a delegate t+at re0erences eecutable code 0or t+e anonymous 0unction- conversion to an epression
tree type creates an epression tree representation o0 t+e anonymous 0unction.
Epression trees are e00icient in<memory data representations o0 anonymous 0unctions and ma7e t+e structure o0
t+e anonymous 0unction transparent and eplicit.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. !7
C# Language Specification
Fust li7e a delegate type 6- )#&ressionD6E is said to +ave parameter and return types- w+ic+ are t+e same as
t+ose o0 6.
T+e 0ollowing eample represents an anonymous 0unction bot+ as eecutable code and as an epression tree.
)ecause a conversion eists to VuncDintintE- a conversion also eists to )#&ressionDVuncDintintEEC
VuncDintintE del + # +E # < 2; .. Code
)#&ressionDVuncDintintEE e#& + # +E # < 2; .. 6ata
*ollowing t+ese assignments- t+e delegate del re0erences a met+od t+at returns # < 2- and t+e epression tree
e#& re0erences a data structure t+at describes t+e epression # +E # < 2.
T+e eact de0inition o0 t+e generic type )#&ressionD6E as well as t+e precise rules 0or constructing an
epression tree w+en an anonymous 0unction is converted to an epression tree type- are bot+ outside t+e scope
o0 t+is speci0ication- and are described elsew+ere.
Two t+ings are important to ma7e eplicitC
=ot all anonymous 0unctions can be represented as epression trees. *or instance- anonymous 0unctions
wit+ statement bodies- and anonymous 0unctions containing assignment epressions cannot be
represented. 1n t+ese cases- a conversion still eists- but will 0ail at compile time.
)#&ressionD6E o00ers an instance met+od Com&ile w+ic+ produces a delegate o0 type 6C
VuncDintintE del8 + e#&.Com&ile();
1nvo7ing t+is delegate causes t+e code represented by t+e epression tree to be eecuted. T+us- given
t+e de0initions above- del and del2 are e9uivalent- and t+e 0ollowing two statements will +ave t+e same
e00ectC
int i2 + del(2);
int i8 + del8(2);
(0ter eecuting t+is code- i2 and i8 will bot+ +ave t+e value 8.
!$ Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
&. Variables
,ariables represent storage locations. Every variable +as a type t+at determines w+at values can be stored in t+e
variable. C# is a type<sa0e language- and t+e C# compiler guarantees t+at values stored in variables are always
o0 t+e appropriate type. T+e value o0 a variable can be c+anged t+roug+ assignment or t+roug+ use o0 t+e << and
== operators.
( variable must be definitely assigned JV".3M be0ore its value can be obtained.
(s described in t+e 0ollowing sections- variables are eit+er initially assigned or initially -nassigned. (n initially
assigned variable +as a well<de0ined initial value and is always considered de0initely assigned. (n initially
unassigned variable +as no initial value. *or an initially unassigned variable to be considered de0initely assigned
at a certain location- an assignment to t+e variable must occur in every possible eecution pat+ leading to t+at
location.
&.1 Variable categories
C# de0ines seven categories o0 variablesC static variables- instance variables- array elements- value parameters-
re0erence parameters- output parameters- and local variables. T+e sections t+at 0ollow describe eac+ o0 t+ese
categories.
1n t+e eample
class '
{
&ublic static int #;
int y;
void V(int45 v int a re- int b out int c) {
int i + 2;
c + a < b<<;
!
!
# is a static variable- y is an instance variable- v435 is an array element- a is a value parameter- b is a re0erence
parameter- c is an output parameter- and i is a local variable.
&.1.1 Static "ariables
( 0ield declared wit+ t+e static modi0ier is called a static varia!le. ( static variable comes into eistence
be0ore eecution o0 t+e static constructor JV1..12M 0or its containing type- and ceases to eist w+en t+e
associated application domain ceases to eist.
T+e initial value o0 a static variable is t+e de0ault value JV".2M o0 t+e variablePs type.
*or purposes o0 de0inite assignment c+ec7ing- a static variable is considered initially assigned.
&.1.2 Instance "ariables
( 0ield declared wit+out t+e static modi0ier is called an instance varia!le.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. !!
C# Language Specification
5.1.2.1 #nstance variables in classes
(n instance variable o0 a class comes into eistence w+en a new instance o0 t+at class is created- and ceases to
eist w+en t+ere are no re0erences to t+at instance and t+e instancePs destructor Ji0 anyM +as eecuted.
T+e initial value o0 an instance variable o0 a class is t+e de0ault value JV".2M o0 t+e variablePs type.
*or t+e purpose o0 de0inite assignment c+ec7ing- an instance variable o0 a class is considered initially assigned.
5.1.2.2 #nstance variables in structs
(n instance variable o0 a struct +as eactly t+e same li0etime as t+e struct variable to w+ic+ it belongs. 1n ot+er
words- w+en a variable o0 a struct type comes into eistence or ceases to eist- so too do t+e instance variables
o0 t+e struct.
T+e initial assignment state o0 an instance variable o0 a struct is t+e same as t+at o0 t+e containing struct
variable. 1n ot+er words- w+en a struct variable is considered initially assigned- so too are its instance variables-
and w+en a struct variable is considered initially unassigned- its instance variables are li7ewise unassigned.
&.1.3 *rra! eleents
T+e elements o0 an array come into eistence w+en an array instance is created- and cease to eist w+en t+ere
are no re0erences to t+at array instance.
T+e initial value o0 eac+ o0 t+e elements o0 an array is t+e de0ault value JV".2M o0 t+e type o0 t+e array elements.
*or t+e purpose o0 de0inite assignment c+ec7ing- an array element is considered initially assigned.
&.1.# Value paraeters
( parameter declared wit+out a re- or out modi0ier is a val-e paraeter.
( value parameter comes into eistence upon invocation o0 t+e 0unction member Jmet+od- instance constructor-
accessor- or operatorM or anonymous 0unction to w+ic+ t+e parameter belongs- and is initialiDed wit+ t+e value o0
t+e argument given in t+e invocation. ( value parameter normally ceases to eist upon return o0 t+e 0unction
member or anonymous 0unction. However- i0 t+e value parameter is captured by an anonymous 0unction JV!.14M-
its li0e time etends at least until t+e delegate or epression tree created 0rom t+at anonymous 0unction is eligible
0or garbage collection.
*or t+e purpose o0 de0inite assignment c+ec7ing- a value parameter is considered initially assigned.
&.1.& :eference paraeters
( parameter declared wit+ a re- modi0ier is a reference paraeter.
( re0erence parameter does not create a new storage location. 1nstead- a re0erence parameter represents t+e same
storage location as t+e variable given as t+e argument in t+e 0unction member or anonymous 0unction
invocation. T+us- t+e value o0 a re0erence parameter is always t+e same as t+e underlying variable.
T+e 0ollowing de0inite assignment rules apply to re0erence parameters. =ote t+e di00erent rules 0or output
parameters described in V".1.%.
( variable must be de0initely assigned JV".3M be0ore it can be passed as a re0erence parameter in a 0unction
member or delegate invocation.
6it+in a 0unction member or anonymous 0unction- a re0erence parameter is considered initially assigned.
6it+in an instance met+od or instance accessor o0 a struct type- t+e t"is 7eyword be+aves eactly as a
re0erence parameter o0 t+e struct type JV!.".!M.
1** Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
&.1.' /utput paraeters
( parameter declared wit+ an out modi0ier is an o-tp-t paraeter.
(n output parameter does not create a new storage location. 1nstead- an output parameter represents t+e same
storage location as t+e variable given as t+e argument in t+e 0unction member or delegate invocation. T+us- t+e
value o0 an output parameter is always t+e same as t+e underlying variable.
T+e 0ollowing de0inite assignment rules apply to output parameters. =ote t+e di00erent rules 0or re0erence
parameters described in V".1.".
( variable need not be de0initely assigned be0ore it can be passed as an output parameter in a 0unction
member or delegate invocation.
*ollowing t+e normal completion o0 a 0unction member or delegate invocation- eac+ variable t+at was
passed as an output parameter is considered assigned in t+at eecution pat+.
6it+in a 0unction member or anonymous 0unction- an output parameter is considered initially unassigned.
Every output parameter o0 a 0unction member or anonymous 0unction must be de0initely assigned JV".3M
be0ore t+e 0unction member or anonymous 0unction returns normally.
6it+in an instance constructor o0 a struct type- t+e t"is 7eyword be+aves eactly as an output parameter o0 t+e
struct type JV!.".!M.
&.1.. Local "ariables
( local varia!le is declared by a local-varia,le-declaration- w+ic+ may occur in a ,loc&- a for-state%ent- a
switch-state%ent or a !sing-state%entQ or by a foreach-state%ent or a specific-catch-cla!se 0or a tr+-state%ent.
T+e li0etime o0 a local variable is t+e portion o0 program eecution during w+ic+ storage is guaranteed to be
reserved 0or it. T+is li0etime etends at least 0rom entry into t+e ,loc&- for-state%ent- switch-state%ent- !sing-
state%ent- foreach-state%ent- or specific-catch-cla!se wit+ w+ic+ it is associated- until eecution o0 t+at ,loc&-
for-state%ent- switch-state%ent- !sing-state%ent- foreach-state%ent- or specific-catch-cla!se ends in any way.
JEntering an enclosed ,loc& or calling a met+od suspends- but does not end- eecution o0 t+e current ,loc&- for-
state%ent- switch-state%ent- !sing-state%ent- foreach-state%ent- or specific-catch-cla!se.M 10 t+e local variable
is captured by an anonymous 0unction JV!.14.4.1M- its li0etime etends at least until t+e delegate or epression
tree created 0rom t+e anonymous 0unction- along wit+ any ot+er ob&ects t+at come to re0erence t+e captured
variable- are eligible 0or garbage collection.
10 t+e parent ,loc&- for-state%ent- switch-state%ent- !sing-state%ent- foreach-state%ent- or specific-catch-cla!se
is entered recursively- a new instance o0 t+e local variable is created eac+ time- and its local-varia,le-initiali-er-
i0 any- is evaluated eac+ time.
( local variable introduced by a local-varia,le-declaration is not automatically initialiDed and t+us +as no
de0ault value. *or t+e purpose o0 de0inite assignment c+ec7ing- a local variable introduced by a local-varia,le-
declaration is considered initially unassigned. ( local-varia,le-declaration may include a local-varia,le-
initiali-er- in w+ic+ case t+e variable is considered de0initely assigned in its entire scope- ecept wit+in t+e
epression provided in t+e local-varia,le-initiali-er.
6it+in t+e scope o0 a local variableintroduced by a local-varia,le-declaration- it is a compile<time error to re0er
to t+at local variable in a tetual position t+at precedes its local-varia,le-declarator. 10 t+e local variable
declaration is implicit JV3.".1M- it is also an error to re0er to t+e variable wit+in its local-varia,le-declarator.
( local variable introduced by a foreach-state%ent or a specific-catch-cla!se is considered de0initely assigned in
its entire scope.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 1*1
C# Language Specification
T+e actual li0etime o0 a local variable is implementation<dependent. *or eample- a compiler mig+t statically
determine t+at a local variable in a bloc7 is only used 0or a small portion o0 t+at bloc7. 8sing t+is analysis- t+e
compiler could generate code t+at results in t+e variablePs storage +aving a s+orter li0etime t+an its containing
bloc7.
T+e storage re0erred to by a local re0erence variable is reclaimed independently o0 t+e li0etime o0 t+at local
re0erence variable JV3.$M.
&.2 2efault "alues
T+e 0ollowing categories o0 variables are automatically initialiDed to t+eir de0ault valuesC
#tatic variables.
1nstance variables o0 class instances.
(rray elements.
T+e de0ault value o0 a variable depends on t+e type o0 t+e variable and is determined as 0ollowsC
*or a variable o0 a val!e-t+pe- t+e de0ault value is t+e same as t+e value computed by t+e val!e-t+pePs
de0ault constructor JV4.1.2M.
*or a variable o0 a reference-t+pe- t+e de0ault value is null.
1nitialiDation to de0ault values is typically done by +aving t+e memory manager or garbage collector initialiDe
memory to all<bits<Dero be0ore it is allocated 0or use. *or t+is reason- it is convenient to use all<bits<Dero to
represent t+e null re0erence.
&.3 2efinite assignent
(t a given location in t+e eecutable code o0 a 0unction member- a variable is said to be definitely assigned i0
t+e compiler can prove- by a particular static 0low analysis JV".3.3M- t+at t+e variable +as been automatically
initialiDed or +as been t+e target o0 at least one assignment. 1n0ormally stated- t+e rules o0 de0inite assignment
areC
(n initially assigned variable JV".3.1M is always considered de0initely assigned.
(n initially unassigned variable JV".3.2M is considered de0initely assigned at a given location i0 all possible
eecution pat+s leading to t+at location contain at least one o0 t+e 0ollowingC
o ( simple assignment JV!.1%.1M in w+ic+ t+e variable is t+e le0t operand.
o (n invocation epression JV!."."M or ob&ect creation epression JV!.".1..1M t+at passes t+e variable as an
output parameter.
o *or a local variable- a local variable declaration JV3.".1M t+at includes a variable initialiDer.
T+e 0ormal speci0ication underlying t+e above in0ormal rules is described in V".3.1- V".3.2- and V".3.3.
T+e de0inite assignment states o0 instance variables o0 a str!ct-t+pe variable are trac7ed individually as well as
collectively. 1n additional to t+e rules above- t+e 0ollowing rules apply to str!ct-t+pe variables and t+eir instance
variablesC
(n instance variable is considered de0initely assigned i0 its containing str!ct-t+pe variable is considered
de0initely assigned.
( str!ct-t+pe variable is considered de0initely assigned i0 eac+ o0 its instance variables is considered
de0initely assigned.
1*2 Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
2e0inite assignment is a re9uirement in t+e 0ollowing contetsC
( variable must be de0initely assigned at eac+ location w+ere its value is obtained. T+is ensures t+at
unde0ined values never occur. T+e occurrence o0 a variable in an epression is considered to obtain t+e
value o0 t+e variable- ecept w+en
o t+e variable is t+e le0t operand o0 a simple assignment-
o t+e variable is passed as an output parameter- or
o t+e variable is a str!ct-t+pe variable and occurs as t+e le0t operand o0 a member access.
( variable must be de0initely assigned at eac+ location w+ere it is passed as a re0erence parameter. T+is
ensures t+at t+e 0unction member being invo7ed can consider t+e re0erence parameter initially assigned.
(ll output parameters o0 a 0unction member must be de0initely assigned at eac+ location w+ere t+e 0unction
member returns Jt+roug+ a return statement or t+roug+ eecution reac+ing t+e end o0 t+e 0unction member
bodyM. T+is ensures t+at 0unction members do not return unde0ined values in output parameters- t+us
enabling t+e compiler to consider a 0unction member invocation t+at ta7es a variable as an output parameter
e9uivalent to an assignment to t+e variable.
T+e t"is variable o0 a str!ct-t+pe instance constructor must be de0initely assigned at eac+ location w+ere
t+at instance constructor returns.
&.3.1 Initiall! assigned "ariables
T+e 0ollowing categories o0 variables are classi0ied as initially assignedC
#tatic variables.
1nstance variables o0 class instances.
1nstance variables o0 initially assigned struct variables.
(rray elements.
,alue parameters.
;e0erence parameters.
,ariables declared in a catc" clause or a -oreac" statement.
&.3.2 Initiall! unassigned "ariables
T+e 0ollowing categories o0 variables are classi0ied as initially unassignedC
1nstance variables o0 initially unassigned struct variables.
/utput parameters- including t+e t"is variable o0 struct instance constructors.
5ocal variables- ecept t+ose declared in a catc" clause or a -oreac" statement.
&.3.3 Precise rules for deterining definite assignent
1n order to determine t+at eac+ used variable is de0initely assigned- t+e compiler must use a process t+at is
e9uivalent to t+e one described in t+is section.
T+e compiler processes t+e body o0 eac+ 0unction member t+at +as one or more initially unassigned variables.
*or eac+ initially unassigned variable v- t+e compiler determines a definite assignent state 0or v at eac+ o0 t+e
0ollowing points in t+e 0unction memberC
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 1*3
C# Language Specification
(t t+e beginning o0 eac+ statement
(t t+e end point JV3.1M o0 eac+ statement
/n eac+ arc w+ic+ trans0ers control to anot+er statement or to t+e end point o0 a statement
(t t+e beginning o0 eac+ epression
(t t+e end o0 eac+ epression
T+e de0inite assignment state o0 v can be eit+erC
2e0initely assigned. T+is indicates t+at on all possible control 0lows to t+is point- v +as been assigned a
value.
=ot de0initely assigned. *or t+e state o0 a variable at t+e end o0 an epression o0 type bool- t+e state o0 a
variable t+at isnPt de0initely assigned may Jbut doesnPt necessarilyM 0all into one o0 t+e 0ollowing sub<statesC
o 2e0initely assigned a0ter true epression. T+is state indicates t+at v is de0initely assigned i0 t+e boolean
epression evaluated as true- but is not necessarily assigned i0 t+e boolean epression evaluated as 0alse.
o 2e0initely assigned a0ter 0alse epression. T+is state indicates t+at v is de0initely assigned i0 t+e boolean
epression evaluated as 0alse- but is not necessarily assigned i0 t+e boolean epression evaluated as true.
T+e 0ollowing rules govern +ow t+e state o0 a variable v is determined at eac+ location.
5.3.3.1 .eneral rules /or statements
v is not de0initely assigned at t+e beginning o0 a 0unction member body.
v is de0initely assigned at t+e beginning o0 any unreac+able statement.
T+e de0inite assignment state o0 v at t+e beginning o0 any ot+er statement is determined by c+ec7ing t+e
de0inite assignment state o0 v on all control 0low trans0ers t+at target t+e beginning o0 t+at statement. 10 Jand
only i0M v is de0initely assigned on all suc+ control 0low trans0ers- t+en v is de0initely assigned at t+e
beginning o0 t+e statement. T+e set o0 possible control 0low trans0ers is determined in t+e same way as 0or
c+ec7ing statement reac+ability JV3.1M.
T+e de0inite assignment state o0 v at t+e end point o0 a bloc7- c"ec(ed- unc"ec(ed- i-- ,"ile- do- -or-
-oreac"- loc(- using- or s,itc" statement is determined by c+ec7ing t+e de0inite assignment state o0 v
on all control 0low trans0ers t+at target t+e end point o0 t+at statement. 10 v is de0initely assigned on all suc+
control 0low trans0ers- t+en v is de0initely assigned at t+e end point o0 t+e statement. /t+erwiseQ v is not
de0initely assigned at t+e end point o0 t+e statement. T+e set o0 possible control 0low trans0ers is determined
in t+e same way as 0or c+ec7ing statement reac+ability JV3.1M.
5.3.3.2 (loc0 statements, chec0ed, and unchec0ed statements
T+e de0inite assignment state o0 v on t+e control trans0er to t+e 0irst statement o0 t+e statement list in t+e bloc7
Jor to t+e end point o0 t+e bloc7- i0 t+e statement list is emptyM is t+e same as t+e de0inite assignment statement
o0 v be0ore t+e bloc7- c"ec(ed- or unc"ec(ed statement.
5.3.3.3 %$"ression statements
*or an epression statement st%t t+at consists o0 t+e epression e/prC
v +as t+e same de0inite assignment state at t+e beginning o0 e/pr as at t+e beginning o0 st%t.
1*" Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
10 v i0 de0initely assigned at t+e end o0 e/pr- it is de0initely assigned at t+e end point o0 st%tQ ot+erwiseQ it is
not de0initely assigned at t+e end point o0 st%t.
5.3.3.4 'eclaration statements
10 st%t is a declaration statement wit+out initialiDers- t+en v +as t+e same de0inite assignment state at t+e end
point o0 st%t as at t+e beginning o0 st%t.
10 st%t is a declaration statement wit+ initialiDers- t+en t+e de0inite assignment state 0or v is determined as i0
st%t were a statement list- wit+ one assignment statement 0or eac+ declaration wit+ an initialiDer Jin t+e
order o0 declarationM.
5.3.3.5 #/ statements
*or an i- statement st%t o0 t+e 0ormC
i- ( e/pr ) then-st%t else else-st%t
v +as t+e same de0inite assignment state at t+e beginning o0 e/pr as at t+e beginning o0 st%t.
10 v is de0initely assigned at t+e end o0 e/pr- t+en it is de0initely assigned on t+e control 0low trans0er to
then-st%t and to eit+er else-st%t or to t+e end<point o0 st%t i0 t+ere is no else clause.
10 v +as t+e state Kde0initely assigned a0ter true epressionL at t+e end o0 e/pr- t+en it is de0initely assigned
on t+e control 0low trans0er to then-st%t- and not de0initely assigned on t+e control 0low trans0er to eit+er
else-st%t or to t+e end<point o0 st%t i0 t+ere is no else clause.
10 v +as t+e state Kde0initely assigned a0ter 0alse epressionL at t+e end o0 e/pr- t+en it is de0initely assigned
on t+e control 0low trans0er to else-st%t- and not de0initely assigned on t+e control 0low trans0er to then-st%t.
1t is de0initely assigned at t+e end<point o0 st%t i0 and only i0 it is de0initely assigned at t+e end<point o0
then-st%t.
/t+erwise- v is considered not de0initely assigned on t+e control 0low trans0er to eit+er t+e then-st%t or else-
st%t- or to t+e end<point o0 st%t i0 t+ere is no else clause.
5.3.3.6 S,itch statements
1n a s,itc" statement st%t wit+ a controlling epression e/prC
T+e de0inite assignment state o0 v at t+e beginning o0 e/pr is t+e same as t+e state o0 v at t+e beginning o0
st%t.
T+e de0inite assignment state o0 v on t+e control 0low trans0er to a reac+able switc+ bloc7 statement list is
t+e same as t+e de0inite assignment state o0 v at t+e end o0 e/pr.
5.3.3. 1hile statements
*or a ,"ile statement st%t o0 t+e 0ormC
,"ile ( e/pr ) while-,od+
v +as t+e same de0inite assignment state at t+e beginning o0 e/pr as at t+e beginning o0 st%t.
10 v is de0initely assigned at t+e end o0 e/pr- t+en it is de0initely assigned on t+e control 0low trans0er to
while-,od+ and to t+e end point o0 st%t.
10 v +as t+e state Kde0initely assigned a0ter true epressionL at t+e end o0 e/pr- t+en it is de0initely assigned
on t+e control 0low trans0er to while-,od+- but not de0initely assigned at t+e end<point o0 st%t.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 1*
C# Language Specification
10 v +as t+e state Kde0initely assigned a0ter 0alse epressionL at t+e end o0 e/pr- t+en it is de0initely assigned
on t+e control 0low trans0er to t+e end point o0 st%t- but not de0initely assigned on t+e control 0low trans0er
to while-,od+.
5.3.3.+ 'o statements
*or a do statement st%t o0 t+e 0ormC
do do-,od+ ,"ile ( e/pr ) ;
v +as t+e same de0inite assignment state on t+e control 0low trans0er 0rom t+e beginning o0 st%t to do-,od+
as at t+e beginning o0 st%t.
v +as t+e same de0inite assignment state at t+e beginning o0 e/pr as at t+e end point o0 do-,od+.
10 v is de0initely assigned at t+e end o0 e/pr- t+en it is de0initely assigned on t+e control 0low trans0er to t+e
end point o0 st%t.
10 v +as t+e state Kde0initely assigned a0ter 0alse epressionL at t+e end o0 e/pr- t+en it is de0initely assigned
on t+e control 0low trans0er to t+e end point o0 st%t.
5.3.3.2 3or statements
2e0inite assignment c+ec7ing 0or a -or statement o0 t+e 0ormC
-or ( for-initiali-er ; for-condition ; for-iterator ) e%,edded-state%ent
is done as i0 t+e statement were writtenC
{
for-initiali-er ;
,"ile ( for-condition ) {
e%,edded-state%ent ;
for-iterator ;
!
!
10 t+e for-condition is omitted 0rom t+e -or statement- t+en evaluation o0 de0inite assignment proceeds as i0 for-
condition were replaced wit+ true in t+e above epansion.
5.3.3.14 (rea0, continue, and goto statements
T+e de0inite assignment state o0 v on t+e control 0low trans0er caused by a brea(- continue- or goto
statement is t+e same as t+e de0inite assignment state o0 v at t+e beginning o0 t+e statement.
5.3.3.11 *hro, statements
*or a statement st%t o0 t+e 0orm
t"ro, e/pr ;
T+e de0inite assignment state o0 v at t+e beginning o0 e/pr is t+e same as t+e de0inite assignment state o0 v at t+e
beginning o0 st%t.
5.3.3.12 )eturn statements
*or a statement st%t o0 t+e 0orm
return e/pr ;
1*' Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
T+e de0inite assignment state o0 v at t+e beginning o0 e/pr is t+e same as t+e de0inite assignment state o0 v at
t+e beginning o0 st%t.
10 v is an output parameter- t+en it must be de0initely assigned eit+erC
o a0ter e/pr
o or at t+e end o0 t+e -inally bloc7 o0 a try<-inally or try<catc"<-inally t+at encloses t+e
return statement.
*or a statement stmt o0 t+e 0ormC
return ;
10 v is an output parameter- t+en it must be de0initely assigned eit+erC
o be0ore st%t
o or at t+e end o0 t+e -inally bloc7 o0 a try<-inally or try<catc"<-inally t+at encloses t+e
return statement.
5.3.3.13 *ry5catch statements
*or a statement st%t o0 t+e 0ormC
try tr+-,loc&
catc"(...) catch-,loc&-1
...
catc"(...) catch-,loc&-n
T+e de0inite assignment state o0 v at t+e beginning o0 tr+-,loc& is t+e same as t+e de0inite assignment state
o0 v at t+e beginning o0 st%t.
T+e de0inite assignment state o0 v at t+e beginning o0 catch-,loc&-i J0or any iM is t+e same as t+e de0inite
assignment state o0 v at t+e beginning o0 st%t.
T+e de0inite assignment state o0 v at t+e end<point o0 st%t is de0initely assigned i0 Jand only i0M v is de0initely
assigned at t+e end<point o0 tr+-,loc& and every catch-,loc&-i J0or every i 0rom 1 to nM.
5.3.3.14 *ry5/inally statements
*or a try statement st%t o0 t+e 0ormC
try tr+-,loc& -inally finall+-,loc&
T+e de0inite assignment state o0 v at t+e beginning o0 tr+-,loc& is t+e same as t+e de0inite assignment state
o0 v at t+e beginning o0 st%t.
T+e de0inite assignment state o0 v at t+e beginning o0 finall+-,loc& is t+e same as t+e de0inite assignment
state o0 v at t+e beginning o0 st%t.
T+e de0inite assignment state o0 v at t+e end<point o0 st%t is de0initely assigned i0 Jand only i0M at least one
o0 t+e 0ollowing is trueC
o v is de0initely assigned at t+e end<point o0 tr+-,loc&
o v is de0initely assigned at t+e end<point o0 finall+-,loc&
10 a control 0low trans0er J0or eample- a goto statementM is made t+at begins wit+in tr+-,loc&- and ends outside
o0 tr+-,loc&- t+en v is also considered de0initely assigned on t+at control 0low trans0er i0 v is de0initely assigned
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 1*7
C# Language Specification
at t+e end<point o0 finall+-,loc&. JT+is is not an only i0Ri0 v is de0initely assigned 0or anot+er reason on t+is
control 0low trans0er- t+en it is still considered de0initely assigned.M
5.3.3.15 *ry5catch5/inally statements
2e0inite assignment analysis 0or a try<catc"<-inally statement o0 t+e 0ormC
try tr+-,loc&
catc"(...) catch-,loc&-1
...
catc"(...) catch-,loc&-n
-inally finall+-,loc&
is done as i0 t+e statement were a try<-inally statement enclosing a try<catc" statementC
try {
try tr+-,loc&
catc"(...) catch-,loc&-1
...
catc"(...) catch-,loc&-n
!
-inally finall+-,loc&
T+e 0ollowing eample demonstrates +ow t+e di00erent bloc7s o0 a try statement JV3.1.M a00ect de0inite
assignment.
class '
{
static void V() {
int i j;
try {
goto L':)L;
.. neit"er i nor j de-initely assigned
i + 2;
.. i de-initely assigned
!
catc" {
.. neit"er i nor j de-initely assigned
i + 9;
.. i de-initely assigned
!
-inally {
.. neit"er i nor j de-initely assigned
j + K;
.. j de-initely assigned
!
.. i and j de-initely assigned
L':)L/;
.. j de-initely assigned
!
!
5.3.3.16 3oreach statements
*or a -oreac" statement st%t o0 t+e 0ormC
1*$ Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
-oreac" ( t+pe identifier in e/pr ) e%,edded-state%ent
T+e de0inite assignment state o0 v at t+e beginning o0 e/pr is t+e same as t+e state o0 v at t+e beginning o0
st%t.
T+e de0inite assignment state o0 v on t+e control 0low trans0er to e%,edded-state%ent or to t+e end point o0
st%t is t+e same as t+e state o0 v at t+e end o0 e/pr.
5.3.3.1 6sing statements
*or a using statement st%t o0 t+e 0ormC
using ( reso!rce-ac8!isition ) e%,edded-state%ent
T+e de0inite assignment state o0 v at t+e beginning o0 reso!rce-ac8!isition is t+e same as t+e state o0 v at t+e
beginning o0 st%t.
T+e de0inite assignment state o0 v on t+e control 0low trans0er to e%,edded-state%ent is t+e same as t+e state
o0 v at t+e end o0 reso!rce-ac8!isition.
5.3.3.1+ 7oc0 statements
*or a loc( statement st%t o0 t+e 0ormC
loc( ( e/pr ) e%,edded-state%ent
T+e de0inite assignment state o0 v at t+e beginning o0 e/pr is t+e same as t+e state o0 v at t+e beginning o0
st%t.
T+e de0inite assignment state o0 v on t+e control 0low trans0er to e%,edded-state%ent is t+e same as t+e state
o0 v at t+e end o0 e/pr.
5.3.3.12 8ield statements
*or a yield return statement st%t o0 t+e 0ormC
yield return e/pr ;
T+e de0inite assignment state o0 v at t+e beginning o0 e/pr is t+e same as t+e state o0 v at t+e beginning o0
st%t.
T+e de0inite assignment state o0 v at t+e end o0 st%t is t+e same as t+e state o0 v at t+e end o0 e/pr.
( yield brea( statement +as no e00ect on t+e de0inite assignment state.
5.3.3.24 .eneral rules /or sim"le e$"ressions
T+e 0ollowing rule applies to t+ese 7inds o0 epressionsC literals JV!.".1M- simple names JV!.".2M- member access
epressions JV!.".4M- non<indeed base access epressions JV!.".3M- ty&eo- epressions JV!.".11M- and de0ault
value epressions JV!.".13M.
T+e de0inite assignment state o0 v at t+e end o0 suc+ an epression is t+e same as t+e de0inite assignment
state o0 v at t+e beginning o0 t+e epression.
5.3.3.21 .eneral rules /or e$"ressions ,ith embedded e$"ressions
T+e 0ollowing rules apply to t+ese 7inds o0 epressionsC parent+esiDed epressions JV!.".3M- element access
epressions JV!.".%M- base access epressions wit+ indeing JV!.".3M- increment and decrement epressions
JV!.".$- V!.%."M- cast epressions JV!.%.%M- unary <- =- A- > epressions- binary <- =- >- .- B- DD- EE- D- D+- E- E+-
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 1*!
C# Language Specification
++- @+- is- as- F- H- G epressions JV!.!- V!.3- V!.$- V!.1.M- compound assignment epressions JV!.1%.2M-
c"ec(ed and unc"ec(ed epressions JV!.".12M- plus array and delegate creation epressions JV!.".1.M.
Eac+ o0 t+ese epressions +as one or more sub<epressions t+at are unconditionally evaluated in a 0ied order.
*or eample- t+e binary B operator evaluates t+e le0t +and side o0 t+e operator- t+en t+e rig+t +and side. (n
indeing operation evaluates t+e indeed epression- and t+en evaluates eac+ o0 t+e inde epressions- in order
0rom le0t to rig+t. *or an epression e/pr- w+ic+ +as sub<epressions e/pr1- e/pr2- ...- e/prn- evaluated in t+at
orderC
T+e de0inite assignment state o0 v at t+e beginning o0 e/pr1 is t+e same as t+e de0inite assignment state at t+e
beginning o0 e/pr.
T+e de0inite assignment state o0 v at t+e beginning o0 e/pri Ji greater t+an oneM is t+e same as t+e de0inite
assignment state at t+e end o0 e/pri-1.
T+e de0inite assignment state o0 v at t+e end o0 e/pr is t+e same as t+e de0inite assignment state at t+e end o0
e/prn.
5.3.3.22 #nvocation e$"ressions and ob9ect creation e$"ressions
*or an invocation epression e/pr o0 t+e 0ormC
pri%ar+-e/pression ( arg1 arg2 b argn )
or an ob&ect creation epression o0 t+e 0ormC
ne, t+pe ( arg1 arg2 b argn )
*or an invocation epression- t+e de0inite assignment state o0 v be0ore pri%ar+-e/pression is t+e same as t+e
state o0 v be0ore e/pr.
*or an invocation epression- t+e de0inite assignment state o0 v be0ore arg1 is t+e same as t+e state o0 v a0ter
pri%ar+-e/pression.
*or an ob&ect creation epression- t+e de0inite assignment state o0 v be0ore arg1 is t+e same as t+e state o0 v
be0ore e/pr.
*or eac+ argument argi- t+e de0inite assignment state o0 v a0ter argi is determined by t+e normal epression
rules- ignoring any re- or out modi0iers.
*or eac+ argument argi 0or any i greater t+an one- t+e de0inite assignment state o0 v be0ore argi is t+e same
as t+e state o0 v a0ter argi-1.
10 t+e variable v is passed as an out argument Ji.e.- an argument o0 t+e 0orm Kout vLM in any o0 t+e
arguments- t+en t+e state o0 v a0ter e/pr is de0initely assigned. /t+erwiseQ t+e state o0 v a0ter e/pr is t+e
same as t+e state o0 v a0ter argn.
*or array initialiDers JV!.".1..4M- ob&ect initialiDers JV!.".1..2M- collection initialiDers JV!.".1..3M and
anonymous ob&ect initialiDers JV!.".1..%M- t+e de0inite assignment state is determined by t+e epansion t+at
t+ese constructs are de0ined in terms o0.
5.3.3.23 Sim"le assignment e$"ressions
*or an epression e/pr o0 t+e 0orm w + e/pr-rhsC
T+e de0inite assignment state o0 v be0ore e/pr-rhs is t+e same as t+e de0inite assignment state o0 v be0ore
e/pr.
11* Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
10 w is t+e same variable as v- t+en t+e de0inite assignment state o0 v a0ter e/pr is de0initely assigned.
/t+erwise- t+e de0inite assignment state o0 v a0ter e/pr is t+e same as t+e de0inite assignment state o0 v a0ter
e/pr-rhs.
5.3.3.24 :: e$"ressions
*or an epression e/pr o0 t+e 0orm e/pr-first FF e/pr-secondC
T+e de0inite assignment state o0 v be0ore e/pr-first is t+e same as t+e de0inite assignment state o0 v be0ore
e/pr.
T+e de0inite assignment state o0 v be0ore e/pr-second is de0initely assigned i0 t+e state o0 v a0ter e/pr-first is
eit+er de0initely assigned or Kde0initely assigned a0ter true epressionL. /t+erwise- it is not de0initely
assigned.
T+e de0inite assignment state o0 v a0ter e/pr is determined byC
o 10 t+e state o0 v a0ter e/pr-first is de0initely assigned- t+en t+e state o0 v a0ter e/pr is de0initely assigned.
o /t+erwise- i0 t+e state o0 v a0ter e/pr-second is de0initely assigned- and t+e state o0 v a0ter e/pr-first is
Kde0initely assigned a0ter 0alse epressionL- t+en t+e state o0 v a0ter e/pr is de0initely assigned.
o /t+erwise- i0 t+e state o0 v a0ter e/pr-second is de0initely assigned or Kde0initely assigned a0ter true
epressionL- t+en t+e state o0 v a0ter e/pr is Kde0initely assigned a0ter true epressionL.
o /t+erwise- i0 t+e state o0 v a0ter e/pr-first is Kde0initely assigned a0ter 0alse epressionL- and t+e state o0
v a0ter e/pr-second is Kde0initely assigned a0ter 0alse epressionL- t+en t+e state o0 v a0ter e/pr is
Kde0initely assigned a0ter 0alse epressionL.
o /t+erwise- t+e state o0 v a0ter e/pr is not de0initely assigned.
1n t+e eample
class '
{
static void V(int # int y) {
int i;
i- (# E+ 3 FF (i + y) E+ 3) {
.. i de-initely assigned
!
else {
.. i not de-initely assigned
!
.. i not de-initely assigned
!
!
t+e variable i is considered de0initely assigned in one o0 t+e embedded statements o0 an i- statement but not in
t+e ot+er. 1n t+e i- statement in met+od V- t+e variable i is de0initely assigned in t+e 0irst embedded statement
because eecution o0 t+e epression (i + y) always precedes eecution o0 t+is embedded statement. 1n contrast-
t+e variable i is not de0initely assigned in t+e second embedded statement- since # E+ 3 mig+t +ave tested 0alse-
resulting in t+e variable i being unassigned.
5.3.3.25 ;; e$"ressions
*or an epression e/pr o0 t+e 0orm e/pr-first HH e/pr-secondC
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 111
C# Language Specification
T+e de0inite assignment state o0 v be0ore e/pr-first is t+e same as t+e de0inite assignment state o0 v be0ore
e/pr.
T+e de0inite assignment state o0 v be0ore e/pr-second is de0initely assigned i0 t+e state o0 v a0ter e/pr-first is
eit+er de0initely assigned or Kde0initely assigned a0ter 0alse epressionL. /t+erwise- it is not de0initely
assigned.
T+e de0inite assignment statement o0 v a0ter e/pr is determined byC
o 10 t+e state o0 v a0ter e/pr-first is de0initely assigned- t+en t+e state o0 v a0ter e/pr is de0initely assigned.
o /t+erwise- i0 t+e state o0 v a0ter e/pr-second is de0initely assigned- and t+e state o0 v a0ter e/pr-first is
Kde0initely assigned a0ter true epressionL- t+en t+e state o0 v a0ter e/pr is de0initely assigned.
o /t+erwise- i0 t+e state o0 v a0ter e/pr-second is de0initely assigned or Kde0initely assigned a0ter 0alse
epressionL- t+en t+e state o0 v a0ter e/pr is Kde0initely assigned a0ter 0alse epressionL.
o /t+erwise- i0 t+e state o0 v a0ter e/pr-first is Kde0initely assigned a0ter true epressionL- and t+e state o0
v a0ter e/pr-second is Kde0initely assigned a0ter true epressionL- t+en t+e state o0 v a0ter e/pr is
Kde0initely assigned a0ter true epressionL.
o /t+erwise- t+e state o0 v a0ter e/pr is not de0initely assigned.
1n t+e eample
class '
{
static void S(int # int y) {
int i;
i- (# E+ 3 HH (i + y) E+ 3) {
.. i not de-initely assigned
!
else {
.. i de-initely assigned
!
.. i not de-initely assigned
!
!
t+e variable i is considered de0initely assigned in one o0 t+e embedded statements o0 an i- statement but not in
t+e ot+er. 1n t+e i- statement in met+od S- t+e variable i is de0initely assigned in t+e second embedded
statement because eecution o0 t+e epression (i + y) always precedes eecution o0 t+is embedded statement.
1n contrast- t+e variable i is not de0initely assigned in t+e 0irst embedded statement- since # E+ 3 mig+t +ave
tested true- resulting in t+e variable i being unassigned.
5.3.3.26 < e$"ressions
*or an epression e/pr o0 t+e 0orm @ e/pr-operandC
T+e de0inite assignment state o0 v be0ore e/pr-operand is t+e same as t+e de0inite assignment state o0 v
be0ore e/pr.
T+e de0inite assignment state o0 v a0ter e/pr is determined byC
o 10 t+e state o0 v a0ter e/pr-operand is de0initely assigned- t+en t+e state o0 v a0ter e/pr is de0initely
assigned.
o 10 t+e state o0 v a0ter e/pr-operand is not de0initely assigned- t+en t+e state o0 v a0ter e/pr is not
de0initely assigned.
112 Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
o 10 t+e state o0 v a0ter e/pr-operand is Kde0initely assigned a0ter 0alse epressionL- t+en t+e state o0 v a0ter
e/pr is Kde0initely assigned a0ter true epressionL.
o 10 t+e state o0 v a0ter e/pr-operand is Kde0initely assigned a0ter true epressionL- t+en t+e state o0 v a0ter
e/pr is Kde0initely assigned a0ter 0alse epressionL.
5.3.3.2 == e$"ressions
*or an epression e/pr o0 t+e 0orm e/pr-first 77 e/pr-secondC
T+e de0inite assignment state o0 v be0ore e/pr-first is t+e same as t+e de0inite assignment state o0 v be0ore
e/pr.
T+e de0inite assignment state o0 v be0ore e/pr-second is t+e same as t+e de0inite assignment state o0 v a0ter
e/pr-first.
T+e de0inite assignment statement o0 v a0ter e/pr is determined byC
o 10 e/pr-first is a constant epression JV!.13M wit+ value null- t+en t+e t+e state o0 v a0ter e/pr is t+e same
as t+e state o0 v a0ter e/pr-second.
/t+erwise- t+e state o0 v a0ter e/pr is t+e same as t+e de0inite assignment state o0 v a0ter e/pr-first.
5.3.3.2+ => e$"ressions
*or an epression e/pr o0 t+e 0orm e/pr-cond 7 e/pr-tr!e / e/pr-falseC
T+e de0inite assignment state o0 v be0ore e/pr-cond is t+e same as t+e state o0 v be0ore e/pr.
T+e de0inite assignment state o0 v be0ore e/pr-tr!e is de0initely assigned i0 and only i0 t+e state o0 v a0ter
e/pr-cond is de0initely assigned or Kde0initely assigned a0ter true epressionL.
T+e de0inite assignment state o0 v be0ore e/pr-false is de0initely assigned i0 and only i0 t+e state o0 v a0ter
e/pr-cond is de0initely assigned or Kde0initely assigned a0ter 0alse epressionL.
T+e de0inite assignment state o0 v a0ter e/pr is determined byC
o 10 e/pr-cond is a constant epression JV!.13M wit+ value true t+en t+e state o0 v a0ter e/pr is t+e same
as t+e state o0 v a0ter e/pr-tr!e.
o /t+erwise- i0 e/pr-cond is a constant epression JV!.13M wit+ value -alse t+en t+e state o0 v a0ter e/pr
is t+e same as t+e state o0 v a0ter e/pr-false.
o /t+erwise- i0 t+e state o0 v a0ter e/pr-tr!e is de0initely assigned and t+e state o0 v a0ter e/pr-false is
de0initely assigned- t+en t+e state o0 v a0ter e/pr is de0initely assigned.
o /t+erwise- t+e state o0 v a0ter e/pr is not de0initely assigned.
5.3.3.22 ?nonymous /unctions
*or a la%,da-e/pression or anon+%o!s-%ethod-e/pression e/pr wit+ a body Jeit+er ,loc& or e/pressionM ,od+C
T+e de0inite assignment state o0 an outer variable v be0ore ,od+ is t+e same as t+e state o0 v be0ore e/pr.
T+at is- de0inite assignment state o0 outer variables is in+erited 0rom t+e contet o0 t+e anonymous 0unction.
T+e de0inite assignment state o0 an outer variable v a0ter e/pr is t+e same as t+e state o0 v be0ore e/pr.
T+e eample
delegate bool Vilter(int i);
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 113
C# Language Specification
void V() {
int ma#;
.. )rror ma# is not de-initely assigned
Vilter - + (int n) +E n D ma#;
ma# + K;
6oWor((-);
!
generates a compile<time error since ma# is not de0initely assigned w+ere t+e anonymous 0unction is declared.
T+e eample
delegate void 6();
void V() {
int n;
6 d + () +E { n + 2; !;
d();
.. )rror n is not de-initely assigned
Console.WriteLine(n);
!
also generates a compile<time error since t+e assignment to n in t+e anonymous 0unction +as no a00ect on t+e
de0inite assignment state o0 n outside t+e anonymous 0unction.
&.# Variable references
( varia,le-reference is an e/pression t+at is classi0ied as a variable. ( varia,le-reference denotes a storage
location t+at can be accessed bot+ to 0etc+ t+e current value and to store a new value.
varia,le-reference.
e/pression
1n C and CNN- a varia,le-reference is 7nown as an lval!e.
&.& *toicit! of "ariable references
;eads and writes o0 t+e 0ollowing data types are atomicC bool- c"ar- byte- sbyte- s"ort- us"ort- uint-
int- -loat- and re0erence types. 1n addition- reads and writes o0 enum types wit+ an underlying type in t+e
previous list are also atomic. ;eads and writes o0 ot+er types- including long- ulong- double- and decimal-
as well as user<de0ined types- are not guaranteed to be atomic. (side 0rom t+e library 0unctions designed 0or t+at
purpose- t+ere is no guarantee o0 atomic read<modi0y<write- suc+ as in t+e case o0 increment or decrement.
11" Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
'. Con"ersions
( conversion enables an epression to be treated as being o0 a particluar type. ( conversion may cause an
epression o0 a given type to be treated as +aving a di00erent type- or it may cause an epression wit+out a type
to get a type. Conversions can be iplicit or e,plicit- and t+is determines w+et+er an eplicit cast is re9uired.
*or instance- t+e conversion 0rom type int to type long is implicit- so epressions o0 type int can implicitly
be treated as type long. T+e opposite conversion- 0rom type long to type int- is eplicit and so an eplicit cast
is re9uired.
int a + 289;
long b + a; .. im&licit conversion -rom int to long
int c + (int) b; .. e#&licit conversion -rom long to int
#ome conversions are de0ined by t+e language. Programs may also de0ine t+eir own conversions JV%.4M.
'.1 Iplicit con"ersions
T+e 0ollowing conversions are classi0ied as implicit conversionsC
1dentity conversions
1mplicit numeric conversions
1mplicit enumeration conversions.
1mplicit nullable conversions
=ull literal conversions
1mplicit re0erence conversions
)oing conversions
1mplicit constant epression conversions
8ser<de0ined implicit conversions
(nonymous 0unction conversions
'et+od group conversions
1mplicit conversions can occur in a variety o0 situations- including 0unction member invocations JV!.4.4M- cast
epressions JV!.%.%M- and assignments JV!.1%M.
T+e pre<de0ined implicit conversions always succeed and never cause eceptions to be t+rown. Properly
designed user<de0ined implicit conversions s+ould e+ibit t+ese c+aracteristics as well.
'.1.1 Identit! con"ersion
(n identity conversion converts 0rom any type to t+e same type. T+is conversion eists only suc+ t+at an entity
t+at already +as a re9uired type can be said to be convertible to t+at type.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 11
C# Language Specification
'.1.2 Iplicit nueric con"ersions
T+e implicit numeric conversions areC
*rom sbyte to s"ort- int- long- -loat- double- or decimal.
*rom byte to s"ort- us"ort- int- uint- long- ulong- -loat- double- or decimal.
*rom s"ort to int- long- -loat- double- or decimal.
*rom us"ort to int- uint- long- ulong- -loat- double- or decimal.
*rom int to long- -loat- double- or decimal.
*rom uint to long- ulong- -loat- double- or decimal.
*rom long to -loat- double- or decimal.
*rom ulong to -loat- double- or decimal.
*rom c"ar to us"ort- int- uint- long- ulong- -loat- double- or decimal.
*rom -loat to double.
Conversions 0rom int- uint- long- or ulong to -loat and 0rom long or ulong to double may cause a loss
o0 precision- but will never cause a loss o0 magnitude. T+e ot+er implicit numeric conversions never lose any
in0ormation.
T+ere are no implicit conversions to t+e c"ar type- so values o0 t+e ot+er integral types do not automatically
convert to t+e c"ar type.
'.1.3 Iplicit enueration con"ersions
(n implicit enumeration conversion permits t+e deci%al-integer-literal 3 to be converted to any en!%-t+pe and
to any n!lla,le-t+pe w+ose underlying type is an en!%-t+pe. 1n t+e latter case t+e conversion is evaluated by
converting to t+e underlying en!%-t+pe and wrapping t+e result JV4.1.1.M.
'.1.# Iplicit nullable con"ersions
Prede0ined implicit conversions t+at operate on non<nullable value types can also be used wit+ nullable 0orms o0
t+ose types. *or eac+ o0 t+e prede0ined implicit identity and numeric conversions t+at convert 0rom a non<
nullable value type S to a non<nullable value type 1- t+e 0ollowing implicit nullable conversions eistC
(n implicit conversion 0rom S7 to 17.
(n implicit conversion 0rom S to 17.
Evaluation o0 an implicit nullable conversion based on an underlying conversion 0rom S to 1 proceeds as
0ollowsC
10 t+e nullable conversion is 0rom S7 to 17C
o 10 t+e source value is null JHasUalue property is 0alseM- t+e result is t+e null value o0 type 17.
o /t+erwise- t+e conversion is evaluated as an unwrapping 0rom S7 to S- 0ollowed by t+e underlying
conversion 0rom S to 1- 0ollowed by a wrapping JV4.1.1.M 0rom 1 to 17.
10 t+e nullable conversion is 0rom S to 17- t+e conversion is evaluated as t+e underlying conversion 0rom S
to 1 0ollowed by a wrapping 0rom 1 to 17.
11' Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
'.1.& ;ull literal con"ersions
(n implicit conversion eists 0rom t+e null literal to any nullable type. T+is conversion produces t+e null value
JV4.1.1.M o0 t+e given nullable type.
'.1.' Iplicit reference con"ersions
T+e implicit re0erence conversions areC
*rom any reference-t+pe to object.
*rom any class-t+pe S to any class-t+pe 1- provided S is derived 0rom 1.
*rom any class-t+pe S to any interface-t+pe 1- provided S implements 1.
*rom any interface-t+pe S to any interface-t+pe 1- provided S is derived 0rom 1.
*rom an arra+-t+pe S wit+ an element type S
)
to an arra+-t+pe 1 wit+ an element type 1
)
- provided all o0 t+e
0ollowing are trueC
o S and 1 di00er only in element type. 1n ot+er words- S and 1 +ave t+e same number o0 dimensions.
o )ot+ S
)
and 1
)
are reference-t+pes.
o (n implicit re0erence conversion eists 0rom S
)
to 1
)
.
*rom any arra+-t+pe to System.'rray.
*rom a single<dimensional array type S45 to System.Collections.Seneric.$ListD1E and its base
inter0aces- provided t+at t+ere is an implicit identity or re0erence conversion 0rom S to 1.
*rom any delegate-t+pe to System.6elegate.
*rom t+e null literal to any reference-t+pe.
1mplicit conversions involving type parameters t+at are 7nown to be re0erence types. #ee V%.1.$ 0or more
details on implicit conversions involving type parameters.
T+e implicit re0erence conversions are t+ose conversions between reference-t+pes t+at can be proven to always
succeed- and t+ere0ore re9uire no c+ec7s at run<time.
;e0erence conversions- implicit or eplicit- never c+ange t+e re0erential identity o0 t+e ob&ect being converted.
1n ot+er words- w+ile a re0erence conversion may c+ange t+e type o0 t+e re0erence- it never c+anges t+e type or
value o0 t+e ob&ect being re0erred to.
8nli7e array types- constructed re0erence types do not e+ibit KcovariantL conversions. T+is means t+at a type
ListD:E +as no conversion Jeit+er implicit or eplicitM to ListD'E even i0 : is derived 0rom '. 5i7ewise- no
conversion eists 0rom ListD:E to ListDobjectE.
'.1.. +o%ing con"ersions
( boing conversion permits a val!e-t+pe to be implicitly converted to a re0erence type. ( boing conversion
eists 0rom any non-n!lla,le-val!e-t+pe to object- to System.Ualue1y&e and to any interface-t+pe
implemented by t+e non-n!lla,le-val!e-t+pe. *urt+ermore an en!%-t+pe can be converted to t+e type
System.)num.
( boing conversion eists 0rom a n!lla,le-t+pe to a re0erence type- i0 and only i0 a boing conversion eists
0rom t+e underlying non-n!lla,le-val!e-t+pe to t+e re0erence type.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 117
C# Language Specification
)oing a value o0 a non-n!lla,le-val!e-t+pe consists o0 allocating an ob&ect instance and copying t+e val!e-t+pe
value into t+at instance. ( struct can be boed to t+e type System.Ualue1y&e- since t+at is a base class 0or all
structs JV11.3.2M.
)oing a value o0 a n!lla,le-t+pe proceeds as 0ollowsC
10 t+e source value is null JHasUalue property is 0alseM- t+e result is a null re0erence o0 t+e target type.
/t+erwise- t+e result is a re0erence to a boed 1 produced by unwrapping and boing t+e source value.
)oing conversions are described 0urt+er in V4.3.1.
'.1.0 Iplicit constant e%pression con"ersions
(n implicit constant epression conversion permits t+e 0ollowing conversionsC
( constant-e/pression JV!.13M o0 type int can be converted to type sbyte- byte- s"ort- us"ort- uint-
or ulong- provided t+e value o0 t+e constant-e/pression is wit+in t+e range o0 t+e destination type.
( constant-e/pression o0 type long can be converted to type ulong- provided t+e value o0 t+e constant-
e/pression is not negative.
'.1.1 Iplicit con"ersions in"ol"ing t!pe paraeters
T+e 0ollowing implicit conversions eist 0or a given type parameter 1C
*rom 1 to its e00ective base class C- 0rom 1 to any base class o0 C- and 0rom 1 to any inter0ace implemented
by C. (t run<time- i0 1 is a value type- t+e conversion is eecuted as a boing conversion. /t+erwise- t+e
conversion is eecuted as an implicit re0erence conversion or identity conversion.
*rom 1 to an inter0ace type $ in 1Ps e00ective inter0ace set and 0rom 1 to any base inter0ace o0 $. (t run<
time- i0 1 is a value type- t+e conversion is eecuted as a boing conversion. /t+erwise- t+e conversion is
eecuted as an implicit re0erence conversion or identity conversion.
*rom 1 to a type parameter ;- provided 1 depends on ;. (t run<time- i0 1 is a value type and ; is a re0erence
type- t+e conversion is eecuted as a boing conversion. /t+erwise- i0 bot+ 1 and ; are value types- t+en 1
and ; are necessarily t+e same type and no conversion is per0ormed. /t+erwise- i0 1 is a re0erence type- t+en
; is necessarily also a re0erence type and t+e conversion is eecuted as an implicit re0erence conversion or
identity conversion.
*rom t+e null literal to 1- provided 1 is 7nown to be a re0erence type.
10 1 is 7nown to be a re0erence type JV1..1."M- t+e conversions above are all classi0ied as implicit re0erence
conversions JV%.1.%M. 10 1 is not 7nown to be a re0erence type- t+e conversions described in t+e 0irst two bullets
above are classi0ied as boing conversions JV%.1.!M.
'.1.10 6ser9defined iplicit con"ersions
( user<de0ined implicit conversion consists o0 an optional standard implicit conversion- 0ollowed by eecution
o0 a user<de0ined implicit conversion operator- 0ollowed by anot+er optional standard implicit conversion. T+e
eact rules 0or evaluating user<de0ined implicit conversions are described in V%.4.4.
'.1.11 *non!ous function con"ersions and et-od group con"ersions
(nonymous 0unctions and met+od groups do not +ave types in and o0 t+emselves- but may be implicitly
converted to delegate types or epression tree types. (nonymous 0unction conversions are described in more
detail in V%." and met+od group conversions in V%.%.
11$ Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
'.2 $%plicit con"ersions
T+e 0ollowing conversions are classi0ied as eplicit conversionsC
(ll implicit conversions.
Eplicit numeric conversions.
Eplicit enumeration conversions.
Eplicit nullable conversions.
Eplicit re0erence conversions.
Eplicit inter0ace conversions.
8nboing conversions.
8ser<de0ined eplicit conversions.
Eplicit conversions can occur in cast epressions JV!.%.%M.
T+e set o0 eplicit conversions includes all implicit conversions. T+is means t+at redundant cast epressions are
allowed.
T+e eplicit conversions t+at are not implicit conversions are conversions t+at cannot be proven to always
succeed- conversions t+at are 7nown to possibly lose in0ormation- and conversions across domains o0 types
su00iciently di00erent to merit eplicit notation.
'.2.1 $%plicit nueric con"ersions
T+e eplicit numeric conversions are t+e conversions 0rom a n!%eric-t+pe to anot+er n!%eric-t+pe 0or w+ic+ an
implicit numeric conversion JV%.1.2M does not already eistC
*rom sbyte to byte- us"ort- uint- ulong- or c"ar.
*rom byte to sbyte and c"ar.
*rom s"ort to sbyte- byte- us"ort- uint- ulong- or c"ar.
*rom us"ort to sbyte- byte- s"ort- or c"ar.
*rom int to sbyte- byte- s"ort- us"ort- uint- ulong- or c"ar.
*rom uint to sbyte- byte- s"ort- us"ort- int- or c"ar.
*rom long to sbyte- byte- s"ort- us"ort- int- uint- ulong- or c"ar.
*rom ulong to sbyte- byte- s"ort- us"ort- int- uint- long- or c"ar.
*rom c"ar to sbyte- byte- or s"ort.
*rom -loat to sbyte- byte- s"ort- us"ort- int- uint- long- ulong- c"ar- or decimal.
*rom double to sbyte- byte- s"ort- us"ort- int- uint- long- ulong- c"ar- -loat- or decimal.
*rom decimal to sbyte- byte- s"ort- us"ort- int- uint- long- ulong- c"ar- -loat- or double.
)ecause t+e eplicit conversions include all implicit and eplicit numeric conversions- it is always possible to
convert 0rom any n!%eric-t+pe to any ot+er n!%eric-t+pe using a cast epression JV!.%.%M.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 11!
C# Language Specification
T+e eplicit numeric conversions possibly lose in0ormation or possibly cause eceptions to be t+rown. (n
eplicit numeric conversion is processed as 0ollowsC
*or a conversion 0rom an integral type to anot+er integral type- t+e processing depends on t+e over0low
c+ec7ing contet JV!.".12M in w+ic+ t+e conversion ta7es placeC
o 1n a c"ec(ed contet- t+e conversion succeeds i0 t+e value o0 t+e source operand is wit+in t+e range o0
t+e destination type- but t+rows a System.%ver-lo,)#ce&tion i0 t+e value o0 t+e source operand is
outside t+e range o0 t+e destination type.
o 1n an unc"ec(ed contet- t+e conversion always succeeds- and proceeds as 0ollows.
10 t+e source type is larger t+an t+e destination type- t+en t+e source value is truncated by discarding
its KetraL most signi0icant bits. T+e result is t+en treated as a value o0 t+e destination type.
10 t+e source type is smaller t+an t+e destination type- t+en t+e source value is eit+er sign<etended
or Dero<etended so t+at it is t+e same siDe as t+e destination type. #ign<etension is used i0 t+e
source type is signedQ Dero<etension is used i0 t+e source type is unsigned. T+e result is t+en treated
as a value o0 t+e destination type.
10 t+e source type is t+e same siDe as t+e destination type- t+en t+e source value is treated as a value
o0 t+e destination type.
*or a conversion 0rom decimal to an integral type- t+e source value is rounded towards Dero to t+e nearest
integral value- and t+is integral value becomes t+e result o0 t+e conversion. 10 t+e resulting integral value is
outside t+e range o0 t+e destination type- a System.%ver-lo,)#ce&tion is t+rown.
*or a conversion 0rom -loat or double to an integral type- t+e processing depends on t+e over0low
c+ec7ing contet JV!.".12M in w+ic+ t+e conversion ta7es placeC
o 1n a c"ec(ed contet- t+e conversion proceeds as 0ollowsC
10 t+e value o0 t+e operand is =a= or in0inite- a System.%ver-lo,)#ce&tion is t+rown.
/t+erwise- t+e source operand is rounded towards Dero to t+e nearest integral value. 10 t+is integral
value is wit+in t+e range o0 t+e destination type t+en t+is value is t+e result o0 t+e conversion.
/t+erwise- a System.%ver-lo,)#ce&tion is t+rown.
o 1n an unc"ec(ed contet- t+e conversion always succeeds- and proceeds as 0ollows.
10 t+e value o0 t+e operand is =a= or in0inite- t+e result o0 t+e conversion is an unspeci0ied value o0
t+e destination type.
/t+erwise- t+e source operand is rounded towards Dero to t+e nearest integral value. 10 t+is integral
value is wit+in t+e range o0 t+e destination type t+en t+is value is t+e result o0 t+e conversion.
/t+erwise- t+e result o0 t+e conversion is an unspeci0ied value o0 t+e destination type.
*or a conversion 0rom double to -loat- t+e double value is rounded to t+e nearest -loat value. 10 t+e
double value is too small to represent as a -loat- t+e result becomes positive Dero or negative Dero. 10 t+e
double value is too large to represent as a -loat- t+e result becomes positive in0inity or negative in0inity.
10 t+e double value is =a=- t+e result is also =a=.
*or a conversion 0rom -loat or double to decimal- t+e source value is converted to decimal
representation and rounded to t+e nearest number a0ter t+e 23
t+
decimal place i0 re9uired JV4.1.!M. 10 t+e
source value is too small to represent as a decimal- t+e result becomes Dero. 10 t+e source value is =a=-
in0inity- or too large to represent as a decimal- a System.%ver-lo,)#ce&tion is t+rown.
12* Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
*or a conversion 0rom decimal to -loat or double- t+e decimal value is rounded to t+e nearest double
or -loat value. 6+ile t+is conversion may lose precision- it never causes an eception to be t+rown.
'.2.2 $%plicit enueration con"ersions
T+e eplicit enumeration conversions areC
*rom sbyte- byte- s"ort- us"ort- int- uint- long- ulong- c"ar- -loat- double- or decimal to any
en!%-t+pe.
*rom any en!%-t+pe to sbyte- byte- s"ort- us"ort- int- uint- long- ulong- c"ar- -loat- double-
or decimal.
*rom any en!%-t+pe to any ot+er en!%-t+pe.
(n eplicit enumeration conversion between two types is processed by treating any participating en!%-t+pe as
t+e underlying type o0 t+at en!%-t+pe- and t+en per0orming an implicit or eplicit numeric conversion between
t+e resulting types. *or eample- given an en!%-t+pe ) wit+ and underlying type o0 int- a conversion 0rom ) to
byte is processed as an eplicit numeric conversion JV%.2.1M 0rom int to byte- and a conversion 0rom byte to
) is processed as an implicit numeric conversion JV%.1.2M 0rom byte to int.
'.2.3 $%plicit nullable con"ersions
$,plicit n-lla!le conversions permit prede0ined eplicit conversions t+at operate on non<nullable value types to
also be used wit+ nullable 0orms o0 t+ose types. *or eac+ o0 t+e prede0ined eplicit conversions t+at convert
0rom a non<nullable value type S to a non<nullable value type 1 JV%.1.1- V%.1.2- V%.1.3- V%.2.1- and V%.2.2M- t+e
0ollowing nullable conversions eistC
(n eplicit conversion 0rom S7 to 17.
(n eplicit conversion 0rom S to 17.
(n eplicit conversion 0rom S7 to 1.
Evaluation o0 a nullable conversion based on an underlying conversion 0rom S to 1 proceeds as 0ollowsC
10 t+e nullable conversion is 0rom S7 to 17C
o 10 t+e source value is null JHasUalue property is 0alseM- t+e result is t+e null value o0 type 17.
o /t+erwise- t+e conversion is evaluated as an unwrapping 0rom S7 to S- 0ollowed by t+e underlying
conversion 0rom S to 1- 0ollowed by a wrapping 0rom 1 to 17.
10 t+e nullable conversion is 0rom S to 17- t+e conversion is evaluated as t+e underlying conversion 0rom S
to 1 0ollowed by a wrapping 0rom 1 to 17.
10 t+e nullable conversion is 0rom S7 to 1- t+e conversion is evaluated as an unwrapping 0rom S7 to S
0ollowed by t+e underlying conversion 0rom S to 1.
=ote t+at an attempt to unwrap a nullable value will t+row an eception i0 t+e value is null.
'.2.# $%plicit reference con"ersions
T+e eplicit re0erence conversions areC
*rom object to any ot+er reference-t+pe.
*rom any class-t+pe S to any class-t+pe 1- provided S is a base class o0 1.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 121
C# Language Specification
*rom any class-t+pe S to any interface-t+pe 1- provided S is not sealed and provided S does not implement
1.
*rom any interface-t+pe S to any class-t+pe 1- provided 1 is not sealed or provided 1 implements S.
*rom any interface-t+pe S to any interface-t+pe 1- provided S is not derived 0rom 1.
*rom an arra+-t+pe S wit+ an element type S
)
to an arra+-t+pe 1 wit+ an element type 1
)
- provided all o0 t+e
0ollowing are trueC
o S and 1 di00er only in element type. 1n ot+er words- S and 1 +ave t+e same number o0 dimensions.
o )ot+ S
)
and 1
)
are reference-t+pes.
o (n eplicit re0erence conversion eists 0rom S
)
to 1
)
.
*rom System.'rray and t+e inter0aces it implements to any arra+-t+pe.
*rom a single<dimensional array type S45 to System.Collections.Seneric.$ListD1E and its base
inter0aces- provided t+at t+ere is an eplicit re0erence conversion 0rom S to 1.
*rom System.Collections.Seneric.$ListDSE and its base inter0aces to a single<dimensional array
type 145- provided t+at t+ere is an eplicit identity or re0erence conversion 0rom S to 1.
*rom System.6elegate and t+e inter0aces it implements to any delegate-t+pe.
Eplicit conversions involving type parameters t+at are 7nown to be re0erence types. *or more details on
eplicit conversions involving type parameters- see V%.2.%.
T+e eplicit re0erence conversions are t+ose conversions between re0erence<types t+at re9uire run<time c+ec7s
to ensure t+ey are correct.
*or an eplicit re0erence conversion to succeed at run<time- t+e value o0 t+e source operand must be null- or
t+e act!al type o0 t+e ob&ect re0erenced by t+e source operand must be a type t+at can be converted to t+e
destination type by an implicit re0erence conversion JV%.1.%M. 10 an eplicit re0erence conversion 0ails- a
System.$nvalidCast)#ce&tion is t+rown.
;e0erence conversions- implicit or eplicit- never c+ange t+e re0erential identity o0 t+e ob&ect being converted.
1n ot+er words- w+ile a re0erence conversion may c+ange t+e type o0 t+e re0erence- it never c+anges t+e type or
value o0 t+e ob&ect being re0erred to.
'.2.& 6nbo%ing con"ersions
(n unboing conversion permits a re0erence type to be eplicitly converted to a val!e-t+pe. (n unboing
conversion eists 0rom t+e types object and System.Ualue1y&e to any non-n!lla,le-val!e-t+pe- and 0rom
any interface-t+pe to any non-n!lla,le-val!e-t+pe t+at implements t+e interface-t+pe. *urt+ermore type
System.)num can be unboed to any en!%-t+pe.
(n unboing conversion eists 0rom a re0erence type to a n!lla,le-t+pe i0 an unboing conversion eists 0rom
t+e re0erence type to t+e underlying non-n!lla,le-val!e-t+pe o0 t+e n!lla,le-t+pe.
(n unboing operation consists o0 0irst c+ec7ing t+at t+e ob&ect instance is a boed value o0 t+e given val!e-
t+pe- and t+en copying t+e value out o0 t+e instance. 8nboing a null re0erence to a n!lla,le-t+pe produces t+e
null value o0 t+e n!lla,le-t+pe. ( struct can be unboed 0rom t+e type System.Ualue1y&e- since t+at is a base
class 0or all structs JV11.3.2M.
8nboing conversions are described 0urt+er in V4.3.2.
122 Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
'.2.' $%plicit con"ersions in"ol"ing t!pe paraeters
T+e 0ollowing eplicit conversions eist 0or a given type parameter 1C
*rom t+e e00ective base class C o0 1 to 1 and 0rom any base class o0 C to 1. (t run<time- i0 1 is a value type-
t+e conversion is eecuted as an unboing conversion. /t+erwise- t+e conversion is eecuted as an eplicit
re0erence conversion or identity conversion.
*rom any inter0ace type to 1. (t run<time- i0 1 is a value type- t+e conversion is eecuted as an unboing
conversion. /t+erwise- t+e conversion is eecuted as an eplicit re0erence conversion or identity conversion.
*rom 1 to any interface-t+pe $ provided t+ere is not already an implicit conversion 0rom 1 to $. (t run<time-
i0 1 is a value type- t+e conversion is eecuted as a boing conversion 0ollowed by an eplicit re0erence
conversion. /t+erwise- t+e conversion is eecuted as an eplicit re0erence conversion or identity conversion.
*rom a type parameter ; to 1- provided 1 depends on ;. (t run<time- i0 1 is a value type and ; is a re0erence
type- t+e conversion is eecuted as an unboing conversion. /t+erwise- i0 bot+ 1 and ; are value types- t+en
1 and ; are necessarily t+e same type and no conversion is per0ormed. /t+erwise- i0 1 is a re0erence type-
t+en ; is necessarily also a re0erence type and t+e conversion is eecuted as an eplicit re0erence conversion
or identity conversion.
10 1 is 7nown to be a re0erence type- t+e conversions above are all classi0ied as eplicit re0erence conversions
JV%.2.4M. 10 1 is not 7nown to be a re0erence type- t+e conversions described in t+e 0irst two bullets above are
classi0ied as unboing conversions JV%.2."M.
T+e above rules do not permit a direct eplicit conversion 0rom an unconstrained type parameter to a non<
inter0ace type- w+ic+ mig+t be surprising. T+e reason 0or t+is rule is to prevent con0usion and ma7e t+e
semantics o0 suc+ conversions clear. *or eample- consider t+e 0ollowing declarationC
class ID1E
{
&ublic static long V(1 t) {
return (long)t; .. )rror
!
!
10 t+e direct eplicit conversion o0 t to int were permitted- one mig+t easily epect t+at IDintE.V(M) would
return ML. However- it would not- because t+e standard numeric conversions are only considered w+en t+e types
are 7nown to be numeric at compile time. 1n order to ma7e t+e semantics clear- t+e above eample must instead
be writtenC
class ID1E
{
&ublic static long V(1 t) {
return (long)(object)t; .. %( but ,ill only ,or( ,"en 1 is long
!
!
T+is code will now compile but eecuting IDintE.V(M) would t+en t+row an eception at runtime- since a
boed int cannot be converted directly to a long.
'.2.. 6ser9defined e%plicit con"ersions
( user<de0ined eplicit conversion consists o0 an optional standard eplicit conversion- 0ollowed by eecution o0
a user<de0ined implicit or eplicit conversion operator- 0ollowed by anot+er optional standard eplicit
conversion. T+e eact rules 0or evaluating user<de0ined eplicit conversions are described in V%.4.".
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 123
C# Language Specification
'.3 Standard con"ersions
T+e standard conversions are t+ose pre<de0ined conversions t+at can occur as part o0 a user<de0ined conversion.
'.3.1 Standard iplicit con"ersions
T+e 0ollowing implicit conversions are classi0ied as standard implicit conversionsC
1dentity conversions JV%.1.1M
1mplicit numeric conversions JV%.1.2M
1mplicit nullable conversions JV%.1.4M
1mplicit re0erence conversions JV%.1.%M
)oing conversions JV%.1.!M
1mplicit constant epression conversions JV%.1.3M
1mplicit conversions involving type parameters JV%.1.$M
T+e standard implicit conversions speci0ically eclude user<de0ined implicit conversions.
'.3.2 Standard e%plicit con"ersions
T+e standard eplicit conversions are all standard implicit conversions plus t+e subset o0 t+e eplicit
conversions 0or w+ic+ an opposite standard implicit conversion eists. 1n ot+er words- i0 a standard implicit
conversion eists 0rom a type ' to a type :- t+en a standard eplicit conversion eists 0rom type ' to type : and
0rom type : to type '.
'.# 6ser9defined con"ersions
C# allows t+e pre<de0ined implicit and eplicit conversions to be augmented by -ser-defined conversions. 8ser<
de0ined conversions are introduced by declaring conversion operators JV1..1..3M in class and struct types.
'.#.1 Peritted user9defined con"ersions
C# permits only certain user<de0ined conversions to be declared. 1n particular- it is not possible to rede0ine an
already eisting implicit or eplicit conversion.
*or a given source type S and target type 1- i0 S or 1 are nullable types- let S
3
and 1
3
re0er to t+eir underlying
types- ot+erwise S
3
and 1
3
are e9ual to S and 1 respectively. ( class or struct is permitted to declare a
conversion 0rom a source type S to a target type 1 only i0 all o0 t+e 0ollowing are trueC
S
3
and 1
3
are di00erent types.
Eit+er S
3
or 1
3
is t+e class or struct type in w+ic+ t+e operator declaration ta7es place.
=eit+er S
3
nor 1
3
is an interface-t+pe.
Ecluding user<de0ined conversions- a conversion does not eist 0rom S to 1 or 0rom 1 to S.
T+e restrictions t+at apply to user<de0ined conversions are discussed 0urt+er in V1..1..3.
'.#.2 Lifted con"ersion operators
4iven a user<de0ined conversion operator t+at converts 0rom a non<nullable value type S to a non<nullable value
type 1- a lifted conversion operator eists t+at converts 0rom S7 to 17. T+is li0ted conversion operator per0orms
12" Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
an unwrapping 0rom S7 to S 0ollowed by t+e user<de0ined conversion 0rom S to 1 0ollowed by a wrapping 0rom
1 to 17- ecept t+at a null valued S7 converts directly to a null valued 17.
( li0ted conversion operator +as t+e same implicit or eplicit classi0ication as its underlying user<de0ined
conversion operator. T+e term Kuser<de0ined conversionL applies to t+e use o0 bot+ user<de0ined and li0ted
conversion operators.
'.#.3 $"aluation of user9defined con"ersions
( user<de0ined conversion converts a value 0rom its type- called t+e so-rce type- to anot+er type- called t+e
target type. Evaluation o0 a user<de0ined conversion centers on 0inding t+e ost specific user<de0ined
conversion operator 0or t+e particular source and target types. T+is determination is bro7en into several stepsC
*inding t+e set o0 classes and structs 0rom w+ic+ user<de0ined conversion operators will be considered. T+is
set consists o0 t+e source type and its base classes and t+e target type and its base classes Jwit+ t+e implicit
assumptions t+at only classes and structs can declare user<de0ined operators- and t+at non<class types +ave
no base classesM. *or t+e purposes o0 t+is step- i0 eit+er t+e source or target type is a n!lla,le-t+pe- t+eir
underlying type is used instead.
*rom t+at set o0 types- determining w+ic+ user<de0ined and li0ted conversion operators are applicable. *or a
conversion operator to be applicable- it must be possible to per0orm a standard conversion JV%.3M 0rom t+e
source type to t+e operand type o0 t+e operator- and it must be possible to per0orm a standard conversion
0rom t+e result type o0 t+e operator to t+e target type.
*rom t+e set o0 applicable user<de0ined operators- determining w+ic+ operator is unambiguously t+e most
speci0ic. 1n general terms- t+e most speci0ic operator is t+e operator w+ose operand type is KclosestL to t+e
source type and w+ose result type is KclosestL to t+e target type. 8ser<de0ined conversion operators are
pre0erred over li0ted conversion operators. T+e eact rules 0or establis+ing t+e most speci0ic user<de0ined
conversion operator are de0ined in t+e 0ollowing sections.
/nce a most speci0ic user<de0ined conversion operator +as been identi0ied- t+e actual eecution o0 t+e user<
de0ined conversion involves up to t+ree stepsC
*irst- i0 re9uired- per0orming a standard conversion 0rom t+e source type to t+e operand type o0 t+e user<
de0ined or li0ted conversion operator.
=et- invo7ing t+e user<de0ined or li0ted conversion operator to per0orm t+e conversion.
*inally- i0 re9uired- per0orming a standard conversion 0rom t+e result type o0 t+e user<de0ined or li0ted
conversion operator to t+e target type.
Evaluation o0 a user<de0ined conversion never involves more t+an one user<de0ined or li0ted conversion
operator. 1n ot+er words- a conversion 0rom type S to type 1 will never 0irst eecute a user<de0ined conversion
0rom S to I and t+en eecute a user<de0ined conversion 0rom I to 1.
Eact de0initions o0 evaluation o0 user<de0ined implicit or eplicit conversions are given in t+e 0ollowing
sections. T+e de0initions ma7e use o0 t+e 0ollowing termsC
10 a standard implicit conversion JV%.3.1M eists 0rom a type ' to a type :- and i0 neit+er ' nor : are
interface-t+pes- t+en ' is said to be encopassed !y :- and : is said to encopass '.
T+e ost encopassing type in a set o0 types is t+e one type t+at encompasses all ot+er types in t+e set. 10
no single type encompasses all ot+er types- t+en t+e set +as no most encompassing type. 1n more intuitive
terms- t+e most encompassing type is t+e KlargestL type in t+e setRt+e one type to w+ic+ eac+ o0 t+e ot+er
types can be implicitly converted.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 12
C# Language Specification
T+e ost encopassed type in a set o0 types is t+e one type t+at is encompassed by all ot+er types in t+e set.
10 no single type is encompassed by all ot+er types- t+en t+e set +as no most encompassed type. 1n more
intuitive terms- t+e most encompassed type is t+e KsmallestL type in t+e setRt+e one type t+at can be
implicitly converted to eac+ o0 t+e ot+er types.
'.#.# 6ser9defined iplicit con"ersions
( user<de0ined implicit conversion 0rom type S to type 1 is processed as 0ollowsC
2etermine t+e types S
3
and 1
3
. 10 S or 1 are nullable types- S
3
and 1
3
are t+eir underlying types- ot+erwise S
3
and 1
3
are e9ual to S and 1 respectively.
*ind t+e set o0 types- 6- 0rom w+ic+ user<de0ined conversion operators will be considered. T+is set consists
o0 S
3
Ji0 S
3
is a class or structM- t+e base classes o0 S
3
Ji0 S
3
is a classM- and 1
3
Ji0 1
3
is a class or structM.
*ind t+e set o0 applicable user<de0ined and li0ted conversion operators- ;. T+is set consists o0 t+e user<
de0ined and li0ted implicit conversion operators declared by t+e classes or structs in 6 t+at convert 0rom a
type encompassing S to a type encompassed by 1. 10 ; is empty- t+e conversion is unde0ined and a compile<
time error occurs.
*ind t+e most speci0ic source type- S
I
- o0 t+e operators in ;C
o 10 any o0 t+e operators in ; convert 0rom S- t+en S
I
is S.
o /t+erwise- S
I
is t+e most encompassed type in t+e combined set o0 source types o0 t+e operators in ;. 10
eactly one most encompassed type cannot be 0ound- t+en t+e conversion is ambiguous and a compile<
time error occurs.
*ind t+e most speci0ic target type- 1
I
- o0 t+e operators in ;C
o 10 any o0 t+e operators in ; convert to 1- t+en 1
I
is 1.
o /t+erwise- 1
I
is t+e most encompassing type in t+e combined set o0 target types o0 t+e operators in ;. 10
eactly one most encompassing type cannot be 0ound- t+en t+e conversion is ambiguous and a compile<
time error occurs.
*ind t+e most speci0ic conversion operatorC
o 10 ; contains eactly one user<de0ined conversion operator t+at converts 0rom S
I
to 1
I
- t+en t+is is t+e
most speci0ic conversion operator.
o /t+erwise- i0 ; contains eactly one li0ted conversion operator t+at converts 0rom S
I
to 1
I
- t+en t+is is
t+e most speci0ic conversion operator.
o /t+erwise- t+e conversion is ambiguous and a compile<time error occurs.
*inally- apply t+e conversionC
o 10 S is not S
I
- t+en a standard implicit conversion 0rom S to S
I
is per0ormed.
o T+e most speci0ic conversion operator is invo7ed to convert 0rom S
I
to 1
I
.
o 10 1
I
is not 1- t+en a standard implicit conversion 0rom 1
I
to 1 is per0ormed.
'.#.& 6ser9defined e%plicit con"ersions
( user<de0ined eplicit conversion 0rom type S to type 1 is processed as 0ollowsC
12' Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
2etermine t+e types S
3
and 1
3
. 10 S or 1 are nullable types- S
3
and 1
3
are t+eir underlying types- ot+erwise S
3
and 1
3
are e9ual to S and 1 respectively.
*ind t+e set o0 types- 6- 0rom w+ic+ user<de0ined conversion operators will be considered. T+is set consists
o0 S
3
Ji0 S
3
is a class or structM- t+e base classes o0 S
3
Ji0 S
3
is a classM- 1
3
Ji0 1
3
is a class or structM- and t+e
base classes o0 1
3
Ji0 1
3
is a classM.
*ind t+e set o0 applicable user<de0ined and li0ted conversion operators- ;. T+is set consists o0 t+e user<
de0ined and li0ted implicit or eplicit conversion operators declared by t+e classes or structs in 6 t+at convert
0rom a type encompassing or encompassed by S to a type encompassing or encompassed by 1. 10 ; is empty-
t+e conversion is unde0ined and a compile<time error occurs.
*ind t+e most speci0ic source type- S
I
- o0 t+e operators in ;C
o 10 any o0 t+e operators in ; convert 0rom S- t+en S
I
is S.
o /t+erwise- i0 any o0 t+e operators in ; convert 0rom types t+at encompass S- t+en S
I
is t+e most
encompassed type in t+e combined set o0 source types o0 t+ose operators. 10 no most encompassed type
can be 0ound- t+en t+e conversion is ambiguous and a compile<time error occurs.
o /t+erwise- S
I
is t+e most encompassing type in t+e combined set o0 source types o0 t+e operators in ;. 10
eactly one most encompassing type cannot be 0ound- t+en t+e conversion is ambiguous and a compile<
time error occurs.
*ind t+e most speci0ic target type- 1
I
- o0 t+e operators in ;C
o 10 any o0 t+e operators in ; convert to 1- t+en 1
I
is 1.
o /t+erwise- i0 any o0 t+e operators in ; convert to types t+at are encompassed by 1- t+en 1
I
is t+e most
encompassing type in t+e combined set o0 target types o0 t+ose operators. 10 eactly one most
encompassing type cannot be 0ound- t+en t+e conversion is ambiguous and a compile<time error occurs.
o /t+erwise- 1
I
is t+e most encompassed type in t+e combined set o0 target types o0 t+e operators in ;. 10
no most encompassed type can be 0ound- t+en t+e conversion is ambiguous and a compile<time error
occurs.
*ind t+e most speci0ic conversion operatorC
o 10 ; contains eactly one user<de0ined conversion operator t+at converts 0rom S
I
to 1
I
- t+en t+is is t+e
most speci0ic conversion operator.
o /t+erwise- i0 ; contains eactly one li0ted conversion operator t+at converts 0rom S
I
to 1
I
- t+en t+is is
t+e most speci0ic conversion operator.
o /t+erwise- t+e conversion is ambiguous and a compile<time error occurs.
*inally- apply t+e conversionC
o 10 S is not S
I
- t+en a standard eplicit conversion 0rom S to S
I
is per0ormed.
o T+e most speci0ic user<de0ined conversion operator is invo7ed to convert 0rom S
I
to 1
I
.
o 10 1
I
is not 1- t+en a standard eplicit conversion 0rom 1
I
to 1 is per0ormed.
'.& *non!ous function con"ersions
(n anon+%o!s-%ethod-e/pression or la%,da-e/pression is classi0ied as an anonymous 0unction JV!.14M. T+e
epression does not +ave a type but can be implicitly converted to a compatible delegate type or epression tree
type. #peci0ically- a delegate type 6 is compatible wit+ an anonymous 0unction V providedC
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 127
C# Language Specification
10 V contains an anon+%o!s-f!nction-signat!re- t+en 6 and V +ave t+e same number o0 parameters.
10 V does not contain an anon+%o!s-f!nction-signat!re- t+en 6 may +ave Dero or more parameters o0 any
type- as long as no parameter o0 6 +as t+e out parameter modi0ier.
10 V +as an eplicitly typed parameter list- eac+ parameter in 6 +as t+e same type and modi0iers as t+e
corresponding parameter in V.
10 V +as an implicitly typed parameter list- 6 +as no re- or out parameters.
10 6 +as a void return type and t+e body o0 V is an epression- w+en eac+ parameter o0 V is given t+e type o0
t+e corresponding parameter in 6- t+e body o0 V is a valid epression Jwrt V!M t+at would be permitted as a
state%ent-e/pression JV3.%M.
10 6 +as a void return type and t+e body o0 V is a statement bloc7- w+en eac+ parameter o0 V is given t+e
type o0 t+e corresponding parameter in 6- t+e body o0 V is a valid statement bloc7 Jwrt V3.2M in w+ic+ no
return statement speci0ies an epression.
10 6 +as a non<void return type and t+e body o0 V is an epression- w+en eac+ parameter o0 V is given t+e
type o0 t+e corresponding parameter in 6- t+e body o0 V is a valid epression Jwrt V!M t+at is implicitly
convertible to t+e return type o0 6.
10 6 +as a non<void return type and t+e body o0 V is a statement bloc7- w+en eac+ parameter o0 V is given t+e
type o0 t+e corresponding parameter in 6- t+e body o0 V is a valid statement bloc7 Jwrt V3.2M wit+ a non<
reac+able end point in w+ic+ eac+ return statement speci0ies an epression t+at is implicitly convertible to
t+e return type o0 6.
(n epression tree type )#&ressionD6E is compatible wit+ an anonymous 0unction V i0 t+e delegate type 6 is
compatible wit+ V.
T+e eamples t+at 0ollow use a generic delegate type VuncD'OE w+ic+ represents a 0unction t+at ta7es an
argument o0 type ' and returns a value o0 type OC
delegate O VuncD'OE(' arg);
1n t+e assignments
VuncDintintE -2 + # +E # < 2; .. %(
VuncDintdoubleE -8 + # +E # < 2; .. %(
VuncDdoubleintE -9 + # +E # < 2; .. )rror
t+e parameter and return types o0 eac+ anonymous 0unction are determined 0rom t+e type o0 t+e variable to
w+ic+ t+e anonymous 0unction is assigned.
T+e 0irst assignment success0ully converts t+e anonymous 0unction to t+e delegate type VuncDintintE
because- w+en # is given type int- # < 2 is a valid epression t+at is implicitly convertible to type int.
5i7ewise- t+e second assignment success0ully converts t+e anonymous 0unction to t+e delegate type
VuncDintdoubleE because t+e result o0 # < 2 Jo0 type intM is implicitly convertible to type double.
However- t+e t+ird assignment is a compile<time error because- w+en # is given type double- t+e result o0 # < 2
Jo0 type doubleM is not implicitly convertible to type int.
(nonymous 0unctions may in0luence overload resolution- and participate in type in0erence. #ee V!.4 0or 0urt+er
details.
12$ Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
'.&.1 $"aluation of anon!ous function con"ersions to delegate t!pes
Conversion o0 an anonymous 0unction to a delegate type produces a delegate instance w+ic+ re0erences t+e
anonymous 0unction and t+e Jpossibly emptyM set o0 captured outer variables t+at are active at t+e time o0 t+e
evaluation. 6+en t+e delegate is invo7ed- t+e body o0 t+e anonymous 0unction is eecuted. T+e code in t+e body
is eecuted using t+e set o0 captured outer variables re0erenced by t+e delegate.
T+e invocation list o0 a delegate produced 0rom an anonymous 0unction contains a single entry. T+e eact target
ob&ect and target met+od o0 t+e delegate are unspeci0ied. 1n particular- it is unspeci0ied w+et+er t+e target ob&ect
o0 t+e delegate is null- t+e t"is value o0 t+e enclosing 0unction member- or some ot+er ob&ect.
Conversions o0 semantically identical anonymous 0unctions wit+ t+e same Jpossibly emptyM set o0 captured
outer variable instances to t+e same delegate types are permitted Jbut not re9uiredM to return t+e same delegate
instance. T+e term semantically identical is used +ere to mean t+at eecution o0 t+e anonymous 0unctions will-
in all cases- produce t+e same e00ects given t+e same arguments. T+is rule permits code suc+ as t+e 0ollowing to
be optimiDed.
delegate double Vunction(double #);
class 1est
{
static double45 '&&ly(double45 a Vunction -) {
double45 result + ne, double4a.Lengt"5;
-or (int i + 3; i D a.Lengt"; i<<) result4i5 + -(a4i5);
return result;
!
static void V(double45 a double45 b) {
a + '&&ly(a (double #) +E Mat".Sin(#));
b + '&&ly(b (double y) +E Mat".Sin(y));
...
!
!
#ince t+e two anonymous 0unction delegates +ave t+e same JemptyM set o0 captured outer variables- and since
t+e anonymous 0unctions are semantically identical- t+e compiler is permitted to +ave t+e delegates re0er to t+e
same target met+od. 1ndeed- t+e compiler is permitted to return t+e very same delegate instance 0rom bot+
anonymous 0unction epressions.
'.&.2 $"aluation of anon!ous function con"ersions to e%pression tree t!pes
Conversion o0 an anonymous 0unction to an epression tree type produces an epression tree JV4.%M. 'ore
precisely- evaluation o0 t+e anonymous 0unction conversion leads to t+e construction o0 an ob&ect structure t+at
represents t+e structure o0 t+e anonymous 0unction itsel0. T+e precise structure o0 t+e epression tree- as well as
t+e eact process 0or creating it- are de0ined elsew+ere.
'.&.3 Ipleentation e%aple
T+is section describes a possible implementation o0 anonymous 0unction conversions in terms o0 ot+er C#
constructs. T+e implementation described +ere is based on t+e same principles used by t+e 'icroso0t C#
compiler- but it is by no means a mandated implementation- nor is it t+e only one possible. 1t only brie0ly
mentions conversions to epression trees- as t+eir eact semantics are outside t+e scope o0 t+is speci0ication.
T+e remainder o0 t+is section gives several eamples o0 code t+at contains anonymous 0unctions wit+ di00erent
c+aracteristics. *or eac+ eample- a corresponding translation to code t+at uses only ot+er C# constructs is
provided. 1n t+e eamples- t+e identi0ier 6 is assumed by represent t+e 0ollowing delegate typeC
&ublic delegate void 6();
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 12!
C# Language Specification
T+e simplest 0orm o0 an anonymous 0unction is one t+at captures no outer variablesC
class 1est
{
static void V() {
6 d + () +E { Console.WriteLine("test"); !;
!
!
T+is can be translated to a delegate instantiation t+at re0erences a compiler generated static met+od in w+ic+ t+e
code o0 t+e anonymous 0unction is placedC
class 1est
{
static void V() {
6 d + ne, 6([[Met"od2);
!
static void [[Met"od2() {
Console.WriteLine("test");
!
!
1n t+e 0ollowing eample- t+e anonymous 0unction re0erences instance members o0 t"isC
class 1est
{
int #;
void V() {
6 d + () +E { Console.WriteLine(#); !;
!
!
T+is can be translated to a compiler generated instance met+od containing t+e code o0 t+e anonymous 0unctionC
class 1est
{
int #;
void V() {
6 d + ne, 6([[Met"od2);
!
void [[Met"od2() {
Console.WriteLine(#);
!
!
1n t+is eample- t+e anonymous 0unction captures a local variableC
class 1est
{
void V() {
int y + 289;
6 d + () +E { Console.WriteLine(y); !;
!
!
T+e li0etime o0 t+e local variable must now be etended to at least t+e li0etime o0 t+e anonymous 0unction
delegate. T+is can be ac+ieved by K+oistingL t+e local variable into a 0ield o0 a compiler generated class.
1nstantiation o0 t+e local variable JV!.14.4.2M t+en corresponds to creating an instance o0 t+e compiler generated
13* Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
class- and accessing t+e local variable corresponds to accessing a 0ield in t+e instance o0 t+e compiler generated
class. *urt+ermore- t+e anonymous 0unction becomes an instance met+od o0 t+e compiler generated classC
class 1est
{
void V() {
[[Locals2 [[locals2 + ne, [[Locals2();
[[locals2.y + 289;
6 d + ne, 6([[locals2.[[Met"od2);
!
class [[Locals2
{
&ublic int y;
&ublic void [[Met"od2() {
Console.WriteLine(y);
!
!
!
*inally- t+e 0ollowing anonymous 0unction captures t"is as well as two local variables wit+ di00erent li0etimesC
class 1est
{
int #;
void V() {
int y + 289;
-or (int i + 3; i D 23; i<<) {
int ? + i > 8;
6 d + () +E { Console.WriteLine(# < y < ?); !;
!
!
!
Here- a compiler generated class is created 0or eac+ statement bloc7 in w+ic+ locals are captured suc+ t+at t+e
locals in t+e di00erent bloc7s can +ave independent li0etimes. (n instance o0 [[Locals8- t+e compiler
generated class 0or t+e inner statement bloc7- contains t+e local variable ? and a 0ield t+at re0erences an instance
o0 [[Locals2. (n instance o0 [[Locals2- t+e compiler generated class 0or t+e outer statement bloc7-
contains t+e local variable y and a 0ield t+at re0erences t"is o0 t+e enclosing 0unction member. 6it+ t+ese data
structures it is possible to reac+ all captured outer variables t+roug+ an instance o0 [[Local8- and t+e code o0
t+e anonymous 0unction can t+us be implemented as an instance met+od o0 t+at class.
class 1est
{
void V() {
[[Locals2 [[locals2 + ne, [[Locals2();
[[locals2.[[t"is + t"is;
[[locals2.y + 289;
-or (int i + 3; i D 23; i<<) {
[[Locals8 [[locals8 + ne, [[Locals8();
[[locals8.[[locals2 + [[locals2;
[[locals8.? + i > 8;
6 d + ne, 6([[locals8.[[Met"od2);
!
!
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 131
C# Language Specification
class [[Locals2
{
&ublic 1est [[t"is;
&ublic int y;
!
class [[Locals8
{
&ublic [[Locals2 [[locals2;
&ublic int ?;
&ublic void [[Met"od2() {
Console.WriteLine([[locals2.[[t"is.# < [[locals2.y < ?);
!
!
!
T+e same tec+ni9ue applied +ere to capture local variables can also be used w+en converting anonymous
0unctions to epression treesC ;e0erences to t+e compiler generated ob&ects can be stored in t+e epression tree-
and access to t+e local variables can be represented as 0ield accesses on t+ese ob&ects. T+e advantage o0 t+is
approac+ is t+at it allows t+e Kli0tedL local variables to be s+ared between delegates and epression trees.
'.' )et-od group con"ersions
(n implicit conversion JV%.1M eists 0rom a met+od group JV!.1M to a compatible delegate type. 4iven a delegate
type 6 and an epression ) t+at is classi0ied as a met+od group- an implicit conversion eists 0rom ) to 6 i0 )
contains at least one met+od t+at is applicable in its normal 0orm JV!.4.3.1M to an argument list constructed by
use o0 t+e parameter types and modi0iers o0 6- as described in t+e 0ollowing.
T+e compile<time application o0 a conversion 0rom a met+od group ) to a delegate type 6 is described in t+e
0ollowing. =ote t+at t+e eistence o0 an implicit conversion 0rom ) to 6 does not guarantee t+at t+e compile<
time application o0 t+e conversion will succeed wit+out error.
( single met+od M is selected corresponding to a met+od invocation JV!.".".1M o0 t+e 0orm )(')- wit+ t+e
0ollowing modi0icationsC
o T+e argument list ' is a list o0 epressions- eac+ classi0ied as a variable and wit+ t+e type and modi0ier
Jre- or outM o0 t+e corresponding parameter in t+e for%al-para%eter-list o0 6.
o T+e candidate met+ods considered are only t+ose met+ods t+at are applicable in t+eir normal 0orm
JV!.4.3.1M- not t+ose applicable only in t+eir epanded 0orm.
10 t+e algorit+m o0 V!.".".1 produces an error- t+en a compile<time error occurs. /t+erwise t+e algorit+m
produces a single best met+od M +aving t+e same number o0 parameters as 6 and t+e conversion is
considered to eist.
T+e selected met+od M must be compatible JV1".2M wit+ t+e delegate type 6- or ot+erwise- a compile<time
error occurs.
10 t+e selected met+od M is an instance met+od- t+e instance epression associated wit+ ) determines t+e
target ob&ect o0 t+e delegate.
10 t+e selected met+od ' is an etension met+od w+ic+ is denoted by means o0 a member access on an
instance epression- t+at instance epression determines t+e target ob&ect o0 t+e delegate.
T+e result o0 t+e conversion is a value o0 type 6- namely a newly created delegate t+at re0ers to t+e selected
met+od and target ob&ect.
132 Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
=ote t+at t+is process can lead to t+e creation o0 a delegate to an etension met+od- i0 t+e algorit+m o0
V!.".".1 0ails to 0ind an instance met+od but succeeds in processing t+e invocation o0 )(') as an etension
met+od invocation JV!.".".2M. ( delegate t+us created captures t+e etension met+od as well as its 0irst
argument.
T+e 0ollowing eample demonstrates met+od group conversionsC
delegate string 62(object o);
delegate object 68(string s);
delegate object 69();
delegate string 6J(object o &arams object45 a);
delegate string 6K(int i);
class 1est
{
static string V(object o) {...!
static void S() {
62 d2 + V; .. %(
68 d8 + V; .. %(
69 d9 + V; .. )rror C not a&&licable
6J dJ + V; .. )rror C not a&&licable in normal -orm
6K dK + V; .. )rror C a&&licable but not com&atible
!
!
T+e assignment to d2 implicitly converts t+e met+od group V to a value o0 type 62.
T+e assignment to d8 s+ows +ow it is possible to create a delegate to a met+od t+at +as less derived Jcontra<
variantM parameter types and a more derived JcovariantM return type.
T+e assignment to d9 s+ows +ow no conversion eists i0 t+e met+od is not applicable.
T+e assignment to dJ s+ows +ow t+e met+od must be applicable in its normal 0orm.
T+e assignment to dK s+ows +ow parameter and return types o0 t+e delegate and met+od are allowed to di00er
only 0or re0erence types.
(s wit+ all ot+er implicit and eplicit conversions- t+e cast operator can be used to eplicitly per0orm a met+od
group conversion. T+us- t+e eample
object obj + ne, )ventHandler(my6ialog.%(Clic();
could instead be written
object obj + ()ventHandler)my6ialog.%(Clic(;
'et+od groups may in0luence overload resolution- and participate in type in0erence. #ee V!.4 0or 0urt+er details.
T+e runtime evaluation o0 a met+od group conversion proceeds as 0ollowsC
10 t+e met+od selected at compile<time is an instance met+od- or it is an etension met+od w+ic+ is accessed
as an instance met+od- t+e target ob&ect o0 t+e delegate is determined 0rom t+e instance epression
associated wit+ )C
o T+e instance epression is evaluated. 10 t+is evaluation causes an eception- no 0urt+er steps are
eecuted.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 133
C# Language Specification
o 10 t+e instance epression is o0 a reference-t+pe- t+e value computed by t+e instance epression becomes
t+e target ob&ect. 10 t+e target ob&ect is null- a System.NullOe-erence)#ce&tion is t+rown and no
0urt+er steps are eecuted.
o 10 t+e instance epression is o0 a val!e-t+pe- a boing operation JV4.3.1M is per0ormed to convert t+e
value to an ob&ect- and t+is ob&ect becomes t+e target ob&ect.
/t+erwise t+e selected met+od is part o0 a static met+od call- and t+e target ob&ect o0 t+e delegate is null.
( new instance o0 t+e delegate type 6 is allocated. 10 t+ere is not enoug+ memory available to allocate t+e
new instance- a System.%ut%-Memory)#ce&tion is t+rown and no 0urt+er steps are eecuted.
T+e new delegate instance is initialiDed wit+ a re0erence to t+e met+od t+at was determined at compile<time
and a re0erence to t+e target ob&ect computed above.
13" Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
.. $%pressions
(n epression is a se9uence o0 operators and operands. T+is c+apter de0ines t+e synta- order o0 evaluation o0
operands and operators- and meaning o0 epressions.
..1 $%pression classifications
(n epression is classi0ied as one o0 t+e 0ollowingC
( value. Every value +as an associated type.
( variable. Every variable +as an associated type- namely t+e declared type o0 t+e variable.
( namespace. (n epression wit+ t+is classi0ication can only appear as t+e le0t +and side o0 a %e%,er-
access JV!.".4M. 1n any ot+er contet- an epression classi0ied as a namespace causes a compile<time error.
( type. (n epression wit+ t+is classi0ication can only appear as t+e le0t +and side o0 a %e%,er-access
JV!.".4M- or as an operand 0or t+e as operator JV!.$.11M- t+e is operator JV!.$.1.M- or t+e ty&eo- operator
JV!.".11M. 1n any ot+er contet- an epression classi0ied as a type causes a compile<time error.
( met+od group- w+ic+ is a set o0 overloaded met+ods resulting 0rom a member loo7up JV!.3M. ( met+od
group may +ave an associated instance epression and an associated type argument list. 6+en an instance
met+od is invo7ed- t+e result o0 evaluating t+e instance epression becomes t+e instance represented by
t"is JV!.".!M. ( met+od group is permitted in an invocation-e/pression JV!."."M or a delegate-creation-
e/pression JV!.".1.."M- and can be implicitly converted to a compatible delegate type JV%.%M. 1n any ot+er
contet- an epression classi0ied as a met+od group causes a compile<time error.
( null literal. (n epression wit+ t+is classi0ication can be implicitly converted to a re0erence type or
nullable type.
(n anonymous 0unction. (n epression wit+ t+is classi0ication can be implicitly converted to a compatible
delegate type or epression tree type.
( property access. Every property access +as an associated type- namely t+e type o0 t+e property.
*urt+ermore- a property access may +ave an associated instance epression. 6+en an accessor Jt+e get or
set bloc7M o0 an instance property access is invo7ed- t+e result o0 evaluating t+e instance epression
becomes t+e instance represented by t"is JV!.".!M.
(n event access. Every event access +as an associated type- namely t+e type o0 t+e event. *urt+ermore- an
event access may +ave an associated instance epression. (n event access may appear as t+e le0t +and
operand o0 t+e <+ and =+ operators JV!.1%.3M. 1n any ot+er contet- an epression classi0ied as an event
access causes a compile<time error.
(n indeer access. Every indeer access +as an associated type- namely t+e element type o0 t+e indeer.
*urt+ermore- an indeer access +as an associated instance epression and an associated argument list. 6+en
an accessor Jt+e get or set bloc7M o0 an indeer access is invo7ed- t+e result o0 evaluating t+e instance
epression becomes t+e instance represented by t"is JV!.".!M- and t+e result o0 evaluating t+e argument list
becomes t+e parameter list o0 t+e invocation.
=ot+ing. T+is occurs w+en t+e epression is an invocation o0 a met+od wit+ a return type o0 void. (n
epression classi0ied as not+ing is only valid in t+e contet o0 a state%ent-e/pression JV3.%M.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 13
C# Language Specification
T+e 0inal result o0 an epression is never a namespace- type- met+od group- or event access. ;at+er- as noted
above- t+ese categories o0 epressions are intermediate constructs t+at are only permitted in certain contets.
( property access or indeer access is always reclassi0ied as a value by per0orming an invocation o0 t+e get-
accessor or t+e set-accessor. T+e particular accessor is determined by t+e contet o0 t+e property or indeer
accessC 10 t+e access is t+e target o0 an assignment- t+e set-accessor is invo7ed to assign a new value JV!.1%.1M.
/t+erwise- t+e get-accessor is invo7ed to obtain t+e current value JV!.1.1M.
..1.1 Values of e%pressions
'ost o0 t+e constructs t+at involve an epression ultimately re9uire t+e epression to denote a val-e. 1n suc+
cases- i0 t+e actual epression denotes a namespace- a type- a met+od group- or not+ing- a compile<time error
occurs. However- i0 t+e epression denotes a property access- an indeer access- or a variable- t+e value o0 t+e
property- indeer- or variable is implicitly substitutedC
T+e value o0 a variable is simply t+e value currently stored in t+e storage location identi0ied by t+e variable.
( variable must be considered de0initely assigned JV".3M be0ore its value can be obtained- or ot+erwise a
compile<time error occurs.
T+e value o0 a property access epression is obtained by invo7ing t+e get-accessor o0 t+e property. 10 t+e
property +as no get-accessor- a compile<time error occurs. /t+erwise- a 0unction member invocation
JV!.4.4M is per0ormed- and t+e result o0 t+e invocation becomes t+e value o0 t+e property access epression.
T+e value o0 an indeer access epression is obtained by invo7ing t+e get-accessor o0 t+e indeer. 10 t+e
indeer +as no get-accessor- a compile<time error occurs. /t+erwise- a 0unction member invocation JV!.4.4M
is per0ormed wit+ t+e argument list associated wit+ t+e indeer access epression- and t+e result o0 t+e
invocation becomes t+e value o0 t+e indeer access epression.
..2 /perators
Epressions are constructed 0rom operands and operators. T+e operators o0 an epression indicate w+ic+
operations to apply to t+e operands. Eamples o0 operators include <- =- >- .- and ne,. Eamples o0 operands
include literals- 0ields- local variables- and epressions.
T+ere are t+ree 7inds o0 operatorsC
8nary operators. T+e unary operators ta7e one operand and use eit+er pre0i notation Jsuc+ as C#M or post0i
notation Jsuc+ as #<<M.
)inary operators. T+e binary operators ta7e two operands and all use in0i notation Jsuc+ as # < yM.
Ternary operator. /nly one ternary operator- 7/- eistsQ it ta7es t+ree operands and uses in0i notation
Jc7 #/ yM.
T+e order o0 evaluation o0 operators in an epression is determined by t+e precedence and associativity o0 t+e
operators JV!.2.1M.
/perands in an epression are evaluated 0rom le0t to rig+t. *or eample- in V(i) < S(i<<) > H(i)- met+od V is
called using t+e old value o0 i- t+en met+od S is called wit+ t+e old value o0 i- and- 0inally- met+od H is called
wit+ t+e new value o0 i. T+is is separate 0rom and unrelated to operator precedence.
Certain operators can be overloaded. /perator overloading permits user<de0ined operator implementations to be
speci0ied 0or operations w+ere one or bot+ o0 t+e operands are o0 a user<de0ined class or struct type JV!.2.2M.
13' Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
..2.1 /perator precedence and associati"it!
6+en an epression contains multiple operators- t+e precedence o0 t+e operators controls t+e order in w+ic+ t+e
individual operators are evaluated. *or eample- t+e epression # < y > ? is evaluated as # < (y > ?) because
t+e > operator +as +ig+er precedence t+an t+e binary < operator. T+e precedence o0 an operator is establis+ed by
t+e de0inition o0 its associated grammar production. *or eample- an additive-e/pression consists o0 a se9uence
o0 %!ltiplicative-e/pressions separated by < or = operators- t+us giving t+e < and = operators lower precedence
t+an t+e >- .- and B operators.
T+e 0ollowing table summariDes all operators in order o0 precedence 0rom +ig+est to lowestC
Section Categor# 6perators
!." Primary
#.y -(#) a4#5 #<< #== ne,
ty&eo- de-ault c"ec(ed unc"ec(ed delegate
!.% 8nary
< = @ A <<# ==# (1)#
!.! 'ultiplicative
> . B
!.! (dditive
< =
!.3 #+i0t
DD EE
!.$ ;elational and
type testing
D E D+ E+ is as
!.$ E9uality
++ @+
!.1. 5ogical (=2
F
!.1. 5ogical I/;
G
!.1. 5ogical /;
H
!.11 Conditional (=2
FF
!.11 Conditional /;
HH
!.12 =ull coalescing
77
!.13 Conditional
7/
!.1%-
!.14
(ssignment and
lambda epression
+ >+ .+ B+ <+ =+ DD+ EE+ F+ G+ H+
+E
6+en an operand occurs between two operators wit+ t+e same precedence- t+e associativity o0 t+e operators
controls t+e order in w+ic+ t+e operations are per0ormedC
Ecept 0or t+e assignment operators- all binary operators are left-associative- meaning t+at operations are
per0ormed 0rom le0t to rig+t. *or eample- # < y < ? is evaluated as (# < y) < ?.
T+e assignment operators and t+e conditional operator J7/M are right-associative- meaning t+at operations
are per0ormed 0rom rig+t to le0t. *or eample- # + y + ? is evaluated as # + (y + ?).
Precedence and associativity can be controlled using parent+eses. *or eample- # < y > ? 0irst multiplies y by ?
and t+en adds t+e result to #- but (# < y) > ? 0irst adds # and y and t+en multiplies t+e result by ?.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 137
C# Language Specification
..2.2 /perator o"erloading
(ll unary and binary operators +ave prede0ined implementations t+at are automatically available in any
epression. 1n addition to t+e prede0ined implementations- user<de0ined implementations can be introduced by
including o&erator declarations in classes and structs JV1..1.M. 8ser<de0ined operator implementations always
ta7e precedence over prede0ined operator implementationsC /nly w+en no applicable user<de0ined operator
implementations eist will t+e prede0ined operator implementations be considered- as described in V!.2.3 and
V!.2.4.
T+e overloada!le -nary operators areC
< = @ A << == true -alse
(lt+oug+ true and -alse are not used eplicitly in epressions Jand t+ere0ore are not included in t+e
precedence table in V!.2.1M- t+ey are considered operators because t+ey are invo7ed in several epression
contetsC boolean epressions JV!.1$M and epressions involving t+e conditional JV!.13M- and conditional logical
operators JV!.11M.
T+e overloada!le !inary operators areC
< = > . B F H G DD EE ++ @+ E D E+ D+
/nly t+e operators listed above can be overloaded. 1n particular- it is not possible to overload member access-
met+od invocation- or t+e +- FF- HH- 77- 7/- +E- c"ec(ed- unc"ec(ed- ne,- ty&eo-- de-ault- as- and is
operators.
6+en a binary operator is overloaded- t+e corresponding assignment operator- i0 any- is also implicitly
overloaded. *or eample- an overload o0 operator > is also an overload o0 operator >+. T+is is described 0urt+er
in V!.1%.2. =ote t+at t+e assignment operator itsel0 J+M cannot be overloaded. (n assignment always per0orms a
simple bit<wise copy o0 a value into a variable.
Cast operations- suc+ as (1)#- are overloaded by providing user<de0ined conversions JV%.4M.
Element access- suc+ as a4#5- is not considered an overloadable operator. 1nstead- user<de0ined indeing is
supported t+roug+ indeers JV1..$M.
1n epressions- operators are re0erenced using operator notation- and in declarations- operators are re0erenced
using 0unctional notation. T+e 0ollowing table s+ows t+e relations+ip between operator and 0unctional notations
0or unary and binary operators. 1n t+e 0irst entry- op denotes any overloadable unary pre0i operator. 1n t+e
second entry- op denotes t+e unary post0i << and == operators. 1n t+e t+ird entry- op denotes any overloadable
binary operator.
6perator notation 7unctional notation
op # o&erator op(#)
# op o&erator op(#)
# op y o&erator op(# y)
8ser<de0ined operator declarations always re9uire at least one o0 t+e parameters to be o0 t+e class or struct type
t+at contains t+e operator declaration. T+us- it is not possible 0or a user<de0ined operator to +ave t+e same
signature as a prede0ined operator.
8ser<de0ined operator declarations cannot modi0y t+e synta- precedence- or associativity o0 an operator. *or
eample- t+e . operator is always a binary operator- always +as t+e precedence level speci0ied in V!.2.1- and is
always le0t<associative.
13$ Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
6+ile it is possible 0or a user<de0ined operator to per0orm any computation it pleases- implementations t+at
produce results ot+er t+an t+ose t+at are intuitively epected are strongly discouraged. *or eample- an
implementation o0 o&erator ++ s+ould compare t+e two operands 0or e9uality and return an appropriate bool
result.
T+e descriptions o0 individual operators in V!." t+roug+ V!.11 speci0y t+e prede0ined implementations o0 t+e
operators and any additional rules t+at apply to eac+ operator. T+e descriptions ma7e use o0 t+e terms -nary
operator overload resol-tion- !inary operator overload resol-tion- and n-eric prootion- de0initions o0
w+ic+ are 0ound in t+e 0ollowing sections.
..2.3 6nar! operator o"erload resolution
(n operation o0 t+e 0orm op # or # op- w+ere op is an overloadable unary operator- and # is an epression o0
type I- is processed as 0ollowsC
T+e set o0 candidate user<de0ined operators provided by I 0or t+e operation o&erator op(#) is determined
using t+e rules o0 V!.2.".
10 t+e set o0 candidate user<de0ined operators is not empty- t+en t+is becomes t+e set o0 candidate operators
0or t+e operation. /t+erwise- t+e prede0ined unary o&erator op implementations- including t+eir li0ted
0orms- become t+e set o0 candidate operators 0or t+e operation. T+e prede0ined implementations o0 a given
operator are speci0ied in t+e description o0 t+e operator JV!." and V!.%M.
T+e overload resolution rules o0 V!.4.3 are applied to t+e set o0 candidate operators to select t+e best
operator wit+ respect to t+e argument list (#)- and t+is operator becomes t+e result o0 t+e overload
resolution process. 10 overload resolution 0ails to select a single best operator- a compile<time error occurs.
..2.# +inar! operator o"erload resolution
(n operation o0 t+e 0orm # op y- w+ere op is an overloadable binary operator- # is an epression o0 type I- and
y is an epression o0 type `- is processed as 0ollowsC
T+e set o0 candidate user<de0ined operators provided by I and ` 0or t+e operation o&erator op(# y) is
determined. T+e set consists o0 t+e union o0 t+e candidate operators provided by I and t+e candidate
operators provided by `- eac+ determined using t+e rules o0 V!.2.". 10 I and ` are t+e same type- or i0 I and
` are derived 0rom a common base type- t+en s+ared candidate operators only occur in t+e combined set
once.
10 t+e set o0 candidate user<de0ined operators is not empty- t+en t+is becomes t+e set o0 candidate operators
0or t+e operation. /t+erwise- t+e prede0ined binary o&erator op implementations- including t+eir li0ted
0orms- become t+e set o0 candidate operators 0or t+e operation. T+e prede0ined implementations o0 a given
operator are speci0ied in t+e description o0 t+e operator JV!.! t+roug+ V!.11M.
T+e overload resolution rules o0 V!.4.3 are applied to t+e set o0 candidate operators to select t+e best
operator wit+ respect to t+e argument list (# y)- and t+is operator becomes t+e result o0 t+e overload
resolution process. 10 overload resolution 0ails to select a single best operator- a compile<time error occurs.
..2.& Candidate user9defined operators
4iven a type 1 and an operation o&erator op(')- w+ere op is an overloadable operator and ' is an argument
list- t+e set o0 candidate user<de0ined operators provided by 1 0or o&erator op(') is determined as 0ollowsC
2etermine t+e type 1
3
. 10 1 is a nullable type- 1
3
is its underlying type- ot+erwise 1
3
is e9ual to 1.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 13!
C# Language Specification
*or all o&erator op declarations in 1
3
and all li0ted 0orms o0 suc+ operators- i0 at least one operator is
applicable JV!.4.3.1M wit+ respect to t+e argument list '- t+en t+e set o0 candidate operators consists o0 all
suc+ applicable operators in 1
3
.
/t+erwise- i0 1
3
is object- t+e set o0 candidate operators is empty.
/t+erwise- t+e set o0 candidate operators provided by 1
3
is t+e set o0 candidate operators provided by t+e
direct base class o0 1
3
- or t+e e00ective base class o0 1
3
i0 1
3
is a type parameter.
..2.' ;ueric prootions
=umeric promotion consists o0 automatically per0orming certain implicit conversions o0 t+e operands o0 t+e
prede0ined unary and binary numeric operators. =umeric promotion is not a distinct mec+anism- but rat+er an
e00ect o0 applying overload resolution to t+e prede0ined operators. =umeric promotion speci0ically does not
a00ect evaluation o0 user<de0ined operators- alt+oug+ user<de0ined operators can be implemented to e+ibit
similar e00ects.
(s an eample o0 numeric promotion- consider t+e prede0ined implementations o0 t+e binary > operatorC
int o&erator >(int # int y);
uint o&erator >(uint # uint y);
long o&erator >(long # long y);
ulong o&erator >(ulong # ulong y);
-loat o&erator >(-loat # -loat y);
double o&erator >(double # double y);
decimal o&erator >(decimal # decimal y);
6+en overload resolution rules JV!.4.3M are applied to t+is set o0 operators- t+e e00ect is to select t+e 0irst o0 t+e
operators 0or w+ic+ implicit conversions eist 0rom t+e operand types. *or eample- 0or t+e operation b > s-
w+ere b is a byte and s is a s"ort- overload resolution selects o&erator >(int int) as t+e best operator.
T+us- t+e e00ect is t+at b and s are converted to int- and t+e type o0 t+e result is int. 5i7ewise- 0or t+e
operation i > d- w+ere i is an int and d is a double- overload resolution selects o&erator >(double
double) as t+e best operator.
.2.6.1 6nary numeric "romotions
8nary numeric promotion occurs 0or t+e operands o0 t+e prede0ined <- C- and A unary operators. 8nary numeric
promotion simply consists o0 converting operands o0 type sbyte- byte- s"ort- us"ort- or c"ar to type int.
(dditionally- 0or t+e unary C operator- unary numeric promotion converts operands o0 type uint to type long.
.2.6.2 (inary numeric "romotions
)inary numeric promotion occurs 0or t+e operands o0 t+e prede0ined <- C- >- .- B- F- H- G- ++- @+- E- D- E+- and
D+ binary operators. )inary numeric promotion implicitly converts bot+ operands to a common type w+ic+- in
case o0 t+e non<relational operators- also becomes t+e result type o0 t+e operation. )inary numeric promotion
consists o0 applying t+e 0ollowing rules- in t+e order t+ey appear +ereC
10 eit+er operand is o0 type decimal- t+e ot+er operand is converted to type decimal- or a compile<time
error occurs i0 t+e ot+er operand is o0 type -loat or double.
/t+erwise- i0 eit+er operand is o0 type double- t+e ot+er operand is converted to type double.
/t+erwise- i0 eit+er operand is o0 type -loat- t+e ot+er operand is converted to type -loat.
/t+erwise- i0 eit+er operand is o0 type ulong- t+e ot+er operand is converted to type ulong- or a compile<
time error occurs i0 t+e ot+er operand is o0 type sbyte- s"ort- int- or long.
1"* Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
/t+erwise- i0 eit+er operand is o0 type long- t+e ot+er operand is converted to type long.
/t+erwise- i0 eit+er operand is o0 type uint and t+e ot+er operand is o0 type sbyte- s"ort- or int- bot+
operands are converted to type long.
/t+erwise- i0 eit+er operand is o0 type uint- t+e ot+er operand is converted to type uint.
/t+erwise- bot+ operands are converted to type int.
=ote t+at t+e 0irst rule disallows any operations t+at mi t+e decimal type wit+ t+e double and -loat types.
T+e rule 0ollows 0rom t+e 0act t+at t+ere are no implicit conversions between t+e decimal type and t+e double
and -loat types.
(lso note t+at it is not possible 0or an operand to be o0 type ulong w+en t+e ot+er operand is o0 a signed
integral type. T+e reason is t+at no integral type eists t+at can represent t+e 0ull range o0 ulong as well as t+e
signed integral types.
1n bot+ o0 t+e above cases- a cast epression can be used to eplicitly convert one operand to a type t+at is
compatible wit+ t+e ot+er operand.
1n t+e eample
decimal 'dd*ercent(decimal # double &ercent) {
return # > (2.3 < &ercent . 233.3);
!
a compile<time error occurs because a decimal cannot be multiplied by a double. T+e error is resolved by
eplicitly converting t+e second operand to decimal- as 0ollowsC
decimal 'dd*ercent(decimal # double &ercent) {
return # > (decimal)(2.3 < &ercent . 233.3);
!
..2.. Lifted operators
.ifted operators permit prede0ined and user<de0ined operators t+at operate on non<nullable value types to also
be used wit+ nullable 0orms o0 t+ose types. 5i0ted operators are constructed 0rom prede0ined and user<de0ined
operators t+at meet certain re9uirements- as described in t+e 0ollowingC
*or t+e unary operators
< << = == @ A
a li0ted 0orm o0 an operator eists i0 t+e operand and result types are bot+ non<nullable value types. T+e
li0ted 0orm is constructed by adding a single 7 modi0ier to t+e operand and result types. T+e li0ted operator
produces a null value i0 t+e operand is null. /t+erwise- t+e li0ted operator unwraps t+e operand- applies t+e
underlying operator- and wraps t+e result.
*or t+e binary operators
< = > . B F H G DD EE
a li0ted 0orm o0 an operator eists i0 t+e operand and result types are all non<nullable value types. T+e li0ted
0orm is constructed by adding a single 7 modi0ier to eac+ operand and result type. T+e li0ted operator
produces a null value i0 one or bot+ operands are null Jan eception being t+e F and H operators o0 t+e
bool7 type- as described in V!.1..3M. /t+erwise- t+e li0ted operator unwraps t+e operands- applies t+e
underlying operator- and wraps t+e result.
*or t+e e9uality operators
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 1"1
C# Language Specification
++ @+
a li0ted 0orm o0 an operator eists i0 t+e operand types are bot+ non<nullable value types and i0 t+e result
type is bool. T+e li0ted 0orm is constructed by adding a single 7 modi0ier to eac+ operand type. T+e li0ted
operator considers two null values e9ual- and a null value une9ual to any non<null value. 10 bot+ operands
are non<null- t+e li0ted operator unwraps t+e operands and applies t+e underlying operator to produce t+e
bool result.
*or t+e relational operators
D E D+ E+
a li0ted 0orm o0 an operator eists i0 t+e operand types are bot+ non<nullable value types and i0 t+e result
type is bool. T+e li0ted 0orm is constructed by adding a single 7 modi0ier to eac+ operand type. T+e li0ted
operator produces t+e value -alse i0 one or bot+ operands are null. /t+erwise- t+e li0ted operator unwraps
t+e operands and applies t+e underlying operator to produce t+e bool result.
..3 )eber loo5up
( member loo7up is t+e process w+ereby t+e meaning o0 a name in t+e contet o0 a type is determined. (
member loo7up can occur as part o0 evaluating a si%ple-na%e JV!.".2M or a %e%,er-access JV!.".4M in an
epression. 10 t+e si%ple-na%e or %e%,er-access occurs as t+e si%ple-e/pression o0 an invocation-e/pression
JV!.".".1M- t+e member is said to be invo&ed.
10 a member is a met+od or event- or i0 it is a constant- 0ield or property o0 a delegate type JV1"M- t+en t+e
member is said to be invoca,le.
'ember loo7up considers not only t+e name o0 a member but also t+e number o0 type parameters t+e member
+as and w+et+er t+e member is accessible. *or t+e purposes o0 member loo7up- generic met+ods and nested
generic types +ave t+e number o0 type parameters indicated in t+eir respective declarations and all ot+er
members +ave Dero type parameters.
( member loo7up o0 a name N wit+ a type parameters in a type 1 is processed as 0ollowsC
*irst- a set o0 accessible members named N is determinedC
o 10 1 is a type parameter- t+en t+e set is t+e union o0 t+e sets o0 accessible members named N in eac+ o0
t+e types speci0ied as a primary constraint or secondary constraint JV1..1."M 0or 1- along wit+ t+e set o0
accessible members named N in object.
o /t+erwise- t+e set consists o0 all accessible JV3."M members named N in 1- including in+erited members
and t+e accessible members named N in object. 10 1 is a constructed type- t+e set o0 members is
obtained by substituting type arguments as described in V1..3.2. 'embers t+at include an override
modi0ier are ecluded 0rom t+e set.
=et- i0 a is Dero- all nested types w+ose declarations include type parameters are removed. 10 a is not Dero-
all members wit+ a di00erent number o0 type parameters are removed. =ote t+at w+en a is Dero- met+ods
+aving type parameters are not removed- since t+e type in0erence process JV!.4.2M mig+t be able to in0er t+e
type arguments.
=et- i0 t+e member is invo&ed- all non<invoca,le members are removed 0rom t+e set.
=et- members t+at are +idden by ot+er members are removed 0rom t+e set. *or every member S.M in t+e
set- w+ere S is t+e type in w+ic+ t+e member M is declared- t+e 0ollowing rules are appliedC
o 10 M is a constant- 0ield- property- event- or enumeration member- t+en all members declared in a base
type o0 S are removed 0rom t+e set.
1"2 Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
o 10 M is a type declaration- t+en all non<types declared in a base type o0 S are removed 0rom t+e set- and
all type declarations wit+ t+e same number o0 type parameters as M declared in a base type o0 S are
removed 0rom t+e set.
o 10 M is a met+od- t+en all non<met+od members declared in a base type o0 S are removed 0rom t+e set.
=et- inter0ace members t+at are +idden by class members are removed 0rom t+e set. T+is step only +as an
e00ect i0 1 is a type parameter and 1 +as bot+ an e00ective base class ot+er t+an object and a non<empty
e00ective inter0ace set JV1..1."M. *or every member S.M in t+e set- w+ere S is t+e type in w+ic+ t+e member
M is declared- t+e 0ollowing rules are applied i0 S is a class declaration ot+er t+an objectC
o 10 M is a constant- 0ield- property- event- enumeration member- or type declaration- t+en all members
declared in an inter0ace declaration are removed 0rom t+e set.
o 10 M is a met+od- t+en all non<met+od members declared in an inter0ace declaration are removed 0rom
t+e set- and all met+ods wit+ t+e same signature as M declared in an inter0ace declaration are removed
0rom t+e set.
*inally- +aving removed +idden members- t+e result o0 t+e loo7up is determinedC
o 10 t+e set consists o0 a single member t+at is not a met+od- t+en t+is member is t+e result o0 t+e loo7up.
o /t+erwise- i0 t+e set contains only met+ods- t+en t+is group o0 met+ods is t+e result o0 t+e loo7up.
o /t+erwise- t+e loo7up is ambiguous- and a compile<time error occurs.
*or member loo7ups in types ot+er t+an type parameters and inter0aces- and member loo7ups in inter0aces t+at
are strictly single<in+eritance Jeac+ inter0ace in t+e in+eritance c+ain +as eactly Dero or one direct base
inter0aceM- t+e e00ect o0 t+e loo7up rules is simply t+at derived members +ide base members wit+ t+e same name
or signature. #uc+ single<in+eritance loo7ups are never ambiguous. T+e ambiguities t+at can possibly arise 0rom
member loo7ups in multiple<in+eritance inter0aces are described in V13.2.".
..3.1 +ase t!pes
*or purposes o0 member loo7up- a type 1 is considered to +ave t+e 0ollowing base typesC
10 1 is object- t+en 1 +as no base type.
10 1 is an en!%-t+pe- t+e base types o0 1 are t+e class types System.)num- System.Ualue1y&e- and
object.
10 1 is a str!ct-t+pe- t+e base types o0 1 are t+e class types System.Ualue1y&e and object.
10 1 is a class-t+pe- t+e base types o0 1 are t+e base classes o0 1- including t+e class type object.
10 1 is an interface-t+pe- t+e base types o0 1 are t+e base inter0aces o0 1 and t+e class type object.
10 1 is an arra+-t+pe- t+e base types o0 1 are t+e class types System.'rray and object.
10 1 is a delegate-t+pe- t+e base types o0 1 are t+e class types System.6elegate and object.
..# ,unction ebers
*unction members are members t+at contain eecutable statements. *unction members are always members o0
types and cannot be members o0 namespaces. C# de0ines t+e 0ollowing categories o0 0unction membersC
'et+ods
Properties
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 1"3
C# Language Specification
Events
1ndeers
8ser<de0ined operators
1nstance constructors
#tatic constructors
2estructors
Ecept 0or destructors and static constructors Jw+ic+ cannot be invo7ed eplicitlyM- t+e statements contained in
0unction members are eecuted t+roug+ 0unction member invocations. T+e actual synta 0or writing a 0unction
member invocation depends on t+e particular 0unction member category.
T+e argument list JV!.4.1M o0 a 0unction member invocation provides actual values or variable re0erences 0or t+e
parameters o0 t+e 0unction member.
1nvocations o0 met+ods- indeers- operators and instance constructors employ overload resolution to determine
w+ic+ o0 a candidate set o0 0unction members to invo7e. T+is process is described in V!.4.3.
/nce a particular 0unction member +as been identi0ied at compile<time- possibly t+roug+ overload resolution-
t+e actual run<time process o0 invo7ing t+e 0unction member is described in V!.4.4.
T+e 0ollowing table summariDes t+e processing t+at ta7es place in constructs involving t+e si categories o0
0unction members t+at can be eplicitly invo7ed. 1n t+e table- e- #- y- and value indicate epressions classi0ied
as variables or values- 1 indicates an epression classi0ied as a type- V is t+e simple name o0 a met+od- and * is
t+e simple name o0 a property.
Construct (xa)ple ,escription
'et+od
invocation
V(# y)
/verload resolution is applied to select t+e best met+od V in t+e
containing class or struct. T+e met+od is invo7ed wit+ t+e
argument list (# y). 10 t+e met+od is not static- t+e instance
epression is t"is.
1.V(# y)
/verload resolution is applied to select t+e best met+od V in t+e
class or struct 1. ( compile<time error occurs i0 t+e met+od is
not static. T+e met+od is invo7ed wit+ t+e argument list (#
y).
e.V(# y)
/verload resolution is applied to select t+e best met+od * in t+e
class- struct- or inter0ace given by t+e type o0 e. ( compile<time
error occurs i0 t+e met+od is static. T+e met+od is invo7ed
wit+ t+e instance epression e and t+e argument list (# y).
Property
access
*
T+e get accessor o0 t+e property * in t+e containing class or
struct is invo7ed. ( compile<time error occurs i0 * is write<
only. 10 * is not static- t+e instance epression is t"is.
* + value
T+e set accessor o0 t+e property * in t+e containing class or
struct is invo7ed wit+ t+e argument list (value). ( compile<
time error occurs i0 * is read<only. 10 * is not static- t+e
instance epression is t"is.
1"" Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
Construct (xa)ple ,escription
1.*
T+e get accessor o0 t+e property * in t+e class or struct 1 is
invo7ed. ( compile<time error occurs i0 * is not static or i0 *
is write<only.
1.* + value
T+e set accessor o0 t+e property * in t+e class or struct 1 is
invo7ed wit+ t+e argument list (value). ( compile<time error
occurs i0 * is not static or i0 * is read<only.
e.*
T+e get accessor o0 t+e property * in t+e class- struct- or
inter0ace given by t+e type o0 e is invo7ed wit+ t+e instance
epression e. ( compile<time error occurs i0 * is static or i0
* is write<only.
e.* + value
T+e set accessor o0 t+e property * in t+e class- struct- or
inter0ace given by t+e type o0 e is invo7ed wit+ t+e instance
epression e and t+e argument list (value). ( compile<time
error occurs i0 * is static or i0 * is read<only.
Event access
) <+ value
T+e add accessor o0 t+e event ) in t+e containing class or struct
is invo7ed. 10 ) is not static- t+e instance epression is t"is.
) =+ value
T+e remove accessor o0 t+e event ) in t+e containing class or
struct is invo7ed. 10 ) is not static- t+e instance epression is
t"is.
1.) <+ value
T+e add accessor o0 t+e event ) in t+e class or struct 1 is
invo7ed. ( compile<time error occurs i0 ) is not static.
1.) =+ value
T+e remove accessor o0 t+e event ) in t+e class or struct 1 is
invo7ed. ( compile<time error occurs i0 ) is not static.
e.) <+ value
T+e add accessor o0 t+e event ) in t+e class- struct- or inter0ace
given by t+e type o0 e is invo7ed wit+ t+e instance epression
e. ( compile<time error occurs i0 ) is static.
e.) =+ value
T+e remove accessor o0 t+e event ) in t+e class- struct- or
inter0ace given by t+e type o0 e is invo7ed wit+ t+e instance
epression e. ( compile<time error occurs i0 ) is static.
1ndeer
access
e4# y5
/verload resolution is applied to select t+e best indeer in t+e
class- struct- or inter0ace given by t+e type o0 e. T+e get
accessor o0 t+e indeer is invo7ed wit+ t+e instance epression
e and t+e argument list (# y). ( compile<time error occurs i0
t+e indeer is write<only.
e4# y5 + value
/verload resolution is applied to select t+e best indeer in t+e
class- struct- or inter0ace given by t+e type o0 e. T+e set
accessor o0 t+e indeer is invo7ed wit+ t+e instance epression
e and t+e argument list (# y value). ( compile<time error
occurs i0 t+e indeer is read<only.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 1"
C# Language Specification
Construct (xa)ple ,escription
/perator
invocation
=#
/verload resolution is applied to select t+e best unary operator
in t+e class or struct given by t+e type o0 #. T+e selected
operator is invo7ed wit+ t+e argument list (#).
# < y
/verload resolution is applied to select t+e best binary operator
in t+e classes or structs given by t+e types o0 and y. T+e
selected operator is invo7ed wit+ t+e argument list (# y).
1nstance
constructor
invocation
ne, 1(# y)
/verload resolution is applied to select t+e best instance
constructor in t+e class or struct 1. T+e instance constructor is
invo7ed wit+ t+e argument list (# y).
..#.1 *rguent lists
Every 0unction member and delegate invocation includes an argument list w+ic+ provides actual values or
variable re0erences 0or t+e parameters o0 t+e 0unction member. T+e synta 0or speci0ying t+e argument list o0 a
0unction member invocation depends on t+e 0unction member categoryC
*or instance constructors- met+ods- and delegates- t+e arguments are speci0ied as an arg!%ent-list- as
described below.
*or properties- t+e argument list is empty w+en invo7ing t+e get accessor- and consists o0 t+e epression
speci0ied as t+e rig+t operand o0 t+e assignment operator w+en invo7ing t+e set accessor.
*or events- t+e argument list consists o0 t+e epression speci0ied as t+e rig+t operand o0 t+e <+ or =+
operator.
*or indeers- t+e argument list consists o0 t+e epressions speci0ied between t+e s9uare brac7ets in t+e
indeer access. 6+en invo7ing t+e set accessor- t+e argument list additionally includes t+e epression
speci0ied as t+e rig+t operand o0 t+e assignment operator.
*or user<de0ined operators- t+e argument list consists o0 t+e single operand o0 t+e unary operator or t+e two
operands o0 t+e binary operator.
T+e arguments o0 properties JV1..!M- events JV1..3M- and user<de0ined operators JV1..1.M are always passed as
value parameters JV1..%.1.1M. T+e arguments o0 indeers JV1..$M are always passed as value parameters
JV1..%.1.1M or parameter arrays JV1..%.1.4M. ;e0erence and output parameters are not supported 0or t+ese
categories o0 0unction members.
T+e arguments o0 an instance constructor- met+od- or delegate invocation are speci0ied as an arg!%ent-listC
arg!%ent-list.
arg!%ent
arg!%ent-list ? arg!%ent
arg!%ent.
e/pression
%ef varia,le-reference
'u$ varia,le-reference
(n arg!%ent-list consists o0 one or more arg!%ents- separated by commas. Eac+ argument can ta7e one o0 t+e
0ollowing 0ormsC
(n e/pression- indicating t+at t+e argument is passed as a value parameter JV1..%.1.1M.
1"' Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
T+e 7eyword re- 0ollowed by a varia,le-reference JV".4M- indicating t+at t+e argument is passed as a
re0erence parameter JV1..%.1.2M. ( variable must be de0initely assigned JV".3M be0ore it can be passed as a
re0erence parameter. T+e 7eyword out 0ollowed by a varia,le-reference JV".4M- indicating t+at t+e argument
is passed as an output parameter JV1..%.1.3M. ( variable is considered de0initely assigned JV".3M 0ollowing a
0unction member invocation in w+ic+ t+e variable is passed as an output parameter.
2uring t+e run<time processing o0 a 0unction member invocation JV!.4.4M- t+e epressions or variable re0erences
o0 an argument list are evaluated in order- 0rom le0t to rig+t- as 0ollowsC
*or a value parameter- t+e argument epression is evaluated and an implicit conversion JV%.1M to t+e
corresponding parameter type is per0ormed. T+e resulting value becomes t+e initial value o0 t+e value
parameter in t+e 0unction member invocation.
*or a re0erence or output parameter- t+e variable re0erence is evaluated and t+e resulting storage location
becomes t+e storage location represented by t+e parameter in t+e 0unction member invocation. 10 t+e
variable re0erence given as a re0erence or output parameter is an array element o0 a reference-t+pe- a run<
time c+ec7 is per0ormed to ensure t+at t+e element type o0 t+e array is identical to t+e type o0 t+e parameter.
10 t+is c+ec7 0ails- a System.'rray1y&eMismatc")#ce&tion is t+rown.
'et+ods- indeers- and instance constructors may declare t+eir rig+t<most parameter to be a parameter array
JV1..%.1.4M. #uc+ 0unction members are invo7ed eit+er in t+eir normal 0orm or in t+eir epanded 0orm depending
on w+ic+ is applicable JV!.4.3.1MC
6+en a 0unction member wit+ a parameter array is invo7ed in its normal 0orm- t+e argument given 0or t+e
parameter array must be a single epression o0 a type t+at is implicitly convertible JV%.1M to t+e parameter
array type. 1n t+is case- t+e parameter array acts precisely li7e a value parameter.
6+en a 0unction member wit+ a parameter array is invo7ed in its epanded 0orm- t+e invocation must
speci0y Dero or more arguments 0or t+e parameter array- w+ere eac+ argument is an epression o0 a type t+at
is implicitly convertible JV%.1M to t+e element type o0 t+e parameter array. 1n t+is case- t+e invocation creates
an instance o0 t+e parameter array type wit+ a lengt+ corresponding to t+e number o0 arguments- initialiDes
t+e elements o0 t+e array instance wit+ t+e given argument values- and uses t+e newly created array instance
as t+e actual argument.
T+e epressions o0 an argument list are always evaluated in t+e order t+ey are written. T+us- t+e eample
class 1est
{
static void V(int # int y int ?) {
System.Console.WriteLine("# + {3! y + {2! ? + {8!" # y ?);
!
static void Main() {
int i + 3;
V(i<< i<< i<<);
!
!
produces t+e output
# + 3 y + 2 ? + 8
T+e array co<variance rules JV12."M permit a value o0 an array type '45 to be a re0erence to an instance o0 an
array type :45- provided an implicit re0erence conversion eists 0rom : to '. )ecause o0 t+ese rules- w+en an
array element o0 a reference-t+pe is passed as a re0erence or output parameter- a run<time c+ec7 is re9uired to
ensure t+at t+e actual element type o0 t+e array is identical to t+at o0 t+e parameter. 1n t+e eample
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 1"7
C# Language Specification
class 1est
{
static void V(re- object #) {...!
static void Main() {
object45 a + ne, object4235;
object45 b + ne, string4235;
V(re- a435); .. %(
V(re- b425); .. 'rray1y&eMismatc")#ce&tion
!
!
t+e second invocation o0 V causes a System.'rray1y&eMismatc")#ce&tion to be t+rown because t+e
actual element type o0 b is string and not object.
6+en a 0unction member wit+ a parameter array is invo7ed in its epanded 0orm- t+e invocation is processed
eactly as i0 an array creation epression wit+ an array initialiDer JV!.".1..4M was inserted around t+e epanded
parameters. *or eample- given t+e declaration
void V(int # int y &arams object45 args);
t+e 0ollowing invocations o0 t+e epanded 0orm o0 t+e met+od
V(23 83);
V(23 83 93 J3);
V(23 83 2 ""ello" 9.3);
correspond eactly to
V(23 83 ne, object45 {!);
V(23 83 ne, object45 {93 J3!);
V(23 83 ne, object45 {2 ""ello" 9.3!);
1n particular- note t+at an empty array is created w+en t+ere are Dero arguments given 0or t+e parameter array.
..#.2 T!pe inference
6+en a generic met+od is called wit+out speci0ying type arguments- a type inference process attempts to in0er
type arguments 0or t+e call. T+e presence o0 type in0erence allows a more convenient synta to be used 0or
calling a generic met+od- and allows t+e programmer to avoid speci0ying redundant type in0ormation. *or
eample- given t+e met+od declarationC
class C"ooser
{
static Oandom rand + ne, Oandom();
&ublic static 1 C"ooseD1E(1 -irst 1 second) {
return (rand.Ne#t(8) ++ 3)7 -irst/ second;
!
!
it is possible to invo7e t+e C"oose met+od wit+out eplicitly speci0ying a type argumentC
int i + C"ooser.C"oose(K 829); .. Calls C"ooseDintE
string s + C"ooser.C"oose("-oo" "bar"); .. Calls C"ooseDstringE
T+roug+ type in0erence- t+e type arguments int and string are determined 0rom t+e arguments to t+e met+od.
Type in0erence occurs as part o0 t+e compile<time processing o0 a met+od invocation JV!.".".1M and ta7es place
be0ore t+e overload resolution step o0 t+e invocation. 6+en a particular met+od group is speci0ied in a met+od
invocation- and no type arguments are speci0ied as part o0 t+e met+od invocation- type in0erence is applied to
1"$ Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
eac+ generic met+od in t+e met+od group. 10 type in0erence succeeds- t+en t+e in0erred type arguments are used
to determine t+e types o0 arguments 0or subse9uent overload resolution. 10 overload resolution c+ooses a generic
met+od as t+e one to invo7e- t+en t+e in0erred type arguments are used as t+e actual type arguments 0or t+e
invocation. 10 type in0erence 0or a particular met+od 0ails- t+at met+od does not participate in overload
resolution. T+e 0ailure o0 type in0erence- in and o0 itsel0- does not cause a compile<time error. However- it o0ten
leads to a compile<time error w+en overload resolution t+en 0ails to 0ind any applicable met+ods.
10 t+e supplied number o0 arguments is di00erent t+an t+e number o0 parameters in t+e met+od- t+en in0erence
immediately 0ails. /t+erwise- assume t+at t+e generic met+od +as t+e 0ollowing signatureC
1
r
MDI
2
bI
n
E(1
2
#
2
b 1
m
#
m
)
6it+ a met+od call o0 t+e 0orm M()
2
b)
m
) t+e tas7 o0 type in0erence is to 0ind uni9ue type arguments S
2
bS
n
0or
eac+ o0 t+e type parameters I
2
bI
n
so t+at t+e call MDS
2
bS
n
E()
2
b)
m
)becomes valid.
2uring t+e process o0 in0erence eac+ type parameter I
i
is eit+er fi/ed to a particular type S
i
or !nfi/ed wit+ an
associated set o0 ,o!nds. Eac+ o0 t+e bounds is some type 1. 1nitially eac+ type variable I
i
is un0ied wit+ an
empty set o0 bounds.
Type in0erence ta7es place in p+ases. Eac+ p+ase will try to in0er type arguments 0or more type variables based
on t+e 0indings o0 t+e previous p+ase. T+e 0irst p+ase ma7es some initial in0erences o0 bounds- w+ereas t+e
second p+ase 0ies type variables to speci0ic types and in0ers 0urt+er bounds. T+e second p+ase may +ave to be
repeated a number o0 times.
3ote. Type in0erence ta7es place not only w+en a generic met+od is called. Type in0erence 0or conversion o0
met+od groups is described in V!.4.2.12 and 0inding t+e best common type o0 a set o0 epressions is described in
V!.4.2.13.
.4.2.1 *he /irst "hase
*or eac+ o0 t+e met+od arguments )
i
C
i0 )
i
is an anonymous 0unction or a met+od group- an eplicit parameter type in0erence JV!.4.2.!M is
made 0rom )
i
wit+ type 1
i
ot+erwise an output type in0erence JV!.4.2.%M is made 0rom )
i
wit+ type 1
i
.4.2.2 *he second "hase
T+e second p+ase proceeds as 0ollowsC
(ll un0ied type variables I
i
w+ic+ do not depend on JV!.4.2."M any I
j
are 0ied JV!.4.2.1.M.
10 no suc+ type variables eist- all un0ied type variables I
i
are 0ied 0or w+ic+ all o0 t+e 0ollowing +oldC
o T+ere is at least one type variable I
j
t+at depends on I
i
o I
i
+as a non<empty set o0 bounds
10 no suc+ type variables eist and t+ere are still un0ied type variables- type in0erence 0ails.
/t+erwise- i0 no 0urt+er un0ied type variables eist- type in0erence succeeds.
/t+erwise- 0or all arguments )
i
wit+ corresponding parameter type 1
i
w+ere t+e output types JV!.4.2.4M
contain un0ied type variables I
j
but t+e input types JV!.4.2.3M do not- an output type in0erence
JV!.4.2.%M is made 0or )
i
wit+ type 1
i
. T+en t+e second p+ase is repeated.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 1"!
C# Language Specification
.4.2.3 #n"ut ty"es
10 ) is a met+od group or implicitly typed anonymous 0unction and 1 is a delegate type or epression tree type
t+en all t+e parameter types o0 1 are inp!t t+pes of ) with t+pe 1.
.4.2.4 &ut"ut ty"es
10 ) is a met+od group or an anonymous 0unction and 1 is a delegate type or epression tree type t+en t+e return
type o0 1 is an o!tp!t t+pe of ) with t+pe 1.
.4.2.5 'e"endence
(n un0ied type variable I
i
depends directl+ on an un0ied type variable I
j
i0 0or some argument )
(
wit+ type 1
(
I
j
occurs in an input type o0 )
(
wit+ type 1
(
and I
i
occurs in an output type o0 )
(
wit+ type 1
(
.
I
j
depends on I
i
i0 I
j
depends directly on I
i
or i0 I
i
depends directly on I
(
and I
(
depends on I
j
. T+us
Kdepends onL is t+e transitive but not re0leive closure o0 Kdepends directly onL.
.4.2.6 &ut"ut ty"e in/erences
(n output type in0erence is made 0rom an epression ) wit+ type 1 in t+e 0ollowing wayC
10 ) is an anonymous 0unction wit+ in0erred return type ; JV!.4.2.11M and 1 is a delegate type or epression
tree type wit+ return type 1
b
- t+en a lower<bound in0erence JV!.4.2.$M is made 0rom ; 0or 1
b
.
/t+erwise- i0 ) is a met+od group and 1 is a delegate type or epression tree type return type 1
b
wit+
parameter types 1
2
b1
(
and return type 1
b
- and overload resolution o0 ) wit+ t+e types 1
2
b1
(
yields a single
met+od wit+ return type ;- t+en a lower<bound in0erence is made 0rom ; 0or 1
b
.
/t+erwise- i0 e is an epression wit+ type ;- t+en a lower<bound in0erence is made 0rom ; 0or 1.
/t+erwise- no in0erences are made.
.4.2. %$"licit "arameter ty"e in/erences
(n eplicit parameter type in0erence is made 0rom an epression ) wit+ type 1 in t+e 0ollowing wayC
10 ) is an eplicitly typed anonymous 0unction wit+ parameter types ;
2
b;
(
and 1 is a delegate type wit+
parameter types U
2
bU
(
t+en 0or eac+ ;
i
an eact in0erence JV!.4.2.3M is made 0rom ;
i
0or t+e corresponding U
i.
.4.2.+ %$act in/erences
(n eact in0erence 0rom a type ; 0or a type U is made as 0ollowsC
10 U is one o0 t+e un0ied I
i
t+en ; is added to t+e set o0 bounds 0or I
i
.
/t+erwise i0 ; is an array type ;
e
4b5 and U is an array type U
e
4b5 o0 t+e same ran7 t+en an eact in0erence
0rom ;
e
to U
e
is made.
/t+erwise i0 U is a constructed type CDU
2
bU
(
E and ; is a constructed type CD;
2
b;
(
E t+en an eact in0erence
is made 0rom eac+ ;
i
to t+e corresponding U
i
.
/t+erwise no in0erences are made.
.4.2.2 7o,er5bound in/erences
( lower<bound in0erence 0rom a type ; 0or a type U is made as 0ollowsC
10 U is one o0 t+e un0ied I
i
t+en ; is added to t+e set o0 bounds 0or I
i
.
1* Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
/t+erwise i0 ; is an array type ;
e
4b5 and U is eit+er an array type U
e
4b5o0 t+e same ran7- or i0 ; is a one<
dimensional array type ;
e
45and U is one o0 $)numerableDU
e
E- $CollectionDU
e
E or $ListDU
e
E t+en
o 10 ;
e
is 7nown to be a re0erence type t+en a lower<bound in0erence 0rom ;
e
to U
e
is made
o /t+erwise an eact in0erence 0rom ;
e
to U
e
is made
/t+erwise i0 U is a constructed type CDU
2
bU
(
E and t+ere is a uni9ue set o0 types ;
2
b;
(
suc+ t+at a standard
implicit conversion eists 0rom ; to CD;
2
b;
(
E t+en an eact in0erence is made 0rom eac+ ;
i
0or t+e
corresponding U
i
.
/t+erwise- no in0erences are made.
.4.2.14 3i$ing
(n un0ied type variable I
i
wit+ a set o0 bounds is fi/ed as 0ollowsC
T+e set o0 candidate t+pes ;
j
starts out as t+e set o0 all types in t+e set o0 bounds 0or I
i
.
6e t+en eamine eac+ bound 0or I
i
in turnC *or eac+ bound ; o0 I
i
all types ;
j
to w+ic+ t+ere is not a
standard implicit conversion 0rom ; are removed 0rom t+e candidate set.
10 among t+e remaining candidate types ;
j
t+ere is a uni9ue type U 0rom w+ic+ t+ere is a standard implicit
conversion to all t+e ot+er candidate types- t+en I
i
is 0ied to U.
/t+erwise- type in0erence 0ails.
.4.2.11 #n/erred return ty"e
T+e inferred ret-rn type o0 an anonymous 0unction V is used during type in0erence and overload resolution. T+e
in0erred return type can only be determined 0or an anonymous 0unction w+ere all parameter types are 7nown-
eit+er because t+ey are eplicitly given- provided t+roug+ an anonymous 0unction conversion or in0erred during
type in0erence on an enclosing generic met+od invocation. T+e in0erred return type is determined as 0ollowsC
10 t+e body o0 V is an e/pression- t+en t+e in0erred return type o0 V is t+e type o0 t+at epression.
10 t+e body o0 V is a ,loc& and t+e set o0 epressions in t+e bloc7Ps return statements +as a best common
type 1 JV!.4.2.13M- t+en t+e in0erred return type o0 V is 1.
/t+erwise- a return type cannot be in0erred 0or ).
(s an eample o0 type in0erence involving anonymous 0unctions- consider t+e Select etension met+od
declared in t+e System.LinQ.)numerable classC
names&ace System.LinQ
{
&ublic static class )numerable
{
&ublic static $)numerableD1OesultE SelectD1Source1OesultE(
t"is $)numerableD1SourceE source
VuncD1Source1OesultE selector)
{
-oreac" (1Source element in source) yield return selector(element);
!
!
!
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 11
C# Language Specification
(ssuming t+e System.LinQ namespace was imported wit+ a using clause- and given a class Customer wit+
a Name property o0 type string- t+e Select met+od can be used to select t+e names o0 a list o0 customersC
ListDCustomerE customers + SetCustomerList();
$)numerableDstringE names + customers.Select(c +E c.Name);
T+e etension met+od invocation JV!.".".2M o0 Select is processed by rewriting t+e invocation to a static
met+od invocationC
$)numerableDstringE names + )numerable.Select(customers c +E c.Name);
#ince type arguments were not eplicitly speci0ied- type in0erence is used to in0er t+e type arguments. *irst- t+e
customers argument is related to t+e source parameter- in0erring 1 to be Customer. T+en- using t+e
anonymous 0unction type in0erence process described above- c is given type Customer- and t+e epression
c.Name is related to t+e return type o0 t+e selector parameter- in0erring S to be string. T+us- t+e invocation
is e9uivalent to
SeQuence.SelectDCustomerstringE(customers (Customer c) +E c.Name)
and t+e result is o0 type $)numerableDstringE.
T+e 0ollowing eample demonstrates +ow anonymous 0unction type in0erence allows type in0ormation to K0lowL
between arguments in a generic met+od invocation. 4iven t+e met+od
static P VDI`PE(I value VuncDI`E -2 VuncD`PE -8) {
return -8(-2(value));
!
type in0erence 0or t+e invocation
double seconds + V("2/2K/93" s +E 1imeS&an.*arse(s) t +E t.1otalSeconds);
proceeds as 0ollowsC *irst- t+e argument "2/2K/93" is related to t+e value parameter- in0erring I to be
string. T+en- t+e parameter o0 t+e 0irst anonymous 0unction- s- is given t+e in0erred type string- and t+e
epression 1imeS&an.*arse(s) is related to t+e return type o0 -2- in0erring ` to be System.1imeS&an.
*inally- t+e parameter o0 t+e second anonymous 0unction- t- is given t+e in0erred type System.1imeS&an- and
t+e epression t.1otalSeconds is related to t+e return type o0 -8- in0erring P to be double. T+us- t+e result
o0 t+e invocation is o0 type double.
.4.2.12 *y"e in/erence /or conversion o/ method grou"s
#imilar to calls o0 generic met+ods- type in0erence must also be applied w+en a met+od group M containing a
generic met+od is converted to a given delegate type 6 (cX.X). 4iven a met+od
1
r
MDI
2
bI
n
E(1
2
#
2
b 1
m
#
m
)
and t+e met+od group M being assigned to t+e delegate type 6 t+e tas7 o0 type in0erence is to 0ind type arguments
S
2
bS
n
so t+at t+e epressionC
MDS
2
bS
n
E
becomes compatible JV1".1M wit+ 6.
8nli7e t+e type in0erence algorit+m 0or generic met+od calls- in t+is case t+ere are only argument t+pes- no
argument e/pressions. 1n particular- t+ere are no anonymous 0unctions and +ence no need 0or multiple p+ases o0
in0erence.
1nstead- all I
i
are considered un0ied- and a lower<bound in0erence is made 0rom eac+ argument type ;
j
o0 6 to
t+e corresponding parameter type 1
j
o0 M. 10 0or any o0 t+e I
i
no bounds were 0ound- type in0erence 0ails.
/t+erwise- all I
i
are 0ied to corresponding S
i
- w+ic+ are t+e result o0 type in0erence.
12 Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
.4.2.13 3inding the best common ty"e o/ a set o/ e$"ressions
1n some cases- a common type needs to be in0erred 0or a set o0 epressions. 1n particular- t+e element types o0
implicitly typed arrays and t+e return types o0 anonymous 0unctions wit+ ,loc& bodies are 0ound in t+is way.
1ntuitively- given a set o0 epressions )
2
b)
m
t+is in0erence s+ould be e9uivalent to calling a met+od
1
r
MDIE(I #
2
b I #
m
)
wit+ t+e )
i
as arguments.
'ore precisely- t+e in0erence starts out wit+ an un0ied type variable I. /utput type in0erences are t+en made
0rom eac+ )
i
wit+ type I. *inally- I is 0ied and t+e resulting type S is t+e resulting common type 0or t+e
epressions.
..#.3 /"erload resolution
/verload resolution is a compile<time mec+anism 0or selecting t+e best 0unction member to invo7e given an
argument list and a set o0 candidate 0unction members. /verload resolution selects t+e 0unction member to
invo7e in t+e 0ollowing distinct contets wit+in C#C
1nvocation o0 a met+od named in an invocation-e/pression JV!.".".1M.
1nvocation o0 an instance constructor named in an o,<ect-creation-e/pression JV!.".1..1M.
1nvocation o0 an indeer accessor t+roug+ an ele%ent-access JV!.".%M.
1nvocation o0 a prede0ined or user<de0ined operator re0erenced in an epression JV!.2.3 and V!.2.4M.
Eac+ o0 t+ese contets de0ines t+e set o0 candidate 0unction members and t+e list o0 arguments in its own uni9ue
way- as described in detail in t+e sections listed above. *or eample- t+e set o0 candidates 0or a met+od
invocation does not include met+ods mar7ed override JV!.3M- and met+ods in a base class are not candidates i0
any met+od in a derived class is applicable JV!.".".1M.
/nce t+e candidate 0unction members and t+e argument list +ave been identi0ied- t+e selection o0 t+e best
0unction member is t+e same in all casesC
4iven t+e set o0 applicable candidate 0unction members- t+e best 0unction member in t+at set is located. 10
t+e set contains only one 0unction member- t+en t+at 0unction member is t+e best 0unction member.
/t+erwise- t+e best 0unction member is t+e one 0unction member t+at is better t+an all ot+er 0unction
members wit+ respect to t+e given argument list- provided t+at eac+ 0unction member is compared to all
ot+er 0unction members using t+e rules in V!.4.3.2. 10 t+ere is not eactly one 0unction member t+at is better
t+an all ot+er 0unction members- t+en t+e 0unction member invocation is ambiguous and a compile<time
error occurs.
T+e 0ollowing sections de0ine t+e eact meanings o0 t+e terms applica!le f-nction e!er and !etter f-nction
e!er.
.4.3.1 ?""licable /unction member
( 0unction member is said to be an applica!le f-nction e!er wit+ respect to an argument list ' w+en all o0
t+e 0ollowing are trueC
T+e number o0 arguments in ' is identical to t+e number o0 parameters in t+e 0unction member declaration.
*or eac+ argument in '- t+e parameter passing mode o0 t+e argument Ji.e.- value- re-- or outM is identical to
t+e parameter passing mode o0 t+e corresponding parameter- and
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 13
C# Language Specification
o 0or a value parameter or a parameter array- an implicit conversion JV%.1M eists 0rom t+e argument to t+e
type o0 t+e corresponding parameter- or
o 0or a re- or out parameter- t+e type o0 t+e argument is identical to t+e type o0 t+e corresponding
parameter. (0ter all- a re- or out parameter is an alias 0or t+e argument passed.
*or a 0unction member t+at includes a parameter array- i0 t+e 0unction member is applicable by t+e above rules-
it is said to be applicable in its noral for. 10 a 0unction member t+at includes a parameter array is not
applicable in its normal 0orm- t+e 0unction member may instead be applicable in its e,panded forC
T+e epanded 0orm is constructed by replacing t+e parameter array in t+e 0unction member declaration wit+
Dero or more value parameters o0 t+e element type o0 t+e parameter array suc+ t+at t+e number o0 arguments
in t+e argument list ' matc+es t+e total number o0 parameters. 10 ' +as 0ewer arguments t+an t+e number o0
0ied parameters in t+e 0unction member declaration- t+e epanded 0orm o0 t+e 0unction member cannot be
constructed and is t+us not applicable.
/t+erwise- t+e epanded 0orm is applicable i0 0or eac+ argument in ' t+e parameter passing mode o0 t+e
argument is identical to t+e parameter passing mode o0 t+e corresponding parameter- and
o 0or a 0ied value parameter or a value parameter created by t+e epansion- an implicit conversion JV%.1M
eists 0rom t+e type o0 t+e argument to t+e type o0 t+e corresponding parameter- or
o 0or a re- or out parameter- t+e type o0 t+e argument is identical to t+e type o0 t+e corresponding
parameter.
.4.3.2 (etter /unction member
4iven an argument list ' wit+ a set o0 argument epressions ] )
2
- )
8
- ...- )
N
^ and two applicable 0unction
members M
*
and M
^
wit+ parameter types ] *
2
- *
8
- ...- *
N
^ and ] ^
2
- ^
8
- ...- ^
N
^- M
*
is de0ined to be a !etter
f-nction e!er t+an M
^
i0
0or eac+ argument- t+e implicit conversion 0rom )
I
to ^
I
is not better t+an t+e implicit conversion 0rom )
I
to
*
I
- and
0or at least one argument- t+e conversion 0rom )
I
to *
I
is better t+an t+e conversion 0rom )
I
to ^
I
.
6+en per0orming t+is evaluation- i0 M
*
or M
^
is applicable in its epanded 0orm- t+en *
I
or ^
I
re0ers to a
parameter in t+e epanded 0orm o0 t+e parameter list.
1n case t+e parameter type se9uences {*
2
- *
8
- _- *
N
! and {^
2
- ^
8
- _- ^
N
! are identical- t+e 0ollowing tie<
brea7ing rules are applied- in order- to determine t+e better 0unction member.
10 M
*
is a non<generic met+od and M
^
is a generic met+od- t+en M
*
is better t+an M
^
.
/t+erwise- i0 M
*
is applicable in its normal 0orm and M
^
+as a &arams array and is applicable only in its
epanded 0orm- t+en M
*
is better t+an M
^
.
/t+erwise- i0 M
*
+as 0ewer declared parameters t+an M
^
- t+en M
*
is better t+an M
^
. T+is can occur i0 bot+
met+ods +ave &arams arrays and are applicable only in t+eir epanded 0orms.
/t+erwise- i0 M
*
+as more speci0ic parameter types t+an M
^
- t+en M
*
is better t+an M
^
. 5et {O
2
- O
8
- _- O
N
! and
{S
2
- S
8
- _- S
N
! represent t+e uninstantiated and unepanded parameter types o0 M
*
and M
^
. M
*
Ps parameter
types are more speci0ic t+an M
^
Ps i0- 0or eac+ parameter- O
I
is not less speci0ic t+an S
I
- and- 0or at least one
parameter- O
I
is more speci0ic t+an S
I
C
o ( type parameter is less speci0ic t+an a non<type parameter.
1" Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
o ;ecursively- a constructed type is more speci0ic t+an anot+er constructed type Jwit+ t+e same number o0
type argumentsM i0 at least one type argument is more speci0ic and no type argument is less speci0ic t+an
t+e corresponding type argument in t+e ot+er.
o (n array type is more speci0ic t+an anot+er array type Jwit+ t+e same number o0 dimensionsM i0 t+e
element type o0 t+e 0irst is more speci0ic t+an t+e element type o0 t+e second.
/t+erwise i0 one member is a non<li0ted operator and t+e ot+er is a li0ted operator- t+e non<li0ted one is
better.
/t+erwise- neit+er 0unction member is better.
.4.3.3 (etter conversion /rom e$"ression
4iven an implicit conversion C
2
t+at converts 0rom an epression ) to a type 1
2
- and an implicit conversion C
8

t+at converts 0rom an epression ) to a type 1
8
- t+e !etter conversion o0 t+e two conversions is determined as
0ollowsC
10 1
2
and 1
8
are t+e same type- neit+er conversion is better.
10 ) +as a type S and t+e conversion 0rom S to 1
2
is better t+an t+e conversion 0rom S to 1
8
- t+en C
2
is t+e
better conversion.
10 ) +as a type S and t+e conversion 0rom S to 1
8
is better t+an t+e conversion 0rom S to 1
2
- t+en C
8
is t+e
better conversion.
10 ) is an anonymous 0unction- 1
2
and 1
8
are delegate types or epression tree types wit+ identical parameter
lists- and an in0erred return type I eists 0or ) in t+e contet o0 t+at parameter list JV!.4.2.11MC
i0 1
2
+as a return type `
2
- and 1
8
+as a return type `
8
- and t+e conversion 0rom I to `
2
is better t+an t+e
conversion 0rom I to `
8
- t+en C
2
is t+e better conversion.
i0 1
2
+as a return type `
2
- and 1
8
+as a return type `
8
- and t+e conversion 0rom I to `
8
is better t+an t+e
conversion 0rom I to `
2
- t+en C
8
is t+e better conversion.
i0 1
2
+as a return type `- and 1
8
is void returning- t+en C
2
is t+e better conversion.
i0 1
2
is void returning- and 1
8
+as a return type `- t+en C
8
is t+e better conversion.
/t+erwise- neit+er conversion is better.
.4.3.4 (etter conversion /rom ty"e
4iven a conversion C
2
t+at converts 0rom a type S to a type 1
2
- and a conversion C
8
t+at converts 0rom a type S
to a type 1
8
- t+e !etter conversion o0 t+e two conversions is determined as 0ollowsC
10 1
2
and 1
8
are t+e same type- neit+er conversion is better.
10 S is 1
2
- C
2
is t+e better conversion.
10 S is 1
8
- C
8
is t+e better conversion.
10 an implicit conversion 0rom 1
2
to 1
8
eists- and no implicit conversion 0rom 1
8
to 1
2
eists- C
2
is t+e better
conversion.
10 an implicit conversion 0rom 1
8
to 1
2
eists- and no implicit conversion 0rom 1
2
to 1
8
eists- C
8
is t+e better
conversion.
10 1
2
is sbyte and 1
8
is byte- us"ort- uint- or ulong- C
2
is t+e better conversion.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 1
C# Language Specification
10 1
8
is sbyte and 1
2
is byte- us"ort- uint- or ulong- C
8
is t+e better conversion.
10 1
2
is s"ort and 1
8
is us"ort- uint- or ulong- C
2
is t+e better conversion.
10 1
8
is s"ort and 1
2
is us"ort- uint- or ulong- C
8
is t+e better conversion.
10 1
2
is int and 1
8
is uint- or ulong- C
2
is t+e better conversion.
10 1
8
is int and 1
2
is uint- or ulong- C
8
is t+e better conversion.
10 1
2
is long and 1
8
is ulong- C
2
is t+e better conversion.
10 1
8
is long and 1
2
is ulong- C
8
is t+e better conversion.
/t+erwise- neit+er conversion is better.
=ote t+at t+is may de0ine a conversion to be better even in cases w+ere no implicit conversion is de0ined.
T+us- 0or instance t+e conversion o0 t+e epression X to s"ort is better t+an t+e conversion o0 X to us"ort-
because a conversion o0 any type to s"ort is better t+an a conversion to us"ort.
.4.3.5 &verloading in generic classes
6+ile signatures as declared must be uni9ue- it is possible t+at substitution o0 type arguments results in identical
signatures. 1n suc+ cases- t+e tie<brea7ing rules o0 overload resolution above will pic7 t+e most speci0ic member.
T+e 0ollowing eamples s+ow overloads t+at are valid and invalid according to t+is ruleC
inter-ace $2D1E {...!
inter-ace $8D1E {...!
class S2D;E
{
int V2(; u); .. %verload resulotion -or SDintE.V2
int V2(int i); .. ,ill &ic( non=generic
void V8($2D;E a); .. Ualid overload
void V8($8D;E a);
!
class S8D;UE
{
void V9(; u U v); .. Ualid but overload resolution -or
void V9(U v ; u); .. S8DintintE.V9 ,ill -ail
void VJ(; u $2DUE v); .. Ualid but overload resolution -or
void VJ($2DUE v ; u); .. S8D$2DintEintE.VJ ,ill -ail
void VK(; u2 $2DUE v8); .. Ualid overload
void VK(U v2 ; u8);
void VX(re- ; u); .. valid overload
void VX(out U v);
!
..#.# ,unction eber in"ocation
T+is section describes t+e process t+at ta7es place at run<time to invo7e a particular 0unction member. 1t is
assumed t+at a compile<time process +as already determined t+e particular member to invo7e- possibly by
applying overload resolution to a set o0 candidate 0unction members.
*or purposes o0 describing t+e invocation process- 0unction members are divided into two categoriesC
1' Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
#tatic 0unction members. T+ese are instance constructors- static met+ods- static property accessors- and user<
de0ined operators. #tatic 0unction members are always non<virtual.
1nstance 0unction members. T+ese are instance met+ods- instance property accessors- and indeer accessors.
1nstance 0unction members are eit+er non<virtual or virtual- and are always invo7ed on a particular instance.
T+e instance is computed by an instance epression- and it becomes accessible wit+in t+e 0unction member
as t"is JV!.".!M.
T+e run<time processing o0 a 0unction member invocation consists o0 t+e 0ollowing steps- w+ere M is t+e
0unction member and- i0 M is an instance member- ) is t+e instance epressionC
10 M is a static 0unction memberC
o T+e argument list is evaluated as described in V!.4.1.
o M is invo7ed.
10 M is an instance 0unction member declared in a val!e-t+peC
o ) is evaluated. 10 t+is evaluation causes an eception- t+en no 0urt+er steps are eecuted.
o 10 ) is not classi0ied as a variable- t+en a temporary local variable o0 )Ps type is created and t+e value o0
) is assigned to t+at variable. ) is t+en reclassi0ied as a re0erence to t+at temporary local variable. T+e
temporary variable is accessible as t"is wit+in M- but not in any ot+er way. T+us- only w+en ) is a true
variable is it possible 0or t+e caller to observe t+e c+anges t+at M ma7es to t"is.
o T+e argument list is evaluated as described in V!.4.1.
o M is invo7ed. T+e variable re0erenced by ) becomes t+e variable re0erenced by t"is.
10 M is an instance 0unction member declared in a reference-t+peC
o ) is evaluated. 10 t+is evaluation causes an eception- t+en no 0urt+er steps are eecuted.
o T+e argument list is evaluated as described in V!.4.1.
o 10 t+e type o0 ) is a val!e-t+pe- a boing conversion JV4.3.1M is per0ormed to convert ) to type object-
and ) is considered to be o0 type object in t+e 0ollowing steps. 1n t+is case- M could only be a member
o0 System.%bject.
o T+e value o0 ) is c+ec7ed to be valid. 10 t+e value o0 ) is null- a
System.NullOe-erence)#ce&tion is t+rown and no 0urt+er steps are eecuted.
o T+e 0unction member implementation to invo7e is determinedC
10 t+e compile<time type o0 ) is an inter0ace- t+e 0unction member to invo7e is t+e implementation
o0 M provided by t+e run<time type o0 t+e instance re0erenced by ). T+is 0unction member is
determined by applying t+e inter0ace mapping rules JV13.4.4M to determine t+e implementation o0 M
provided by t+e run<time type o0 t+e instance re0erenced by ).
/t+erwise- i0 M is a virtual 0unction member- t+e 0unction member to invo7e is t+e implementation
o0 M provided by t+e run<time type o0 t+e instance re0erenced by ). T+is 0unction member is
determined by applying t+e rules 0or determining t+e most derived implementation JV1..%.3M o0 M
wit+ respect to t+e run<time type o0 t+e instance re0erenced by ).
/t+erwise- M is a non<virtual 0unction member- and t+e 0unction member to invo7e is M itsel0.
o T+e 0unction member implementation determined in t+e step above is invo7ed. T+e ob&ect re0erenced by
) becomes t+e ob&ect re0erenced by t"is.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 17
C# Language Specification
.4.4.1 #nvocations on bo$ed instances
( 0unction member implemented in a val!e-t+pe can be invo7ed t+roug+ a boed instance o0 t+at val!e-t+pe in
t+e 0ollowing situationsC
6+en t+e 0unction member is an override o0 a met+od in+erited 0rom type object and is invo7ed
t+roug+ an instance epression o0 type object.
6+en t+e 0unction member is an implementation o0 an inter0ace 0unction member and is invo7ed t+roug+ an
instance epression o0 an interface-t+pe.
6+en t+e 0unction member is invo7ed t+roug+ a delegate.
1n t+ese situations- t+e boed instance is considered to contain a variable o0 t+e val!e-t+pe- and t+is variable
becomes t+e variable re0erenced by t"is wit+in t+e 0unction member invocation. 1n particular- t+is means t+at
w+en a 0unction member is invo7ed on a boed instance- it is possible 0or t+e 0unction member to modi0y t+e
value contained in t+e boed instance.
..& Priar! e%pressions
Primary epressions include t+e simplest 0orms o0 epressions.
pri%ar+-e/pression.
pri%ar+-no-arra+-creation-e/pression
arra+-creation-e/pression
pri%ar+-no-arra+-creation-e/pression.
literal
si%ple-na%e
parenthesi-ed-e/pression
%e%,er-access
invocation-e/pression
ele%ent-access
this-access
,ase-access
post-incre%ent-e/pression
post-decre%ent-e/pression
o,<ect-creation-e/pression
delegate-creation-e/pression
anon+%o!s-o,<ect-creation-e/pression
t+peof-e/pression
chec&ed-e/pression
!nchec&ed-e/pression
defa!lt-val!e-e/pression
anon+%o!s-%ethod-e/pression
Primary epressions are divided between arra+-creation-e/pressions and pri%ar+-no-arra+-creation-
e/pressions. Treating array<creation<epression in t+is way- rat+er t+an listing it along wit+ t+e ot+er simple
epression 0orms- enables t+e grammar to disallow potentially con0using code suc+ as
object o + ne, int495425;
w+ic+ would ot+erwise be interpreted as
object o + (ne, int495)425;
1$ Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
..&.1 Literals
( pri%ar+-e/pression t+at consists o0 a literal JV2.4.4M is classi0ied as a value.
..&.2 Siple naes
( si%ple-na%e consists o0 an identi0ier- optionally 0ollowed by a type argument listC
si%ple-na%e.
identifier t+pe-arg!%ent-listopt
( si%ple-na%e is eit+er o0 t+e 0orm $ or o0 t+e 0orm $D'
2
... '
a
E- w+ere $ is a single identi0ier and D'
2
...
'
a
E is an optional t+pe-arg!%ent-list. 6+en no t+pe-arg!%ent-list is speci0ied- consider a to be Dero. T+e
si%ple-na%e is evaluated and classi0ied as 0ollowsC
10 a is Dero and t+e si%ple-na%e appears wit+in a ,loc& and i0 t+e ,loc&Ps Jor an enclosing ,loc&PsM local
variable declaration space JV3.3M contains a local variable- parameter or constant wit+ name $- t+en t+e
si%ple-na%e re0ers to t+at local variable- parameter or constant and is classi0ied as a variable or value.
10 a is Dero and t+e si%ple-na%e appears wit+in t+e body o0 a generic met+od declaration and i0 t+at
declaration includes a type parameter wit+ name $- t+en t+e si%ple-na%e re0ers to t+at type parameter.
/t+erwise- 0or eac+ instance type 1 JV1..3.1M- starting wit+ t+e instance type o0 t+e immediately enclosing
type declaration and continuing wit+ t+e instance type o0 eac+ enclosing class or struct declaration Ji0 anyMC
o 10 a is Dero and t+e declaration o0 1 includes a type parameter wit+ name $- t+en t+e si%ple-na%e re0ers
to t+at type parameter.
o /t+erwise- i0 a member loo7up JV!.3M o0 $ in 1 wit+ a type arguments produces a matc+C
10 1 is t+e instance type o0 t+e immediately enclosing class or struct type and t+e loo7up identi0ies
one or more met+ods- t+e result is a met+od group wit+ an associated instance epression o0 t"is.
10 a type argument list was speci0ied- it is used in calling a generic met+od JV!.".".1M.
/t+erwise- i0 1 is t+e instance type o0 t+e immediately enclosing class or struct type- i0 t+e loo7up
identi0ies an instance member- and i0 t+e re0erence occurs wit+in t+e ,loc& o0 an instance
constructor- an instance met+od- or an instance accessor- t+e result is t+e same as a member access
JV!.".4M o0 t+e 0orm t"is.$. T+is can only +appen w+en a is Dero.
/t+erwise- t+e result is t+e same as a member access JV!.".4M o0 t+e 0orm 1.$ or 1.$D'
2
... '
a
E.
1n t+is case- it is a compile<time error 0or t+e si%ple-na%e to re0er to an instance member.
/t+erwise- 0or eac+ namespace N- starting wit+ t+e namespace in w+ic+ t+e si%ple-na%e occurs- continuing
wit+ eac+ enclosing namespace Ji0 anyM- and ending wit+ t+e global namespace- t+e 0ollowing steps are
evaluated until an entity is locatedC
o 10 a is Dero and $ is t+e name o0 a namespace in N- t+enC
10 t+e location w+ere t+e si%ple-na%e occurs is enclosed by a namespace declaration 0or N and t+e
namespace declaration contains an e/tern-alias-directive or !sing-alias-directive t+at associates t+e
name $ wit+ a namespace or type- t+en t+e si%ple-na%e is ambiguous and a compile<time error
occurs.
/t+erwise- t+e si%ple-na%e re0ers to t+e namespace named $ in N.
o /t+erwise- i0 N contains an accessible type +aving name $ and a type parameters- t+enC
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 1!
C# Language Specification
10 a is Dero and t+e location w+ere t+e si%ple-na%e occurs is enclosed by a namespace declaration
0or N and t+e namespace declaration contains an e/tern-alias-directive or !sing-alias-directive t+at
associates t+e name $ wit+ a namespace or type- t+en t+e si%ple-na%e is ambiguous and a compile<
time error occurs.
/t+erwise- t+e na%espace-or-t+pe-na%e re0ers to t+e type constructed wit+ t+e given type
arguments.
o /t+erwise- i0 t+e location w+ere t+e si%ple-na%e occurs is enclosed by a namespace declaration 0or NC
10 a is Dero and t+e namespace declaration contains an e/tern-alias-directive or !sing-alias-directive
t+at associates t+e name $ wit+ an imported namespace or type- t+en t+e si%ple-na%e re0ers to t+at
namespace or type.
/t+erwise- i0 t+e namespaces imported by t+e !sing-na%espace-directives o0 t+e namespace
declaration contain eactly one type +aving name $ and a type parameters- t+en t+e si%ple-na%e
re0ers to t+at type constructed wit+ t+e given type arguments.
/t+erwise- i0 t+e namespaces imported by t+e !sing-na%espace-directives o0 t+e namespace
declaration contain more t+an one type +aving name $ and a type parameters- t+en t+e si%ple-na%e
is ambiguous and an error occurs.
=ote t+at t+is entire step is eactly parallel to t+e corresponding step in t+e processing o0 a na%espace-or-
t+pe-na%e JV3.3M.
/t+erwise- t+e si%ple-na%e is unde0ined and a compile<time error occurs.
.5.2.1 #nvariant meaning in bloc0s
*or eac+ occurrence o0 a given identi0ier as a si%ple-na%e in an epression or declarator- every ot+er occurrence
o0 t+e same identi0ier as a si%ple-na%e in an epression or declarator wit+in t+e immediately enclosing ,loc&
JV3.2M or switch-,loc& JV3.!.2M must re0er to t+e same entity. T+is rule ensures t+at t+e meaning o0 a name is
always t+e same wit+in a bloc7.
T+e eample
class 1est
{
double #;
void V(bool b) {
# + 2.3;
i- (b) {
int #;
# + 2;
!
!
!
results in a compile<time error because # re0ers to di00erent entities wit+in t+e outer bloc7 Jt+e etent o0 w+ic+
includes t+e nested bloc7 in t+e i- statementM. 1n contrast- t+e eample
class 1est
{
double #;
1'* Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
void V(bool b) {
i- (b) {
# + 2.3;
!
else {
int #;
# + 2;
!
!
!
is permitted because t+e name # is never used in t+e outer bloc7.
=ote t+at t+e rule o0 invariant meaning applies only to simple names. 1t is per0ectly valid 0or t+e same identi0ier
to +ave one meaning as a simple name and anot+er meaning as rig+t operand o0 a member access JV!.".4M. *or
eampleC
struct *oint
{
int # y;
&ublic *oint(int # int y) {
t"is.# + #;
t"is.y + y;
!
!
T+e eample above illustrates a common pattern o0 using t+e names o0 0ields as parameter names in an instance
constructor. 1n t+e eample- t+e simple names # and y re0er to t+e parameters- but t+at does not prevent t+e
member access epressions t"is.# and t"is.y 0rom accessing t+e 0ields.
..&.3 Parent-esi<ed e%pressions
( parenthesi-ed-e/pression consists o0 an e/pression enclosed in parent+eses.
parenthesi-ed-e/pression.
( e/pression )
( parenthesi-ed-e/pression is evaluated by evaluating t+e e/pression wit+in t+e parent+eses. 10 t+e e/pression
wit+in t+e parent+eses denotes a namespace- type- or met+od group- a compile<time error occurs. /t+erwise- t+e
result o0 t+e parenthesi-ed-e/pression is t+e result o0 t+e evaluation o0 t+e contained e/pression.
..&.# )eber access
( %e%,er-access consists o0 a pri%ar+-e/pression- a predefined-t+pe- or a 8!alified-alias-%e%,er- 0ollowed by
a K.L to7en- 0ollowed by an identifier- optionally 0ollowed by a t+pe-arg!%ent-list.
%e%,er-access.
pri%ar+-e/pression 9 identifier t+pe-arg!%ent-listopt
predefined-t+pe 9 identifier t+pe-arg!%ent-listopt
8!alified-alias-%e%,er 9 identifier
predefined-t+pe. one of
"''l ")$e &h!% de&im!l d'u"le fl'!$ i*$ l'*+
'"/e&$ #")$e #h'%$ #$%i*+ ui*$ ul'*+ u#h'%$
T+e 8!alified-alias-%e%,er production is de0ined in V$.!.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 1'1
C# Language Specification
( %e%,er-access is eit+er o0 t+e 0orm ).$ or o0 t+e 0orm ).$D'
2
... '
a
E- w+ere ) is a primary<epression- $
is a single identi0ier and D'
2
... '
a
E is an optional t+pe-arg!%ent-list. 6+en no t+pe-arg!%ent-list is speci0ied-
consider a to be Dero. T+e %e%,er-access is evaluated and classi0ied as 0ollowsC
10 a is Dero and ) is a namespace and ) contains a nested namespace wit+ name $- t+en t+e result is t+at
namespace.
/t+erwise- i0 ) is a namespace and ) contains an accessible type +aving name $ and a type parameters- t+en
t+e result is t+at type constructed wit+ t+e given type arguments.
10 ) is a predefined-t+pe or a pri%ar+-e/pression classi0ied as a type- i0 ) is not a type parameter- and i0 a
member loo7up JV!.3M o0 $ in ) wit+ a type parameters produces a matc+- t+en ).$ is evaluated and
classi0ied as 0ollowsC
o 10 $ identi0ies a type- t+en t+e result is t+at type constructed wit+ t+e given type arguments.
o 10 $ identi0ies one or more met+ods- t+en t+e result is a met+od group wit+ no associated instance
epression. 10 a type argument list was speci0ied- it is used in calling a generic met+od JV!.".".1M.
o 10 $ identi0ies a static property- t+en t+e result is a property access wit+ no associated instance
epression.
o 10 $ identi0ies a static 0ieldC
10 t+e 0ield is readonly and t+e re0erence occurs outside t+e static constructor o0 t+e class or struct
in w+ic+ t+e 0ield is declared- t+en t+e result is a value- namely t+e value o0 t+e static 0ield $ in ).
/t+erwise- t+e result is a variable- namely t+e static 0ield $ in ).
o 10 $ identi0ies a static eventC
10 t+e re0erence occurs wit+in t+e class or struct in w+ic+ t+e event is declared- and t+e event was
declared wit+out event-accessor-declarations JV1..3M- t+en ).$ is processed eactly as i0 $ were a
static 0ield.
/t+erwise- t+e result is an event access wit+ no associated instance epression.
o 10 $ identi0ies a constant- t+en t+e result is a value- namely t+e value o0 t+at constant.
o 10 $ identi0ies an enumeration member- t+en t+e result is a value- namely t+e value o0 t+at enumeration
member.
o /t+erwise- ).$ is an invalid member re0erence- and a compile<time error occurs.
10 ) is a property access- indeer access- variable- or value- t+e type o0 w+ic+ is 1- and a member loo7up
JV!.3M o0 $ in 1 wit+ a type arguments produces a matc+- t+en ).$ is evaluated and classi0ied as 0ollowsC
o *irst- i0 ) is a property or indeer access- t+en t+e value o0 t+e property or indeer access is obtained
JV!.1.1M and ) is reclassi0ied as a value.
o 10 $ identi0ies one or more met+ods- t+en t+e result is a met+od group wit+ an associated instance
epression o0 ). 10 a type argument list was speci0ied- it is used in calling a generic met+od JV!.".".1M.
o 10 $ identi0ies an instance property- t+en t+e result is a property access wit+ an associated instance
epression o0 ).
o 10 1 is a class-t+pe and $ identi0ies an instance 0ield o0 t+at class-t+peC
10 t+e value o0 ) is null- t+en a System.NullOe-erence)#ce&tion is t+rown.
1'2 Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
/t+erwise- i0 t+e 0ield is readonly and t+e re0erence occurs outside an instance constructor o0 t+e
class in w+ic+ t+e 0ield is declared- t+en t+e result is a value- namely t+e value o0 t+e 0ield $ in t+e
ob&ect re0erenced by ).
/t+erwise- t+e result is a variable- namely t+e 0ield $ in t+e ob&ect re0erenced by ).
o 10 1 is a str!ct-t+pe and $ identi0ies an instance 0ield o0 t+at str!ct-t+peC
10 ) is a value- or i0 t+e 0ield is readonly and t+e re0erence occurs outside an instance constructor
o0 t+e struct in w+ic+ t+e 0ield is declared- t+en t+e result is a value- namely t+e value o0 t+e 0ield $
in t+e struct instance given by ).
/t+erwise- t+e result is a variable- namely t+e 0ield $ in t+e struct instance given by ).
o 10 $ identi0ies an instance eventC
10 t+e re0erence occurs wit+in t+e class or struct in w+ic+ t+e event is declared- and t+e event was
declared wit+out event-accessor-declarations JV1..3M- t+en ).$ is processed eactly as i0 $ was an
instance 0ield.
/t+erwise- t+e result is an event access wit+ an associated instance epression o0 ).
/t+erwise- an attempt is made to process ).$ as an etension met+od invocation JV!.".".2M. 10 t+is 0ails-
).$ is an invalid member re0erence- and a compile<time error occurs.
.5.4.1 #dentical sim"le names and ty"e names
1n a member access o0 t+e 0orm ).$- i0 ) is a single identi0ier- and i0 t+e meaning o0 ) as a si%ple-na%e JV!.".2M
is a constant- 0ield- property- local variable- or parameter wit+ t+e same type as t+e meaning o0 ) as a t+pe-na%e
JV3.3M- t+en bot+ possible meanings o0 ) are permitted. T+e two possible meanings o0 ).$ are never ambiguous-
since $ must necessarily be a member o0 t+e type ) in bot+ cases. 1n ot+er words- t+e rule simply permits access
to t+e static members and nested types o0 ) w+ere a compile<time error would ot+erwise +ave occurred. *or
eampleC
struct Color
{
&ublic static readonly Color W"ite + ne, Color(...);
&ublic static readonly Color :lac( + ne, Color(...);
&ublic Color Com&lement() {...!
!
class '
{
&ublic Color Color; .. Vield Color o- ty&e Color
void V() {
Color + Color.:lac(; .. Oe-erences Color.:lac( static member
Color + Color.Com&lement(); .. $nvo(es Com&lement() on Color -ield
!
static void S() {
Color c + Color.W"ite; .. Oe-erences Color.W"ite static member
!
!
6it+in t+e ' class- t+ose occurrences o0 t+e Color identi0ier t+at re0erence t+e Color type are underlined- and
t+ose t+at re0erence t+e Color 0ield are not underlined.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 1'3
C# Language Specification
.5.4.2 .rammar ambiguities
T+e productions 0or si%ple-na%e JV!.".2M and %e%,er-access JV!.".4M can give rise to ambiguities in t+e
grammar 0or epressions. *or eample- t+e statementC
V(SD':E(M));
could be interpreted as a call to V wit+ two arguments- S D ' and : E (M). (lternatively- it could be interpreted
as a call to V wit+ one argument- w+ic+ is a call to a generic met+od S wit+ two type arguments and one regular
argument.
10 a se9uence o0 to7ens can be parsed Jin contetM as a si%ple-na%e JV!.".2M- %e%,er-access JV!.".4M- or
pointer-%e%,er-access JV13.".2M ending wit+ a t+pe-arg!%ent-list JV4.4.1M- t+e to7en immediately 0ollowing t+e
closing E to7en is eamined. 10 it is one o0
( ) 5 ! / ; . 7 ++ @+
t+en t+e t+pe-arg!%ent-list is retained as part o0 t+e si%ple-na%e- %e%,er-access or pointer-%e%,er-access and
any ot+er possible parse o0 t+e se9uence o0 to7ens is discarded. /t+erwise- t+e t+pe-arg!%ent-list is not
considered to be part o0 t+e si%ple-na%e- %e%,er-access or pointer-%e%,er-access- even i0 t+ere is no ot+er
possible parse o0 t+e se9uence o0 to7ens. =ote t+at t+ese rules are not applied w+en parsing a t+pe-arg!%ent-list
in a na%espace-or-t+pe-na%e JV3.3M. T+e statement
V(SD':E(M));
will- according to t+is rule- be interpreted as a call to V wit+ one argument- w+ic+ is a call to a generic met+od S
wit+ two type arguments and one regular argument. T+e statements
V(S D ' : E M);
V(S D ' : EE M);
will eac+ be interpreted as a call to V wit+ two arguments. T+e statement
# + V D ' E <y;
will be interpreted as a less t+an operator- greater t+an operator- and unary plus operator- as i0 t+e statement +ad
been written # + (V D ') E (<y)- instead o0 as a si%ple-na%e wit+ a t+pe-arg!%ent-list 0ollowed by a binary
plus operator. 1n t+e statement
# + y is CD1E < ?;
t+e to7ens CD1E are interpreted as a na%espace-or-t+pe-na%e wit+ a t+pe-arg!%ent-list.
..&.& In"ocation e%pressions
(n invocation-e/pression is used to invo7e a met+od.
invocation-e/pression.
pri%ar+-e/pression ( arg!%ent-listopt )
T+e pri%ar+-e/pression o0 an invocation-e/pression must be a met+od group or a value o0 a delegate-t+pe. 10 t+e
pri%ar+-e/pression is a met+od group- t+e invocation-e/pression is a met+od invocation JV!.".".1M. 10 t+e
pri%ar+-e/pression is a value o0 a delegate-t+pe- t+e invocation-e/pression is a delegate invocation JV!.".".3M. 10
t+e pri%ar+-e/pression is neit+er a met+od group nor a value o0 a delegate-t+pe- a compile<time error occurs.
T+e optional arg!%ent-list JV!.4.1M provides values or variable re0erences 0or t+e parameters o0 t+e met+od.
T+e result o0 evaluating an invocation-e/pression is classi0ied as 0ollowsC
10 t+e invocation-e/pression invo7es a met+od or delegate t+at returns void- t+e result is not+ing. (n
epression t+at is classi0ied as not+ing cannot be an operand o0 any operator- and is permitted only in t+e
contet o0 a state%ent-e/pression JV3.%M.
1'" Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
/t+erwise- t+e result is a value o0 t+e type returned by t+e met+od or delegate.
.5.5.1 Method invocations
*or a met+od invocation- t+e pri%ar+-e/pression o0 t+e invocation-e/pression must be a met+od group. T+e
met+od group identi0ies t+e one met+od to invo7e or t+e set o0 overloaded met+ods 0rom w+ic+ to c+oose a
speci0ic met+od to invo7e. 1n t+e latter case- determination o0 t+e speci0ic met+od to invo7e is based on t+e
contet provided by t+e types o0 t+e arguments in t+e arg!%ent-list.
T+e compile<time processing o0 a met+od invocation o0 t+e 0orm M(')- w+ere M is a met+od group Jpossibly
including a t+pe-arg!%ent-listM- and ' is an optional arg!%ent-list- consists o0 t+e 0ollowing stepsC
T+e set o0 candidate met+ods 0or t+e met+od invocation is constructed. *or eac+ met+od V associated wit+
t+e met+od group MC
o 10 V is non<generic- V is a candidate w+enC
M +as no type argument list- and
V is applicable wit+ respect to ' JV!.4.3.1M.
o 10 V is generic and M +as no type argument list- V is a candidate w+enC
Type in0erence JV!.4.2M succeeds- in0erring a list o0 type arguments 0or t+e call- and
/nce t+e in0erred type arguments are substituted 0or t+e corresponding met+od type parameters- all
constructed types in t+e parameter list o0 * satis0y t+eir constraints JV4.4.4M- and t+e parameter list
o0 V is applicable wit+ respect to ' JV!.4.3.1M.
o 10 V is generic and M includes a type argument list- V is a candidate w+enC
V +as t+e same number o0 met+od type parameters as were supplied in t+e type argument list- and
/nce t+e type arguments are substituted 0or t+e corresponding met+od type parameters- all
constructed types in t+e parameter list o0 * satis0y t+eir constraints JV4.4.4M- and t+e parameter list
o0 V is applicable wit+ respect to ' JV!.4.3.1M.
T+e set o0 candidate met+ods is reduced to contain only met+ods 0rom t+e most derived typesC *or eac+
met+od C.V in t+e set- w+ere C is t+e type in w+ic+ t+e met+od V is declared- all met+ods declared in a base
type o0 C are removed 0rom t+e set. *urt+ermore- i0 C is a class type ot+er t+an object- all met+ods
declared in an inter0ace type are removed 0rom t+e set. JT+is latter rule only +as a00ect w+en t+e met+od
group was t+e result o0 a member loo7up on a type parameter +aving an e00ective base class ot+er t+an
ob&ect and a non<empty e00ective inter0ace set.M
10 t+e resulting set o0 candidate met+ods is empty- t+en 0urt+er processing along t+e 0ollowing steps are
abandoned- and instead an attempt is made to process t+e invocation as an etension met+od invocation
JV!.".".2M. 10 t+is 0ails- t+en no applicable met+ods eist- and a compile<time error occurs.
10 t+e candidate met+ods are not all declared in t+e same type- t+e met+od invocation is ambiguous- and a
compile<time error occurs. JT+is latter situation can only occur 0or an invocation o0 a met+od in an inter0ace
t+at +as multiple direct base inter0aces- as described in V13.2."- or 0or an invocation o0 a met+od on a type
parameter.M
T+e best met+od o0 t+e set o0 candidate met+ods is identi0ied using t+e overload resolution rules o0 V!.4.3. 10
a single best met+od cannot be identi0ied- t+e met+od invocation is ambiguous- and a compile<time error
occurs. 6+en per0orming overload resolution- t+e parameters o0 a generic met+od are considered a0ter
substituting t+e type arguments Jsupplied or in0erredM 0or t+e corresponding met+od type parameters.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 1'
C# Language Specification
*inal validation o0 t+e c+osen best met+od is per0ormedC
o T+e met+od is validated in t+e contet o0 t+e met+od groupC 10 t+e best met+od is a static met+od- t+e
met+od group must +ave resulted 0rom a si%ple-na%e or a %e%,er-access t+roug+ a type. 10 t+e best
met+od is an instance met+od- t+e met+od group must +ave resulted 0rom a si%ple-na%e- a %e%,er-
access t+roug+ a variable or value- or a ,ase-access. 10 neit+er o0 t+ese re9uirements is true- a compile<
time error occurs.
o 10 t+e best met+od is a generic met+od- t+e type arguments Jsupplied or in0erredM are c+ec7ed against t+e
constraints JV4.4.4M declared on t+e generic met+od. 10 any type argument does not satis0y t+e
corresponding constraintJsM on t+e type parameter- a compile<time error occurs.
/nce a met+od +as been selected and validated at compile<time by t+e above steps- t+e actual run<time
invocation is processed according to t+e rules o0 0unction member invocation described in V!.4.4.
T+e intuitive e00ect o0 t+e resolution rules described above is as 0ollowsC To locate t+e particular met+od
invo7ed by a met+od invocation- start wit+ t+e type indicated by t+e met+od invocation and proceed up t+e
in+eritance c+ain until at least one applicable- accessible- non<override met+od declaration is 0ound. T+en
per0orm type in0erence and overload resolution on t+e set o0 applicable- accessible- non<override met+ods
declared in t+at type and invo7e t+e met+od t+us selected. 10 no met+od was 0ound- try instead to process t+e
invocation as an etension met+od invocation.
.5.5.2 %$tension method invocations
1n a met+od invocation JV!.".".1M o0 one o0 t+e 0orms
e/pr . identifier ( )
e/pr . identifier ( args )
e/pr . identifier D t+peargs E ( )
e/pr . identifier D t+peargs E ( args )
i0 t+e normal processing o0 t+e invocation 0inds no applicable met+ods- an attempt is made to process t+e
construct as an etension met+od invocation. T+e ob&ective is to 0ind t+e best t+pe-na%e C- so t+at t+e
corresponding static met+od invocation can ta7e placeC
C . identifier ( e/pr )
C . identifier ( e/pr args )
C . identifier D t+peargs E ( e/pr )
C . identifier D t+peargs E ( e/pr args )
T+e searc+ 0or C proceeds as 0ollowsC
#tarting wit+ t+e closest enclosing namespace declaration- continuing wit+ eac+ enclosing namespace
declaration- and ending wit+ t+e containing compilation unit- successive attempts are made to 0ind a
candidate set o0 etension met+odsC
o 10 t+e given namespace or compilation unit directly contains non<generic type declarations C
i
wit+
etension met+ods M
j
t+at +ave t+e name identifier and are accessible and applicable wit+ respect to t+e
desired static met+od invocation above- t+en t+e set o0 t+ose etension met+ods is t+e candidate set.
o 10 namespaces imported by using namespace directives in t+e given namespace or compilation unit
directly contain non<generic type declarations C
i
wit+ etension met+ods M
j
t+at +ave t+e name
1'' Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
identifier and are accessible and applicable wit+ respect to t+e desired static met+od invocation above-
t+en t+e set o0 t+ose etension met+ods is t+e candidate set.
10 no candidate set is 0ound in any enclosing namespace declaration or compilation unit- a compile<time
error occurs.
/t+erwise- overload resolution is applied to t+e candidate set as described in JV!.4.3M. 10 no single best
met+od is 0ound- a compile<time error occurs.
C is t+e type wit+in w+ic+ t+e best met+od is declared as an etension met+od.
8sing C as a target- t+e met+od call is t+en processed as a static met+od invocation JV!.4.4M.
T+e preceding rules mean t+at instance met+ods ta7e precedence over etension met+ods- t+at etension
met+ods available in inner namespace declarations ta7e precedence over etension met+ods available in outer
namespace declarations- and t+at etension met+ods declared directly in a namespace ta7e precedence over
etension met+ods imported into t+at same namespace wit+ a using namespace directive. *or eampleC
&ublic static class )
{
&ublic static void V(t"is object obj int i) { !
&ublic static void V(t"is object obj string s) { !
!
class ' { !
class :
{
&ublic void V(int i) { !
!
class C
{
&ublic void V(object obj) { !
!
class I
{
static void 1est(' a : b C c) {
a.V(2); .. ).V(object int)
a.V(""ello"); .. ).V(object string)
b.V(2); .. :.V(int)
b.V(""ello"); .. ).V(object string)
c.V(2); .. C.V(object)
c.V(""ello"); .. C.V(object)
!
!
1n t+e eample- :Ps met+od ta7es precedence over t+e 0irst etension met+od- and CPs met+od ta7es precedence
over bot+ etension met+ods.
&ublic static class C
{
&ublic static void V(t"is int i) { Console.WriteLine("C.V({3!)" i); !
&ublic static void S(t"is int i) { Console.WriteLine("C.S({3!)" i); !
&ublic static void H(t"is int i) { Console.WriteLine("C.H({3!)" i); !
!
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 1'7
C# Language Specification
names&ace N2
{
&ublic static class 6
{
&ublic static void V(t"is int i) { Console.WriteLine("6.V({3!)" i); !
&ublic static void S(t"is int i) { Console.WriteLine("6.S({3!)" i); !
!
!
names&ace N8
{
using N2;
&ublic static class )
{
&ublic static void V(t"is int i) { Console.WriteLine(").V({3!)" i); !
!
class 1est
{
static void Main(string45 args)
{
2.V();
8.S();
9.H();
!
!
!
T+e output o0 t+is eample isC
).V(2)
6.S(8)
C.H(9)
6.S ta7es precendece over C.S- and ).V ta7es precedence over bot+ 6.V and C.V.
.5.5.3 'elegate invocations
*or a delegate invocation- t+e pri%ar+-e/pression o0 t+e invocation-e/pression must be a value o0 a delegate-
t+pe. *urt+ermore- considering t+e delegate-t+pe to be a 0unction member wit+ t+e same parameter list as t+e
delegate-t+pe- t+e delegate-t+pe must be applicable JV!.4.3.1M wit+ respect to t+e arg!%ent-list o0 t+e
invocation-e/pression.
T+e run<time processing o0 a delegate invocation o0 t+e 0orm 6(')- w+ere 6 is a pri%ar+-e/pression o0 a
delegate-t+pe and ' is an optional arg!%ent-list- consists o0 t+e 0ollowing stepsC
6 is evaluated. 10 t+is evaluation causes an eception- no 0urt+er steps are eecuted.
T+e value o0 6 is c+ec7ed to be valid. 10 t+e value o0 6 is null- a System.NullOe-erence)#ce&tion is
t+rown and no 0urt+er steps are eecuted.
/t+erwise- 6 is a re0erence to a delegate instance. *unction member invocations JV!.4.4M are per0ormed on
eac+ o0 t+e callable entities in t+e invocation list o0 t+e delegate. *or callable entities consisting o0 an
instance and instance met+od- t+e instance 0or t+e invocation is t+e instance contained in t+e callable entity.
1'$ Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
..&.' $leent access
(n ele%ent-access consists o0 a pri%ar+-no-arra+-creation-e/pression- 0ollowed by a K4K to7en- 0ollowed by an
e/pression-list- 0ollowed by a K5L to7en. T+e e/pression-list consists o0 one or more e/pressions- separated by
commas.
ele%ent-access.
pri%ar+-no-arra+-creation-e/pression = e/pression-list >
e/pression-list.
e/pression
e/pression-list ? e/pression
10 t+e pri%ar+-no-arra+-creation-e/pression o0 an ele%ent-access is a value o0 an arra+-t+pe- t+e ele%ent-
access is an array access JV!.".%.1M. /t+erwise- t+e pri%ar+-no-arra+-creation-e/pression must be a variable or
value o0 a class- struct- or inter0ace type t+at +as one or more indeer members- in w+ic+ case t+e ele%ent-
access is an indeer access JV!.".%.2M.
.5.6.1 ?rray access
*or an array access- t+e pri%ar+-no-arra+-creation-e/pression o0 t+e ele%ent-access must be a value o0 an
arra+-t+pe. T+e number o0 epressions in t+e e/pression-list must be t+e same as t+e ran7 o0 t+e arra+-t+pe- and
eac+ epression must be o0 type int- uint- long- ulong- or o0 a type t+at can be implicitly converted to one or
more o0 t+ese types.
T+e result o0 evaluating an array access is a variable o0 t+e element type o0 t+e array- namely t+e array element
selected by t+e valueJsM o0 t+e epressionJsM in t+e e/pression-list.
T+e run<time processing o0 an array access o0 t+e 0orm *4'5- w+ere * is a pri%ar+-no-arra+-creation-
e/pression o0 an arra+-t+pe and ' is an e/pression-list- consists o0 t+e 0ollowing stepsC
* is evaluated. 10 t+is evaluation causes an eception- no 0urt+er steps are eecuted.
T+e inde epressions o0 t+e e/pression-list are evaluated in order- 0rom le0t to rig+t. *ollowing evaluation
o0 eac+ inde epression- an implicit conversion JV%.1M to one o0 t+e 0ollowing types is per0ormedC int-
uint- long- ulong. T+e 0irst type in t+is list 0or w+ic+ an implicit conversion eists is c+osen. *or
instance- i0 t+e inde epression is o0 type s"ort t+en an implicit conversion to int is per0ormed- since
implicit conversions 0rom s"ort to int and 0rom s"ort to long are possible. 10 evaluation o0 an inde
epression or t+e subse9uent implicit conversion causes an eception- t+en no 0urt+er inde epressions are
evaluated and no 0urt+er steps are eecuted.
T+e value o0 * is c+ec7ed to be valid. 10 t+e value o0 * is null- a System.NullOe-erence)#ce&tion is
t+rown and no 0urt+er steps are eecuted.
T+e value o0 eac+ epression in t+e e/pression-list is c+ec7ed against t+e actual bounds o0 eac+ dimension
o0 t+e array instance re0erenced by *. 10 one or more values are out o0 range- a
System.$nde#%ut%-Oange)#ce&tion is t+rown and no 0urt+er steps are eecuted.
T+e location o0 t+e array element given by t+e inde epressionJsM is computed- and t+is location becomes
t+e result o0 t+e array access.
.5.6.2 #nde$er access
*or an indeer access- t+e pri%ar+-no-arra+-creation-e/pression o0 t+e ele%ent-access must be a variable or
value o0 a class- struct- or inter0ace type- and t+is type must implement one or more indeers t+at are applicable
wit+ respect to t+e e/pression-list o0 t+e ele%ent-access.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 1'!
C# Language Specification
T+e compile<time processing o0 an indeer access o0 t+e 0orm *4'5- w+ere * is a pri%ar+-no-arra+-creation-
e/pression o0 a class- struct- or inter0ace type 1- and ' is an e/pression-list- consists o0 t+e 0ollowing stepsC
T+e set o0 indeers provided by 1 is constructed. T+e set consists o0 all indeers declared in 1 or a base type
o0 1 t+at are not override declarations and are accessible in t+e current contet JV3."M.
T+e set is reduced to t+ose indeers t+at are applicable and not +idden by ot+er indeers. T+e 0ollowing
rules are applied to eac+ indeer S.$ in t+e set- w+ere S is t+e type in w+ic+ t+e indeer $ is declaredC
o 10 $ is not applicable wit+ respect to ' JV!.4.3.1M- t+en $ is removed 0rom t+e set.
o 10 $ is applicable wit+ respect to ' JV!.4.3.1M- t+en all indeers declared in a base type o0 S are removed
0rom t+e set.
o 10 $ is applicable wit+ respect to ' JV!.4.3.1M and S is a class type ot+er t+an object- all indeers
declared in an inter0ace are removed 0rom t+e set.
10 t+e resulting set o0 candidate indeers is empty- t+en no applicable indeers eist- and a compile<time
error occurs.
T+e best indeer o0 t+e set o0 candidate indeers is identi0ied using t+e overload resolution rules o0 V!.4.3. 10
a single best indeer cannot be identi0ied- t+e indeer access is ambiguous- and a compile<time error occurs.
T+e inde epressions o0 t+e e/pression-list are evaluated in order- 0rom le0t to rig+t. T+e result o0
processing t+e indeer access is an epression classi0ied as an indeer access. T+e indeer access epression
re0erences t+e indeer determined in t+e step above- and +as an associated instance epression o0 * and an
associated argument list o0 '.
2epending on t+e contet in w+ic+ it is used- an indeer access causes invocation o0 eit+er t+e get-accessor or
t+e set-accessor o0 t+e indeer. 10 t+e indeer access is t+e target o0 an assignment- t+e set-accessor is invo7ed
to assign a new value JV!.1%.1M. 1n all ot+er cases- t+e get-accessor is invo7ed to obtain t+e current value
JV!.1.1M.
..&.. T-is access
( this-access consists o0 t+e reserved word t"is.
this-access.
$hi#
( this-access is permitted only in t+e ,loc& o0 an instance constructor- an instance met+od- or an instance
accessor. 1t +as one o0 t+e 0ollowing meaningsC
6+en t"is is used in a pri%ar+-e/pression wit+in an instance constructor o0 a class- it is classi0ied as a
value. T+e type o0 t+e value is t+e instance type JV1..3.1M o0 t+e class wit+in w+ic+ t+e usage occurs- and t+e
value is a re0erence to t+e ob&ect being constructed.
6+en t"is is used in a pri%ar+-e/pression wit+in an instance met+od or instance accessor o0 a class- it is
classi0ied as a value. T+e type o0 t+e value is t+e instance type JV1..3.1M o0 t+e class wit+in w+ic+ t+e usage
occurs- and t+e value is a re0erence to t+e ob&ect 0or w+ic+ t+e met+od or accessor was invo7ed.
6+en t"is is used in a pri%ar+-e/pression wit+in an instance constructor o0 a struct- it is classi0ied as a
variable. T+e type o0 t+e variable is t+e instance type JV1..3.1M o0 t+e struct wit+in w+ic+ t+e usage occurs-
and t+e variable represents t+e struct being constructed. T+e t"is variable o0 an instance constructor o0 a
struct be+aves eactly t+e same as an out parameter o0 t+e struct typeRin particular- t+is means t+at t+e
variable must be de0initely assigned in every eecution pat+ o0 t+e instance constructor.
17* Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
6+en t"is is used in a pri%ar+-e/pression wit+in an instance met+od or instance accessor o0 a struct- it is
classi0ied as a variable. T+e type o0 t+e variable is t+e instance type JV1..3.1M o0 t+e struct wit+in w+ic+ t+e
usage occurs.
o 10 t+e met+od or accessor is not an iterator JV1..14M- t+e t"is variable represents t+e struct 0or w+ic+
t+e met+od or accessor was invo7ed- and be+aves eactly t+e same as a re- parameter o0 t+e struct
type.
o 10 t+e met+od or accessor is an iterator- t+e t"is variable represents a cop+ o0 t+e struct 0or w+ic+ t+e
met+od or accessor was invo7ed- and be+aves eactly t+e same as a val!e parameter o0 t+e struct type.
8se o0 t"is in a pri%ar+-e/pression in a contet ot+er t+an t+e ones listed above is a compile<time error. 1n
particular- it is not possible to re0er to t"is in a static met+od- a static property accessor- or in a varia,le-
initiali-er o0 a 0ield declaration.
..&.0 +ase access
( ,ase-access consists o0 t+e reserved word base 0ollowed by eit+er a K.L to7en and an identi0ier or an
e/pression-list enclosed in s9uare brac7etsC
,ase-access.
"!#e 9 identifier
"!#e = e/pression-list >
( ,ase-access is used to access base class members t+at are +idden by similarly named members in t+e current
class or struct. ( ,ase-access is permitted only in t+e ,loc& o0 an instance constructor- an instance met+od- or an
instance accessor. 6+en base.$ occurs in a class or struct- $ must denote a member o0 t+e base class o0 t+at
class or struct. 5i7ewise- w+en base4)5 occurs in a class- an applicable indeer must eist in t+e base class.
(t compile<time- ,ase-access epressions o0 t+e 0orm base.$ and base4)5 are evaluated eactly as i0 t+ey
were written ((:)t"is).$ and ((:)t"is)4)5- w+ere : is t+e base class o0 t+e class or struct in w+ic+ t+e
construct occurs. T+us- base.$ and base4)5 correspond to t"is.$ and t"is4)5- ecept t"is is viewed as
an instance o0 t+e base class.
6+en a ,ase-access re0erences a virtual 0unction member Ja met+od- property- or indeerM- t+e determination o0
w+ic+ 0unction member to invo7e at run<time JV!.4.4M is c+anged. T+e 0unction member t+at is invo7ed is
determined by 0inding t+e most derived implementation JV1..%.3M o0 t+e 0unction member wit+ respect to :
Jinstead o0 wit+ respect to t+e run<time type o0 t"is- as would be usual in a non<base accessM. T+us- wit+in an
override o0 a virtual 0unction member- a ,ase-access can be used to invo7e t+e in+erited implementation o0
t+e 0unction member. 10 t+e 0unction member re0erenced by a ,ase-access is abstract- a compile<time error
occurs.
..&.1 Postfi% increent and decreent operators
post-incre%ent-e/pression.
pri%ar+-e/pression ++
post-decre%ent-e/pression.
pri%ar+-e/pression ::
T+e operand o0 a post0i increment or decrement operation must be an epression classi0ied as a variable- a
property access- or an indeer access. T+e result o0 t+e operation is a value o0 t+e same type as t+e operand.
10 t+e operand o0 a post0i increment or decrement operation is a property or indeer access- t+e property or
indeer must +ave bot+ a get and a set accessor. 10 t+is is not t+e case- a compile<time error occurs.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 171
C# Language Specification
8nary operator overload resolution JV!.2.3M is applied to select a speci0ic operator implementation. Prede0ined <
< and == operators eist 0or t+e 0ollowing typesC sbyte- byte- s"ort- us"ort- int- uint- long- ulong-
c"ar- -loat- double- decimal- and any enum type. T+e prede0ined << operators return t+e value produced
by adding 1 to t+e operand- and t+e prede0ined == operators return t+e value produced by subtracting 1 0rom t+e
operand. 1n a c"ec(ed contet- i0 t+e result o0 t+is addition or subtraction is outside t+e range o0 t+e result type
and t+e result type is an integral type or enum type- a System.%ver-lo,)#ce&tion is t+rown.
T+e run<time processing o0 a post0i increment or decrement operation o0 t+e 0orm #<< or #== consists o0 t+e
0ollowing stepsC
10 # is classi0ied as a variableC
o # is evaluated to produce t+e variable.
o T+e value o0 # is saved.
o T+e selected operator is invo7ed wit+ t+e saved value o0 # as its argument.
o T+e value returned by t+e operator is stored in t+e location given by t+e evaluation o0 #.
o T+e saved value o0 # becomes t+e result o0 t+e operation.
10 # is classi0ied as a property or indeer accessC
o T+e instance epression Ji0 # is not staticM and t+e argument list Ji0 # is an indeer accessM associated
wit+ # are evaluated- and t+e results are used in t+e subse9uent get and set accessor invocations.
o T+e get accessor o0 # is invo7ed and t+e returned value is saved.
o T+e selected operator is invo7ed wit+ t+e saved value o0 # as its argument.
o T+e set accessor o0 # is invo7ed wit+ t+e value returned by t+e operator as its value argument.
o T+e saved value o0 # becomes t+e result o0 t+e operation.
T+e << and == operators also support pre0i notation JV!.%."M. T+e result o0 #<< or #== is t+e value o0 # ,efore
t+e operation- w+ereas t+e result o0 <<# or ==# is t+e value o0 # after t+e operation. 1n eit+er case- # itsel0 +as
t+e same value a0ter t+e operation.
(n o&erator << or o&erator == implementation can be invo7ed using eit+er post0i or pre0i notation. 1t is
not possible to +ave separate operator implementations 0or t+e two notations.
..&.10 T-e new operator
T+e ne, operator is used to create new instances o0 types.
T+ere are t+ree 0orms o0 ne, epressionsC
/b&ect creation epressions are used to create new instances o0 class types and value types.
(rray creation epressions are used to create new instances o0 array types.
2elegate creation epressions are used to create new instances o0 delegate types.
T+e ne, operator implies creation o0 an instance o0 a type- but does not necessarily imply dynamic allocation o0
memory. 1n particular- instances o0 value types re9uire no additional memory beyond t+e variables in w+ic+
t+ey reside- and no dynamic allocations occur w+en ne, is used to create instances o0 value types.
172 Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
.5.14.1 &b9ect creation e$"ressions
(n o,<ect-creation-e/pression is used to create a new instance o0 a class-t+pe or a val!e-t+pe.
o,<ect-creation-e/pression.
*ew t+pe ( arg!%ent-listopt ) o,<ect-or-collection-initiali-eropt
*ew t+pe o,<ect-or-collection-initiali-er
o,<ect-or-collection-initiali-er.
o,<ect-initiali-er
collection-initiali-er
T+e t+pe o0 an o,<ect-creation-e/pression must be a class-t+pe- a val!e-t+pe or a t+pe-para%eter. T+e t+pe
cannot be an abstract class-t+pe.
T+e optional arg!%ent-list JV!.4.1M is permitted only i0 t+e t+pe is a class-t+pe or a str!ct-t+pe.
(n ob&ect creation epression can omit t+e constructor argument list and enclosing parent+eses provided it
includes an ob&ect initialiDer or collection initialiDer. /mitting t+e constructor argument list and enclosing
parent+eses is e9uivalent to speci0ying an empty argument list.
Processing o0 an ob&ect creation epression t+at includes an ob&ect initialiDer or collection initialiDer consists o0
0irst processing t+e instance constructor and t+en processing t+e member or element initialiDations speci0ied by
t+e ob&ect initialiDer JV!.".1..2M or collection initialiDer JV!.".1..3M.
T+e compile<time processing o0 an o,<ect-creation-e/pression o0 t+e 0orm ne, 1(')- w+ere 1 is a class-t+pe or
a val!e-t+pe and ' is an optional arg!%ent-list- consists o0 t+e 0ollowing stepsC
10 1 is a val!e-t+pe and ' is not presentC
o T+e o,<ect-creation-e/pression is a de0ault constructor invocation. T+e result o0 t+e o,<ect-creation-
e/pression is a value o0 type 1- namely t+e de0ault value 0or 1 as de0ined in V4.1.1.
/t+erwise- i0 1 is a t+pe-para%eter and ' is not presentC
o 10 no value type constraint or constructor constraint JV1..1."M +as been speci0ied 0or 1- a compile<time
error occurs.
o T+e result o0 t+e o,<ect-creation-e/pression is a value o0 t+e run<time type t+at t+e type parameter +as
been bound to- namely t+e result o0 invo7ing t+e de0ault constructor o0 t+at type. T+e run<time type may
be a re0erence type or a value type.
/t+erwise- i0 1 is a class-t+pe or a str!ct-t+peC
o 10 1 is an abstract class-t+pe- a compile<time error occurs.
o T+e instance constructor to invo7e is determined using t+e overload resolution rules o0 V!.4.3. T+e set
o0 candidate instance constructors consists o0 all accessible instance constructors declared in 1 w+ic+
are applicable wit+ respect to ' JV!.4.3.1M. 10 t+e set o0 candidate instance constructors is empty- or i0 a
single best instance constructor cannot be identi0ied- a compile<time error occurs.
o T+e result o0 t+e o,<ect-creation-e/pression is a value o0 type 1- namely t+e value produced by invo7ing
t+e instance constructor determined in t+e step above.
/t+erwise- t+e o,<ect-creation-e/pression is invalid- and a compile<time error occurs.
T+e run<time processing o0 an o,<ect-creation-e/pression o0 t+e 0orm ne, 1(')- w+ere 1 is class-t+pe or a
str!ct-t+pe and ' is an optional arg!%ent-list- consists o0 t+e 0ollowing stepsC
10 1 is a class-t+peC
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 173
C# Language Specification
o ( new instance o0 class 1 is allocated. 10 t+ere is not enoug+ memory available to allocate t+e new
instance- a System.%ut%-Memory)#ce&tion is t+rown and no 0urt+er steps are eecuted.
o (ll 0ields o0 t+e new instance are initialiDed to t+eir de0ault values JV".2M.
o T+e instance constructor is invo7ed according to t+e rules o0 0unction member invocation JV!.4.4M. (
re0erence to t+e newly allocated instance is automatically passed to t+e instance constructor and t+e
instance can be accessed 0rom wit+in t+at constructor as t"is.
10 1 is a str!ct-t+peC
o (n instance o0 type 1 is created by allocating a temporary local variable. #ince an instance constructor
o0 a str!ct-t+pe is re9uired to de0initely assign a value to eac+ 0ield o0 t+e instance being created- no
initialiDation o0 t+e temporary variable is necessary.
o T+e instance constructor is invo7ed according to t+e rules o0 0unction member invocation JV!.4.4M. (
re0erence to t+e newly allocated instance is automatically passed to t+e instance constructor and t+e
instance can be accessed 0rom wit+in t+at constructor as t"is.
.5.14.2 &b9ect initiali@ers
(n o!1ect initiali3er speci0ies values 0or Dero or more 0ields or properties o0 an ob&ect.
o,<ect-initiali-er.
{ %e%,er-initiali-er-listopt }
{ %e%,er-initiali-er-list ? }
%e%,er-initiali-er-list.
%e%,er-initiali-er
%e%,er-initiali-er-list ? %e%,er-initiali-er
%e%,er-initiali-er.
identifier = initiali-er-val!e
initiali-er-val!e.
e/pression
o,<ect-or-collection-initiali-er
(n ob&ect initialiDer consists o0 a se9uence o0 member initialiDers- enclosed by { and ! to7ens and separated by
commas. Eac+ member initialiDer must name an accessible 0ield or property o0 t+e ob&ect being initialiDed-
0ollowed by an e9uals sign and an epression or an ob&ect initialiDer or collection initialiDer. 1t is an error 0or an
ob&ect initialiDer to include more t+an one member initialiDer 0or t+e same 0ield or property. 1t is not possible 0or
t+e ob&ect initialiDer to re0er to t+e newly created ob&ect it is initialiDing.
( member initialiDer t+at speci0ies an epression a0ter t+e e9uals sign is processed in t+e same way as an
assignment JV!.1%.1M to t+e 0ield or property.
( member initialiDer t+at speci0ies an ob&ect initialiDer a0ter t+e e9uals sign is a nested o!1ect initiali3er- i.e. an
initialiDation o0 an embedded ob&ect. 1nstead o0 assigning a new value to t+e 0ield or property- t+e assignments in
t+e nested ob&ect initialiDer are treated as assignments to members o0 t+e 0ield or property. =ested ob&ect
initialiDers cannot be applied to properties wit+ a value type- or to read<only 0ields wit+ a value type.
( member initialiDer t+at speci0ies a collection initialiDer a0ter t+e e9uals sign is an initialiDation o0 an embedded
collection. 1nstead o0 assigning a new collection to t+e 0ield or property- t+e elements given in t+e initialiDer are
added to t+e collection re0erenced by t+e 0ield or property. T+e 0ield or property must be o0 a collection type t+at
satis0ies t+e re9uirements speci0ied in V!.".1..3.
T+e 0ollowing class represents a point wit+ two coordinatesC
17" Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
&ublic class *oint
{
int # y;
&ublic int I { get { return #; ! set { # + value; ! !
&ublic int ` { get { return y; ! set { y + value; ! !
!
(n instance o0 *oint can be created and initialiDed as 0ollowsC
*oint a + ne, *oint { I + 3 ` + 2 !;
w+ic+ +as t+e same e00ect as
*oint [[a + ne, *oint();
[[a.I + 3;
[[a.` + 2;
*oint a + [[a;
w+ere [[a is an ot+erwise invisible and inaccessible temporary variable. T+e 0ollowing class represents a
rectangle created 0rom two pointsC
&ublic class Oectangle
{
*oint &2 &8;
&ublic *oint *2 { get { return &2; ! set { &2 + value; ! !
&ublic *oint *8 { get { return &8; ! set { &8 + value; ! !
!
(n instance o0 Oectangle can be created and initialiDed as 0ollowsC
Oectangle r + ne, Oectangle {
*2 + ne, *oint { I + 3 ` + 2 !
*8 + ne, *oint { I + 8 ` + 9 !
!;
w+ic+ +as t+e same e00ect as
Oectangle [[r + ne, Oectangle();
*oint [[&2 + ne, *oint();
[[&2.I + 3;
[[&2.` + 2;
[[r.*2 + [[&2;
*oint [[&8 + ne, *oint();
[[&8.I + 8;
[[&8.` + 9;
[[r.*8 + [[&8;
Oectangle r + [[r;
w+ere [[r- [[&2 and [[&8 are temporary variables t+at are ot+erwise invisible and inaccessible.
10 Oectangle_s constructor allocates t+e two embedded *oint instances
&ublic class Oectangle
{
*oint &2 + ne, *oint();
*oint &8 + ne, *oint();
&ublic *oint *2 { get { return &2; ! !
&ublic *oint *8 { get { return &8; ! !
!
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 17
C# Language Specification
t+e 0ollowing construct can be used to initialiDe t+e embedded *oint instances instead o0 assigning new
instancesC
Oectangle r + ne, Oectangle {
*2 + { I + 3 ` + 2 !
*8 + { I + 8 ` + 9 !
!;
w+ic+ +as t+e same e00ect as
Oectangle [[r + ne, Oectangle();
[[r.*2.I + 3;
[[r.*2.` + 2;
[[r.*8.I + 8;
[[r.*8.` + 9;
Oectangle r + [[r;
.5.14.3 !ollection initiali@ers
( collection initialiDer speci0ies t+e elements o0 a collection.
collection-initiali-er.
{ ele%ent-initiali-er-list }
{ ele%ent-initiali-er-list ? }
ele%ent-initiali-er-list.
ele%ent-initiali-er
ele%ent-initiali-er-list ? ele%ent-initiali-er
ele%ent-initiali-er.
non-assign%ent-e/pression
{ e/pression-list }
( collection initialiDer consists o0 a se9uence o0 element initialiDers- enclosed by { and ! to7ens and separated
by commas. Eac+ element initialiDer speci0ies an element to be added to t+e collection ob&ect being initialiDed-
and consists o0 a list o0 epressions enclosed by { and ! to7ens and separated by commas. ( single<epression
element initialiDer can be written wit+out braces- but cannot t+en be an assignment epression- to avoid
ambiguity wit+ member initialiDers. T+e non-assign%ent-e/pression production is de0ined in V!.1!.
T+e 0ollowing is an eample o0 an ob&ect creation epression t+at includes a collection initialiDerC
ListDintE digits + ne, ListDintE { 3 2 8 9 J K X M Y L !;
T+e collection ob&ect to w+ic+ a collection initialiDer is applied must be o0 a type t+at implements
System.Collections.$)numerable or a compile<time error occurs. *or eac+ speci0ied element in order- t+e
collection initialiDer invo7es an 'dd met+od on t+e target ob&ect wit+ t+e epression list o0 t+e element
initialiDer as argument list- applying normal overload resolution 0or eac+ invocation. T+us- t+e collection ob&ect
must contain an applicable 'dd met+od 0or eac+ element initialiDer.
T+e 0ollowing class represents a contact wit+ a name and a list o0 p+one numbersC
&ublic class Contact
{
string name;
ListDstringE &"oneNumbers + ne, ListDstringE();
&ublic string Name { get { return name; ! set { name + value; ! !
&ublic ListDstringE *"oneNumbers { get { return &"oneNumbers; ! !
!
17' Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
( ListDContactE can be created and initialiDed as 0ollowsC
var contacts + ne, ListDContactE {
ne, Contact {
Name + "C"ris Smit""
*"oneNumbers + { "83X=KKK=3232" "J8K=YY8=Y3Y3" !
!
ne, Contact {
Name + ":ob Harris"
*"oneNumbers + { "XK3=KKK=32LL" !
!
!;
w+ic+ +as t+e same e00ect as
var contacts + ne, ListDContactE();
Contact [[c2 + ne, Contact();
[[c2.Name + "C"ris Smit"";
[[c2.*"oneNumbers.'dd("83X=KKK=3232");
[[c2.*"oneNumbers.'dd("J8K=YY8=Y3Y3");
contacts.'dd([[c2);
Contact [[c8 + ne, Contact();
[[c8.Name + ":ob Harris";
[[c8.*"oneNumbers.'dd("XK3=KKK=32LL");
contacts.'dd([[c8);
w+ere [[c2 and [[c8 are temporary variables t+at are ot+erwise invisible and inaccessible.
.5.14.4 ?rray creation e$"ressions
(n arra+-creation-e/pression is used to create a new instance o0 an arra+-t+pe.
arra+-creation-e/pression.
*ew non-arra+-t+pe = e/pression-list > ran&-specifiersopt arra+-initiali-eropt
*ew arra+-t+pe arra+-initiali-er
*ew ran&-specifier arra+-initiali-er
(n array creation epression o0 t+e 0irst 0orm allocates an array instance o0 t+e type t+at results 0rom deleting
eac+ o0 t+e individual epressions 0rom t+e epression list. *or eample- t+e array creation epression ne,
int423 835 produces an array instance o0 type int45- and t+e array creation epression ne, int423545
produces an array o0 type int4545. Eac+ epression in t+e epression list must be o0 type int- uint- long-
or ulong- or o0 a type t+at can be implicitly converted to one or more o0 t+ese types. T+e value o0 eac+
epression determines t+e lengt+ o0 t+e corresponding dimension in t+e newly allocated array instance. #ince
t+e lengt+ o0 an array dimension must be nonnegative- it is a compile<time error to +ave a constant-e/pression
wit+ a negative value in t+e epression list.
Ecept in an unsa0e contet JV13.1M- t+e layout o0 arrays is unspeci0ied.
10 an array creation epression o0 t+e 0irst 0orm includes an array initialiDer- eac+ epression in t+e epression
list must be a constant and t+e ran7 and dimension lengt+s speci0ied by t+e epression list must matc+ t+ose o0
t+e array initialiDer.
1n an array creation epression o0 t+e second or t+ird 0orm- t+e ran7 o0 t+e speci0ied array type or ran7 speci0ier
must matc+ t+at o0 t+e array initialiDer. T+e individual dimension lengt+s are in0erred 0rom t+e number o0
elements in eac+ o0 t+e corresponding nesting levels o0 t+e array initialiDer. T+us- t+e epression
ne, int45 {{3 2! {8 9! {J K!!
eactly corresponds to
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 177
C# Language Specification
ne, int49 85 {{3 2! {8 9! {J K!!
(n array creation epression o0 t+e t+ird 0orm is re0erred to as an iplicitly typed array creation e,pression. 1t
is similar to t+e second 0orm- ecept t+at t+e element type o0 t+e array is not eplicitly given- but determined as
t+e best common type JV!.4.2.13M o0 t+e set o0 epressions in t+e array initialiDer. *or a multidimensional array-
i.e.- one w+ere t+e ran&-specifier contains at least one comma- t+is set comprises all e/pressions 0ound in nested
arra+-initiali-ers.
(rray initialiDers are described 0urt+er in V12.%.
T+e result o0 evaluating an array creation epression is classi0ied as a value- namely a re0erence to t+e newly
allocated array instance. T+e run<time processing o0 an array creation epression consists o0 t+e 0ollowing stepsC
T+e dimension lengt+ epressions o0 t+e e/pression-list are evaluated in order- 0rom le0t to rig+t. *ollowing
evaluation o0 eac+ epression- an implicit conversion JV%.1M to one o0 t+e 0ollowing types is per0ormedC int-
uint- long- ulong. T+e 0irst type in t+is list 0or w+ic+ an implicit conversion eists is c+osen. 10
evaluation o0 an epression or t+e subse9uent implicit conversion causes an eception- t+en no 0urt+er
epressions are evaluated and no 0urt+er steps are eecuted.
T+e computed values 0or t+e dimension lengt+s are validated as 0ollows. 10 one or more o0 t+e values are
less t+an Dero- a System.%ver-lo,)#ce&tion is t+rown and no 0urt+er steps are eecuted.
(n array instance wit+ t+e given dimension lengt+s is allocated. 10 t+ere is not enoug+ memory available to
allocate t+e new instance- a System.%ut%-Memory)#ce&tion is t+rown and no 0urt+er steps are
eecuted.
(ll elements o0 t+e new array instance are initialiDed to t+eir de0ault values JV".2M.
10 t+e array creation epression contains an array initialiDer- t+en eac+ epression in t+e array initialiDer is
evaluated and assigned to its corresponding array element. T+e evaluations and assignments are per0ormed
in t+e order t+e epressions are written in t+e array initialiDerRin ot+er words- elements are initialiDed in
increasing inde order- wit+ t+e rig+tmost dimension increasing 0irst. 10 evaluation o0 a given epression or
t+e subse9uent assignment to t+e corresponding array element causes an eception- t+en no 0urt+er elements
are initialiDed Jand t+e remaining elements will t+us +ave t+eir de0ault valuesM.
(n array creation epression permits instantiation o0 an array wit+ elements o0 an array type- but t+e elements o0
suc+ an array must be manually initialiDed. *or eample- t+e statement
int4545 a + ne, int4233545;
creates a single<dimensional array wit+ 1.. elements o0 type int45. T+e initial value o0 eac+ element is null.
1t is not possible 0or t+e same array creation epression to also instantiate t+e sub<arrays- and t+e statement
int4545 a + ne, int423354K5; .. )rror
results in a compile<time error. 1nstantiation o0 t+e sub<arrays must instead be per0ormed manually- as in
int4545 a + ne, int4233545;
-or (int i + 3; i D 233; i<<) a4i5 + ne, int4K5;
6+en an array o0 arrays +as a KrectangularL s+ape- t+at is w+en t+e sub<arrays are all o0 t+e same lengt+- it is
more e00icient to use a multi<dimensional array. 1n t+e eample above- instantiation o0 t+e array o0 arrays creates
1.1 ob&ectsRone outer array and 1.. sub<arrays. 1n contrast-
int45 + ne, int4233 K5;
creates only a single ob&ect- a two<dimensional array- and accomplis+es t+e allocation in a single statement.
T+e 0ollowing are eamples o0 implicitly typed array creation epressionsC
var a + ne,45 { 2 23 233 2333 !; .. int45
17$ Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
var b + ne,45 { 2 2.K 8 8.K !; .. double45
var c + ne,45 { { ""ello" null ! { ",orld" "@" ! !; .. string45
var d + ne,45 { 2 "one" 8 "t,o" !; .. )rror
T+e last epression causes a compile<time error because neit+er int nor string is implicitly convertible to t+e
ot+er- and so t+ere is no best common type. (n eplicitly typed array creation epression must be used in t+is
case- 0or eample speci0ying t+e type to be object45. (lternatively- one o0 t+e elements can be cast to a
common base type- w+ic+ would t+en become t+e in0erred element type.
1mplicitly typed array creation epressions can be combined wit+ anonymous ob&ect initialiDers JV!.".1..%M to
create anonymously typed data structures. *or eampleC
var contacts + ne,45 {
ne, {
Name + "C"ris Smit""
*"oneNumbers + ne,45 { "83X=KKK=3232" "J8K=YY8=Y3Y3" !
!
ne, {
Name + ":ob Harris"
*"oneNumbers + ne,45 { "XK3=KKK=32LL" !
!
!;
.5.14.5 'elegate creation e$"ressions
( delegate-creation-e/pression is used to create a new instance o0 a delegate-t+pe.
delegate-creation-e/pression.
*ew delegate-t+pe ( e/pression )
T+e argument o0 a delegate creation epression must be a met+od group- an anonymous 0unction or a value o0 a
delegate-t+pe. 10 t+e argument is a met+od group- it identi0ies t+e met+od and- 0or an instance met+od- t+e ob&ect
0or w+ic+ to create a delegate. 10 t+e argument is an anonymous 0unction it directly de0ines t+e parameters and
met+od body o0 t+e delegate target. 10 t+e argument is a value o0 a delegate-t+pe- it identi0ies a delegate instance
o0 w+ic+ to create a copy.
T+e compile<time processing o0 a delegate-creation-e/pression o0 t+e 0orm ne, 6())- w+ere 6 is a delegate-
t+pe and ) is an e/pression- consists o0 t+e 0ollowing stepsC
10 ) is a met+od group- t+e delegate creation epression is processed in t+e same way as a met+od group
conversion JV%.%M 0rom ) to 6.
10 ) is an anonymous 0unction- t+e delegate creation epression is processed in t+e same way as an
anonymous 0unction conversion JV%."M 0rom ) to 6.
10 ) is a value o0 a delegate type- ) must be compatible JV1".1M wit+ 6- and t+e result is a re0erence to a newly
created delegate o0 type 6 t+at re0ers to t+e same invocation list as ). 10 ) is not compatible wit+ 6- a
compile<time error occurs.
T+e run<time processing o0 a delegate-creation-e/pression o0 t+e 0orm ne, 6())- w+ere 6 is a delegate-t+pe
and ) is an e/pression- consists o0 t+e 0ollowing stepsC
10 ) is a met+od group- t+e delegate creation epression is evaluated as a met+od group conversion JV%.%M
0rom ) to 6.
10 ) is an anonymous 0unction- t+e delegate creation is evaluated as an anonymous 0unction conversion 0rom
) to 6 JV%."M.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 17!
C# Language Specification
10 ) is a value o0 a delegate-t+peC
o ) is evaluated. 10 t+is evaluation causes an eception- no 0urt+er steps are eecuted.
o 10 t+e value o0 ) is null- a System.NullOe-erence)#ce&tion is t+rown and no 0urt+er steps are
eecuted.
o ( new instance o0 t+e delegate type 6 is allocated. 10 t+ere is not enoug+ memory available to allocate
t+e new instance- a System.%ut%-Memory)#ce&tion is t+rown and no 0urt+er steps are eecuted.
o T+e new delegate instance is initialiDed wit+ t+e same invocation list as t+e delegate instance given by
).
T+e invocation list o0 a delegate is determined w+en t+e delegate is instantiated and t+en remains constant 0or
t+e entire li0etime o0 t+e delegate. 1n ot+er words- it is not possible to c+ange t+e target callable entities o0 a
delegate once it +as been created. 6+en two delegates are combined or one is removed 0rom anot+er JV1".1M- a
new delegate resultsQ no eisting delegate +as its contents c+anged.
1t is not possible to create a delegate t+at re0ers to a property- indeer- user<de0ined operator- instance
constructor- destructor- or static constructor.
(s described above- w+en a delegate is created 0rom a met+od group- t+e 0ormal parameter list and return type
o0 t+e delegate determine w+ic+ o0 t+e overloaded met+ods to select. 1n t+e eample
delegate double 6oubleVunc(double #);
class '
{
6oubleVunc - + ne, 6oubleVunc(SQuare);
static -loat SQuare(-loat #) {
return # > #;
!
static double SQuare(double #) {
return # > #;
!
!
t+e '.- 0ield is initialiDed wit+ a delegate t+at re0ers to t+e second SQuare met+od because t+at met+od eactly
matc+es t+e 0ormal parameter list and return type o0 6oubleVunc. Had t+e second SQuare met+od not been
present- a compile<time error would +ave occurred.
.5.14.6 ?nonymous ob9ect creation e$"ressions
(n anon+%o!s-o,<ect-creation-e/pression is used to create an ob&ect o0 an anonymous type.
anon+%o!s-o,<ect-creation-e/pression.
*ew anon+%o!s-o,<ect-initiali-er
anon+%o!s-o,<ect-initiali-er.
{ %e%,er-declarator-listopt }
{ %e%,er-declarator-list ? }
%e%,er-declarator-list.
%e%,er-declarator
%e%,er-declarator-list ? %e%,er-declarator
1$* Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
%e%,er-declarator.
si%ple-na%e
%e%,er-access
identifier = e/pression
(n anonymous ob&ect initialiDer declares an anonymous type and returns an instance o0 t+at type. (n
anonymous type is a nameless class type t+at in+erits directly 0rom object. T+e members o0 an anonymous
type are a se9uence o0 read<only properties in0erred 0rom t+e anonymous ob&ect initialiDer used to create an
instance o0 t+e type. #peci0ically- an anonymous ob&ect initialiDer o0 t+e 0orm
ne, { p1 + e1 p2 + e2 > pn + en !
declares an anonymous type o0 t+e 0orm
class [['nonymous2
{
&rivate readonly 91 f1 ;
&rivate readonly 92 f2 ;
>
&rivate readonly 9n fn ;
&ublic [['nonymous2(91 a1 92 a2> 9n an) {
f1 + a1 ;
f2 + a2 ;
>
fn + an ;
!
&ublic 91 p1 { get { return f1 ; ! !
&ublic 92 p2 { get { return f2 ; ! !
>
&ublic 91 p1 { get { return f1 ; ! !
&ublic override bool )Quals(object o) { b !
&ublic override int SetHas"Code() { b !
!
w+ere eac+ 9/ is t+e type o0 t+e corresponding epression e/. T+e epression used in a %e%,er-declarator must
+ave a type. T+us- it is a compile<time error 0or an epression in a %e%,er-declarator to be null or an
anonymous 0unction. 1t is also a compile time error 0or t+e epression to +ave an unsa0e type.
T+e name o0 an anonymous type is automatically generated by t+e compiler and cannot be re0erenced in
program tet.
6it+in t+e same program- two anonymous ob&ect initialiDers t+at speci0y a se9uence o0 properties o0 t+e same
names and compile<time types in t+e same order will produce instances o0 t+e same anonymous type.
1n t+e eample
var &2 + ne, { Name + "La,nmo,er" *rice + JLK.33 !;
var &8 + ne, { Name + "S"ovel" *rice + 8X.LK !;
&2 + &8;
t+e assignment on t+e last line is permitted because &2 and &8 are o0 t+e same anonymous type.
T+e )Quals and SetHas"code met+ods on anonymous types override t+e met+ods in+erited 0rom object-
and are de0ined in terms o0 t+e )Quals and SetHas"code o0 t+e properties- so t+at two instances o0 t+e same
anonymous type are e9ual i0 and only i0 all t+eir properties are e9ual.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 1$1
C# Language Specification
( member declarator can be abbreviated to a simple name JV!.".2M or a member access JV!.".4M. T+is is called a
pro1ection initiali3er and is s+ort+and 0or a declaration o0 and assignment to a property wit+ t+e same name.
#peci0ically- member declarators o0 t+e 0orms
identifier e/pr . identifier
are precisely e9uivalent to t+e 0ollowing- respectivelyC
identifer + identifier identifier + e/pr . identifier
T+us- in a pro&ection initialiDer t+e identifier selects bot+ t+e value and t+e 0ield or property to w+ic+ t+e value is
assigned. 1ntuitively- a pro&ection initialiDer pro&ects not &ust a value- but also t+e name o0 t+e value.
..&.11 T-e t!peof operator
T+e ty&eo- operator is used to obtain t+e System.1y&e ob&ect 0or a type.
t+peof-e/pression.
$).e'f ( t+pe )
$).e'f ( !n,o!nd-t+pe-na%e )
$).e'f ( ,'id )
!n,o!nd-t+pe-na%e.
identifier generic-di%ension-specifieropt
identifier @@ identifier generic-di%ension-specifieropt
!n,o!nd-t+pe-na%e . identifier generic-di%ension-specifieropt
generic-di%ension-specifier.
I co%%asopt J
co%%as.
?
co%%as ?
T+e 0irst 0orm o0 t+peof-e/pression consists o0 a ty&eo- 7eyword 0ollowed by a parent+esiDed t+pe. T+e result
o0 an epression o0 t+is 0orm is t+e System.1y&e ob&ect 0or t+e indicated type. T+ere is only one
System.1y&e ob&ect 0or any given type. T+is means t+at 0or a type 1- ty&eo-(1) ++ ty&eo-(1) is always
true.
T+e second 0orm o0 t+peof-e/pression consists o0 a ty&eo- 7eyword 0ollowed by a parent+esiDed !n,o!nd-
t+pe-na%e. (n !n,o!nd-t+pe-na%e is very similar to a t+pe-na%e JV3.3M ecept t+at an !n,o!nd-t+pe-na%e
contains generic-di%ension-specifiers w+ere a t+pe-na%e contains t+pe-arg!%ent-lists. 6+en t+e operand o0 a
t+peof-e/pression is a se9uence o0 to7ens t+at satis0ies t+e grammars o0 bot+ !n,o!nd-t+pe-na%e and t+pe-
na%e- namely w+en it contains neit+er a generic-di%ension-specifier nor a t+pe-arg!%ent-list- t+e se9uence o0
to7ens is considered to be a t+pe-na%e. T+e meaning o0 an !n,o!nd-t+pe-na%e is determined as 0ollowsC
Convert t+e se9uence o0 to7ens to a t+pe-na%e by replacing eac+ generic-di%ension-specifier wit+ a t+pe-
arg!%ent-list +aving t+e same number o0 commas and t+e 7eyword object as eac+ t+pe-arg!%ent.
Evaluate t+e resulting t+pe-na%e- w+ile ignoring all type parameter constraints.
T+e !n,o!nd-t+pe-na%e resolves to t+e unbound generic type associated wit+ t+e resulting constructed type
JV4.4.3M.
T+e result o0 t+e t+peof-e/pression is t+e System.1y&e ob&ect 0or t+e resulting unbound generic type.
T+e t+ird 0orm o0 t+peof-e/pression consists o0 a ty&eo- 7eyword 0ollowed by a parent+esiDed void 7eyword.
T+e result o0 an epression o0 t+is 0orm is t+e System.1y&e ob&ect t+at represents t+e absence o0 a type. T+e
1$2 Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
type ob&ect returned by ty&eo-(void) is distinct 0rom t+e type ob&ect returned 0or any type. T+is special type
ob&ect is use0ul in class libraries t+at allow re0lection onto met+ods in t+e language- w+ere t+ose met+ods wis+
to +ave a way to represent t+e return type o0 any met+od- including void met+ods- wit+ an instance o0
System.1y&e.
T+e ty&eo- operator can be used on a type parameter. T+e result is t+e System.1y&e ob&ect 0or t+e run<time
type t+at was bound to t+e type parameter. T+e ty&eo- operator can also be used on a constructed type or an
unbound generic type JV4.4.3M. T+e System.1y&e ob&ect 0or an unbound generic type is not t+e same as t+e
System.1y&e ob&ect o0 t+e instance type. T+e instance type is always a closed constructed type at run<time so
its System.1y&e ob&ect depends on t+e runtime type arguments in use- w+ile t+e unbound generic type +as no
type arguments.
T+e eample
using System;
class ID1E
{
&ublic static void *rint1y&es() {
1y&e45 t + {
ty&eo-(int)
ty&eo-(System.$nt98)
ty&eo-(string)
ty&eo-(double45)
ty&eo-(void)
ty&eo-(1)
ty&eo-(ID1E)
ty&eo-(IDID1EE)
ty&eo-(IDE)
!;
-or (int i + 3; i D t.Lengt"; i<<) {
Console.WriteLine(t4i5);
!
!
!
class 1est
{
static void Main() {
IDintE.*rint1y&es();
!
!
produces t+e 0ollowing outputC
System.$nt98
System.$nt98
System.String
System.6ouble45
System.Uoid
System.$nt98
Id24System.$nt985
Id24Id24System.$nt9855
Id2415
=ote t+at int and System.$nt98 are t+e same type.
(lso note t+at t+e result o0 ty&eo-(IDE) does not depend on t+e type argument but t+e result o0
ty&eo-(ID1E) does.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 1$3
C# Language Specification
..&.12 T-e c-ec5ed and unc-ec5ed operators
T+e c"ec(ed and unc"ec(ed operators are used to control t+e overflo2 chec"ing conte,t 0or integral<type
arit+metic operations and conversions.
chec&ed-e/pression.
&he&(ed ( e/pression )
!nchec&ed-e/pression.
u*&he&(ed ( e/pression )
T+e c"ec(ed operator evaluates t+e contained epression in a c+ec7ed contet- and t+e unc"ec(ed operator
evaluates t+e contained epression in an unc+ec7ed contet. ( chec&ed-e/pression or !nchec&ed-e/pression
corresponds eactly to a parenthesi-ed-e/pression JV!.".3M- ecept t+at t+e contained epression is evaluated in
t+e given over0low c+ec7ing contet.
T+e over0low c+ec7ing contet can also be controlled t+roug+ t+e c"ec(ed and unc"ec(ed statements JV3.11M.
T+e 0ollowing operations are a00ected by t+e over0low c+ec7ing contet establis+ed by t+e c"ec(ed and
unc"ec(ed operators and statementsC
T+e prede0ined << and == unary operators JV!.".$ and V!.%."M- w+en t+e operand is o0 an integral type.
T+e prede0ined = unary operator JV!.%.2M- w+en t+e operand is o0 an integral type.
T+e prede0ined <- =- >- and . binary operators JV!.!M- w+en bot+ operands are o0 integral types.
Eplicit numeric conversions JV%.2.1M 0rom one integral type to anot+er integral type- or 0rom -loat or
double to an integral type.
6+en one o0 t+e above operations produce a result t+at is too large to represent in t+e destination type- t+e
contet in w+ic+ t+e operation is per0ormed controls t+e resulting be+aviorC
1n a c"ec(ed contet- i0 t+e operation is a constant epression JV!.13M- a compile<time error occurs.
/t+erwise- w+en t+e operation is per0ormed at run<time- a System.%ver-lo,)#ce&tion is t+rown.
1n an unc"ec(ed contet- t+e result is truncated by discarding any +ig+<order bits t+at do not 0it in t+e
destination type.
*or non<constant epressions Jepressions t+at are evaluated at run<timeM t+at are not enclosed by any c"ec(ed
or unc"ec(ed operators or statements- t+e de0ault over0low c+ec7ing contet is unc"ec(ed unless eternal
0actors Jsuc+ as compiler switc+es and eecution environment con0igurationM call 0or c"ec(ed evaluation.
*or constant epressions Jepressions t+at can be 0ully evaluated at compile<timeM- t+e de0ault over0low
c+ec7ing contet is always c"ec(ed. 8nless a constant epression is eplicitly placed in an unc"ec(ed
contet- over0lows t+at occur during t+e compile<time evaluation o0 t+e epression always cause compile<time
errors.
T+e body o0 an anonymous 0unction is not a00ected by c"ec(ed or unc"ec(ed contets in w+ic+ t+e
anonymous 0unction occurs.
1n t+e eample
class 1est
{
static readonly int # + 2333333;
static readonly int y + 2333333;
1$" Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
static int V() {
return c"ec(ed(# > y); .. 1"ro,s %ver-lo,)#ce&tion
!
static int S() {
return unc"ec(ed(# > y); .. Oeturns =M8M9MLLXY
!
static int H() {
return # > y; .. 6e&ends on de-ault
!
!
no compile<time errors are reported since neit+er o0 t+e epressions can be evaluated at compile<time. (t run<
time- t+e V met+od t+rows a System.%ver-lo,)#ce&tion- and t+e S met+od returns S!2!3!$$%3 Jt+e lower
32 bits o0 t+e out<o0<range resultM. T+e be+avior o0 t+e H met+od depends on t+e de0ault over0low c+ec7ing
contet 0or t+e compilation- but it is eit+er t+e same as V or t+e same as S.
1n t+e eample
class 1est
{
const int # + 2333333;
const int y + 2333333;
static int V() {
return c"ec(ed(# > y); .. Com&ile error over-lo,
!
static int S() {
return unc"ec(ed(# > y); .. Oeturns =M8M9MLLXY
!
static int H() {
return # > y; .. Com&ile error over-lo,
!
!
t+e over0lows t+at occur w+en evaluating t+e constant epressions in V and H cause compile<time errors to be
reported because t+e epressions are evaluated in a c"ec(ed contet. (n over0low also occurs w+en evaluating
t+e constant epression in S- but since t+e evaluation ta7es place in an unc"ec(ed contet- t+e over0low is not
reported.
T+e c"ec(ed and unc"ec(ed operators only a00ect t+e over0low c+ec7ing contet 0or t+ose operations t+at are
tetually contained wit+in t+e K(L and K)L to7ens. T+e operators +ave no e00ect on 0unction members t+at are
invo7ed as a result o0 evaluating t+e contained epression. 1n t+e eample
class 1est
{
static int Multi&ly(int # int y) {
return # > y;
!
static int V() {
return c"ec(ed(Multi&ly(2333333 2333333));
!
!
t+e use o0 c"ec(ed in V does not a00ect t+e evaluation o0 # > y in Multi&ly- so # > y is evaluated in t+e
de0ault over0low c+ec7ing contet.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 1$
C# Language Specification
T+e unc"ec(ed operator is convenient w+en writing constants o0 t+e signed integral types in +eadecimal
notation. *or eampleC
class 1est
{
&ublic const int 'll:its + unc"ec(ed((int)3#VVVVVVVV);
&ublic const int Hig":it + unc"ec(ed((int)3#Y3333333);
!
)ot+ o0 t+e +eadecimal constants above are o0 type uint. )ecause t+e constants are outside t+e int range-
wit+out t+e unc"ec(ed operator- t+e casts to int would produce compile<time errors.
T+e c"ec(ed and unc"ec(ed operators and statements allow programmers to control certain aspects o0 some
numeric calculations. However- t+e be+avior o0 some numeric operators depends on t+eir operandsP data types.
*or eample- multiplying two decimals always results in an eception on over0low even wit+in an eplicitly
unc"ec(ed construct. #imilarly- multiplying two 0loats never results in an eception on over0low even wit+in
an eplicitly c"ec(ed construct. 1n addition- ot+er operators are never a00ected by t+e mode o0 c+ec7ing-
w+et+er de0ault or eplicit.
..&.13 2efault "alue e%pressions
( de0ault value epression is used to obtain t+e de0ault value JV".2M o0 a type. Typically a de0ault value
epression is used 0or type parameters- since it may not be 7nown i0 t+e type parameter is a value type or a
re0erence type. J=o conversion eists 0rom t+e null literal to a type parameter unless t+e type parameter is
7nown to be a re0erence type.M
defa!lt-val!e-e/pression.
def!ul$ ( t+pe )
10 t+e t+pe in a defa!lt-val!e-e/pression evaluates at run<time to a re0erence type- t+e result is null converted to
t+at type. 10 t+e t+pe in a defa!lt-val!e-e/pression evaluates at run<time to a value type- t+e result is t+e val!e-
t+pePs de0ault value JV4.1.2M.
( defa!lt-val!e-e/pression is a constant epression JV!.13M i0 t+e type is a re0erence type or a type parameter
t+at is 7nown to be a re0erence type JV1..1."M. 1n addition- a defa!lt-val!e-e/pression is a constant epression i0
t+e type is one o0 t+e 0ollowing value typesC sbyte- byte- s"ort- us"ort- int- uint- long- ulong- c"ar-
-loat- double- decimal- bool- or any enumeration type.
..&.1# *non!ous et-od e%pressions
(n anon+%o!s-%ethod-e/pression is one o0 two ways o0 de0ining an anonymous 0unction. T+ese are 0urt+er
described in V!.14.
..' 6nar! operators
T+e <- =- @- A- <<- ==- and cast operators are called t+e unary operators.
!nar+-e/pression.
pri%ar+-e/pression
+ !nar+-e/pression
: !nar+-e/pression
F !nar+-e/pression
G !nar+-e/pression
pre-incre%ent-e/pression
pre-decre%ent-e/pression
cast-e/pression
1$' Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
..'.1 6nar! plus operator
*or an operation o0 t+e 0orm <#- unary operator overload resolution JV!.2.3M is applied to select a speci0ic
operator implementation. T+e operand is converted to t+e parameter type o0 t+e selected operator- and t+e type
o0 t+e result is t+e return type o0 t+e operator. T+e prede0ined unary plus operators areC
int o&erator <(int #);
uint o&erator <(uint #);
long o&erator <(long #);
ulong o&erator <(ulong #);
-loat o&erator <(-loat #);
double o&erator <(double #);
decimal o&erator <(decimal #);
*or eac+ o0 t+ese operators- t+e result is simply t+e value o0 t+e operand.
..'.2 6nar! inus operator
*or an operation o0 t+e 0orm C#- unary operator overload resolution JV!.2.3M is applied to select a speci0ic
operator implementation. T+e operand is converted to t+e parameter type o0 t+e selected operator- and t+e type
o0 t+e result is t+e return type o0 t+e operator. T+e prede0ined negation operators areC
1nteger negationC
int o&erator C(int #);
long o&erator C(long #);
T+e result is computed by subtracting # 0rom Dero. 10 t+e value o0 o0 # is t+e smallest representable value o0
t+e operand type JU2
31
0or int or U2
%3
0or long)- t+en t+e mat+ematical negation o0 # is not representable
wit+in t+e operand type. 10 t+is occurs wit+in a c"ec(ed contet- a System.%ver-lo,)#ce&tion is
t+rownQ i0 it occurs wit+in an unc"ec(ed contet- t+e result is t+e value o0 t+e operand and t+e over0low is
not reported.
10 t+e operand o0 t+e negation operator is o0 type uint- it is converted to type long- and t+e type o0 t+e
result is long. (n eception is t+e rule t+at permits t+e int value U214!433%43 JU2
31
M to be written as a
decimal integer literal JV2.4.4.2M.
10 t+e operand o0 t+e negation operator is o0 type ulong- a compile<time error occurs. (n eception is t+e
rule t+at permits t+e long value U$2233!2.3%3"4!!"3.3 JU2
%3
M to be written as a decimal integer literal
JV2.4.4.2M.
*loating<point negationC
-loat o&erator C(-loat #);
double o&erator C(double #);
T+e result is t+e value o0 # wit+ its sign inverted. 10 # is =a=- t+e result is also =a=.
2ecimal negationC
decimal o&erator C(decimal #);
T+e result is computed by subtracting # 0rom Dero. 2ecimal negation is e9uivalent to using t+e unary minus
operator o0 type System.6ecimal.
..'.3 Logical negation operator
*or an operation o0 t+e 0orm @#- unary operator overload resolution JV!.2.3M is applied to select a speci0ic
operator implementation. T+e operand is converted to t+e parameter type o0 t+e selected operator- and t+e type
o0 t+e result is t+e return type o0 t+e operator. /nly one prede0ined logical negation operator eistsC
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 1$7
C# Language Specification
bool o&erator @(bool #);
T+is operator computes t+e logical negation o0 t+e operandC 10 t+e operand is true- t+e result is -alse. 10 t+e
operand is -alse- t+e result is true.
..'.# +itwise copleent operator
*or an operation o0 t+e 0orm A#- unary operator overload resolution JV!.2.3M is applied to select a speci0ic
operator implementation. T+e operand is converted to t+e parameter type o0 t+e selected operator- and t+e type
o0 t+e result is t+e return type o0 t+e operator. T+e prede0ined bitwise complement operators areC
int o&erator A(int #);
uint o&erator A(uint #);
long o&erator A(long #);
ulong o&erator A(ulong #);
*or eac+ o0 t+ese operators- t+e result o0 t+e operation is t+e bitwise complement o0 #.
Every enumeration type ) implicitly provides t+e 0ollowing bitwise complement operatorC
) o&erator A() #);
T+e result o0 evaluating [#- w+ere # is an epression o0 an enumeration type ) wit+ an underlying type ;- is
eactly t+e same as evaluating JEM(A(;)#).
..'.& Prefi% increent and decreent operators
pre-incre%ent-e/pression.
++ !nar+-e/pression
pre-decre%ent-e/pression.
:: !nar+-e/pression
T+e operand o0 a pre0i increment or decrement operation must be an epression classi0ied as a variable- a
property access- or an indeer access. T+e result o0 t+e operation is a value o0 t+e same type as t+e operand.
10 t+e operand o0 a pre0i increment or decrement operation is a property or indeer access- t+e property or
indeer must +ave bot+ a get and a set accessor. 10 t+is is not t+e case- a compile<time error occurs.
8nary operator overload resolution JV!.2.3M is applied to select a speci0ic operator implementation. Prede0ined <
< and == operators eist 0or t+e 0ollowing typesC sbyte- byte- s"ort- us"ort- int- uint- long- ulong-
c"ar- -loat- double- decimal- and any enum type. T+e prede0ined << operators return t+e value produced
by adding 1 to t+e operand- and t+e prede0ined == operators return t+e value produced by subtracting 1 0rom t+e
operand. 1n a c"ec(ed contet- i0 t+e result o0 t+is addition or subtraction is outside t+e range o0 t+e result type
and t+e result type is an integral type or enum type- a System.%ver-lo,)#ce&tion is t+rown.
T+e run<time processing o0 a pre0i increment or decrement operation o0 t+e 0orm <<# or ==# consists o0 t+e
0ollowing stepsC
10 # is classi0ied as a variableC
o # is evaluated to produce t+e variable.
o T+e selected operator is invo7ed wit+ t+e value o0 # as its argument.
o T+e value returned by t+e operator is stored in t+e location given by t+e evaluation o0 #.
o T+e value returned by t+e operator becomes t+e result o0 t+e operation.
10 # is classi0ied as a property or indeer accessC
1$$ Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
o T+e instance epression Ji0 # is not staticM and t+e argument list Ji0 # is an indeer accessM associated
wit+ # are evaluated- and t+e results are used in t+e subse9uent get and set accessor invocations.
o T+e get accessor o0 # is invo7ed.
o T+e selected operator is invo7ed wit+ t+e value returned by t+e get accessor as its argument.
o T+e set accessor o0 # is invo7ed wit+ t+e value returned by t+e operator as its value argument.
o T+e value returned by t+e operator becomes t+e result o0 t+e operation.
T+e << and == operators also support post0i notation JV!.".$M. T+e result o0 #<< or #== is t+e value o0 # ,efore
t+e operation- w+ereas t+e result o0 <<# or ==# is t+e value o0 # after t+e operation. 1n eit+er case- # itsel0 +as
t+e same value a0ter t+e operation.
(n o&erator << or o&erator == implementation can be invo7ed using eit+er post0i or pre0i notation. 1t is
not possible to +ave separate operator implementations 0or t+e two notations.
..'.' Cast e%pressions
( cast-e/pression is used to eplicitly convert an epression to a given type.
cast-e/pression.
( t+pe ) !nar+-e/pression
( cast-e/pression o0 t+e 0orm (1))- w+ere 1 is a t+pe and ) is a !nar+-e/pression- per0orms an eplicit
conversion JV%.2M o0 t+e value o0 ) to type 1. 10 no eplicit conversion eists 0rom ) to 1- a compile<time error
occurs. /t+erwise- t+e result is t+e value produced by t+e eplicit conversion. T+e result is always classi0ied as a
value- even i0 ) denotes a variable.
T+e grammar 0or a cast-e/pression leads to certain syntactic ambiguities. *or eample- t+e epression (#)Cy
could eit+er be interpreted as a cast-e/pression Ja cast o0 Cy to type #M or as an additive-e/pression combined
wit+ a parenthesi-ed-e/pression Jw+ic+ computes t+e value # C y).
To resolve cast-e/pression ambiguities- t+e 0ollowing rule eistsC ( se9uence o0 one or more to&ens JV2.3.3M
enclosed in parent+eses is considered t+e start o0 a cast-e/pression only i0 at least one o0 t+e 0ollowing are trueC
T+e se9uence o0 to7ens is correct grammar 0or a t+pe- but not 0or an e/pression.
T+e se9uence o0 to7ens is correct grammar 0or a t+pe- and t+e to7en immediately 0ollowing t+e closing
parent+eses is t+e to7en KAL- t+e to7en K@L- t+e to7en K(L- an identifier JV2.4.1M- a literal JV2.4.4M- or any
&e+word JV2.4.3M ecept as and is.
T+e term Kcorrect grammarL above means only t+at t+e se9uence o0 to7ens must con0orm to t+e particular
grammatical production. 1t speci0ically does not consider t+e actual meaning o0 any constituent identi0iers. *or
eample- i0 # and y are identi0iers- t+en #.y is correct grammar 0or a type- even i0 #.y doesnPt actually denote a
type.
*rom t+e disambiguation rule it 0ollows t+at- i0 # and y are identi0iers- (#)y- (#)(y)- and (#)(=y) are cast-
e/pressions- but (#)=y is not- even i0 # identi0ies a type. However- i0 # is a 7eyword t+at identi0ies a prede0ined
type Jsuc+ as intM- t+en all 0our 0orms are cast-e/pressions Jbecause suc+ a 7eyword could not possibly be an
epression by itsel0M.
... *rit-etic operators
T+e >- .- B- <- and C operators are called t+e arit+metic operators.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 1$!
C# Language Specification
%!ltiplicative-e/pression.
!nar+-e/pression
%!ltiplicative-e/pression * !nar+-e/pression
%!ltiplicative-e/pression / !nar+-e/pression
%!ltiplicative-e/pression B !nar+-e/pression
additive-e/pression.
%!ltiplicative-e/pression
additive-e/pression + %!ltiplicative-e/pression
additive-e/pression M %!ltiplicative-e/pression
....1 )ultiplication operator
*or an operation o0 t+e 0orm # > y- binary operator overload resolution JV!.2.4M is applied to select a speci0ic
operator implementation. T+e operands are converted to t+e parameter types o0 t+e selected operator- and t+e
type o0 t+e result is t+e return type o0 t+e operator.
T+e prede0ined multiplication operators are listed below. T+e operators all compute t+e product o0 # and y.
1nteger multiplicationC
int o&erator >(int # int y);
uint o&erator >(uint # uint y);
long o&erator >(long # long y);
ulong o&erator >(ulong # ulong y);
1n a c"ec(ed contet- i0 t+e product is outside t+e range o0 t+e result type- a
System.%ver-lo,)#ce&tion is t+rown. 1n an unc"ec(ed contet- over0lows are not reported and any
signi0icant +ig+<order bits outside t+e range o0 t+e result type are discarded.
*loating<point multiplicationC
-loat o&erator >(-loat # -loat y);
double o&erator >(double # double y);
T+e product is computed according to t+e rules o0 1EEE !"4 arit+metic. T+e 0ollowing table lists t+e results
o0 all possible combinations o0 nonDero 0inite values- Deros- in0inities- and =a=Ps. 1n t+e table- # and y are
positive 0inite values. ? is t+e result o0 # > y. 10 t+e result is too large 0or t+e destination type- ? is in0inity. 10
t+e result is too small 0or t+e destination type- ? is Dero.
<y Cy <3 C3 <e Ce NaN
<# <? C? <3 C3 <e Ce NaN
C# C? <? C3 <3 Ce <e NaN
<3 <3 C3 <3 C3 NaN NaN NaN
C3 C3 <3 C3 <3 NaN NaN NaN
<e <e Ce NaN NaN <e Ce NaN
Ce Ce <e NaN NaN Ce <e NaN
NaN NaN NaN NaN NaN NaN NaN NaN
2ecimal multiplicationC
decimal o&erator >(decimal # decimal y);
1!* Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
10 t+e resulting value is too large to represent in t+e decimal 0ormat- a System.%ver-lo,)#ce&tion is
t+rown. 10 t+e result value is too small to represent in t+e decimal 0ormat- t+e result is Dero. T+e scale o0
t+e result- be0ore any rounding- is t+e sum o0 t+e scales o0 t+e two operands.
2ecimal multiplication is e9uivalent to using t+e multiplication operator o0 type System.6ecimal.
....2 2i"ision operator
*or an operation o0 t+e 0orm # . y- binary operator overload resolution JV!.2.4M is applied to select a speci0ic
operator implementation. T+e operands are converted to t+e parameter types o0 t+e selected operator- and t+e
type o0 t+e result is t+e return type o0 t+e operator.
T+e prede0ined division operators are listed below. T+e operators all compute t+e 9uotient o0 # and y.
1nteger divisionC
int o&erator .(int # int y);
uint o&erator .(uint # uint y);
long o&erator .(long # long y);
ulong o&erator .(ulong # ulong y);
10 t+e value o0 t+e rig+t operand is Dero- a System.6ivide:yPero)#ce&tion is t+rown.
T+e division rounds t+e result towards Dero- and t+e absolute value o0 t+e result is t+e largest possible
integer t+at is less t+an t+e absolute value o0 t+e 9uotient o0 t+e two operands. T+e result is Dero or positive
w+en t+e two operands +ave t+e same sign and Dero or negative w+en t+e two operands +ave opposite signs.
10 t+e le0t operand is t+e smallest representable int or long value and t+e rig+t operand is C2- an over0low
occurs. 1n a c"ec(ed contet- t+is causes a System.'rit"metic)#ce&tion Jor a subclass t+ereo0M to be
t+rown. 1n an unc"ec(ed contet- it is implementation<de0ined as to w+et+er a
System.'rit"metic)#ce&tion Jor a subclass t+ereo0M is t+rown or t+e over0low goes unreported wit+
t+e resulting value being t+at o0 t+e le0t operand.
*loating<point divisionC
-loat o&erator .(-loat # -loat y);
double o&erator .(double # double y);
T+e 9uotient is computed according to t+e rules o0 1EEE !"4 arit+metic. T+e 0ollowing table lists t+e results
o0 all possible combinations o0 nonDero 0inite values- Deros- in0inities- and =a=Ps. 1n t+e table- # and y are
positive 0inite values. ? is t+e result o0 # . y. 10 t+e result is too large 0or t+e destination type- ? is in0inity. 10
t+e result is too small 0or t+e destination type- ? is Dero.
<y Cy <3 C3 <e Ce NaN
<# <? C? <e Ce <3 C3 NaN
C# C? <? Ce <e C3 <3 NaN
<3 <3 C3 NaN NaN <3 C3 NaN
C3 C3 <3 NaN NaN C3 <3 NaN
<e <e Ce <e Ce NaN NaN NaN
Ce Ce <e Ce <e NaN NaN NaN
NaN NaN NaN NaN NaN NaN NaN NaN
2ecimal divisionC
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 1!1
C# Language Specification
decimal o&erator .(decimal # decimal y);
10 t+e value o0 t+e rig+t operand is Dero- a System.6ivide:yPero)#ce&tion is t+rown. 10 t+e resulting
value is too large to represent in t+e decimal 0ormat- a System.%ver-lo,)#ce&tion is t+rown. 10 t+e
result value is too small to represent in t+e decimal 0ormat- t+e result is Dero. T+e scale o0 t+e result is t+e
smallest scale t+at will preserve a result e9ual to t+e nearest representantable decimal value to t+e true
mat+ematical result.
2ecimal division is e9uivalent to using t+e division operator o0 type System.6ecimal.
....3 :eainder operator
*or an operation o0 t+e 0orm # B y- binary operator overload resolution JV!.2.4M is applied to select a speci0ic
operator implementation. T+e operands are converted to t+e parameter types o0 t+e selected operator- and t+e
type o0 t+e result is t+e return type o0 t+e operator.
T+e prede0ined remainder operators are listed below. T+e operators all compute t+e remainder o0 t+e division
between # and y.
1nteger remainderC
int o&erator B(int # int y);
uint o&erator B(uint # uint y);
long o&erator B(long # long y);
ulong o&erator B(ulong # ulong y);
T+e result o0 # B y is t+e value produced by # C (# . y) > y. 10 y is Dero- a
System.6ivide:yPero)#ce&tion is t+rown.
10 t+e le0t operand is t+e smallest int or long value and t+e rig+t operand is =2- a
System.%ver-lo,)#ce&tion is t+rown. 1n no case does # B y t+row an eception w+ere # . y would not
t+row an eception.
*loating<point remainderC
-loat o&erator B(-loat # -loat y);
double o&erator B(double # double y);
T+e 0ollowing table lists t+e results o0 all possible combinations o0 nonDero 0inite values- Deros- in0inities-
and =a=Ps. 1n t+e table- # and y are positive 0inite values. ? is t+e result o0 # B y and is computed as # C n >
y- w+ere n is t+e largest possible integer t+at is less t+an or e9ual to # . y. T+is met+od o0 computing t+e
remainder is analogous to t+at used 0or integer operands- but di00ers 0rom t+e 1EEE !"4 de0inition Jin w+ic+
n is t+e integer closest to # . yM.
<y Cy <3 C3 <e Ce NaN
<# <? <? NaN NaN # # NaN
C# C? C? NaN NaN C# C# NaN
<3 <3 <3 NaN NaN <3 <3 NaN
C3 C3 C3 NaN NaN C3 C3 NaN
<e NaN NaN NaN NaN NaN NaN NaN
Ce NaN NaN NaN NaN NaN NaN NaN
NaN NaN NaN NaN NaN NaN NaN NaN
1!2 Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
2ecimal remainderC
decimal o&erator B(decimal # decimal y);
10 t+e value o0 t+e rig+t operand is Dero- a System.6ivide:yPero)#ce&tion is t+rown. T+e scale o0 t+e
result- be0ore any rounding- is t+e larger o0 t+e scales o0 t+e two operands- and t+e sign o0 t+e result- i0 non<
Dero- is t+e same as t+at o0 #.
2ecimal remainder is e9uivalent to using t+e remainder operator o0 type System.6ecimal.
....# *ddition operator
*or an operation o0 t+e 0orm # < y- binary operator overload resolution JV!.2.4M is applied to select a speci0ic
operator implementation. T+e operands are converted to t+e parameter types o0 t+e selected operator- and t+e
type o0 t+e result is t+e return type o0 t+e operator.
T+e prede0ined addition operators are listed below. *or numeric and enumeration types- t+e prede0ined addition
operators compute t+e sum o0 t+e two operands. 6+en one or bot+ operands are o0 type string- t+e prede0ined
addition operators concatenate t+e string representation o0 t+e operands.
1nteger additionC
int o&erator <(int # int y);
uint o&erator <(uint # uint y);
long o&erator <(long # long y);
ulong o&erator <(ulong # ulong y);
1n a c"ec(ed contet- i0 t+e sum is outside t+e range o0 t+e result type- a System.%ver-lo,)#ce&tion is
t+rown. 1n an unc"ec(ed contet- over0lows are not reported and any signi0icant +ig+<order bits outside t+e
range o0 t+e result type are discarded.
*loating<point additionC
-loat o&erator <(-loat # -loat y);
double o&erator <(double # double y);
T+e sum is computed according to t+e rules o0 1EEE !"4 arit+metic. T+e 0ollowing table lists t+e results o0
all possible combinations o0 nonDero 0inite values- Deros- in0inities- and =a=Ps. 1n t+e table- # and y are
nonDero 0inite values- and ? is t+e result o0 # < y. 10 # and y +ave t+e same magnitude but opposite signs- ?
is positive Dero. 10 # < y is too large to represent in t+e destination type- ? is an in0inity wit+ t+e same sign as
# < y.
y <3 C3 <e Ce NaN
# ? # # <e Ce NaN
<3 y <3 <3 <e Ce NaN
C3 y <3 C3 <e Ce NaN
<e <e <e <e <e NaN NaN
Ce Ce Ce Ce NaN Ce NaN
NaN NaN NaN NaN NaN NaN NaN
2ecimal additionC
decimal o&erator <(decimal # decimal y);
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 1!3
C# Language Specification
10 t+e resulting value is too large to represent in t+e decimal 0ormat- a System.%ver-lo,)#ce&tion is
t+rown. T+e scale o0 t+e result- be0ore any rounding- is t+e larger o0 t+e scales o0 t+e two operands.
2ecimal addition is e9uivalent to using t+e addition operator o0 type System.6ecimal.
Enumeration addition. Every enumeration type implicitly provides t+e 0ollowing prede0ined operators-
w+ere ) is t+e enum type- and ; is t+e underlying type o0 )C
) o&erator <() # ; y);
) o&erator <(; # ) y);
T+e operators are evaluated eactly as ())((;)# < (;)y).
#tring concatenationC
string o&erator <(string # string y);
string o&erator <(string # object y);
string o&erator <(object # string y);
T+e binary < operator per0orms string concatenation w+en one or bot+ operands are o0 type string. 10 an
operand o0 string concatenation is null- an empty string is substituted. /t+erwise- any non<string argument
is converted to its string representation by invo7ing t+e virtual 1oString met+od in+erited 0rom type
object. 10 1oString returns null- an empty string is substituted.
using System;
class 1est
{
static void Main() {
string s + null;
Console.WriteLine("s + E" < s < "D"); .. dis&lays s + ED
int i + 2;
Console.WriteLine("i + " < i); .. dis&lays i + 2
-loat - + 2.8933)<2KV;
Console.WriteLine("- + " < -); .. dis&lays - + 2.89)<2K
decimal d + 8.L33m;
Console.WriteLine("d + " < d); .. dis&lays d + 8.L33
!
!
T+e result o0 t+e string concatenation operator is a string t+at consists o0 t+e c+aracters o0 t+e le0t operand
0ollowed by t+e c+aracters o0 t+e rig+t operand. T+e string concatenation operator never returns a null
value. ( System.%ut%-Memory)#ce&tion may be t+rown i0 t+ere is not enoug+ memory available to
allocate t+e resulting string.
2elegate combination. Every delegate type implicitly provides t+e 0ollowing prede0ined operator- w+ere 6 is
t+e delegate typeC
6 o&erator <(6 # 6 y);
T+e binary < operator per0orms delegate combination w+en bot+ operands are o0 some delegate type 6. J10
t+e operands +ave di00erent delegate types- a compile<time error occurs.M 10 t+e 0irst operand is null- t+e
result o0 t+e operation is t+e value o0 t+e second operand Jeven i0 t+at is also nullM. /t+erwise- i0 t+e second
operand is null- t+en t+e result o0 t+e operation is t+e value o0 t+e 0irst operand. /t+erwise- t+e result o0 t+e
operation is a new delegate instance t+at- w+en invo7ed- invo7es t+e 0irst operand and t+en invo7es t+e
second operand. *or eamples o0 delegate combination- see V!.!." and V1".4. #ince System.6elegate is
not a delegate type- o&erator < is not de0ined 0or it.
1!" Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
....& Subtraction operator
*or an operation o0 t+e 0orm # C y- binary operator overload resolution JV!.2.4M is applied to select a speci0ic
operator implementation. T+e operands are converted to t+e parameter types o0 t+e selected operator- and t+e
type o0 t+e result is t+e return type o0 t+e operator.
T+e prede0ined subtraction operators are listed below. T+e operators all subtract y 0rom #.
1nteger subtractionC
int o&erator C(int # int y);
uint o&erator C(uint # uint y);
long o&erator C(long # long y);
ulong o&erator C(ulong # ulong y);
1n a c"ec(ed contet- i0 t+e di00erence is outside t+e range o0 t+e result type- a
System.%ver-lo,)#ce&tion is t+rown. 1n an unc"ec(ed contet- over0lows are not reported and any
signi0icant +ig+<order bits outside t+e range o0 t+e result type are discarded.
*loating<point subtractionC
-loat o&erator C(-loat # -loat y);
double o&erator C(double # double y);
T+e di00erence is computed according to t+e rules o0 1EEE !"4 arit+metic. T+e 0ollowing table lists t+e
results o0 all possible combinations o0 nonDero 0inite values- Deros- in0inities- and =a=s. 1n t+e table- # and y
are nonDero 0inite values- and ? is t+e result o0 # C y. 10 # and y are e9ual- ? is positive Dero. 10 # C y is too
large to represent in t+e destination type- ? is an in0inity wit+ t+e same sign as # C y.
y <3 C3 <e Ce NaN
# ? # # Ce <e NaN
<3 Cy <3 <3 Ce <e NaN
C3 Cy C3 <3 Ce <e NaN
<e <e <e <e NaN <e NaN
Ce Ce Ce Ce Ce NaN NaN
NaN NaN NaN NaN NaN NaN NaN
2ecimal subtractionC
decimal o&erator C(decimal # decimal y);
10 t+e resulting value is too large to represent in t+e decimal 0ormat- a System.%ver-lo,)#ce&tion is
t+rown. T+e scale o0 t+e result- be0ore any rounding- is t+e larger o0 t+e scales o0 t+e two operands.
2ecimal subtraction is e9uivalent to using t+e subtraction operator o0 type System.6ecimal.
Enumeration subtraction. Every enumeration type implicitly provides t+e 0ollowing prede0ined operator-
w+ere ) is t+e enum type- and ; is t+e underlying type o0 )C
; o&erator C() # ) y);
T+is operator is evaluated eactly as (;)((;)# C (;)y). 1n ot+er words- t+e operator computes t+e
di00erence between t+e ordinal values o0 # and y- and t+e type o0 t+e result is t+e underlying type o0 t+e
enumeration.
) o&erator C() # ; y);
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 1!
C# Language Specification
T+is operator is evaluated eactly as ())((;)# C y). 1n ot+er words- t+e operator subtracts a value 0rom
t+e underlying type o0 t+e enumeration- yielding a value o0 t+e enumeration.
2elegate removal. Every delegate type implicitly provides t+e 0ollowing prede0ined operator- w+ere 6 is t+e
delegate typeC
6 o&erator C(6 # 6 y);
T+e binary C operator per0orms delegate removal w+en bot+ operands are o0 some delegate type 6. 10 t+e
operands +ave di00erent delegate types- a compile<time error occurs. 10 t+e 0irst operand is null- t+e result
o0 t+e operation is null. /t+erwise- i0 t+e second operand is null- t+en t+e result o0 t+e operation is t+e
value o0 t+e 0irst operand. /t+erwise- bot+ operands represent invocation lists JV1".1M +aving one or more
entries- and t+e result is a new invocation list consisting o0 t+e 0irst operandPs list wit+ t+e second operandPs
entries removed 0rom it- provided t+e second operandPs list is a proper contiguous sublist o0 t+e 0irstPs.
JTo determine sublist e9uality- corresponding entries are compared as 0or t+e delegate e9uality operator
JV!.$.3M.M /t+erwise- t+e result is t+e value o0 t+e le0t operand. =eit+er o0 t+e operandsP lists is c+anged in
t+e process. 10 t+e second operandPs list matc+es multiple sublists o0 contiguous entries in t+e 0irst operandPs
list- t+e rig+t<most matc+ing sublist o0 contiguous entries is removed. 10 removal results in an empty list- t+e
result is null. *or eampleC
delegate void 6(int #);
class C
{
&ublic static void M2(int i) { .> b >. !
&ublic static void M8(int i) { .> b >. !
!
class 1est
{
static void Main() {
6 cd2 + ne, 6(C.M2);
6 cd8 + ne, 6(C.M8);
6 cd9 + cd2 < cd8 < cd8 < cd2; .. M2 < M8 < M8 < M2
cd9 =+ cd2; .. +E M2 < M8 < M8
cd9 + cd2 < cd8 < cd8 < cd2; .. M2 < M8 < M8 < M2
cd9 =+ cd2 < cd8; .. +E M8 < M2
cd9 + cd2 < cd8 < cd8 < cd2; .. M2 < M8 < M8 < M2
cd9 =+ cd8 < cd8; .. +E M2 < M2
cd9 + cd2 < cd8 < cd8 < cd2; .. M2 < M8 < M8 < M2
cd9 =+ cd8 < cd2; .. +E M2 < M8
cd9 + cd2 < cd8 < cd8 < cd2; .. M2 < M8 < M8 < M2
cd9 =+ cd2 < cd2; .. +E M2 < M8 < M8 < M2
!
!
..0 S-ift operators
T+e DD and EE operators are used to per0orm bit s+i0ting operations.
shift-e/pression.
additive-e/pression
shift-e/pression II additive-e/pression
shift-e/pression right-shift additive-e/pression
1!' Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
*or an operation o0 t+e 0orm # DD count or # EE count- binary operator overload resolution JV!.2.4M is applied
to select a speci0ic operator implementation. T+e operands are converted to t+e parameter types o0 t+e selected
operator- and t+e type o0 t+e result is t+e return type o0 t+e operator.
6+en declaring an overloaded s+i0t operator- t+e type o0 t+e 0irst operand must always be t+e class or struct
containing t+e operator declaration- and t+e type o0 t+e second operand must always be int.
T+e prede0ined s+i0t operators are listed below.
#+i0t le0tC
int o&erator DD(int # int count);
uint o&erator DD(uint # int count);
long o&erator DD(long # int count);
ulong o&erator DD(ulong # int count);
T+e DD operator s+i0ts # le0t by a number o0 bits computed as described below.
T+e +ig+<order bits outside t+e range o0 t+e result type o0 # are discarded- t+e remaining bits are s+i0ted le0t-
and t+e low<order empty bit positions are set to Dero.
#+i0t rig+tC
int o&erator EE(int # int count);
uint o&erator EE(uint # int count);
long o&erator EE(long # int count);
ulong o&erator EE(ulong # int count);
T+e EE operator s+i0ts # rig+t by a number o0 bits computed as described below.
6+en # is o0 type int or long- t+e low<order bits o0 # are discarded- t+e remaining bits are s+i0ted rig+t-
and t+e +ig+<order empty bit positions are set to Dero i0 # is non<negative and set to one i0 # is negative.
6+en # is o0 type uint or ulong- t+e low<order bits o0 # are discarded- t+e remaining bits are s+i0ted rig+t-
and t+e +ig+<order empty bit positions are set to Dero.
*or t+e prede0ined operators- t+e number o0 bits to s+i0t is computed as 0ollowsC
6+en t+e type o0 # is int or uint- t+e s+i0t count is given by t+e low<order 0ive bits o0 count. 1n ot+er
words- t+e s+i0t count is computed 0rom count F 3#2V.
6+en t+e type o0 # is long or ulong- t+e s+i0t count is given by t+e low<order si bits o0 count. 1n ot+er
words- t+e s+i0t count is computed 0rom count F 3#9V.
10 t+e resulting s+i0t count is Dero- t+e s+i0t operators simply return t+e value o0 #.
#+i0t operations never cause over0lows and produce t+e same results in c"ec(ed and unc"ec(ed contets.
6+en t+e le0t operand o0 t+e EE operator is o0 a signed integral type- t+e operator per0orms an arith%etic s+i0t
rig+t w+erein t+e value o0 t+e most signi0icant bit Jt+e sign bitM o0 t+e operand is propagated to t+e +ig+<order
empty bit positions. 6+en t+e le0t operand o0 t+e EE operator is o0 an unsigned integral type- t+e operator
per0orms a logical s+i0t rig+t w+erein +ig+<order empty bit positions are always set to Dero. To per0orm t+e
opposite operation o0 t+at in0erred 0rom t+e operand type- eplicit casts can be used. *or eample- i0 # is a
variable o0 type int- t+e operation unc"ec(ed((int)((uint)# EE y)) per0orms a logical s+i0t rig+t o0 #.
..1 :elational and t!pe9testing operators
T+e ++- @+- D- E- D+- E+- is and as operators are called t+e relational and type<testing operators.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 1!7
C# Language Specification
relational-e/pression.
shift-e/pression
relational-e/pression I shift-e/pression
relational-e/pression J shift-e/pression
relational-e/pression IH shift-e/pression
relational-e/pression JH shift-e/pression
relational-e/pression i# t+pe
relational-e/pression !# t+pe
e8!alit+-e/pression.
relational-e/pression
e8!alit+-e/pression HH relational-e/pression
e8!alit+-e/pression FH relational-e/pression
T+e is operator is described in V!.$.1. and t+e as operator is described in V!.$.11.
T+e ++- @+- D- E- D+ and E+ operators are coparison operators. *or an operation o0 t+e 0orm # op y- w+ere op
is a comparison operator- overload resolution JV!.2.4M is applied to select a speci0ic operator implementation.
T+e operands are converted to t+e parameter types o0 t+e selected operator- and t+e type o0 t+e result is t+e
return type o0 t+e operator.
T+e prede0ined comparison operators are described in t+e 0ollowing sections. (ll prede0ined comparison
operators return a result o0 type bool- as described in t+e 0ollowing table.
6peration /esult
# ++ y
true i0 # is e9ual to y- -alse ot+erwise
# @+ y
true i0 # is not e9ual to y- -alse ot+erwise
# D y
true i0 # is less t+an y- -alse ot+erwise
# E y
true i0 # is greater t+an y- -alse ot+erwise
# D+ y
true i0 # is less t+an or e9ual to y- -alse ot+erwise
# E+ y
true i0 # is greater t+an or e9ual to y- -alse ot+erwise
..1.1 Integer coparison operators
T+e prede0ined integer comparison operators areC
bool o&erator ++(int # int y);
bool o&erator ++(uint # uint y);
bool o&erator ++(long # long y);
bool o&erator ++(ulong # ulong y);
bool o&erator @+(int # int y);
bool o&erator @+(uint # uint y);
bool o&erator @+(long # long y);
bool o&erator @+(ulong # ulong y);
bool o&erator D(int # int y);
bool o&erator D(uint # uint y);
bool o&erator D(long # long y);
bool o&erator D(ulong # ulong y);
1!$ Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
bool o&erator E(int # int y);
bool o&erator E(uint # uint y);
bool o&erator E(long # long y);
bool o&erator E(ulong # ulong y);
bool o&erator D+(int # int y);
bool o&erator D+(uint # uint y);
bool o&erator D+(long # long y);
bool o&erator D+(ulong # ulong y);
bool o&erator E+(int # int y);
bool o&erator E+(uint # uint y);
bool o&erator E+(long # long y);
bool o&erator E+(ulong # ulong y);
Eac+ o0 t+ese operators compares t+e numeric values o0 t+e two integer operands and returns a bool value t+at
indicates w+et+er t+e particular relation is true or -alse.
..1.2 ,loating9point coparison operators
T+e prede0ined 0loating<point comparison operators areC
bool o&erator ++(-loat # -loat y);
bool o&erator ++(double # double y);
bool o&erator @+(-loat # -loat y);
bool o&erator @+(double # double y);
bool o&erator D(-loat # -loat y);
bool o&erator D(double # double y);
bool o&erator E(-loat # -loat y);
bool o&erator E(double # double y);
bool o&erator D+(-loat # -loat y);
bool o&erator D+(double # double y);
bool o&erator E+(-loat # -loat y);
bool o&erator E+(double # double y);
T+e operators compare t+e operands according to t+e rules o0 t+e 1EEE !"4 standardC
10 eit+er operand is =a=- t+e result is -alse 0or all operators ecept @+- 0or w+ic+ t+e result is true. *or
any two operands- # @+ y always produces t+e same result as @(# ++ y). However- w+en one or bot+
operands are =a=- t+e D- E- D+- and E+ operators do not produce t+e same results as t+e logical negation o0
t+e opposite operator. *or eample- i0 eit+er o0 # and y is =a=- t+en # D y is -alse- but @(# E+ y) is true.
6+en neit+er operand is =a=- t+e operators compare t+e values o0 t+e two 0loating<point operands wit+
respect to t+e ordering
Ce D Cma# D ... D Cmin D C3.3 ++ <3.3 D <min D ... D <ma# D <e
w+ere min and ma# are t+e smallest and largest positive 0inite values t+at can be represented in t+e given
0loating<point 0ormat. =otable e00ects o0 t+is ordering areC
o =egative and positive Deros are considered e9ual.
o ( negative in0inity is considered less t+an all ot+er values- but e9ual to anot+er negative in0inity.
o ( positive in0inity is considered greater t+an all ot+er values- but e9ual to anot+er positive in0inity.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 1!!
C# Language Specification
..1.3 2ecial coparison operators
T+e prede0ined decimal comparison operators areC
bool o&erator ++(decimal # decimal y);
bool o&erator @+(decimal # decimal y);
bool o&erator D(decimal # decimal y);
bool o&erator E(decimal # decimal y);
bool o&erator D+(decimal # decimal y);
bool o&erator E+(decimal # decimal y);
Eac+ o0 t+ese operators compares t+e numeric values o0 t+e two decimal operands and returns a bool value t+at
indicates w+et+er t+e particular relation is true or -alse. Eac+ decimal comparison is e9uivalent to using t+e
corresponding relational or e9uality operator o0 type System.6ecimal.
..1.# +oolean e7ualit! operators
T+e prede0ined boolean e9uality operators areC
bool o&erator ++(bool # bool y);
bool o&erator @+(bool # bool y);
T+e result o0 ++ is true i0 bot+ # and y are true or i0 bot+ # and y are -alse. /t+erwise- t+e result is -alse.
T+e result o0 @+ is -alse i0 bot+ # and y are true or i0 bot+ # and y are -alse. /t+erwise- t+e result is true.
6+en t+e operands are o0 type bool- t+e @+ operator produces t+e same result as t+e G operator.
..1.& $nueration coparison operators
Every enumeration type implicitly provides t+e 0ollowing prede0ined comparison operatorsC
bool o&erator ++() # ) y);
bool o&erator @+() # ) y);
bool o&erator D() # ) y);
bool o&erator E() # ) y);
bool o&erator D+() # ) y);
bool o&erator E+() # ) y);
T+e result o0 evaluating # op y- w+ere # and y are epressions o0 an enumeration type ) wit+ an underlying type
;- and op is one o0 t+e comparison operators- is eactly t+e same as evaluating ((;)#) op ((;)y). 1n ot+er
words- t+e enumeration type comparison operators simply compare t+e underlying integral values o0 t+e two
operands.
..1.' :eference t!pe e7ualit! operators
T+e prede0ined re0erence type e9uality operators areC
bool o&erator ++(object # object y);
bool o&erator @+(object # object y);
T+e operators return t+e result o0 comparing t+e two re0erences 0or e9uality or non<e9uality.
2** Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
#ince t+e prede0ined re0erence type e9uality operators accept operands o0 type object- t+ey apply to all types
t+at do not declare applicable o&erator ++ and o&erator @+ members. Conversely- any applicable user<
de0ined e9uality operators e00ectively +ide t+e prede0ined re0erence type e9uality operators.
T+e prede0ined re0erence type e9uality operators re9uire one o0 t+e 0ollowingC
)ot+ operands are reference-t+pe values or t+e value null. *urt+ermore- a standard implicit conversion
JV%.3.1M eists 0rom t+e type o0 eit+er operand to t+e type o0 t+e ot+er operand.
/ne operand is a value o0 type 1 w+ere 1 is a t+pe-para%eter and t+e ot+er operand is t+e value null.
*urt+ermore 1 does not +ave t+e value type constraint.
8nless one o0 t+ese conditions are true- a compile<time error occurs. =otable implications o0 t+ese rules areC
1t is a compile<time error to use t+e prede0ined re0erence type e9uality operators to compare two re0erences
t+at are 7nown to be di00erent at compile<time. *or eample- i0 t+e compile<time types o0 t+e operands are
two class types ' and :- and i0 neit+er ' nor : derives 0rom t+e ot+er- t+en it would be impossible 0or t+e
two operands to re0erence t+e same ob&ect. T+us- t+e operation is considered a compile<time error.
T+e prede0ined re0erence type e9uality operators do not permit value type operands to be compared.
T+ere0ore- unless a struct type declares its own e9uality operators- it is not possible to compare values o0
t+at struct type.
T+e prede0ined re0erence type e9uality operators never cause boing operations to occur 0or t+eir operands.
1t would be meaningless to per0orm suc+ boing operations- since re0erences to t+e newly allocated boed
instances would necessarily di00er 0rom all ot+er re0erences.
10 an operand o0 a type parameter type 1 is compared to null- and t+e runtime type o0 1 is a value type- t+e
result o0 t+e comparison is -alse.
T+e 0ollowing eample c+ec7s w+et+er an argument o0 an unconstrained type parameter type is null.
class CD1E
{
void V(1 #) {
i- (# ++ null) t"ro, ne, 'rgumentNull)#ce&tion();
...
!
!
T+e # ++ null construct is permitted even t+oug+ 1 could represent a value type- and t+e result is simply
de0ined to be -alse w+en 1 is a value type.
*or an operation o0 t+e 0orm # ++ y or # @+ y- i0 any applicable o&erator ++ or o&erator @+ eists- t+e
operator overload resolution JV!.2.4M rules will select t+at operator instead o0 t+e prede0ined re0erence type
e9uality operator. However- it is always possible to select t+e prede0ined re0erence type e9uality operator by
eplicitly casting one or bot+ o0 t+e operands to type object. T+e eample
using System;
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 2*1
C# Language Specification
class 1est
{
static void Main() {
string s + "1est";
string t + string.Co&y(s);
Console.WriteLine(s ++ t);
Console.WriteLine((object)s ++ t);
Console.WriteLine(s ++ (object)t);
Console.WriteLine((object)s ++ (object)t);
!
!
produces t+e output
1rue
Valse
Valse
Valse
T+e s and t variables re0er to two distinct string instances containing t+e same c+aracters. T+e 0irst
comparison outputs 1rue because t+e prede0ined string e9uality operator JV!.$.!M is selected w+en bot+
operands are o0 type string. T+e remaining comparisons all output Valse because t+e prede0ined re0erence
type e9uality operator is selected w+en one or bot+ o0 t+e operands are o0 type object.
=ote t+at t+e above tec+ni9ue is not meaning0ul 0or value types. T+e eample
class 1est
{
static void Main() {
int i + 289;
int j + 289;
System.Console.WriteLine((object)i ++ (object)j);
!
!
outputs Valse because t+e casts create re0erences to two separate instances o0 boed int values.
..1.. String e7ualit! operators
T+e prede0ined string e9uality operators areC
bool o&erator ++(string # string y);
bool o&erator @+(string # string y);
Two string values are considered e9ual w+en one o0 t+e 0ollowing is trueC
)ot+ values are null.
)ot+ values are non<null re0erences to string instances t+at +ave identical lengt+s and identical c+aracters in
eac+ c+aracter position.
T+e string e9uality operators compare string val!es rat+er t+an string references. 6+en two separate string
instances contain t+e eact same se9uence o0 c+aracters- t+e values o0 t+e strings are e9ual- but t+e re0erences
are di00erent. (s described in V!.$.%- t+e re0erence type e9uality operators can be used to compare string
re0erences instead o0 string values.
..1.0 2elegate e7ualit! operators
Every delegate type implicitly provides t+e 0ollowing prede0ined comparison operatorsC
2*2 Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
bool o&erator ++(System.6elegate # System.6elegate y);
bool o&erator @+(System.6elegate # System.6elegate y);
Two delegate instances are considered e9ual as 0ollowsC
10 eit+er o0 t+e delegate instances is null- t+ey are e9ual i0 and only i0 bot+ are null.
10 t+e delegates +ave di00erent runtime type t+ey are never e9ual.
10 bot+ o0 t+e delegate instances +ave an invocation list JV1".1M- t+ose instances are e9ual i0 and only i0 t+eir
invocation lists are t+e same lengt+- and eac+ entry in onePs invocation list is e9ual Jas de0ined belowM to t+e
corresponding entry- in order- in t+e ot+erPs invocation list.
T+e 0ollowing rules govern t+e e9uality o0 invocation list entriesC
10 two invocation list entries bot+ re0er to t+e same static met+od t+en t+e entries are e9ual.
10 two invocation list entries bot+ re0er to t+e same non<static met+od on t+e same target ob&ect Jas de0ined
by t+e re0erence e9uality operatorsM t+en t+e entries are e9ual.
1nvocation list entries produced 0rom evaluation o0 semantically identical anon+%o!s-f!nction-e/pressions
wit+ t+e same Jpossibly emptyM set o0 captured outer variable instances are permitted Jbut not re9uiredM to be
e9ual.
..1.1 $7ualit! operators and null
T+e ++ and @+ operators permit one operand to be a value o0 a nullable type and t+e ot+er to be t+e null literal-
even i0 no prede0ined or user<de0ined operator Jin unli0ted or li0ted 0ormM eists 0or t+e operation.
*or an operation o0 one o0 t+e 0orms
# ++ null null ++ # # @+ null null @+ #
w+ere # is an epression o0 a nullable type- i0 operator overload resolution JV!.2.4M 0ails to 0ind an applicable
operator- t+e result is instead computed 0rom t+e HasUalue property o0 #. #peci0ically- t+e 0irst two 0orms are
translated into @#.HasUalue- and last two 0orms are translated into #.HasUalue.
..1.10 T-e is operator
T+e is operator is used to dynamically c+ec7 i0 t+e run<time type o0 an ob&ect is compatible wit+ a given type.
T+e result o0 t+e operation ) is 1- w+ere ) is an epression and 1 is a type- is a boolean value indicating
w+et+er ) can success0ully be converted to type 1 by a re0erence conversion- a boing conversion- or an
unboing conversion. T+e operation is evaluated as 0ollows- a0ter type arguments +ave been substituted 0or all
type parametersC
10 ) is an anonymous 0unction- a compile time error occurs
10 ) is a met+od group or t+e null literal- o0 i0 t+e type o0 ) is a re0erence type or a nullable type and t+e
value o0 ) is null- t+e result is 0alse.
/t+erwise- let 6 represent t+e dynamic type o0 ) as 0ollowsC
o 10 t+e type o0 ) is a re0erence type- 6 is t+e run<time type o0 t+e instance re0erence by ).
o 10 t+e type o0 ) is a nullable type- 6 is t+e underlying type o0 t+at nullable type.
o 10 t+e type o0 ) is a non<nullable value type- 6 is t+e type o0 ).
T+e result o0 t+e operation depends on 6 and 1 as 0ollowsC
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 2*3
C# Language Specification
o 10 1 is a re0erence type- t+e result is true i0 6 and 1 are t+e same type- i0 6 is a re0erence type and an
implicit re0erence conversion 0rom 6 to 1 eists- or i0 6 is a value type and a boing conversion 0rom 6
to 1 eists.
o 10 1 is a nullable type- t+e result is true i0 6 is t+e underlying type o0 1.
o 10 1 is a non<nullable value type- t+e result is true i0 6 and 1 are t+e same type.
o /t+erwise- t+e result is 0alse.
=ote t+at user de0ined conversions- are not considered by t+e is operator.
..1.11 T-e as operator
T+e as operator is used to eplicitly convert a value to a given re0erence type or nullable type. 8nli7e a cast
epression JV!.%.%M- t+e as operator never t+rows an eception. 1nstead- i0 t+e indicated conversion is not
possible- t+e resulting value is null.
1n an operation o0 t+e 0orm ) as 1- ) must be an epression and 1 must be a re0erence type- a type parameter
7nown to be a re0erence type- or a nullable type. *urt+ermore- at least one o0 t+e 0ollowing must be true- or
ot+erwise a compile<time error occursC
(n identity JV%.1.1M- implicit re0erence JV%.1.%M- boing JV%.1.!M- eplicit re0erence JV%.2.4M- or unboing
JV%.2."M conversion eists 0rom t+e type o0 ) to 1.
T+e type o0 ) or 1 is an open type.
) is t+e null literal.
T+e operation ) as 1 produces t+e same result as
) is 1 7 (1)()) / (1)null
ecept t+at ) is only evaluated once. T+e compiler can be epected to optimiDe ) as 1 to per0orm at most
one dynamic type c+ec7 as opposed to t+e two dynamic type c+ec7s implied by t+e epansion above.
=ote t+at some conversions- suc+ as user de0ined conversions- are not possible wit+ t+e as operator and s+ould
instead be per0ormed using cast epressions.
1n t+e eample
class I
{
&ublic string V(object o) {
return o as string; .. %a string is a re-erence ty&e
!
&ublic 1 SD1E(object o) ,"ere 1/ 'ttribute {
return o as 1; .. %( 1 "as a class constraint
!
&ublic ; HD;E(object o) {
return o as ;; .. )rror ; is unconstrained
!
!
t+e type parameter 1 o0 S is 7nown to be a re0erence type- because it +as t+e class constraint. T+e type parameter
; o0 H is not +oweverQ +ence t+e use o0 t+e as operator in H is disallowed.
2*" Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
..10 Logical operators
T+e F- G- and H operators are called t+e logical operators.
and-e/pression.
e8!alit+-e/pression
and-e/pression C e8!alit+-e/pression
e/cl!sive-or-e/pression.
and-e/pression
e/cl!sive-or-e/pression E and-e/pression
incl!sive-or-e/pression.
e/cl!sive-or-e/pression
incl!sive-or-e/pression D e/cl!sive-or-e/pression
*or an operation o0 t+e 0orm # op y- w+ere op is one o0 t+e logical operators- overload resolution JV!.2.4M is
applied to select a speci0ic operator implementation. T+e operands are converted to t+e parameter types o0 t+e
selected operator- and t+e type o0 t+e result is t+e return type o0 t+e operator.
T+e prede0ined logical operators are described in t+e 0ollowing sections.
..10.1 Integer logical operators
T+e prede0ined integer logical operators areC
int o&erator F(int # int y);
uint o&erator F(uint # uint y);
long o&erator F(long # long y);
ulong o&erator F(ulong # ulong y);
int o&erator H(int # int y);
uint o&erator H(uint # uint y);
long o&erator H(long # long y);
ulong o&erator H(ulong # ulong y);
int o&erator G(int # int y);
uint o&erator G(uint # uint y);
long o&erator G(long # long y);
ulong o&erator G(ulong # ulong y);
T+e F operator computes t+e bitwise logical 'N6 o0 t+e two operands- t+e H operator computes t+e bitwise
logical %O o0 t+e two operands- and t+e G operator computes t+e bitwise logical eclusive %O o0 t+e two
operands. =o over0lows are possible 0rom t+ese operations.
..10.2 $nueration logical operators
Every enumeration type ) implicitly provides t+e 0ollowing prede0ined logical operatorsC
) o&erator F() # ) y);
) o&erator H() # ) y);
) o&erator G() # ) y);
T+e result o0 evaluating # op y- w+ere # and y are epressions o0 an enumeration type ) wit+ an underlying type
;- and op is one o0 t+e logical operators- is eactly t+e same as evaluating JEM((;)# op (;)y). 1n ot+er words-
t+e enumeration type logical operators simply per0orm t+e logical operation on t+e underlying type o0 t+e two
operands.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 2*
C# Language Specification
..10.3 +oolean logical operators
T+e prede0ined boolean logical operators areC
bool o&erator F(bool # bool y);
bool o&erator H(bool # bool y);
bool o&erator G(bool # bool y);
T+e result o0 # F y is true i0 bot+ # and y are true. /t+erwise- t+e result is -alse.
T+e result o0 # H y is true i0 eit+er # or y is true. /t+erwise- t+e result is -alse.
T+e result o0 # G y is true i0 # is true and y is -alse- or # is -alse and y is true. /t+erwise- t+e result is
-alse. 6+en t+e operands are o0 type bool- t+e G operator computes t+e same result as t+e @+ operator.
..10.# ;ullable boolean logical operators
T+e nullable boolean type bool7 can represent t+ree values- true- -alse- and null- and is conceptually
similar to t+e t+ree<valued type used 0or boolean epressions in #E5. To ensure t+at t+e results produced by t+e
F and H operators 0or bool7 operands are consistent wit+ #E5Ps t+ree<valued logic- t+e 0ollowing prede0ined
operators are providedC
bool7 o&erator F(bool7 # bool7 y);
bool7 o&erator H(bool7 # bool7 y);
T+e 0ollowing table lists t+e results produced by t+ese operators 0or all combinations o0 t+e values true-
-alse- and null.
# y # F y # H y
true true true true
true -alse -alse true
true null null true
-alse true -alse true
-alse -alse -alse -alse
-alse null -alse null
null true null true
null -alse -alse null
null null null null
..11 Conditional logical operators
T+e FF and HH operators are called t+e conditional logical operators. T+ey are also called t+e Ks+ort<circuitingL
logical operators.
conditional-and-e/pression.
incl!sive-or-e/pression
conditional-and-e/pression CC incl!sive-or-e/pression
conditional-or-e/pression.
conditional-and-e/pression
conditional-or-e/pression DD conditional-and-e/pression
2*' Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
T+e FF and HH operators are conditional versions o0 t+e F and H operatorsC
T+e operation # FF y corresponds to t+e operation # F y- ecept t+at y is evaluated only i0 # is not -alse.
T+e operation # HH y corresponds to t+e operation # H y- ecept t+at y is evaluated only i0 # is not true.
(n operation o0 t+e 0orm # FF y or # HH y is processed by applying overload resolution JV!.2.4M as i0 t+e
operation was written # F y or # H y. T+en-
10 overload resolution 0ails to 0ind a single best operator- or i0 overload resolution selects one o0 t+e
prede0ined integer logical operators- a compile<time error occurs.
/t+erwise- i0 t+e selected operator is one o0 t+e prede0ined boolean logical operators JV!.1..3M or nullable
boolean logical operators JV!.1..4M- t+e operation is processed as described in V!.11.1.
/t+erwise- t+e selected operator is a user<de0ined operator- and t+e operation is processed as described in
V!.11.2.
1t is not possible to directly overload t+e conditional logical operators. However- because t+e conditional logical
operators are evaluated in terms o0 t+e regular logical operators- overloads o0 t+e regular logical operators are-
wit+ certain restrictions- also considered overloads o0 t+e conditional logical operators. T+is is described 0urt+er
in V!.11.2.
..11.1 +oolean conditional logical operators
6+en t+e operands o0 FF or HH are o0 type bool- or w+en t+e operands are o0 types t+at do not de0ine an
applicable o&erator F or o&erator H- but do de0ine implicit conversions to bool- t+e operation is processed
as 0ollowsC
T+e operation # FF y is evaluated as # 7 y / -alse. 1n ot+er words- # is 0irst evaluated and converted to
type bool. T+en- i0 # is true- y is evaluated and converted to type bool- and t+is becomes t+e result o0 t+e
operation. /t+erwise- t+e result o0 t+e operation is -alse.
T+e operation # HH y is evaluated as # 7 true / y. 1n ot+er words- # is 0irst evaluated and converted to type
bool. T+en- i0 # is true- t+e result o0 t+e operation is true. /t+erwise- y is evaluated and converted to
type bool- and t+is becomes t+e result o0 t+e operation.
..11.2 6ser9defined conditional logical operators
6+en t+e operands o0 FF or HH are o0 types t+at declare an applicable user<de0ined o&erator F or
o&erator H- bot+ o0 t+e 0ollowing must be true- w+ere 1 is t+e type in w+ic+ t+e selected operator is declaredC
T+e return type and t+e type o0 eac+ parameter o0 t+e selected operator must be 1. 1n ot+er words- t+e
operator must compute t+e logical 'N6 or t+e logical %O o0 two operands o0 type 1- and must return a result
o0 type 1.
1 must contain declarations o0 o&erator true and o&erator -alse.
( compile<time error occurs i0 eit+er o0 t+ese re9uirements is not satis0ied. /t+erwise- t+e FF or HH operation is
evaluated by combining t+e user<de0ined o&erator true or o&erator -alse wit+ t+e selected user<de0ined
operatorC
T+e operation # FF y is evaluated as 1.-alse(#) 7 # / 1.F(# y)- w+ere 1.-alse(#) is an invocation
o0 t+e o&erator -alse declared in 1- and 1.F(# y) is an invocation o0 t+e selected o&erator F. 1n
ot+er words- # is 0irst evaluated and o&erator -alse is invo7ed on t+e result to determine i0 # is de0initely
0alse. T+en- i0 # is de0initely 0alse- t+e result o0 t+e operation is t+e value previously computed 0or #.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 2*7
C# Language Specification
/t+erwise- y is evaluated- and t+e selected o&erator F is invo7ed on t+e value previously computed 0or #
and t+e value computed 0or y to produce t+e result o0 t+e operation.
T+e operation # HH y is evaluated as 1.true(#) 7 # / 1.H(# y)- w+ere 1.true(#) is an invocation o0
t+e o&erator true declared in 1- and 1.H(# y) is an invocation o0 t+e selected o&erator H. 1n ot+er
words- # is 0irst evaluated and o&erator true is invo7ed on t+e result to determine i0 # is de0initely true.
T+en- i0 # is de0initely true- t+e result o0 t+e operation is t+e value previously computed 0or #. /t+erwise- y
is evaluated- and t+e selected o&erator H is invo7ed on t+e value previously computed 0or # and t+e value
computed 0or y to produce t+e result o0 t+e operation.
1n eit+er o0 t+ese operations- t+e epression given by # is only evaluated once- and t+e epression given by y is
eit+er not evaluated or evaluated eactly once.
*or an eample o0 a type t+at implements o&erator true and o&erator -alse- see V11.4.2.
..12 T-e null coalescing operator
T+e 77 operator is called t+e null coalescing operator.
n!ll-coalescing-e/pression.
conditional-or-e/pression
conditional-or-e/pression KK n!ll-coalescing-e/pression
( null coalescing epression o0 t+e 0orm a 77 b re9uires a to be o0 a nullable type or re0erence type. 10 a is non<
null- t+e result o0 a 77 b is aQ ot+erwise- t+e result is b. T+e operation evaluates b only i0 a is null.
T+e null coalescing operator is rig+t<associative- meaning t+at operations are grouped 0rom rig+t to le0t. *or
eample- an epression o0 t+e 0orm a 77 b 77 c is evaluated as a 77 (b 77 c). 1n general terms- an epression
o0 t+e 0orm )
2
77 )
8
77 ... 77 )
N
returns t+e 0irst o0 t+e operands t+at is non<null- or null i0 all operands are null.
T+e type o0 t+e epression a 77 b depends on w+ic+ implicit conversions are available between t+e types o0 t+e
operands. 1n order o0 pre0erence- t+e type o0 a 77 b is '
3
- '- or :- w+ere ' is t+e type o0 a- : is t+e type o0 b
Jprovided t+at b +as a typeM- and '
3
is t+e underlying type o0 ' i0 ' is a nullable type- or ' ot+erwise.
#peci0ically- a 77 b is processed as 0ollowsC
10 ' is not a nullable type or a re0erence type- a compile<time error occurs.
10 ' is a nullable type and an implicit conversion eists 0rom b to '
3
- t+e result type is '
3
. (t run<time- a is
0irst evaluated. 10 a is not null- a is unwrapped to type '
3
- and t+is becomes t+e result. /t+erwise- b is
evaluated and converted to type '
3
- and t+is becomes t+e result.
/t+erwise- i0 an implicit conversion eists 0rom b to '- t+e result type is '. (t run<time- a is 0irst evaluated.
10 a is not null- a becomes t+e result. /t+erwise- b is evaluated and converted to type '- and t+is becomes
t+e result.
/t+erwise- i0 b +as a type : and an implicit conversion eists 0rom '
3
to :- t+e result type is :. (t run<time-
a is 0irst evaluated. 10 a is not null- a is unwrapped to type '
3
Junless ' and '
3
are t+e same typeM and
converted to type :- and t+is becomes t+e result. /t+erwise- b is evaluated and becomes t+e result.
/t+erwise- a and b are incompatible- and a compile<time error occurs.
..13 Conditional operator
T+e 7/ operator is called t+e conditional operator. 1t is at times also called t+e ternary operator.
2*$ Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
conditional-e/pression.
n!ll-coalescing-e/pression
n!ll-coalescing-e/pression K e/pression @ e/pression
( conditional epression o0 t+e 0orm b 7 # / y 0irst evaluates t+e condition b. T+en- i0 b is true- # is evaluated
and becomes t+e result o0 t+e operation. /t+erwise- y is evaluated and becomes t+e result o0 t+e operation. (
conditional epression never evaluates bot+ # and y.
T+e conditional operator is rig+t<associative- meaning t+at operations are grouped 0rom rig+t to le0t. *or
eample- an epression o0 t+e 0orm a 7 b / c 7 d / e is evaluated as a 7 b / (c 7 d / e).
T+e 0irst operand o0 t+e 7/ operator must be an epression o0 a type t+at can be implicitly converted to bool- or
an epression o0 a type t+at implements o&erator true. 10 neit+er o0 t+ese re9uirements is satis0ied- a
compile<time error occurs.
T+e second and t+ird operands o0 t+e 7/ operator control t+e type o0 t+e conditional epression. 5et I and ` be
t+e types o0 t+e second and t+ird operands. T+en-
10 I and ` are t+e same type- t+en t+is is t+e type o0 t+e conditional epression.
/t+erwise- i0 an implicit conversion JV%.1M eists 0rom I to `- but not 0rom ` to I- t+en ` is t+e type o0 t+e
conditional epression.
/t+erwise- i0 an implicit conversion JV%.1M eists 0rom ` to I- but not 0rom I to `- t+en I is t+e type o0 t+e
conditional epression.
/t+erwise- no epression type can be determined- and a compile<time error occurs.
T+e run<time processing o0 a conditional epression o0 t+e 0orm b 7 # / y consists o0 t+e 0ollowing stepsC
*irst- b is evaluated- and t+e bool value o0 b is determinedC
o 10 an implicit conversion 0rom t+e type o0 b to bool eists- t+en t+is implicit conversion is per0ormed to
produce a bool value.
o /t+erwise- t+e o&erator true de0ined by t+e type o0 b is invo7ed to produce a bool value.
10 t+e bool value produced by t+e step above is true- t+en # is evaluated and converted to t+e type o0 t+e
conditional epression- and t+is becomes t+e result o0 t+e conditional epression.
/t+erwise- y is evaluated and converted to t+e type o0 t+e conditional epression- and t+is becomes t+e
result o0 t+e conditional epression.
..1# *non!ous function e%pressions
(n anonyo-s f-nction is an epression t+at represents an Kin<lineL met+od de0inition. (n anonymous
0unction does not +ave a value in and o0 itsel0- but is convertible to a compatible delegate or epression tree
type. T+e evaluation o0 an anonymous 0unction conversion depends on t+e target type o0 t+e conversionC 10 it is a
delegate type- t+e conversion evaluates to a delegate value re0erencing t+e met+od w+ic+ t+e anonymous
0unction de0ines. 10 it is an epression tree type- t+e conversion evaluates to an epression tree w+ic+ represents
t+e structure o0 t+e met+od as an ob&ect structure.
*or +istorical reasons t+ere are two syntactic 0lavors o0 anonymous 0unctions- namely la%,da-e/pressions and
anon+%o!s-%ethod-e/pressions. *or almost all purposes- la%,da-e/pressions are more concise and epressive
t+an anon+%o!s-%ethod-e/pressions- w+ic+ remain in t+e language 0or bac7wards compatibility.
la%,da-e/pression.
anon+%o!s-f!nction-signat!re HJ anon+%o!s-f!nction-,od+
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 2*!
C# Language Specification
anon+%o!s-%ethod-e/pression.
dele+!$e e/plicit-anon+%o!s-f!nction-signat!reopt ,loc&
anon+%o!s-f!nction-signat!re.
e/plicit-anon+%o!s-f!nction-signat!re
i%plicit-anon+%o!s-f!nction-signat!re
e/plicit-anon+%o!s-f!nction-signat!re.
( e/plicit-anon+%o!s-f!nction-para%eter-listopt )
e/plicit-anon+%o!s-f!nction-para%eter-list
e/plicit-anon+%o!s-f!nction-para%eter
e/plicit-anon+%o!s-f!nction-para%eter-list ? e/plicit-anon+%o!s-f!nction-para%eter
e/plicit-anon+%o!s-f!nction-para%eter.
anon+%o!s-f!nction-para%eter-%odifieropt t+pe identifier
anon+%o!s-f!nction-para%eter-%odifier.
%ef
'u$
i%plicit-anon+%o!s-f!nction-signat!re.
( i%plicit-anon+%o!s-f!nction-para%eter-listopt )
i%plicit-anon+%o!s-f!nction-para%eter
i%plicit-anon+%o!s-f!nction-para%eter-list
i%plicit-anon+%o!s-f!nction-para%eter
i%plicit-anon+%o!s-f!nction-para%eter-list ? i%plicit-anon+%o!s-f!nction-para%eter
i%plicit-anon+%o!s-f!nction-para%eter.
identifier
anon+%o!s-f!nction-,od+.
e/pression
,loc&
T+e +E operator +as t+e same precedence as assignment J+M and is rig+t<associative.
T+e parameters o0 an anonymous 0unction in t+e 0orm o0 a la%,da-e/pression can be eplicitly or implicitly
typed. 1n an eplicitly typed parameter list- t+e type o0 eac+ parameter is eplicitly stated. 1n an implicitly typed
parameter list- t+e types o0 t+e parameters are in0erred 0rom t+e contet in w+ic+ t+e anonymous 0unction occurs
Rspeci0ically- w+en t+e anonymous 0unction is converted to a compatible delegate type or epression tree type-
t+at type provides t+e parameter types JV%."M.
1n an anonymous 0unction wit+ a single- implicitly typed parameter- t+e parent+eses may be omitted 0rom t+e
parameter list. 1n ot+er words- an anonymous 0unction o0 t+e 0orm
( para% ) +E e/pr
can be abbreviated to
para% +E e/pr
T+e parameter list o0 an anonymous 0unction in t+e 0orm o0 an anon+%o!s-%ethod-e/pression is optional. 10
given- t+e parameters must be eplicitly typed. 10 not- t+e anonymous 0unction is convertible to a delegate wit+
any parameter list not containing out parameters.
#ome eamples o0 anonymous 0unctions 0ollow belowC
# +E # < 2 .. $m&licitly ty&ed e#&ression body
21* Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
# +E { return # < 2; ! .. $m&licitly ty&ed statement body
(int #) +E # < 2 .. )#&licitly ty&ed e#&ression body
(int #) +E { return # < 2; ! .. )#&licitly ty&ed statement body
(# y) +E # > y .. Multi&le &arameters
() +E Console.WriteLine() .. No &arameters
delegate (int #) { return # < 2; ! .. 'nonymous met"od e#&ression
delegate { return 2 < 2; ! .. *arameter list omitted
T+e be+avior o0 la%,da-e/pressions and anon+%o!s-%ethod-e/pressions is t+e same ecept 0or t+e 0ollowing
pointsC
anon+%o!s-%ethod-e/pressions permit t+e parameter list to be omitted entirely- yielding convertibility
to delegate types o0 any list o0 value parameters.
la%,da-e/pressions permit parameter types to be omitted and in0erred w+ereas anon+%o!s-%ethod-
e/pressions re9uire parameter types to be eplicitly stated.
T+e body o0 a la%,da-e/pression can be an epression or a statement bloc7 w+ereas t+e body o0 an
anon+%o!s-%ethod-e/pression must be a statement bloc7.
#ince only la%,da-e/pressions can +ave an e/pression body- no anon+%o!s-%ethod-e/pression can be
success0ully converted to an epression tree type JV4.%M.
..1#.1 *non!ous function signatures
T+e optional anon+%o!s-f!nction-signat!re o0 an anonymous 0unction de0ines t+e names and optionally t+e
types o0 t+e 0ormal parameters 0or t+e anonymous 0unction. T+e scope o0 t+e parameters o0 t+e anonymous
0unction is t+e anon+%o!s-f!nction-,od+. JV3.!M Toget+er wit+ t+e parameter list Ji0 givenM t+e anonymous<
met+od<body constitutes a declaration space JV3.3M. 1t is t+us a compile<time error 0or t+e name o0 a parameter
o0 t+e anonymous 0unction to matc+ t+e name o0 a local variable- local constant or parameter w+ose scope
includes t+e anon+%o!s-%ethod-e/pression or la%,da-e/pression.
10 an anonymous 0unction +as an e/plicit-anon+%o!s-f!nction-signat!re- t+en t+e set o0 compatible delegate
types and epression tree types is restricted to t+ose t+at +ave t+e same parameter types and modi0iers in t+e
same order. 1n contrast to met+od group conversions JV%.%M- contra<variance o0 anonymous 0unction parameter
types is not supported. 10 an anonymous 0unction does not +ave an anon+%o!s-f!nction-signat!re- t+en t+e set
o0 compatible delegate types and epression tree types is restricted to t+ose t+at +ave no out parameters.
=ote t+at an anon+%o!s-f!nction-signat!re cannot include attributes or a parameter array. =evert+eless- an
anon+%o!s-f!nction-signat!re may be compatible wit+ a delegate type w+ose parameter list contains a
parameter array.
=ote also t+at conversion to an epression tree type- even i0 compatible- may still 0ail at compile time JV4.%M.
..1#.2 *non!ous function bodies
T+e body Je/pression or ,loc&M o0 an anonymous 0unction is sub&ect to t+e 0ollowing rulesC
10 t+e anonymous 0unction includes a signature- t+e parameters speci0ied in t+e signature are available in t+e
body. 10 t+e anonymous 0unction +as no signature it can be converted to a delegate type or epression type
+aving parameters JV%."M- but t+e parameters cannot be accessed in t+e body.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 211
C# Language Specification
Ecept 0or re- or out parameters speci0ied in t+e signature Ji0 anyM o0 t+e nearest enclosing anonymous
0unction- it is a compile<time error 0or t+e body to access a re- or out parameter.
6+en t+e type o0 t"is is a struct type- it is a compile<time error 0or t+e body to access t"is. T+is is true
w+et+er t+e access is eplicit Jas in t"is.#M or implicit Jas in # w+ere # is an instance member o0 t+e
structM. T+is rule simply pro+ibits suc+ access and does not a00ect w+et+er member loo7up results in a
member o0 t+e struct.
T+e body +as access to t+e outer variables JV!.14.4M o0 t+e anonymous 0unction. (ccess o0 an outer variable
will re0erence t+e instance o0 t+e variable t+at is active at t+e time t+e la%,da-e/pression or anon+%o!s-
%ethod-e/pression is evaluated JV!.14."M.
1t is a compile<time error 0or t+e body to contain a goto statement- brea( statement- or continue
statement w+ose target is outside t+e body or wit+in t+e body o0 a contained anonymous 0unction.
( return statement in t+e body returns control 0rom an invocation o0 t+e nearest enclosing anonymous
0unction- not 0rom t+e enclosing 0unction member. (n epression speci0ied in a return statement must be
compatible wit+ t+e delegate type or epression tree type to w+ic+ t+e nearest enclosing la%,da-e/pression
or anon+%o!s-%ethod-e/pression is converted JV%."M.
1t is eplicitly unspeci0ied w+et+er t+ere is any way to eecute t+e bloc7 o0 an anonymous 0unction ot+er t+an
t+roug+ evaluation and invocation o0 t+e la%,da-e/pression or anon+%o!s-%ethod-e/pression. 1n particular- t+e
compiler may c+oose to implement an anonymous 0unction by synt+esiDing one or more named met+ods or
types. T+e names o0 any suc+ synt+esiDed elements must be o0 a 0orm reserved 0or compiler use.
..1#.3 /"erload resolution
(nonymous 0unctions in an argument list participate in type in0erence and overload resolution. Please re0er to
V!.4.2.3 0or t+e eact rules.
T+e 0ollowing eample illustrates t+e e00ect o0 anonymous 0unctions on overload resolution.
class $temListD1E/ ListD1E
{
&ublic int Sum(VuncD1intE selector) {
int sum + 3;
-oreac" (1 item in t"is) sum <+ selector(item);
return sum;
!
&ublic double Sum(VuncD1doubleE selector) {
double sum + 3;
-oreac" (1 item in t"is) sum <+ selector(item);
return sum;
!
!
T+e $temListD1E class +as two Sum met+ods. Eac+ ta7es a selector argument- w+ic+ etracts t+e value to
sum over 0rom a list item. T+e etracted value can be eit+er an int or a double and t+e resulting sum is
li7ewise eit+er an int or a double.
T+e Sum met+ods could 0or eample be used to compute sums 0rom a list o0 detail lines in an order.
212 Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
class 6etail
{
&ublic int ;nitCount;
&ublic double ;nit*rice;
...
!
void Com&uteSums() {
$temListD6etailE order6etails + Set%rder6etails(...);
int total;nits + order6etails.Sum(d +E d.;nitCount);
double order1otal + order6etails.Sum(d +E d.;nit*rice > d.;nitCount);
...
!
1n t+e 0irst invocation o0 order6etails.Sum- bot+ Sum met+ods are applicable because t+e anonymous
0unction d +E d.;nitCount is compatible wit+ bot+ VuncD6etailintE and VuncD6etaildoubleE.
However- overload resolution pic7s t+e 0irst Sum met+od because t+e conversion to VuncD6etailintE is
better t+an t+e conversion to VuncD6etaildoubleE.
1n t+e second invocation o0 order6etails.Sum- only t+e second Sum met+od is applicable because t+e
anonymous 0unction d +E d.;nit*rice > d.;nitCount produces a value o0 type double. T+us- overload
resolution pic7s t+e second Sum met+od 0or t+at invocation.
..1#.# /uter "ariables
(ny local variable- value parameter- or parameter array w+ose scope includes t+e la%,da-e/pression or
anon+%o!s-%ethod-e/pression is called an o-ter varia!le o0 t+e anonymous 0unction. 1n an instance 0unction
member o0 a class- t+e t"is value is considered a value parameter and is an outer variable o0 any anonymous
0unction contained wit+in t+e 0unction member.
.14.4.1 !a"tured outer variables
6+en an outer variable is re0erenced by an anonymous 0unction- t+e outer variable is said to +ave been
capt-red by t+e anonymous 0unction. /rdinarily- t+e li0etime o0 a local variable is limited to eecution o0 t+e
bloc7 or statement wit+ w+ic+ it is associated JV".1.!M. However- t+e li0etime o0 a captured outer variable is
etended at least until t+e delegate or epression tree created 0rom t+e anonymous 0unction becomes eligible 0or
garbage collection.
1n t+e eample
using System;
delegate int 6();
class 1est
{
static 6 V() {
int # + 3;
6 result + () +E <<#;
return result;
!
static void Main() {
6 d + V();
Console.WriteLine(d());
Console.WriteLine(d());
Console.WriteLine(d());
!
!
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 213
C# Language Specification
t+e local variable # is captured by t+e anonymous 0unction- and t+e li0etime o0 # is etended at least until t+e
delegate returned 0rom V becomes eligible 0or garbage collection Jw+ic+ doesnPt +appen until t+e very end o0 t+e
programM. #ince eac+ invocation o0 t+e anonymous 0unction operates on t+e same instance o0 #- t+e output o0 t+e
eample isC
2
8
9
6+en a local variable or a value parameter is captured by an anonymous 0unction- t+e local variable or
parameter is no longer considered to be a 0ied variable JV13.3M- but is instead considered to be a moveable
variable. T+us any unsa-e code t+at ta7es t+e address o0 a captured outer variable must 0irst use t+e -i#ed
statement to 0i t+e variable.
.14.4.2 #nstantiation o/ local variables
( local variable is considered to be instantiated w+en eecution enters t+e scope o0 t+e variable. *or eample-
w+en t+e 0ollowing met+od is invo7ed- t+e local variable # is instantiated and initialiDed t+ree timesRonce 0or
eac+ iteration o0 t+e loop.
static void V() {
-or (int i + 3; i D 9; i<<) {
int # + i > 8 < 2;
...
!
!
However- moving t+e declaration o0 # outside t+e loop results in a single instantiation o0 #C
static void V() {
int #;
-or (int i + 3; i D 9; i<<) {
# + i > 8 < 2;
...
!
!
6+en not captured- t+ere is no way to observe eactly +ow o0ten a local variable is instantiatedRbecause t+e
li0etimes o0 t+e instantiations are dis&oint- it is possible 0or eac+ instantation to simply use t+e same storage
location. However- w+en an anonymous 0unction captures a local variable- t+e e00ects o0 instantiation become
apparent.
T+e eample
using System;
delegate void 6();
class 1est
{
static 645 V() {
645 result + ne, 6495;
-or (int i + 3; i D 9; i<<) {
int # + i > 8 < 2;
result4i5 + () +E { Console.WriteLine(#); !;
!
return result;
!
21" Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
static void Main() {
-oreac" (6 d in V()) d();
!
!
produces t+e outputC
2
9
K
However- w+en t+e declaration o0 # is moved outside t+e loopC
static 645 V() {
645 result + ne, 6495;
int #;
-or (int i + 3; i D 9; i<<) {
# + i > 8 < 2;
result4i5 + () +E { Console.WriteLine(#); !;
!
return result;
!
t+e output isC
K
K
K
10 a 0or<loop declares an iteration variable- t+at variable itsel0 is considered to be declared outside o0 t+e loop.
T+us- i0 t+e eample is c+anged to capture t+e iteration variable itsel0C
static 645 V() {
645 result + ne, 6495;
-or (int i + 3; i D 9; i<<) {
result4i5 + () +E { Console.WriteLine(i); !;
!
return result;
!
only one instance o0 t+e iteration variable is captured- w+ic+ produces t+e outputC
9
9
9
1t is possible 0or anonymous 0unction delegates to s+are some captured variables yet +ave separate instances o0
ot+ers. *or eample- i0 V is c+anged to
static 645 V() {
645 result + ne, 6495;
int # + 3;
-or (int i + 3; i D 9; i<<) {
int y + 3;
result4i5 + () +E { Console.WriteLine("{3! {2!" <<# <<y); !;
!
return result;
!
t+e t+ree delegates capture t+e same instance o0 # but separate instances o0 y- and t+e output isC
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 21
C# Language Specification
2 2
8 2
9 2
#eparate anonymous 0unctions can capture t+e same instance o0 an outer variable. 1n t+e eampleC
using System;
delegate void Setter(int value);
delegate int Setter();
class 1est
{
static void Main() {
int # + 3;
Setter s + (int value) +E { # + value; !;
Setter g + () +E { return #; !;
s(K);
Console.WriteLine(g());
s(23);
Console.WriteLine(g());
!
!
t+e two anonymous 0unctions capture t+e same instance o0 t+e local variable #- and t+ey can t+us
KcommunicateL t+roug+ t+at variable. T+e output o0 t+e eample isC
K
23
..1#.& $"aluation of anon!ous function e%pressions
(n anonymous 0unction V must always be converted to a delegate type 6 or an epression tree type )- eit+er
directly or t+roug+ t+e eecution o0 a delegate creation epression ne, 6(V). T+is conversion determines t+e
result o0 t+e anonymous 0unction- as described in V%.".
..1& =uer! e%pressions
7-ery e,pressions provide a language integrated synta 0or 9ueries t+at is similar to relational and +ierarc+ical
9uery languages suc+ as #E5 and IEuery.
8!er+-e/pression.
fro%-cla!se 8!er+-,od+
fro%-cla!se.
f%'m t+peopt identifier i* e/pression
8!er+-,od+.
8!er+-,od+-cla!sesopt select-or-gro!p-cla!se 8!er+-contin!ationopt
8!er+-,od+-cla!ses.
8!er+-,od+-cla!se
8!er+-,od+-cla!ses 8!er+-,od+-cla!se
21' Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
8!er+-,od+-cla!se.
fro%-cla!se
let-cla!se
where-cla!se
<oin-cla!se
<oin-into-cla!se
order,+-cla!se
let-cla!se.
le$ identifier H e/pression
where-cla!se.
whe%e ,oolean-e/pression
<oin-cla!se.
/'i* t+peopt identifier i* e/pression '* e/pression eNu!l# e/pression
<oin-into-cla!se.
/'i* t+peopt identifier i* e/pression '* e/pression eNu!l# e/pression i*$' identifier
order,+-cla!se.
'%de%") orderings
orderings.
ordering
orderings ? ordering
ordering.
e/pression ordering-directionopt
ordering-direction.
!#&e*di*+
de#&e*di*+
select-or-gro!p-cla!se.
select-cla!se
gro!p-cla!se
select-cla!se.
#ele&$ e/pression
gro!p-cla!se.
+%'u. e/pression ") e/pression
8!er+-contin!ation.
i*$' identifier 8!er+-,od+
( 9uery epression begins wit+ a -rom clause and ends wit+ eit+er a select or grou& clause. T+e initial -rom
clause can be 0ollowed by Dero or more -rom- let- ,"ere- join or orderby clauses. Eac+ -rom clause is a
generator introducing a range varia!le w+ic+ ranges over t+e elements o0 a se4-ence. Eac+ let clause
introduces a range variable representing a value computed by means o0 previous range variables. Eac+ ,"ere
clause is a 0ilter t+at ecludes items 0rom t+e result. Eac+ join clause compares speci0ied 7eys o0 t+e source
se9uence wit+ 7eys o0 anot+er se9uence- yielding matc+ing pairs. Eac+ orderby clause reorders items
according to speci0ied criteria.T+e 0inal select or grou& clause speci0ies t+e s+ape o0 t+e result in terms o0 t+e
range variables. *inally- an into clause can be used to KspliceL 9ueries by treating t+e results o0 one 9uery as a
generator in a subse9uent 9uery.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 217
C# Language Specification
..1&.1 *biguities in 7uer! e%pressions
Euery epressions contain a number o0 Kcontetual 7eywordsL- i.e.- identi0iers t+at +ave special meaning in a
given contet. #peci0ically t+ese are -rom- ,"ere- join- on- eQuals- into- let- orderby- ascending-
descending- select- grou& and by. 1n order to avoid ambiguities in 9uery epressions caused by mied use
o0 t+ese identi0iers as 7eywords or simple names- t+ese identi0iers are considered 7eywords w+en occurring
anyw+ere wit+in a 9uery epression.
*or t+is purpose- a 9uery epression is any epression t+at starts wit+ K-rom identifierL 0ollowed by any to7en
ecept K;L- K+L or KL.
1n order to use t+ese words as identi0iers wit+in a 9uery epression- t+ey can be pre0ied wit+ K\L JV2.4.2M.
..1&.2 =uer! e%pression translation
T+e C# language does not speci0y t+e eecution semantics o0 9uery epressions. ;at+er- 9uery epressions are
translated into invocations o0 met+ods t+at ad+ere to t+e 9uery epression pattern JV!.1".3M. #peci0ically- 9uery
epressions are translated into invocations o0 met+ods named W"ere- Select- SelectMany- ]oin-
Srou&]oin- %rder:y- %rder:y6escending- 1"en:y- 1"en:y6escending- Srou&:y- and Cast.T+ese
met+ods are epected to +ave particular signatures and result types- as described in V!.1".3. T+ese met+ods can
be instance met+ods o0 t+e ob&ect being 9ueried or etension met+ods t+at are eternal to t+e ob&ect- and t+ey
implement t+e actual eecution o0 t+e 9uery.
T+e translation 0rom 9uery epressions to met+od invocations is a syntactic mapping t+at occurs be0ore any type
binding or overload resolution +as been per0ormed. T+e translation is guaranteed to be syntactically correct- but
it is not guaranteed to produce semantically correct C# code. *ollowing translation o0 9uery epressions- t+e
resulting met+od invocations are processed as regular met+od invocations- and t+is may in turn uncover errors-
0or eample i0 t+e met+ods do not eist- i0 arguments +ave wrong types- or i0 t+e met+ods are generic and type
in0erence 0ails.
( 9uery epression is processed by repeatedly applying t+e 0ollowing translations until no 0urt+er reductions are
possible. T+e translations are listed in order o0 applicationC eac+ section assumes t+at t+e translations in t+e
preceding sections +ave been per0ormed e+austively- and once e+austed- a section will not later be revisited in
t+e processing o0 t+e same 9uery epression.
Certain translations in&ect range variables wit+ transparent identifiers denoted by >. T+e special properties o0
transparent identi0iers are discussed 0urt+er in V!.1".2.!.
.15.2.1 Select and grou"by clauses ,ith continuations
( 9uery epression wit+ a continuation
-rom > into / >
is translated into
-rom / in ( -rom > ) >
T+e translations in t+e 0ollowing sections assume t+at 9ueries +ave no into continuations.
T+e eample
-rom c in customers
grou& c by c.Country into g
select ne, { Country + g.aey CustCount + g.Count() !
is translated into
21$ Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
-rom g in
-rom c in customers
grou& c by c.Country
select ne, { Country + g.aey CustCount + g.Count() !
t+e 0inal translation o0 w+ic+ is
customers.
Srou&:y(c +E c.Country).
Select(g +E ne, { Country + g.aey CustCount + g.Count() !)
.15.2.2 %$"licit range variable ty"es
( -rom clause t+at eplicitly speci0ies a range variable type
-rom 9 / in e
is translated into
-rom / in ( e ) . Cast D 9 E ( )
( join clause t+at eplicitly speci0ies a range variable type
join 9 / in e on &1 eQuals &2
is translated into
join / in ( e ) . Cast D 9 E ( ) on &1 eQuals &2
T+e translations in t+e 0ollowing sections assume t+at 9ueries +ave no eplicit range variable types.
T+e eample
-rom Customer c in customers
,"ere c.City ++ "London"
select c
is translated into
-rom c in customers.CastDCustomerE()
,"ere c.City ++ "London"
select c
t+e 0inal translation o0 w+ic+ is
customers.
CastDCustomerE().
W"ere(c +E c.City ++ "London")
Eplicit range variable types are use0ul 0or 9uerying collections t+at implement t+e non<generic $)numerable
inter0ace- but not t+e generic $)numerableD1E inter0ace. 1n t+e eample above- t+is would be t+e case i0
customers were o0 type 'rrayList.
.15.2.3 'egenerate Auery e$"ressions
( 9uery epression o0 t+e 0orm
-rom / in e select /
is translated into
( e ) . Select ( / +E / )
T+e eample
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 21!
C# Language Specification
-rom c in customers
select c
1s translated into
customers.Select(c +E c)
( degenerate 9uery epression is one t+at trivially selects t+e elements o0 t+e source. ( later p+ase o0 t+e
translation removes degenerate 9ueries introduced by ot+er translation steps by replacing t+em wit+ t+eir source.
1t is important +owever to ensure t+at t+e result o0 a 9uery epression is never t+e source ob&ect itsel0- as t+at
would reveal t+e type and identity o0 t+e source to t+e client o0 t+e 9uery. T+ere0ore t+is step protects degenerate
9ueries written directly in source code by eplicitly calling Select on t+e source. 1t is t+en up to t+e
implementers o0 Select and ot+er 9uery operators to ensure t+at t+ese met+ods never return t+e source ob&ect
itsel0.
.15.2.4 3rom, let, ,here, 9oin and orderby clauses
( 9uery epression wit+ a second -rom clause 0ollowed by a select clause
-rom /1 in e1
-rom /2 in e2
select v
is translated into
( e1 ) . SelectMany( /1 +E e2 ( /1 /2 ) +E v )
( 9uery epression wit+ a second -rom clause 0ollowed by somet+ing ot+er t+an a select clauseC
-rom /1 in e1
-rom /2 in e2
b
is translated into
-rom > in ( e1 ) . SelectMany( /1 +E e2 ( /1 /2 ) +E ne, { /1 /2 ! )
b
( 9uery epression wit+ a let clause
-rom / in e
let + + f
>
is translated into
-rom > in ( e ) . Select ( / +E ne, { / + + f ! )
b
( 9uery epression wit+ a ,"ere clause
-rom / in e
,"ere f
>
is translated into
-rom / in ( e ) . W"ere ( / +E f )
b
( 9uery epression wit+ a join clause wit+out an into 0ollowed by a select clause
22* Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
-rom /1 in e1
join /2 in e2 on &1 eQuals &2
select v
is translated into
( e1 ) . ]oin( e2 /1 +E &1 /2 +E &2 ( /1 /2 ) +E v )
( 9uery epression wit+ a join clause wit+out an into 0ollowed by somet+ing ot+er t+an a select clause
-rom /1 in e1
join /2 in e2 on &1 eQuals &2
b
is translated into
-rom > in ( e1 ) . ]oin(
e2 /1 +E &1 /2 +E &2 ( /1 /2 ) +E ne, { /1 /2 !)
b
( 9uery epression wit+ a join clause wit+ an into 0ollowed by a select clause
-rom /1 in e1
join /2 in e2 on &1 eQuals &2 into g
select v
is translated into
( e1 ) . Srou&]oin( e2 /1 +E &1 /2 +E &2 ( /1 g ) +E v )
( 9uery epression wit+ a join clause wit+ an into 0ollowed by somet+ing ot+er t+an a select clause
-rom /1 in e1
join /2 in e2 on &1 eQuals &2 into g
b
is translated into
-rom > in ( e1 ) . Srou&]oin(
e2 /1 +E &1 /2 +E &2 ( /1 g ) +E ne, { /1 g !)
b
( 9uery epression wit+ an orderby clause
-rom / in e
orderby &1 &2 b &n
>
is translated into
-rom / in ( e ) .
%rder:y ( / +E &1 ) .
1"en:y ( / +E &2 ) .
> .
1"en:y ( / +E &n )
b
10 an ordering clause speci0ies a descending direction indicator- an invocation o0 %rder:y6escending or
1"en:y6escending is produced instead.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 221
C# Language Specification
T+e 0ollowing translations assume t+at t+ere are no let- ,"ere- join or orderby clauses- and no more t+an
t+e one initial -rom clause in eac+ 9uery epression.
T+e eample
-rom c in customers
-rom o in c.%rders
select ne, { c.Name o.%rder$6 o.1otal !
is translated into
customers.
SelectMany(c +E c.%rders
(co) +E ne, { c.Name o.%rder$6 o.1otal !
)
T+e eample
-rom c in customers
-rom o in c.%rders
orderby o.1otal descending
select ne, { c.Name o.%rder$6 o.1otal !
is translated into
-rom > in customers.
SelectMany(c +E c.%rders (co) +E ne, { c o !)
orderby o.1otal descending
select ne, { c.Name o.%rder$6 o.1otal !
t+e 0inal translation o0 w+ic+ is
customers.
SelectMany(c +E c.%rders (co) +E ne, { c o !).
%rder:y6escending(# +E #.o.1otal).
Select(# +E ne, { #.c.Name #.o.%rder$6 #.o.1otal !)
w+ere # is a compiler generated identi0ier t+at is ot+erwise invisible and inaccessible.
T+e eample
-rom o in orders
let t + o.6etails.Sum(d +E d.;nit*rice > d.^uantity)
,"ere t E+ 2333
select ne, { o.%rder$6 1otal + t !
is translated into
-rom > in orders.
Select(o +E ne, { o t + o.6etails.Sum(d +E d.;nit*rice > d.^uantity) !)
,"ere t E+ 2333
select ne, { o.%rder$6 1otal + t !
t+e 0inal translation o0 w+ic+ is
orders.
Select(o +E ne, { o t + o.6etails.Sum(d +E d.;nit*rice > d.^uantity) !).
W"ere(# +E #.t E+ 2333).
Select(# +E ne, { #.o.%rder$6 1otal + #.t !)
w+ere # is a compiler generated identi0ier t+at is ot+erwise invisible and inaccessible.
T+e eample
222 Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
-rom c in customers
join o in orders on c.Customer$6 eQuals o.Customer$6
select ne, { c.Name o.%rder6ate o.1otal !
is translated into
customers.]oin(orders c +E c.Customer$6 o +E o.Customer$6
(c o) +E ne, { c.Name o.%rder6ate o.1otal !)
T+e eample
-rom c in customers
join o in orders on c.Customer$6 eQuals o.Customer$6 into co
let n + co.Count()
,"ere n E+ 23
select ne, { c.Name %rderCount + n !
is translated into
-rom > in customers.
Srou&]oin(orders c +E c.Customer$6 o +E o.Customer$6
(c co) +E ne, { c co !)
let n + co.Count()
,"ere n E+ 23
select ne, { c.Name %rderCount + n !
t+e 0inal translation o0 w+ic+ is
customers.
Srou&]oin(orders c +E c.Customer$6 o +E o.Customer$6
(c co) +E ne, { c co !).
Select(# +E ne, { # n + #.co.Count() !).
W"ere(y +E y.n E+ 23).
Select(y +E ne, { y.#.c.Name %rderCount + y.n)
w+ere # and y are compiler generated identi0iers t+at are ot+erwise invisible and inaccessible.
T+e eample
-rom o in orders
orderby o.Customer.Name o.1otal descending
select o
+as t+e 0inal translation
orders.
%rder:y(o +E o.Customer.Name).
1"en:y6escending(o +E o.1otal)
.15.2.5 Select clauses
( 9uery epression o0 t+e 0orm
-rom / in e select v
is translated into
( e ) . Select ( / +E v )
ecept w+en v is t+e identi0ier /- t+e translation is simply
( e )
*or eample
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 223
C# Language Specification
-rom c in customers.W"ere(c +E c.City ++ RLondonT)
select c
is simply translated into
customers.W"ere(c +E c.City ++ RLondonT)
.15.2.6 .rou"by clauses
( 9uery epression o0 t+e 0orm
-rom / in e grou& v by &
is translated into
( e ) . Srou&:y ( / +E & / +E v )
ecept w+en v is t+e identi0ier /- t+e translation is
( e ) . Srou&:y ( / +E & )
T+e eample
-rom c in customers
grou& c.Name by c.Country
is translated into
customers.
Srou&:y(c +E c.Country c +E c.Name)
.15.2. *rans"arent identi/iers
Certain translations in&ect range variables wit+ transparent identifiers denoted by >. Transparent identi0iers are
not a proper language 0eatureQ t+ey eist only as an intermediate step in t+e 9uery epression translation process.
6+en a 9uery translation in&ects a transparent identi0ier- 0urt+er translation steps propagate t+e transparent
identi0ier into anonymous 0unctions and anonymous ob&ect initialiDers. 1n t+ose contets- transparent identi0iers
+ave t+e 0ollowing be+aviorC
6+en a transparent identi0ier occurs as a parameter in an anonymous 0unction- t+e members o0 t+e
associated anonymous type are automatically in scope in t+e body o0 t+e anonymous 0unction.
6+en a member wit+ a transparent identi0ier is in scope- t+e members o0 t+at member are in scope as well.
6+en a transparent identi0ier occurs as a member declarator in an anonymous ob&ect initialiDer- it introduces
a member wit+ a transparent identi0ier.
1n t+e translation steps described above- transparent identi0iers are always introduced toget+er wit+
anonymous types- wit+ t+e intent o0 capturing multiple range variables as members o0 a single ob&ect. (n
implementation o0 C# is permitted to use a di00erent mec+anism t+an anonymous types to group toget+er
multiple range variables. T+e 0ollowing translation eamples assume t+at anonymous types are used- and
s+ow +ow transparent identi0iers can be translated away.
T+e eample
-rom c in customers
-rom o in c.%rders
orderby o.1otal descending
select ne, { c.Name o.1otal !
is translated into
22" Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
-rom > in customers.
SelectMany(c +E c.%rders (co) +E ne, { c o !)
orderby o.1otal descending
select ne, { c.Name o.1otal !
w+ic+ is 0urt+er translated into
customers.
SelectMany(c +E c.%rders (co) +E ne, { c o !).
%rder:y6escending(> +E o.1otal).
Select(> +E ne, { c.Name o.1otal !)
w+ic+- w+en transparent identi0iers are erased- is e9uivalent to
customers.
SelectMany(c +E c.%rders (co) +E ne, { c o !).
%rder:y6escending(# +E #.o.1otal).
Select(# +E ne, { #.c.Name #.o.1otal !)
w+ere # is a compiler generated identi0ier t+at is ot+erwise invisible and inaccessible.
T+e eample
-rom c in customers
join o in orders on c.Customer$6 eQuals o.Customer$6
join d in details on o.%rder$6 eQuals d.%rder$6
join & in &roducts on d.*roduct$6 eQuals &.*roduct$6
select ne, { c.Name o.%rder6ate &.*roductName !
is translated into
-rom > in customers.
]oin(orders c +E c.Customer$6 o +E o.Customer$6
(c o) +E ne, { c o !)
join d in details on o.%rder$6 eQuals d.%rder$6
join & in &roducts on d.*roduct$6 eQuals &.*roduct$6
select ne, { c.Name o.%rder6ate &.*roductName !
w+ic+ is 0urt+er reduced to
customers.
]oin(orders c +E c.Customer$6 o +E o.Customer$6 (c o) +E ne, { c o !).
]oin(details > +E o.%rder$6 d +E d.%rder$6 (> d) +E ne, { > d !).
]oin(&roducts > +E d.*roduct$6 & +E &.*roduct$6 (> &) +E ne, { > & !).
Select(> +E ne, { c.Name o.%rder6ate &.*roductName !)
t+e 0inal translation o0 w+ic+ is
customers.
]oin(orders c +E c.Customer$6 o +E o.Customer$6
(c o) +E ne, { c o !).
]oin(details # +E #.o.%rder$6 d +E d.%rder$6
(# d) +E ne, { # d !).
]oin(&roducts y +E y.d.*roduct$6 & +E &.*roduct$6
(y &) +E ne, { y & !).
Select(? +E ne, { ?.y.#.c.Name ?.y.#.o.%rder6ate ?.&.*roductName !)
w+ere #- y- and ? are compiler generated identi0iers t+at are ot+erwise invisible and inaccessible.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 22
C# Language Specification
..1&.3 T-e 7uer! e%pression pattern
T+e 7-ery e,pression pattern establis+es a pattern o0 met+ods t+at types can implement to support 9uery
epressions. )ecause 9uery epressions are translated to met+od invocations by means o0 a syntactic mapping-
types +ave considerable 0leibility in +ow t+ey implement t+e 9uery epression pattern. *or eample- t+e
met+ods o0 t+e pattern can be implemented as instance met+ods or as etension met+ods because t+e two +ave
t+e same invocation synta- and t+e met+ods can re9uest delegates or epression trees because anonymous
0unctions are convertible to bot+.
T+e recommended s+ape o0 a generic type CD1E t+at supports t+e 9uery epression pattern is s+own below. (
generic type is used in order to illustrate t+e proper relations+ips between parameter and result types- but it is
possible to implement t+e pattern 0or non<generic types as well.
delegate O VuncD12OE(12 arg2);
delegate O VuncD1218OE(12 arg2 18 arg8);
class C
{
&ublic CD1E CastD1E();
!
class CD1E / C
{
&ublic CD1E W"ere(VuncD1boolE &redicate);
&ublic CD;E SelectD;E(VuncD1;E selector);
&ublic CDUE SelectManyD;UE(VuncD1CD;EE selector
VuncD1;UE resultSelector);
&ublic CDUE ]oinD;aUE(CD;E inner VuncD1aE outeraeySelector
VuncD;aE inneraeySelector VuncD1;UE resultSelector);
&ublic CDUE Srou&]oinD;aUE(CD;E inner VuncD1aE outeraeySelector
VuncD;aE inneraeySelector VuncD1CD;EUE resultSelector);
&ublic %D1E %rder:yDaE(VuncD1aE (eySelector);
&ublic %D1E %rder:y6escendingDaE(VuncD1aE (eySelector);
&ublic CDSDa1EE Srou&:yDaE(VuncD1aE (eySelector);
&ublic CDSDa)EE Srou&:yDa)E(VuncD1aE (eySelector
VuncD1)E elementSelector);
!
class %D1E / CD1E
{
&ublic %D1E 1"en:yDaE(VuncD1aE (eySelector);
&ublic %D1E 1"en:y6escendingDaE(VuncD1aE (eySelector);
!
class SDa1E / CD1E
{
&ublic a aey { get; !
!
T+e met+ods above use t+e generic delegate types VuncD12 OE and VuncD12 18 OE- but t+ey could e9ually
well +ave used ot+er delegate or epression tree types wit+ t+e same relations+ips in parameter and result types.
=otice t+e recommended relations+ip between CD1E and %D1E w+ic+ ensures t+at t+e 1"en:y and
1"en:y6escending met+ods are available only on t+e result o0 an %rder:y or %rder:y6escending. (lso
22' Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
notice t+e recommended s+ape o0 t+e result o0 Srou&:yRa se9uence o0 se9uences- w+ere eac+ inner se9uence
+as an additional aey property.
T+e System.LinQ namespace provides an implementation o0 t+e 9uery operator pattern 0or any type t+at
implements t+e System.Collections.Seneric.$)numerableD1E inter0ace.
..1' *ssignent operators
T+e assignment operators assign a new value to a variable- a property- an event- or an indeer element.
assign%ent.
!nar+-e/pression assign%ent-operator e/pression
assign%ent-operator.
H
+H
:H
*H
/H
BH
CH
DH
EH
IIH
right-shift-assign%ent
T+e le0t operand o0 an assignment must be an epression classi0ied as a variable- a property access- an indeer
access- or an event access.
T+e + operator is called t+e siple assignent operator. 1t assigns t+e value o0 t+e rig+t operand to t+e variable-
property- or indeer element given by t+e le0t operand. T+e le0t operand o0 t+e simple assignment operator may
not be an event access Jecept as described in V1..3.1M. T+e simple assignment operator is described in V!.1%.1.
T+e assignment operators ot+er t+an t+e + operator are called t+e copo-nd assignent operators. T+ese
operators per0orm t+e indicated operation on t+e two operands- and t+en assign t+e resulting value to t+e
variable- property- or indeer element given by t+e le0t operand. T+e compound assignment operators are
described in V!.1%.2.
T+e <+ and =+ operators wit+ an event access epression as t+e le0t operand are called t+e event assign%ent
operators. =o ot+er assignment operator is valid wit+ an event access as t+e le0t operand. T+e event assignment
operators are described in V!.1%.3.
T+e assignment operators are rig+t<associative- meaning t+at operations are grouped 0rom rig+t to le0t. *or
eample- an epression o0 t+e 0orm a + b + c is evaluated as a + Jb + c).
..1'.1 Siple assignent
T+e + operator is called t+e simple assignment operator. 1n a simple assignment- t+e rig+t operand must be an
epression o0 a type t+at is implicitly convertible to t+e type o0 t+e le0t operand. T+e operation assigns t+e value
o0 t+e rig+t operand to t+e variable- property- or indeer element given by t+e le0t operand.
T+e result o0 a simple assignment epression is t+e value assigned to t+e le0t operand. T+e result +as t+e same
type as t+e le0t operand and is always classi0ied as a value.
10 t+e le0t operand is a property or indeer access- t+e property or indeer must +ave a set accessor. 10 t+is is not
t+e case- a compile<time error occurs.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 227
C# Language Specification
T+e run<time processing o0 a simple assignment o0 t+e 0orm # + y consists o0 t+e 0ollowing stepsC
10 # is classi0ied as a variableC
o # is evaluated to produce t+e variable.
o y is evaluated and- i0 re9uired- converted to t+e type o0 # t+roug+ an implicit conversion JV%.1M.
o 10 t+e variable given by # is an array element o0 a reference-t+pe- a run<time c+ec7 is per0ormed to
ensure t+at t+e value computed 0or y is compatible wit+ t+e array instance o0 w+ic+ # is an element. T+e
c+ec7 succeeds i0 y is null- or i0 an implicit re0erence conversion JV%.1.%M eists 0rom t+e actual type o0
t+e instance re0erenced by y to t+e actual element type o0 t+e array instance containing #. /t+erwise- a
System.'rray1y&eMismatc")#ce&tion is t+rown.
o T+e value resulting 0rom t+e evaluation and conversion o0 y is stored into t+e location given by t+e
evaluation o0 #.
10 # is classi0ied as a property or indeer accessC
o T+e instance epression Ji0 # is not staticM and t+e argument list Ji0 # is an indeer accessM associated
wit+ # are evaluated- and t+e results are used in t+e subse9uent set accessor invocation.
o y is evaluated and- i0 re9uired- converted to t+e type o0 # t+roug+ an implicit conversion JV%.1M.
o T+e set accessor o0 # is invo7ed wit+ t+e value computed 0or y as its value argument.
T+e array co<variance rules JV12."M permit a value o0 an array type '45 to be a re0erence to an instance o0 an
array type :45- provided an implicit re0erence conversion eists 0rom : to '. )ecause o0 t+ese rules- assignment
to an array element o0 a reference-t+pe re9uires a run<time c+ec7 to ensure t+at t+e value being assigned is
compatible wit+ t+e array instance. 1n t+e eample
string45 sa + ne, string4235;
object45 oa + sa;
oa435 + null; .. %(
oa425 + "Hello"; .. %(
oa485 + ne, 'rrayList(); .. 'rray1y&eMismatc")#ce&tion
t+e last assignment causes a System.'rray1y&eMismatc")#ce&tion to be t+rown because an instance o0
'rrayList cannot be stored in an element o0 a string45.
6+en a property or indeer declared in a str!ct-t+pe is t+e target o0 an assignment- t+e instance epression
associated wit+ t+e property or indeer access must be classi0ied as a variable. 10 t+e instance epression is
classi0ied as a value- a compile<time error occurs. )ecause o0 V!.".4- t+e same rule also applies to 0ields.
4iven t+e declarationsC
struct *oint
{
int # y;
&ublic *oint(int # int y) {
t"is.# + #;
t"is.y + y;
!
&ublic int I {
get { return #; !
set { # + value; !
!
22$ Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
&ublic int ` {
get { return y; !
set { y + value; !
!
!
struct Oectangle
{
*oint a b;
&ublic Oectangle(*oint a *oint b) {
t"is.a + a;
t"is.b + b;
!
&ublic *oint ' {
get { return a; !
set { a + value; !
!
&ublic *oint : {
get { return b; !
set { b + value; !
!
!
in t+e eample
*oint & + ne, *oint();
&.I + 233;
&.` + 233;
Oectangle r + ne, Oectangle();
r.' + ne, *oint(23 23);
r.: + &;
t+e assignments to &.I- &.`- r.'- and r.: are permitted because & and r are variables. However- in t+e
eample
Oectangle r + ne, Oectangle();
r.'.I + 23;
r.'.` + 23;
r.:.I + 233;
r.:.` + 233;
t+e assignments are all invalid- since r.' and r.: are not variables.
..1'.2 Copound assignent
(n operation o0 t+e 0orm # op+ y is processed by applying binary operator overload resolution JV!.2.4M as i0 t+e
operation was written # op y. T+en-
10 t+e return type o0 t+e selected operator is i%plicitl+ convertible to t+e type o0 #- t+e operation is evaluated
as # + # op y- ecept t+at # is evaluated only once.
/t+erwise- i0 t+e selected operator is a prede0ined operator- i0 t+e return type o0 t+e selected operator is
e/plicitl+ convertible to t+e type o0 #- and i0 y is i%plicitl+ convertible to t+e type o0 # or t+e operator is a
s+i0t operator- t+en t+e operation is evaluated as # + (1)(# op y)- w+ere 1 is t+e type o0 #- ecept t+at # is
evaluated only once.
/t+erwise- t+e compound assignment is invalid- and a compile<time error occurs.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 22!
C# Language Specification
T+e term Kevaluated only onceL means t+at in t+e evaluation o0 # op y- t+e results o0 any constituent epressions
o0 # are temporarily saved and t+en reused w+en per0orming t+e assignment to #. *or eample- in t+e
assignment '()4:()5 N+ C()- w+ere ' is a met+od returning int45- and : and C are met+ods returning int-
t+e met+ods are invo7ed only once- in t+e order '- :- C.
6+en t+e le0t operand o0 a compound assignment is a property access or indeer access- t+e property or indeer
must +ave bot+ a get accessor and a set accessor. 10 t+is is not t+e case- a compile<time error occurs.
T+e second rule above permits # op+ y to be evaluated as # + (1)(# op y) in certain contets. T+e rule eists
suc+ t+at t+e prede0ined operators can be used as compound operators w+en t+e le0t operand is o0 type sbyte-
byte- s"ort- us"ort- or c"ar. Even w+en bot+ arguments are o0 one o0 t+ose types- t+e prede0ined operators
produce a result o0 type int- as described in V!.2.%.2. T+us- wit+out a cast it would not be possible to assign t+e
result to t+e le0t operand.
T+e intuitive e00ect o0 t+e rule 0or prede0ined operators is simply t+at # op+ y is permitted i0 bot+ o0 # op y and
# + y are permitted. 1n t+e eample
byte b + 3;
c"ar c" + WZ3W;
int i + 3;
b <+ 2; .. %(
b <+ 2333; .. )rror b + 2333 not &ermitted
b <+ i; .. )rror b + i not &ermitted
b <+ (byte)i; .. %(
c" <+ 2; .. )rror c" + 2 not &ermitted
c" <+ (c"ar)2; .. %(
t+e intuitive reason 0or eac+ error is t+at a corresponding simple assignment would also +ave been an error.
T+is also means t+at compound assignment operations support li0ted operations. 1n t+e eample
int7 i + 3;
i <+ 2; .. %(
t+e li0ted operator <(int7int7) is used.
..1'.3 $"ent assignent
10 t+e le0t operand o0 a <+ or =+ operator is classi0ied as an event access- t+en t+e epression is evaluated as
0ollowsC
T+e instance epression- i0 any- o0 t+e event access is evaluated.
T+e rig+t operand o0 t+e <+ or =+ operator is evaluated- and- i0 re9uired- converted to t+e type o0 t+e le0t
operand t+roug+ an implicit conversion JV%.1M.
(n event accessor o0 t+e event is invo7ed- wit+ argument list consisting o0 t+e rig+t operand- a0ter
evaluation and- i0 necessary- conversion. 10 t+e operator was <+- t+e add accessor is invo7edQ i0 t+e operator
was =+- t+e remove accessor is invo7ed.
(n event assignment epression does not yield a value. T+us- an event assignment epression is valid only in
t+e contet o0 a state%ent-e/pression JV3.%M.
..1. $%pression
(n e/pression is eit+er a non-assign%ent-e/pression or an assign%ent.
23* Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
e/pression.
non-assign%ent-e/pression
assign%ent
non-assign%ent-e/pression.
conditional-e/pression
la%,da-e/pression
8!er+-e/pression
..10 Constant e%pressions
( constant-e/pression is an epression t+at can be 0ully evaluated at compile<time.
constant-e/pression.
e/pression
( constant epression must be t+e null literal or a value wit+ one o0 t+e 0ollowing typesC sbyte- byte-
s"ort- us"ort- int- uint- long- ulong- c"ar- -loat- double- decimal- bool- string- or any
enumeration type. /nly t+e 0ollowing constructs are permitted in constant epressionsC
5iterals Jincluding t+e null literalM.
;e0erences to const members o0 class and struct types.
;e0erences to members o0 enumeration types.
;e0erences to const parameters or local variables
Parent+esiDed sub<epressions- w+ic+ are t+emselves constant epressions.
Cast epressions- provided t+e target type is one o0 t+e types listed above.
c"ec(ed and unc"ec(ed epressions
2e0ault value epressions
T+e prede0ined <- C- @- and A unary operators.
T+e prede0ined <- C- >- .- B- DD- EE- F- H- G- FF- HH- ++- @+- D- E- D+- and E+ binary operators- provided
eac+ operand is o0 a type listed above.
T+e 7/ conditional operator.
T+e 0ollowing conversions are permitted in constant epressionsC
1dentity conversions
=umeric conversions
Enumeration conversions
Constant epression conversions
1mplicit and eplicit re0erence conversions- provided t+at t+e source o0 t+e conversions is a constant
epression t+at evaluates to t+e null value.
/t+er conversions including boing- unboing and implicit re0erence conversions o0 non<null values are not
permitted in constant epressions. *or eampleC
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 231
C# Language Specification
class C {
const object i + K; .. error/ bo#ing conversion not &ermitted
const object str + R"elloT; .. error/ im&licit re-erence conversion
!
t+e initialiDation o0 iis an error because a boing conversion is re9uired. T+e initialiDation o0 str is an error
because an implicit re0erence conversion 0rom a non<null value is re9uired.
6+enever an epression 0ul0ills t+e re9uirements listed above- t+e epression is evaluated at compile<time. T+is
is true even i0 t+e epression is a sub<epression o0 a larger epression t+at contains non<constant constructs.
T+e compile<time evaluation o0 constant epressions uses t+e same rules as run<time evaluation o0 non<constant
epressions- ecept t+at w+ere run<time evaluation would +ave t+rown an eception- compile<time evaluation
causes a compile<time error to occur.
8nless a constant epression is eplicitly placed in an unc"ec(ed contet- over0lows t+at occur in integral<type
arit+metic operations and conversions during t+e compile<time evaluation o0 t+e epression always cause
compile<time errors JV!.13M.
Constant epressions occur in t+e contets listed below. 1n t+ese contets- a compile<time error occurs i0 an
epression cannot be 0ully evaluated at compile<time.
Constant declarations JV1..4M.
Enumeration member declarations JV14.3M.
case labels o0 a s,itc" statement JV3.!.2M.
goto case statements JV3.$.3M.
2imension lengt+s in an array creation epression JV!.".1..4M t+at includes an initialiDer.
(ttributes JV1!M.
(n implicit constant epression conversion JV%.1.3M permits a constant epression o0 type int to be converted
to sbyte- byte- s"ort- us"ort- uint- or ulong- provided t+e value o0 t+e constant epression is wit+in t+e
range o0 t+e destination type.
..11 +oolean e%pressions
( ,oolean-e/pression is an epression t+at yields a result o0 type bool.
,oolean-e/pression.
e/pression
T+e controlling conditional epression o0 an if-state%ent JV3.!.1M- while-state%ent JV3.3.1M- do-state%ent
JV3.3.2M- or for-state%ent JV3.3.3M is a ,oolean-e/pression. T+e controlling conditional epression o0 t+e 7/
operator JV!.13M 0ollows t+e same rules as a ,oolean-e/pression- but 0or reasons o0 operator precedence is
classi0ied as a conditional-or-e/pression.
( ,oolean-e/pression is re9uired to be o0 a type t+at can be implicitly converted to bool or o0 a type t+at
implements o&erator true. 10 neit+er re9uirement is satis0ied- a compile<time error occurs.
6+en a boolean epression is o0 a type t+at cannot be implicitly converted to bool but does implement
o&erator true- t+en 0ollowing evaluation o0 t+e epression- t+e o&erator true implementation provided by
t+at type is invo7ed to produce a bool value.
T+e 6::ool struct type in V11.4.2 provides an eample o0 a type t+at implements o&erator true and
o&erator -alse.
232 Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
0. Stateents
C# provides a variety o0 statements. 'ost o0 t+ese statements will be 0amiliar to developers w+o +ave
programmed in C and CNN.
state%ent.
la,eled-state%ent
declaration-state%ent
e%,edded-state%ent
e%,edded-state%ent.
,loc&
e%pt+-state%ent
e/pression-state%ent
selection-state%ent
iteration-state%ent
<!%p-state%ent
tr+-state%ent
chec&ed-state%ent
!nchec&ed-state%ent
loc&-state%ent
!sing-state%ent
+ield-state%ent
T+e e%,edded-state%ent nonterminal is used 0or statements t+at appear wit+in ot+er statements. T+e use o0
e%,edded-state%ent rat+er t+an state%ent ecludes t+e use o0 declaration statements and labeled statements in
t+ese contets. T+e eample
void V(bool b) {
i- (b)
int i + JJ;
!
results in a compile<time error because an i- statement re9uires an e%,edded-state%ent rat+er t+an a state%ent
0or its i0 branc+. 10 t+is code were permitted- t+en t+e variable i would be declared- but it could never be used.
=ote- +owever- t+at by placing iPs declaration in a bloc7- t+e eample is valid.
0.1 $nd points and reac-abilit!
Every statement +as an end point. 1n intuitive terms- t+e end point o0 a statement is t+e location t+at
immediately 0ollows t+e statement. T+e eecution rules 0or composite statements Jstatements t+at contain
embedded statementsM speci0y t+e action t+at is ta7en w+en control reac+es t+e end point o0 an embedded
statement. *or eample- w+en control reac+es t+e end point o0 a statement in a bloc7- control is trans0erred to
t+e net statement in t+e bloc7.
10 a statement can possibly be reac+ed by eecution- t+e statement is said to be reacha!le. Conversely- i0 t+ere is
no possibility t+at a statement will be eecuted- t+e statement is said to be -nreacha!le.
1n t+e eample
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 233
C# Language Specification
void V() {
Console.WriteLine("reac"able");
goto Label;
Console.WriteLine("unreac"able");
Label/
Console.WriteLine("reac"able");
!
t+e second invocation o0 Console.WriteLine is unreac+able because t+ere is no possibility t+at t+e statement
will be eecuted.
( warning is reported i0 t+e compiler determines t+at a statement is unreac+able. 1t is speci0ically not an error
0or a statement to be unreac+able.
To determine w+et+er a particular statement or end point is reac+able- t+e compiler per0orms 0low analysis
according to t+e reac+ability rules de0ined 0or eac+ statement. T+e 0low analysis ta7es into account t+e values o0
constant epressions JV!.13M t+at control t+e be+avior o0 statements- but t+e possible values o0 non<constant
epressions are not considered. 1n ot+er words- 0or purposes o0 control 0low analysis- a non<constant epression
o0 a given type is considered to +ave any possible value o0 t+at type.
1n t+e eample
void V() {
const int i + 2;
i- (i ++ 8) Console.WriteLine("unreac"able");
!
t+e boolean epression o0 t+e i- statement is a constant epression because bot+ operands o0 t+e ++ operator are
constants. (s t+e constant epression is evaluated at compile<time- producing t+e value -alse- t+e
Console.WriteLine invocation is considered unreac+able. However- i0 i is c+anged to be a local variable
void V() {
int i + 2;
i- (i ++ 8) Console.WriteLine("reac"able");
!
t+e Console.WriteLine invocation is considered reac+able- even t+oug+- in reality- it will never be eecuted.
T+e ,loc& o0 a 0unction member is always considered reac+able. )y successively evaluating t+e reac+ability
rules o0 eac+ statement in a bloc7- t+e reac+ability o0 any given statement can be determined.
1n t+e eample
void V(int #) {
Console.WriteLine("start");
i- (# D 3) Console.WriteLine("negative");
!
t+e reac+ability o0 t+e second Console.WriteLine is determined as 0ollowsC
T+e 0irst Console.WriteLine epression statement is reac+able because t+e bloc7 o0 t+e V met+od is
reac+able.
T+e end point o0 t+e 0irst Console.WriteLine epression statement is reac+able because t+at statement is
reac+able.
T+e i- statement is reac+able because t+e end point o0 t+e 0irst Console.WriteLine epression statement
is reac+able.
23" Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
T+e second Console.WriteLine epression statement is reac+able because t+e boolean epression o0 t+e
i- statement does not +ave t+e constant value -alse.
T+ere are two situations in w+ic+ it is a compile<time error 0or t+e end point o0 a statement to be reac+ableC
)ecause t+e s,itc" statement does not permit a switc+ section to K0all t+roug+L to t+e net switc+ section-
it is a compile<time error 0or t+e end point o0 t+e statement list o0 a switc+ section to be reac+able. 10 t+is
error occurs- it is typically an indication t+at a brea( statement is missing.
1t is a compile<time error 0or t+e end point o0 t+e bloc7 o0 a 0unction member t+at computes a value to be
reac+able. 10 t+is error occurs- it typically is an indication t+at a return statement is missing.
0.2 +loc5s
( ,loc& permits multiple statements to be written in contets w+ere a single statement is allowed.
,loc&.
{ state%ent-listopt }
( ,loc& consists o0 an optional state%ent-list JV3.2.1M- enclosed in braces. 10 t+e statement list is omitted- t+e
bloc7 is said to be empty.
( bloc7 may contain declaration statements JV3."M. T+e scope o0 a local variable or constant declared in a bloc7
is t+e bloc7.
6it+in a bloc7- t+e meaning o0 a name used in an epression contet must always be t+e same JV!.".2.1M.
( bloc7 is eecuted as 0ollowsC
10 t+e bloc7 is empty- control is trans0erred to t+e end point o0 t+e bloc7.
10 t+e bloc7 is not empty- control is trans0erred to t+e statement list. 6+en and i0 control reac+es t+e end
point o0 t+e statement list- control is trans0erred to t+e end point o0 t+e bloc7.
T+e statement list o0 a bloc7 is reac+able i0 t+e bloc7 itsel0 is reac+able.
T+e end point o0 a bloc7 is reac+able i0 t+e bloc7 is empty or i0 t+e end point o0 t+e statement list is reac+able.
( ,loc& t+at contains one or more yield statements JV3.14M is called an iterator bloc7. 1terator bloc7s are used
to implement 0unction members as iterators JV1..14M. #ome additional restrictions apply to iterator bloc7sC
1t is a compile<time error 0or a return statement to appear in an iterator bloc7 Jbut yield return
statements are permittedM.
1t is a compile<time error 0or an iterator bloc7 to contain an unsa0e contet JV13.1M. (n iterator bloc7 always
de0ines a sa0e contet- even w+en its declaration is nested in an unsa0e contet.
0.2.1 Stateent lists
( stateent list consists o0 one or more statements written in se9uence. #tatement lists occur in ,loc&s JV3.2M
and in switch-,loc&s JV3.!.2M.
state%ent-list.
state%ent
state%ent-list state%ent
( statement list is eecuted by trans0erring control to t+e 0irst statement. 6+en and i0 control reac+es t+e end
point o0 a statement- control is trans0erred to t+e net statement. 6+en and i0 control reac+es t+e end point o0 t+e
last statement- control is trans0erred to t+e end point o0 t+e statement list.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 23
C# Language Specification
( statement in a statement list is reac+able i0 at least one o0 t+e 0ollowing is trueC
T+e statement is t+e 0irst statement and t+e statement list itsel0 is reac+able.
T+e end point o0 t+e preceding statement is reac+able.
T+e statement is a labeled statement and t+e label is re0erenced by a reac+able goto statement.
T+e end point o0 a statement list is reac+able i0 t+e end point o0 t+e last statement in t+e list is reac+able.
0.3 T-e ept! stateent
(n e%pt+-state%ent does not+ing.
e%pt+-state%ent.
A
(n empty statement is used w+en t+ere are no operations to per0orm in a contet w+ere a statement is re9uired.
Eecution o0 an empty statement simply trans0ers control to t+e end point o0 t+e statement. T+us- t+e end point
o0 an empty statement is reac+able i0 t+e empty statement is reac+able.
(n empty statement can be used w+en writing a ,"ile statement wit+ a null bodyC
bool *rocessMessage() {...!
void *rocessMessages() {
,"ile (*rocessMessage())
;
!
(lso- an empty statement can be used to declare a label &ust be0ore t+e closing K!L o0 a bloc7C
void V() {
...
i- (done) goto e#it;
...
e#it/ ;
!
0.# Labeled stateents
( la,eled-state%ent permits a statement to be pre0ied by a label. 5abeled statements are permitted in bloc7s-
but are not permitted as embedded statements.
la,eled-state%ent.
identifier @ state%ent
( labeled statement declares a label wit+ t+e name given by t+e identifier. T+e scope o0 a label is t+e w+ole
bloc7 in w+ic+ t+e label is declared- including any nested bloc7s. 1t is a compile<time error 0or two labels wit+
t+e same name to +ave overlapping scopes.
( label can be re0erenced 0rom goto statements JV3.$.3M wit+in t+e scope o0 t+e label. T+is means t+at goto
statements can trans0er control wit+in bloc7s and out o0 bloc7s- but never into bloc7s.
5abels +ave t+eir own declaration space and do not inter0ere wit+ ot+er identi0iers. T+e eample
23' Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
int V(int #) {
i- (# E+ 3) goto #;
# + =#;
#/ return #;
!
is valid and uses t+e name # as bot+ a parameter and a label.
Eecution o0 a labeled statement corresponds eactly to eecution o0 t+e statement 0ollowing t+e label.
1n addition to t+e reac+ability provided by normal 0low o0 control- a labeled statement is reac+able i0 t+e label is
re0erenced by a reac+able goto statement. JEceptionC 10 a goto statement is inside a try t+at includes a
-inally bloc7- and t+e labeled statement is outside t+e try- and t+e end point o0 t+e -inally bloc7 is
unreac+able- t+en t+e labeled statement is not reac+able 0rom t+at goto statement.M
0.& 2eclaration stateents
( declaration-state%ent declares a local variable or constant. 2eclaration statements are permitted in bloc7s- but
are not permitted as embedded statements.
declaration-state%ent.
local-varia,le-declaration A
local-constant-declaration A
0.&.1 Local "ariable declarations
( local-varia,le-declaration declares one or more local variables.
local-varia,le-declaration.
local-varia,le-t+pe local-varia,le-declarators
local-varia,le-t+pe.
t+pe
,!%
local-varia,le-declarators.
local-varia,le-declarator
local-varia,le-declarators ? local-varia,le-declarator
local-varia,le-declarator.
identifier
identifier = local-varia,le-initiali-er
local-varia,le-initiali-er.
e/pression
arra+-initiali-er
T+e local-varia,le-t+pe o0 a local-varia,le-declaration eit+er directly speci0ies t+e type o0 t+e variables
introduced by t+e declaration- or indicates wit+ t+e 7eyword var t+at t+e type s+ould be in0erred based on an
initialiDer. T+e type is 0ollowed by a list o0 local-varia,le-declarators- eac+ o0 w+ic+ introduces a new variable.
( local-varia,le-declarator consists o0 an identifier t+at names t+e variable- optionally 0ollowed by an K+L
to7en and a local-varia,le-initiali-er t+at gives t+e initial value o0 t+e variable.
6+en t+e local-varia,le-t+pe is speci0ied as var and no type named var is in scope- t+e declaration is an
iplicitly typed local varia!le declaration- w+ose type is in0erred 0rom t+e type o0 t+e associated initialiDer
epression. 1mplicitly typed local variable declarations are sub&ect to t+e 0ollowing restrictionsC
T+e local-varia,le-declaration cannot include multiple local-varia,le-declarators.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 237
C# Language Specification
T+e local-varia,le-declarator must include a local-varia,le-initiali-er.
T+e local-varia,le-initiali-er must be an e/pression.
T+e initialiDer e/pression must +ave a compile<time type.
T+e initialiDer e/pression cannot re0er to t+e declared variable itsel0
T+e 0ollowing are eamples o0 incorrect implicitly typed local variable declarationsC
var #; .. )rror no initiali?er to in-er ty&e -rom
var y + {2 8 9!; .. )rror array initiali?er not &ermitted
var ? + null; .. )rror null does not "ave a ty&e
var u + # +E # < 2; .. )rror anonymous -unctions do not "ave a ty&e
var v + v<<; .. )rror initiali?er cannot re-er to variable itsel-
T+e value o0 a local variable is obtained in an epression using a si%ple-na%e JV!.".2M- and t+e value o0 a local
variable is modi0ied using an assign%ent JV!.1%M. ( local variable must be de0initely assigned JV".3M at eac+
location w+ere its value is obtained.
T+e scope o0 a local variable declared in a local-varia,le-declaration is t+e bloc7 in w+ic+ t+e declaration
occurs. 1t is an error to re0er to a local variable in a tetual position t+at precedes t+e local-varia,le-declarator
o0 t+e local variable. 6it+in t+e scope o0 a local variable- it is a compile<time error to declare anot+er local
variable or constant wit+ t+e same name.
( local variable declaration t+at declares multiple variables is e9uivalent to multiple declarations o0 single
variables wit+ t+e same type. *urt+ermore- a variable initialiDer in a local variable declaration corresponds
eactly to an assignment statement t+at is inserted immediately a0ter t+e declaration.
T+e eample
void V() {
int # + 2 y ? + # > 8;
!
corresponds eactly to
void V() {
int #; # + 2;
int y;
int ?; ? + # > 8;
!
1n an implicitly typed local variable declaration- t+e type o0 t+e local variable being declared is ta7en to be t+e
same as t+e type o0 t+e epression used to initialiDe t+e variable. *or eampleC
var i + K;
var s + "Hello";
var d + 2.3;
var numbers + ne, int45 {2 8 9!;
var orders + ne, 6ictionaryDint%rderE();
T+e implicitly typed local variable declarations above are precisely e9uivalent to t+e 0ollowing eplicitly typed
declarationsC
int i + K;
string s + "Hello";
double d + 2.3;
int45 numbers + ne, int45 {2 8 9!;
6ictionaryDint%rderE orders + ne, 6ictionaryDint%rderE();
23$ Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
0.&.2 Local constant declarations
( local-constant-declaration declares one or more local constants.
local-constant-declaration.
&'*#$ t+pe constant-declarators
constant-declarators.
constant-declarator
constant-declarators ? constant-declarator
constant-declarator.
identifier = constant-e/pression
T+e t+pe o0 a local-constant-declaration speci0ies t+e type o0 t+e constants introduced by t+e declaration. T+e
type is 0ollowed by a list o0 constant-declarators- eac+ o0 w+ic+ introduces a new constant. ( constant-
declarator consists o0 an identifier t+at names t+e constant- 0ollowed by an K+L to7en- 0ollowed by a constant-
e/pression JV!.13M t+at gives t+e value o0 t+e constant.
T+e t+pe and constant-e/pression o0 a local constant declaration must 0ollow t+e same rules as t+ose o0 a
constant member declaration JV1..4M.
T+e value o0 a local constant is obtained in an epression using a si%ple-na%e JV!.".2M.
T+e scope o0 a local constant is t+e bloc7 in w+ic+ t+e declaration occurs. 1t is an error to re0er to a local
constant in a tetual position t+at precedes its constant-declarator. 6it+in t+e scope o0 a local constant- it is a
compile<time error to declare anot+er local variable or constant wit+ t+e same name.
( local constant declaration t+at declares multiple constants is e9uivalent to multiple declarations o0 single
constants wit+ t+e same type.
0.' $%pression stateents
(n e/pression-state%ent evaluates a given epression. T+e value computed by t+e epression- i0 any- is
discarded.
e/pression-state%ent.
state%ent-e/pression A
state%ent-e/pression.
invocation-e/pression
o,<ect-creation-e/pression
assign%ent
post-incre%ent-e/pression
post-decre%ent-e/pression
pre-incre%ent-e/pression
pre-decre%ent-e/pression
=ot all epressions are permitted as statements. 1n particular- epressions suc+ as # < y and # ++ 2 t+at merely
compute a value Jw+ic+ will be discardedM- are not permitted as statements.
Eecution o0 an e/pression-state%ent evaluates t+e contained epression and t+en trans0ers control to t+e end
point o0 t+e e/pression-state%ent. T+e end point o0 an e/pression-state%ent is reac+able i0 t+at e/pression-
state%ent is reac+able.
0.. Selection stateents
#election statements select one o0 a number o0 possible statements 0or eecution based on t+e value o0 some
epression.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 23!
C# Language Specification
selection-state%ent.
if-state%ent
switch-state%ent
0...1 T-e if stateent
T+e i- statement selects a statement 0or eecution based on t+e value o0 a boolean epression.
if-state%ent.
if ( ,oolean-e/pression ) e%,edded-state%ent
if ( ,oolean-e/pression ) e%,edded-state%ent el#e e%,edded-state%ent
(n else part is associated wit+ t+e leically nearest preceding i- t+at is allowed by t+e synta. T+us- an i-
statement o0 t+e 0orm
i- (#) i- (y) V(); else S();
is e9uivalent to
i- (#) {
i- (y) {
V();
!
else {
S();
!
!
(n i- statement is eecuted as 0ollowsC
T+e ,oolean-e/pression JV!.1$M is evaluated.
10 t+e boolean epression yields true- control is trans0erred to t+e 0irst embedded statement. 6+en and i0
control reac+es t+e end point o0 t+at statement- control is trans0erred to t+e end point o0 t+e i- statement.
10 t+e boolean epression yields -alse and i0 an else part is present- control is trans0erred to t+e second
embedded statement. 6+en and i0 control reac+es t+e end point o0 t+at statement- control is trans0erred to
t+e end point o0 t+e i- statement.
10 t+e boolean epression yields -alse and i0 an else part is not present- control is trans0erred to t+e end
point o0 t+e i- statement.
T+e 0irst embedded statement o0 an i- statement is reac+able i0 t+e i- statement is reac+able and t+e boolean
epression does not +ave t+e constant value -alse.
T+e second embedded statement o0 an i- statement- i0 present- is reac+able i0 t+e i- statement is reac+able and
t+e boolean epression does not +ave t+e constant value true.
T+e end point o0 an i- statement is reac+able i0 t+e end point o0 at least one o0 its embedded statements is
reac+able. 1n addition- t+e end point o0 an i- statement wit+ no else part is reac+able i0 t+e i- statement is
reac+able and t+e boolean epression does not +ave t+e constant value true.
0...2 T-e switc- stateent
T+e switc+ statement selects 0or eecution a statement list +aving an associated switc+ label t+at corresponds to
t+e value o0 t+e switc+ epression.
switch-state%ent.
#wi$&h ( e/pression ) switch-,loc&
2"* Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
switch-,loc&.
{ switch-sectionsopt }
switch-sections.
switch-section
switch-sections switch-section
switch-section.
switch-la,els state%ent-list
switch-la,els.
switch-la,el
switch-la,els switch-la,el
switch-la,el.
&!#e constant-e/pression @
def!ul$ @
( switch-state%ent consists o0 t+e 7eyword s,itc"- 0ollowed by a parent+esiDed epression Jcalled t+e switc+
epressionM- 0ollowed by a switch-,loc&. T+e switch-,loc& consists o0 Dero or more switch-sections- enclosed in
braces. Eac+ switch-section consists o0 one or more switch-la,els 0ollowed by a state%ent-list JV3.2.1M.
T+e governing type o0 a s,itc" statement is establis+ed by t+e switc+ epression. 10 t+e type o0 t+e switc+
epression is sbyte- byte- s"ort- us"ort- int- uint- long- ulong- c"ar- string- or an en!%-t+pe- t+en
t+at is t+e governing type o0 t+e s,itc" statement. /t+erwise- eactly one user<de0ined implicit conversion
JV%.4M must eist 0rom t+e type o0 t+e switc+ epression to one o0 t+e 0ollowing possible governing typesC
sbyte- byte- s"ort- us"ort- int- uint- long- ulong- c"ar- string. 10 no suc+ implicit conversion eists-
or i0 more t+an one suc+ implicit conversion eists- a compile<time error occurs.
T+e constant epression o0 eac+ case label must denote a value o0 a type t+at is implicitly convertible JV%.1M to
t+e governing type o0 t+e s,itc" statement. ( compile<time error occurs i0 two or more case labels in t+e
same s,itc" statement speci0y t+e same constant value.
T+ere can be at most one de-ault label in a switc+ statement.
( s,itc" statement is eecuted as 0ollowsC
T+e switc+ epression is evaluated and converted to t+e governing type.
10 one o0 t+e constants speci0ied in a case label in t+e same s,itc" statement is e9ual to t+e value o0 t+e
switc+ epression- control is trans0erred to t+e statement list 0ollowing t+e matc+ed case label.
10 none o0 t+e constants speci0ied in case labels in t+e same s,itc" statement is e9ual to t+e value o0 t+e
switc+ epression- and i0 a de-ault label is present- control is trans0erred to t+e statement list 0ollowing t+e
de-ault label.
10 none o0 t+e constants speci0ied in case labels in t+e same s,itc" statement is e9ual to t+e value o0 t+e
switc+ epression- and i0 no de-ault label is present- control is trans0erred to t+e end point o0 t+e s,itc"
statement.
10 t+e end point o0 t+e statement list o0 a switc+ section is reac+able- a compile<time error occurs. T+is is 7nown
as t+e Kno 0all t+roug+L rule. T+e eample
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 2"1
C# Language Specification
s,itc" (i) {
case 3/
CasePero();
brea(;
case 2/
Case%ne();
brea(;
de-ault/
Case%t"ers();
brea(;
!
is valid because no switc+ section +as a reac+able end point. 8nli7e C and CNN- eecution o0 a switc+ section is
not permitted to K0all t+roug+L to t+e net switc+ section- and t+e eample
s,itc" (i) {
case 3/
CasePero();
case 2/
CasePero%r%ne();
de-ault/
Case'ny();
!
results in a compile<time error. 6+en eecution o0 a switc+ section is to be 0ollowed by eecution o0 anot+er
switc+ section- an eplicit goto case or goto de-ault statement must be usedC
s,itc" (i) {
case 3/
CasePero();
goto case 2;
case 2/
CasePero%r%ne();
goto de-ault;
de-ault/
Case'ny();
brea(;
!
'ultiple labels are permitted in a switch-section. T+e eample
s,itc" (i) {
case 3/
CasePero();
brea(;
case 2/
Case%ne();
brea(;
case 8/
de-ault/
Case1,o();
brea(;
!
is valid. T+e eample does not violate t+e Kno 0all t+roug+L rule because t+e labels case 8/ and de-ault/ are
part o0 t+e same switch-section.
T+e Kno 0all t+roug+L rule prevents a common class o0 bugs t+at occur in C and CNN w+en brea( statements
are accidentally omitted. 1n addition- because o0 t+is rule- t+e switc+ sections o0 a s,itc" statement can be
2"2 Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
arbitrarily rearranged wit+out a00ecting t+e be+avior o0 t+e statement. *or eample- t+e sections o0 t+e s,itc"
statement above can be reversed wit+out a00ecting t+e be+avior o0 t+e statementC
s,itc" (i) {
de-ault/
Case'ny();
brea(;
case 2/
CasePero%r%ne();
goto de-ault;
case 3/
CasePero();
goto case 2;
!
T+e statement list o0 a switc+ section typically ends in a brea(- goto case- or goto de-ault statement- but
any construct t+at renders t+e end point o0 t+e statement list unreac+able is permitted. *or eample- a ,"ile
statement controlled by t+e boolean epression true is 7nown to never reac+ its end point. 5i7ewise- a t"ro,
or return statement always trans0ers control elsew+ere and never reac+es its end point. T+us- t+e 0ollowing
eample is validC
s,itc" (i) {
case 3/
,"ile (true) V();
case 2/
t"ro, ne, 'rgument)#ce&tion();
case 8/
return;
!
T+e governing type o0 a s,itc" statement may be t+e type string. *or eampleC
void 6oCommand(string command) {
s,itc" (command.1oLo,er()) {
case "run"/
6oOun();
brea(;
case "save"/
6oSave();
brea(;
case "Quit"/
6o^uit();
brea(;
de-ault/
$nvalidCommand(command);
brea(;
!
!
5i7e t+e string e9uality operators JV!.$.!M- t+e s,itc" statement is case sensitive and will eecute a given
switc+ section only i0 t+e switc+ epression string eactly matc+es a case label constant.
6+en t+e governing type o0 a s,itc" statement is string- t+e value null is permitted as a case label
constant.
T+e state%ent-lists o0 a switch-,loc& may contain declaration statements JV3."M. T+e scope o0 a local variable or
constant declared in a switc+ bloc7 is t+e switc+ bloc7.
6it+in a switc+ bloc7- t+e meaning o0 a name used in an epression contet must always be t+e same JV!.".2.1M.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 2"3
C# Language Specification
T+e statement list o0 a given switc+ section is reac+able i0 t+e s,itc" statement is reac+able and at least one o0
t+e 0ollowing is trueC
T+e switc+ epression is a non<constant value.
T+e switc+ epression is a constant value t+at matc+es a case label in t+e switc+ section.
T+e switc+ epression is a constant value t+at doesnPt matc+ any case label- and t+e switc+ section contains
t+e de-ault label.
( switc+ label o0 t+e switc+ section is re0erenced by a reac+able goto case or goto de-ault statement.
T+e end point o0 a s,itc" statement is reac+able i0 at least one o0 t+e 0ollowing is trueC
T+e s,itc" statement contains a reac+able brea( statement t+at eits t+e s,itc" statement.
T+e s,itc" statement is reac+able- t+e switc+ epression is a non<constant value- and no de-ault label is
present.
T+e s,itc" statement is reac+able- t+e switc+ epression is a constant value t+at doesnPt matc+ any case
label- and no de-ault label is present.
0.0 Iteration stateents
1teration statements repeatedly eecute an embedded statement.
iteration-state%ent.
while-state%ent
do-state%ent
for-state%ent
foreach-state%ent
0.0.1 T-e w-ile stateent
T+e ,"ile statement conditionally eecutes an embedded statement Dero or more times.
while-state%ent.
while ( ,oolean-e/pression ) e%,edded-state%ent
( ,"ile statement is eecuted as 0ollowsC
T+e ,oolean-e/pression JV!.1$M is evaluated.
10 t+e boolean epression yields true- control is trans0erred to t+e embedded statement. 6+en and i0 control
reac+es t+e end point o0 t+e embedded statement Jpossibly 0rom eecution o0 a continue statementM-
control is trans0erred to t+e beginning o0 t+e ,"ile statement.
10 t+e boolean epression yields -alse- control is trans0erred to t+e end point o0 t+e ,"ile statement.
6it+in t+e embedded statement o0 a ,"ile statement- a brea( statement JV3.$.1M may be used to trans0er
control to t+e end point o0 t+e ,"ile statement Jt+us ending iteration o0 t+e embedded statementM- and a
continue statement JV3.$.2M may be used to trans0er control to t+e end point o0 t+e embedded statement Jt+us
per0orming anot+er iteration o0 t+e ,"ile statementM.
T+e embedded statement o0 a ,"ile statement is reac+able i0 t+e ,"ile statement is reac+able and t+e boolean
epression does not +ave t+e constant value -alse.
T+e end point o0 a ,"ile statement is reac+able i0 at least one o0 t+e 0ollowing is trueC
2"" Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
T+e ,"ile statement contains a reac+able brea( statement t+at eits t+e ,"ile statement.
T+e ,"ile statement is reac+able and t+e boolean epression does not +ave t+e constant value true.
0.0.2 T-e do stateent
T+e do statement conditionally eecutes an embedded statement one or more times.
do-state%ent.
d' e%,edded-state%ent while ( ,oolean-e/pression ) A
( do statement is eecuted as 0ollowsC
Control is trans0erred to t+e embedded statement.
6+en and i0 control reac+es t+e end point o0 t+e embedded statement Jpossibly 0rom eecution o0 a
continue statementM- t+e ,oolean-e/pression JV!.1$M is evaluated. 10 t+e boolean epression yields true-
control is trans0erred to t+e beginning o0 t+e do statement. /t+erwise- control is trans0erred to t+e end point
o0 t+e do statement.
6it+in t+e embedded statement o0 a do statement- a brea( statement JV3.$.1M may be used to trans0er control to
t+e end point o0 t+e do statement Jt+us ending iteration o0 t+e embedded statementM- and a continue statement
JV3.$.2M may be used to trans0er control to t+e end point o0 t+e embedded statement.
T+e embedded statement o0 a do statement is reac+able i0 t+e do statement is reac+able.
T+e end point o0 a do statement is reac+able i0 at least one o0 t+e 0ollowing is trueC
T+e do statement contains a reac+able brea( statement t+at eits t+e do statement.
T+e end point o0 t+e embedded statement is reac+able and t+e boolean epression does not +ave t+e constant
value true.
0.0.3 T-e for stateent
T+e -or statement evaluates a se9uence o0 initialiDation epressions and t+en- w+ile a condition is true-
repeatedly eecutes an embedded statement and evaluates a se9uence o0 iteration epressions.
for-state%ent.
f'% ( for-initiali-eropt A for-conditionopt A for-iteratoropt ) e%,edded-state%ent
for-initiali-er.
local-varia,le-declaration
state%ent-e/pression-list
for-condition.
,oolean-e/pression
for-iterator.
state%ent-e/pression-list
state%ent-e/pression-list.
state%ent-e/pression
state%ent-e/pression-list ? state%ent-e/pression
T+e for-initiali-er- i0 present- consists o0 eit+er a local-varia,le-declaration JV3.".1M or a list o0 state%ent-
e/pressions JV3.%M separated by commas. T+e scope o0 a local variable declared by a for-initiali-er starts at t+e
local-varia,le-declarator 0or t+e variable and etends to t+e end o0 t+e embedded statement. T+e scope includes
t+e for-condition and t+e for-iterator.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 2"
C# Language Specification
T+e for-condition- i0 present- must be a ,oolean-e/pression JV!.1$M.
T+e for-iterator- i0 present- consists o0 a list o0 state%ent-e/pressions JV3.%M separated by commas.
( 0or statement is eecuted as 0ollowsC
10 a for-initiali-er is present- t+e variable initialiDers or statement epressions are eecuted in t+e order t+ey
are written. T+is step is only per0ormed once.
10 a for-condition is present- it is evaluated.
10 t+e for-condition is not present or i0 t+e evaluation yields true- control is trans0erred to t+e embedded
statement. 6+en and i0 control reac+es t+e end point o0 t+e embedded statement Jpossibly 0rom eecution o0
a continue statementM- t+e epressions o0 t+e for-iterator- i0 any- are evaluated in se9uence- and t+en
anot+er iteration is per0ormed- starting wit+ evaluation o0 t+e for-condition in t+e step above.
10 t+e for-condition is present and t+e evaluation yields -alse- control is trans0erred to t+e end point o0 t+e
-or statement.
6it+in t+e embedded statement o0 a -or statement- a brea( statement JV3.$.1M may be used to trans0er control
to t+e end point o0 t+e -or statement Jt+us ending iteration o0 t+e embedded statementM- and a continue
statement JV3.$.2M may be used to trans0er control to t+e end point o0 t+e embedded statement Jt+us eecuting
t+e for-iterator and per0orming anot+er iteration o0 t+e -or statement- starting wit+ t+e for-conditionM.
T+e embedded statement o0 a -or statement is reac+able i0 one o0 t+e 0ollowing is trueC
T+e -or statement is reac+able and no for-condition is present.
T+e -or statement is reac+able and a for-condition is present and does not +ave t+e constant value -alse.
T+e end point o0 a -or statement is reac+able i0 at least one o0 t+e 0ollowing is trueC
T+e -or statement contains a reac+able brea( statement t+at eits t+e -or statement.
T+e -or statement is reac+able and a for-condition is present and does not +ave t+e constant value true.
0.0.# T-e foreac- stateent
T+e -oreac" statement enumerates t+e elements o0 a collection- eecuting an embedded statement 0or eac+
element o0 t+e collection.
foreach-state%ent.
f'%e!&h ( local-varia,le-t+pe identifier i* e/pression ) e%,edded-state%ent
T+e t+pe and identifier o0 a -oreac" statement declare t+e iteration varia!le o0 t+e statement. 10 t+e var
7eyword is given as t+e local-varia,le-t+pe- t+e iteration variable is said to be an iplicitly typed iteration
varia!le- and its type is ta7en to be t+e element type o0 t+e -oreac" statement- as speci0ied below. T+e iteration
variable corresponds to a read<only local variable wit+ a scope t+at etends over t+e embedded statement.
2uring eecution o0 a -oreac" statement- t+e iteration variable represents t+e collection element 0or w+ic+ an
iteration is currently being per0ormed. ( compile<time error occurs i0 t+e embedded statement attempts to
modi0y t+e iteration variable Jvia assignment or t+e << and == operatorsM or pass t+e iteration variable as a re-
or out parameter.
T+e compile<time processing o0 a 0oreac+ statement 0irst determines t+e collection type- en-erator type and
eleent type o0 t+e epression. T+is determination proceeds as 0ollowsC
10 t+e type I o0 e/pression is an array type t+en t+ere is an implicit re0erence conversion 0rom I to t+e
System.Collections.$)numerable inter0ace Jsince System.'rray implements t+is inter0aceM. T+e
2"' Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
collection type is t+e System.Collections.$)numerable inter0ace- t+e en-erator type is t+e
System.Collections.$)numerator inter0ace and t+e eleent type is t+e element type o0 t+e array type
I.
/t+erwise- determine w+et+er t+e type I +as an appropriate Set)numerator met+odC
o Per0orm member loo7up on t+e type I wit+ identi0ier Set)numerator and no type arguments. 10 t+e
member loo7up does not produce a matc+- or it produces an ambiguity- or produces a matc+ t+at is not a
met+od group- c+ec7 0or an enumerable inter0ace as described below. 1t is recommended t+at a warning
be issued i0 member loo7up produces anyt+ing ecept a met+od group or no matc+.
o Per0orm overload resolution using t+e resulting met+od group and an empty argument list. 10 overload
resolution results in no applicable met+ods- results in an ambiguity- or results in a single best met+od
but t+at met+od is eit+er static or not public- c+ec7 0or an enumerable inter0ace as described below. 1t is
recommended t+at a warning be issued i0 overload resolution produces anyt+ing ecept an unambiguous
public instance met+od or no applicable met+ods.
o 10 t+e return type ) o0 t+e Set)numerator met+od is not a class- struct or inter0ace type- an error is
produced and no 0urt+er steps are ta7en.
o 'ember loo7up is per0ormed on ) wit+ t+e identi0ier Current and no type arguments. 10 t+e member
loo7up produces no matc+- t+e result is an error- or t+e result is anyt+ing ecept a public instance
property t+at permits reading- an error is produced and no 0urt+er steps are ta7en.
o 'ember loo7up is per0ormed on ) wit+ t+e identi0ier MoveNe#t and no type arguments. 10 t+e member
loo7up produces no matc+- t+e result is an error- or t+e result is anyt+ing ecept a met+od group- an
error is produced and no 0urt+er steps are ta7en.
o /verload resolution is per0ormed on t+e met+od group wit+ an empty argument list. 10 overload
resolution results in no applicable met+ods- results in an ambiguity- or results in a single best met+od
but t+at met+od is eit+er static or not public- or its return type is not bool- an error is produced and no
0urt+er steps are ta7en.
o T+e collection type is I- t+e en-erator type is )- and t+e eleent type is t+e type o0 t+e Current
property.
/t+erwise- c+ec7 0or an enumerable inter0aceC
o 10 t+ere is eactly one type 1 suc+ t+at t+ere is an implicit conversion 0rom I to t+e inter0ace
System.Collections.Seneric.$)numerableD1E- t+en t+e collection type is t+is inter0ace- t+e
en-erator type is t+e inter0ace System.Collections.Seneric.$)numeratorD1E- and t+e
eleent type is 1.
o /t+erwise- i0 t+ere is more t+an one suc+ type 1- t+en an error is produced and no 0urt+er steps are
ta7en.
o /t+erwise- i0 t+ere is an implicit conversion 0rom I to t+e System.Collections.$)numerable
inter0ace- t+en t+e collection type is t+is inter0ace- t+e en-erator type is t+e inter0ace
System.Collections.$)numerator- and t+e eleent type is object.
o /t+erwise- an error is produced and no 0urt+er steps are ta7en.
T+e above steps- i0 success0ul- unambiguously produce a collection type C- enumerator type ) and element type
1. ( 0oreac+ statement o0 t+e 0orm
-oreac" (U v in #) e%,edded-state%ent
is t+en epanded toC
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 2"7
C# Language Specification
{
) e + ((C)(#)).Set)numerator();
try {
U v;
,"ile (e.MoveNe#t()) {
v + (U)(1)e.Current;
e%,edded-state%ent
!
!
-inally {
b .. 6is&ose e
!
!
T+e variable e is not visible to or accessible to t+e epression # or t+e embedded statement or any ot+er source
code o0 t+e program. T+e variable v is read<only in t+e embedded statement. 10 t+ere is not an eplicit
conversion JV%.2M 0rom 1 Jt+e element typeM to U Jt+e t+pe in t+e 0oreac+ statementM- an error is produced and no
0urt+er steps are ta7en. 10 # +as t+e value null- a System.NullOe-erence)#ce&tion is t+rown at run<time.
(n implementation is permitted to implement a given 0oreac+<statement di00erently- e.g. 0or per0ormance
reasons- as long as t+e be+avior is consistent wit+ t+e above epansion.
T+e body o0 t+e 0inally bloc7 is constructed according to t+e 0ollowing stepsC
10 t+ere is an implicit conversion 0rom ) to t+e System.$6is&osable inter0ace- t+en t+e 0inally clause is
epanded to t+e semantic e9uivalent o0C
-inally {
((System.$6is&osable)e).6is&ose();
!
ecept t+at i0 e is a value type- or a type parameter instantiated to a value type- t+en t+e cast o0 e to
System.$6is&osable will not cause boing to occur.
/t+erwise- i0 ) is a sealed type- t+e 0inally clause is epanded to an empty bloc7C
-inally {
!
/t+erwise- t+e 0inally clause is epanded toC
-inally {
System.$6is&osable d + e as System.$6is&osable;
i- (d @+ null) d.6is&ose();
!
T+e local variable d is not visible to or accessible to any user code. 1n particular- it does not con0lict wit+
any ot+er variable w+ose scope includes t+e 0inally bloc7.
T+e order in w+ic+ -oreac" traverses t+e elements o0 an array- is as 0ollowsC *or single<dimensional arrays
elements are traversed in increasing inde order- starting wit+ inde 3 and ending wit+ inde Lengt" C 2. *or
multi<dimensional arrays- elements are traversed suc+ t+at t+e indices o0 t+e rig+tmost dimension are increased
0irst- t+en t+e net le0t dimension- and so on to t+e le0t.
T+e 0ollowing eample prints out eac+ value in a two<dimensional array- in element orderC
using System;
2"$ Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
class 1est
{
static void Main() {
double45 values + {
{2.8 8.9 9.J J.K!
{K.X X.M M.Y Y.L!
!;
-oreac" (double elementUalue in values)
Console.Write("{3! " elementUalue);
Console.WriteLine();
!
!
T+e output produced is as 0ollowsC
2.8 8.9 9.J J.K K.X X.M M.Y Y.L
1n t+e eample
int45 numbers + { 2 9 K M L !;
-oreac" (var n in numbers) Console.WriteLine(n);
t+e type o0 n is in0erred to be int- t+e element type o0 numbers.
0.1 >up stateents
Fump statements unconditionally trans0er control.
<!%p-state%ent.
,rea&-state%ent
contin!e-state%ent
goto-state%ent
ret!rn-state%ent
throw-state%ent
T+e location to w+ic+ a &ump statement trans0ers control is called t+e target o0 t+e &ump statement.
6+en a &ump statement occurs wit+in a bloc7- and t+e target o0 t+at &ump statement is outside t+at bloc7- t+e
&ump statement is said to e,it t+e bloc7. 6+ile a &ump statement may trans0er control out o0 a bloc7- it can never
trans0er control into a bloc7.
Eecution o0 &ump statements is complicated by t+e presence o0 intervening try statements. 1n t+e absence o0
suc+ try statements- a &ump statement unconditionally trans0ers control 0rom t+e &ump statement to its target. 1n
t+e presence o0 suc+ intervening try statements- eecution is more comple. 10 t+e &ump statement eits one or
more try bloc7s wit+ associated -inally bloc7s- control is initially trans0erred to t+e -inally bloc7 o0 t+e
innermost try statement. 6+en and i0 control reac+es t+e end point o0 a -inally bloc7- control is trans0erred
to t+e -inally bloc7 o0 t+e net enclosing try statement. T+is process is repeated until t+e -inally bloc7s o0
all intervening try statements +ave been eecuted.
1n t+e eample
using System;
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 2"!
C# Language Specification
class 1est
{
static void Main() {
,"ile (true) {
try {
try {
Console.WriteLine(":e-ore brea(");
brea(;
!
-inally {
Console.WriteLine("$nnermost -inally bloc(");
!
!
-inally {
Console.WriteLine("%utermost -inally bloc(");
!
!
Console.WriteLine("'-ter brea(");
!
!
t+e -inally bloc7s associated wit+ two try statements are eecuted be0ore control is trans0erred to t+e target
o0 t+e &ump statement.
T+e output produced is as 0ollowsC
:e-ore brea(
$nnermost -inally bloc(
%utermost -inally bloc(
'-ter brea(
0.1.1 T-e brea5 stateent
T+e brea( statement eits t+e nearest enclosing s,itc"- ,"ile- do- -or- or -oreac" statement.
,rea&-state%ent.
"%e!( A
T+e target o0 a brea( statement is t+e end point o0 t+e nearest enclosing s,itc"- ,"ile- do- -or- or -oreac"
statement. 10 a brea( statement is not enclosed by a s,itc"- ,"ile- do- -or- or -oreac" statement- a
compile<time error occurs.
6+en multiple s,itc"- ,"ile- do- -or- or -oreac" statements are nested wit+in eac+ ot+er- a brea(
statement applies only to t+e innermost statement. To trans0er control across multiple nesting levels- a goto
statement JV3.$.3M must be used.
( brea( statement cannot eit a -inally bloc7 JV3.1.M. 6+en a brea( statement occurs wit+in a -inally
bloc7- t+e target o0 t+e brea( statement must be wit+in t+e same -inally bloc7Q ot+erwise- a compile<time
error occurs.
( brea( statement is eecuted as 0ollowsC
10 t+e brea( statement eits one or more try bloc7s wit+ associated -inally bloc7s- control is initially
trans0erred to t+e -inally bloc7 o0 t+e innermost try statement. 6+en and i0 control reac+es t+e end point
o0 a -inally bloc7- control is trans0erred to t+e -inally bloc7 o0 t+e net enclosing try statement. T+is
process is repeated until t+e -inally bloc7s o0 all intervening try statements +ave been eecuted.
Control is trans0erred to t+e target o0 t+e brea( statement.
2* Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
)ecause a brea( statement unconditionally trans0ers control elsew+ere- t+e end point o0 a brea( statement is
never reac+able.
0.1.2 T-e continue stateent
T+e continue statement starts a new iteration o0 t+e nearest enclosing ,"ile- do- -or- or -oreac" statement.
contin!e-state%ent.
&'*$i*ue A
T+e target o0 a continue statement is t+e end point o0 t+e embedded statement o0 t+e nearest enclosing ,"ile-
do- -or- or -oreac" statement. 10 a continue statement is not enclosed by a ,"ile- do- -or- or -oreac"
statement- a compile<time error occurs.
6+en multiple ,"ile- do- -or- or -oreac" statements are nested wit+in eac+ ot+er- a continue statement
applies only to t+e innermost statement. To trans0er control across multiple nesting levels- a goto statement
JV3.$.3M must be used.
( continue statement cannot eit a -inally bloc7 JV3.1.M. 6+en a continue statement occurs wit+in a
-inally bloc7- t+e target o0 t+e continue statement must be wit+in t+e same -inally bloc7Q ot+erwise a
compile<time error occurs.
( continue statement is eecuted as 0ollowsC
10 t+e continue statement eits one or more try bloc7s wit+ associated -inally bloc7s- control is
initially trans0erred to t+e -inally bloc7 o0 t+e innermost try statement. 6+en and i0 control reac+es t+e
end point o0 a -inally bloc7- control is trans0erred to t+e -inally bloc7 o0 t+e net enclosing try
statement. T+is process is repeated until t+e -inally bloc7s o0 all intervening try statements +ave been
eecuted.
Control is trans0erred to t+e target o0 t+e continue statement.
)ecause a continue statement unconditionally trans0ers control elsew+ere- t+e end point o0 a continue
statement is never reac+able.
0.1.3 T-e goto stateent
T+e goto statement trans0ers control to a statement t+at is mar7ed by a label.
goto-state%ent.
+'$' identifier A
+'$' &!#e constant-e/pression ?
+'$' def!ul$ A
T+e target o0 a goto identifier statement is t+e labeled statement wit+ t+e given label. 10 a label wit+ t+e given
name does not eist in t+e current 0unction member- or i0 t+e goto statement is not wit+in t+e scope o0 t+e label-
a compile<time error occurs. T+is rule permits t+e use o0 a goto statement to trans0er control o!t of a nested
scope- but not into a nested scope. 1n t+e eample
using System;
class 1est
{
static void Main(string45 args) {
string45 table + {
{"Oed" ":lue" "Sreen"!
{"Monday" "Wednesday" "Vriday"!
!;
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 21
C# Language Specification
-oreac" (string str in args) {
int ro, colm;
-or (ro, + 3; ro, D+ 2; <<ro,)
-or (colm + 3; colm D+ 8; <<colm)
i- (str ++ table4ro,colm5)
goto done;
Console.WriteLine("{3! not -ound" str);
continue;
done/
Console.WriteLine("Vound {3! at 4{2!54{8!5" str ro, colm);
!
!
!
a goto statement is used to trans0er control out o0 a nested scope.
T+e target o0 a goto case statement is t+e statement list in t+e immediately enclosing s,itc" statement
JV3.!.2M- w+ic+ contains a case label wit+ t+e given constant value. 10 t+e goto case statement is not enclosed
by a s,itc" statement- i0 t+e constant-e/pression is not implicitly convertible JV%.1M to t+e governing type o0
t+e nearest enclosing s,itc" statement- or i0 t+e nearest enclosing s,itc" statement does not contain a case
label wit+ t+e given constant value- a compile<time error occurs.
T+e target o0 a goto de-ault statement is t+e statement list in t+e immediately enclosing s,itc" statement
JV3.!.2M- w+ic+ contains a de-ault label. 10 t+e goto de-ault statement is not enclosed by a s,itc"
statement- or i0 t+e nearest enclosing s,itc" statement does not contain a de-ault label- a compile<time error
occurs.
( goto statement cannot eit a -inally bloc7 JV3.1.M. 6+en a goto statement occurs wit+in a -inally
bloc7- t+e target o0 t+e goto statement must be wit+in t+e same -inally bloc7- or ot+erwise a compile<time
error occurs.
( goto statement is eecuted as 0ollowsC
10 t+e goto statement eits one or more try bloc7s wit+ associated -inally bloc7s- control is initially
trans0erred to t+e -inally bloc7 o0 t+e innermost try statement. 6+en and i0 control reac+es t+e end point
o0 a -inally bloc7- control is trans0erred to t+e -inally bloc7 o0 t+e net enclosing try statement. T+is
process is repeated until t+e -inally bloc7s o0 all intervening try statements +ave been eecuted.
Control is trans0erred to t+e target o0 t+e goto statement.
)ecause a goto statement unconditionally trans0ers control elsew+ere- t+e end point o0 a goto statement is
never reac+able.
0.1.# T-e return stateent
T+e return statement returns control to t+e caller o0 t+e 0unction member in w+ic+ t+e return statement
appears.
ret!rn-state%ent.
%e$u%* e/pressionopt A
( return statement wit+ no epression can be used only in a 0unction member t+at does not compute a value-
t+at is- a met+od wit+ t+e return type void- t+e set accessor o0 a property or indeer- t+e add and remove
accessors o0 an event- an instance constructor- a static constructor- or a destructor.
( return statement wit+ an epression can only be used in a 0unction member t+at computes a value- t+at is- a
met+od wit+ a non<void return type- t+e get accessor o0 a property or indeer- or a user<de0ined operator. (n
22 Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
implicit conversion JV%.1M must eist 0rom t+e type o0 t+e epression to t+e return type o0 t+e containing
0unction member.
1t is a compile<time error 0or a return statement to appear in a -inally bloc7 JV3.1.M.
( return statement is eecuted as 0ollowsC
10 t+e return statement speci0ies an epression- t+e epression is evaluated and t+e resulting value is
converted to t+e return type o0 t+e containing 0unction member by an implicit conversion. T+e result o0 t+e
conversion becomes t+e value returned to t+e caller.
10 t+e return statement is enclosed by one or more try bloc7s wit+ associated -inally bloc7s- control is
initially trans0erred to t+e -inally bloc7 o0 t+e innermost try statement. 6+en and i0 control reac+es t+e
end point o0 a -inally bloc7- control is trans0erred to t+e -inally bloc7 o0 t+e net enclosing try
statement. T+is process is repeated until t+e -inally bloc7s o0 all enclosing try statements +ave been
eecuted.
Control is returned to t+e caller o0 t+e containing 0unction member.
)ecause a return statement unconditionally trans0ers control elsew+ere- t+e end point o0 a return statement
is never reac+able.
0.1.& T-e t-row stateent
T+e t"ro, statement t+rows an eception.
throw-state%ent.
$h%'w e/pressionopt A
( t"ro, statement wit+ an epression t+rows t+e value produced by evaluating t+e epression. T+e epression
must denote a value o0 t+e class type System.)#ce&tion- o0 a class type t+at derives 0rom
System.)#ce&tion or o0 a type parameter type t+at +as System.)#ce&tion Jor a subclass t+ereo0M as its
e00ective base class. 10 evaluation o0 t+e epression produces null- a System.NullOe-erence)#ce&tion is
t+rown instead.
( t"ro, statement wit+ no epression can be used only in a catc" bloc7- in w+ic+ case t+at statement re<
t+rows t+e eception t+at is currently being +andled by t+at catc" bloc7.
)ecause a t"ro, statement unconditionally trans0ers control elsew+ere- t+e end point o0 a t"ro, statement is
never reac+able.
6+en an eception is t+rown- control is trans0erred to t+e 0irst catc" clause in an enclosing try statement t+at
can +andle t+e eception. T+e process t+at ta7es place 0rom t+e point o0 t+e eception being t+rown to t+e point
o0 trans0erring control to a suitable eception +andler is 7nown as e,ception propagation. Propagation o0 an
eception consists o0 repeatedly evaluating t+e 0ollowing steps until a catc" clause t+at matc+es t+e eception
is 0ound. 1n t+is description- t+e thro2 point is initially t+e location at w+ic+ t+e eception is t+rown.
1n t+e current 0unction member- eac+ try statement t+at encloses t+e t+row point is eamined. *or eac+
statement S- starting wit+ t+e innermost try statement and ending wit+ t+e outermost try statement- t+e
0ollowing steps are evaluatedC
o 10 t+e try bloc7 o0 S encloses t+e t+row point and i0 # +as one or more catc" clauses- t+e catc"
clauses are eamined in order o0 appearance to locate a suitable +andler 0or t+e eception. T+e 0irst
catc" clause t+at speci0ies t+e eception type or a base type o0 t+e eception type is considered a
matc+. ( general catc" clause JV3.1.M is considered a matc+ 0or any eception type. 10 a matc+ing
catc" clause is located- t+e eception propagation is completed by trans0erring control to t+e bloc7 o0
t+at catc" clause.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 23
C# Language Specification
o /t+erwise- i0 t+e try bloc7 or a catc" bloc7 o0 S encloses t+e t+row point and i0 S +as a -inally
bloc7- control is trans0erred to t+e -inally bloc7. 10 t+e -inally bloc7 t+rows anot+er eception-
processing o0 t+e current eception is terminated. /t+erwise- w+en control reac+es t+e end point o0 t+e
-inally bloc7- processing o0 t+e current eception is continued.
10 an eception +andler was not located in t+e current 0unction member invocation- t+e 0unction member
invocation is terminated. T+e steps above are t+en repeated 0or t+e caller o0 t+e 0unction member wit+ a
t+row point corresponding to t+e statement 0rom w+ic+ t+e 0unction member was invo7ed.
10 t+e eception processing terminates all 0unction member invocations in t+e current t+read- indicating t+at
t+e t+read +as no +andler 0or t+e eception- t+en t+e t+read is itsel0 terminated. T+e impact o0 suc+
termination is implementation<de0ined.
0.10 T-e tr! stateent
T+e try statement provides a mec+anism 0or catc+ing eceptions t+at occur during eecution o0 a bloc7.
*urt+ermore- t+e try statement provides t+e ability to speci0y a bloc7 o0 code t+at is always eecuted w+en
control leaves t+e try statement.
tr+-state%ent.
$%) ,loc& catch-cla!ses
$%) ,loc& finall+-cla!se
$%) ,loc& catch-cla!ses finall+-cla!se
catch-cla!ses.
specific-catch-cla!ses general-catch-cla!seopt
specific-catch-cla!sesopt general-catch-cla!se
specific-catch-cla!ses.
specific-catch-cla!se
specific-catch-cla!ses specific-catch-cla!se
specific-catch-cla!se.
&!$&h ( class-t+pe identifieropt ) ,loc&
general-catch-cla!se.
&!$&h ,loc&
finall+-cla!se.
fi*!ll) ,loc&
T+ere are t+ree possible 0orms o0 try statementsC
( try bloc7 0ollowed by one or more catc" bloc7s.
( try bloc7 0ollowed by a -inally bloc7.
( try bloc7 0ollowed by one or more catc" bloc7s 0ollowed by a -inally bloc7.
6+en a catc" clause speci0ies a class-t+pe- t+e type must be System.)#ce&tion- a type t+at derives 0rom
System.)#ce&tion or a type parameter type t+at +as System.)#ce&tion Jor a subclass t+ereo0M as its
e00ective base class.
6+en a catc" clause speci0ies bot+ a class-t+pe and an identifier- an e,ception varia!le o0 t+e given name and
type is declared. T+e eception variable corresponds to a local variable wit+ a scope t+at etends over t+e
catc" bloc7. 2uring eecution o0 t+e catc" bloc7- t+e eception variable represents t+e eception currently
being +andled. *or purposes o0 de0inite assignment c+ec7ing- t+e eception variable is considered de0initely
assigned in its entire scope.
2" Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
8nless a catc" clause includes an eception variable name- it is impossible to access t+e eception ob&ect in t+e
catc" bloc7.
( catc" clause t+at speci0ies neit+er an eception type nor an eception variable name is called a general
catc" clause. ( try statement can only +ave one general catc" clause- and i0 one is present it must be t+e last
catc" clause.
#ome programming languages may support eceptions t+at are not representable as an ob&ect derived 0rom
System.)#ce&tion- alt+oug+ suc+ eceptions could never be generated by C# code. ( general catc" clause
may be used to catc+ suc+ eceptions. T+us- a general catc" clause is semantically di00erent 0rom one t+at
speci0ies t+e type System.)#ce&tion- in t+at t+e 0ormer may also catc+ eceptions 0rom ot+er languages.
1n order to locate a +andler 0or an eception- catc" clauses are eamined in leical order. ( compile<time error
occurs i0 a catc" clause speci0ies a type t+at is t+e same as- or is derived 0rom- a type t+at was speci0ied in an
earlier catc" clause 0or t+e same try. 6it+out t+is restriction- it would be possible to write unreac+able catc"
clauses.
6it+in a catc" bloc7- a t"ro, statement JV3.$."M wit+ no epression can be used to re<t+row t+e eception t+at
was caug+t by t+e catc" bloc7. (ssignments to an eception variable do not alter t+e eception t+at is re<
t+rown.
1n t+e eample
using System;
class 1est
{
static void V() {
try {
S();
!
catc" ()#ce&tion e) {
Console.WriteLine(")#ce&tion in V/ " < e.Message);
e + ne, )#ce&tion("V");
t"ro,; .. re=t"ro,
!
!
static void S() {
t"ro, ne, )#ce&tion("S");
!
static void Main() {
try {
V();
!
catc" ()#ce&tion e) {
Console.WriteLine(")#ce&tion in Main/ " < e.Message);
!
!
!
t+e met+od V catc+es an eception- writes some diagnostic in0ormation to t+e console- alters t+e eception
variable- and re<t+rows t+e eception. T+e eception t+at is re<t+rown is t+e original eception- so t+e output
produced isC
)#ce&tion in V/ S
)#ce&tion in Main/ S
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 2
C# Language Specification
10 t+e 0irst catc+ bloc7 +ad t+rown e instead o0 ret+rowing t+e current eception- t+e output produced is would
be as 0ollowsC
)#ce&tion in V/ S
)#ce&tion in Main/ V
1t is a compile<time error 0or a brea(- continue- or goto statement to trans0er control out o0 a -inally
bloc7. 6+en a brea(- continue- or goto statement occurs in a -inally bloc7- t+e target o0 t+e statement
must be wit+in t+e same -inally bloc7- or ot+erwise a compile<time error occurs.
1t is a compile<time error 0or a return statement to occur in a -inally bloc7.
( try statement is eecuted as 0ollowsC
Control is trans0erred to t+e try bloc7.
6+en and i0 control reac+es t+e end point o0 t+e try bloc7C
o 10 t+e try statement +as a -inally bloc7- t+e -inally bloc7 is eecuted.
o Control is trans0erred to t+e end point o0 t+e try statement.
10 an eception is propagated to t+e try statement during eecution o0 t+e try bloc7C
o T+e catc" clauses- i0 any- are eamined in order o0 appearance to locate a suitable +andler 0or t+e
eception. T+e 0irst catc" clause t+at speci0ies t+e eception type or a base type o0 t+e eception type
is considered a matc+. ( general catc" clause is considered a matc+ 0or any eception type. 10 a
matc+ing catc" clause is locatedC
10 t+e matc+ing catc" clause declares an eception variable- t+e eception ob&ect is assigned to t+e
eception variable.
Control is trans0erred to t+e matc+ing catc" bloc7.
6+en and i0 control reac+es t+e end point o0 t+e catc" bloc7C
o 10 t+e try statement +as a -inally bloc7- t+e -inally bloc7 is eecuted.
o Control is trans0erred to t+e end point o0 t+e try statement.
10 an eception is propagated to t+e try statement during eecution o0 t+e catc" bloc7C
o 10 t+e try statement +as a -inally bloc7- t+e -inally bloc7 is eecuted.
o T+e eception is propagated to t+e net enclosing try statement.
o 10 t+e try statement +as no catc" clauses or i0 no catc" clause matc+es t+e eceptionC
10 t+e try statement +as a -inally bloc7- t+e -inally bloc7 is eecuted.
T+e eception is propagated to t+e net enclosing try statement.
T+e statements o0 a -inally bloc7 are always eecuted w+en control leaves a try statement. T+is is true
w+et+er t+e control trans0er occurs as a result o0 normal eecution- as a result o0 eecuting a brea(- continue-
goto- or return statement- or as a result o0 propagating an eception out o0 t+e try statement.
10 an eception is t+rown during eecution o0 a -inally bloc7- and is not caug+t wit+in t+e same 0inally bloc7-
t+e eception is propagated to t+e net enclosing try statement. 10 anot+er eception was in t+e process o0 being
propagated- t+at eception is lost. T+e process o0 propagating an eception is discussed 0urt+er in t+e description
o0 t+e t"ro, statement JV3.$."M.
2' Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
T+e try bloc7 o0 a try statement is reac+able i0 t+e try statement is reac+able.
( catc" bloc7 o0 a try statement is reac+able i0 t+e try statement is reac+able.
T+e -inally bloc7 o0 a try statement is reac+able i0 t+e try statement is reac+able.
T+e end point o0 a try statement is reac+able i0 bot+ o0 t+e 0ollowing are trueC
T+e end point o0 t+e try bloc7 is reac+able or t+e end point o0 at least one catc" bloc7 is reac+able.
10 a -inally bloc7 is present- t+e end point o0 t+e -inally bloc7 is reac+able.
0.11 T-e c-ec5ed and unc-ec5ed stateents
T+e c"ec(ed and unc"ec(ed statements are used to control t+e overflo2 chec"ing conte,t 0or integral<type
arit+metic operations and conversions.
chec&ed-state%ent.
&he&(ed ,loc&
!nchec&ed-state%ent.
u*&he&(ed ,loc&
T+e c"ec(ed statement causes all epressions in t+e ,loc& to be evaluated in a c+ec7ed contet- and t+e
unc"ec(ed statement causes all epressions in t+e ,loc& to be evaluated in an unc+ec7ed contet.
T+e c"ec(ed and unc"ec(ed statements are precisely e9uivalent to t+e c"ec(ed and unc"ec(ed operators
JV!.".12M- ecept t+at t+ey operate on bloc7s instead o0 epressions.
0.12 T-e loc5 stateent
T+e loc( statement obtains t+e mutual<eclusion loc7 0or a given ob&ect- eecutes a statement- and t+en
releases t+e loc7.
loc&-state%ent.
l'&( ( e/pression ) e%,edded-state%ent
T+e epression o0 a loc( statement must denote a value o0 a type 7nown to be a reference-t+pe. =o implicit
boing conversion JV%.1.!M is ever per0ormed 0or t+e epression o0 a loc( statement- and t+us it is a compile<
time error 0or t+e epression to denote a value o0 a val!e-t+pe.
( loc( statement o0 t+e 0orm
loc( (#) ...
w+ere # is an epression o0 a reference-t+pe- is precisely e9uivalent to
System.1"reading.Monitor.)nter(#);
try {
...
!
-inally {
System.1"reading.Monitor.)#it(#);
!
ecept t+at # is only evaluated once.
6+ile a mutual<eclusion loc7 is +eld- code eecuting in t+e same eecution t+read can also obtain and release
t+e loc7. However- code eecuting in ot+er t+reads is bloc7ed 0rom obtaining t+e loc7 until t+e loc7 is released.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 27
C# Language Specification
5oc7ing System.1y&e ob&ects in order to sync+roniDe access to static data is not recommended. /t+er code
mig+t loc7 on t+e same type- w+ic+ can result in deadloc7. ( better approac+ is to sync+roniDe access to static
data by loc7ing a private static ob&ect. *or eampleC
class Cac"e
{
&rivate static object sync"roni?ation%bject + ne, object();
&ublic static void 'dd(object #) {
loc( (Cac"e.sync"roni?ation%bject) {
...
!
!
&ublic static void Oemove(object #) {
loc( (Cac"e.sync"roni?ation%bject) {
...
!
!
!
0.13 T-e using stateent
T+e using statement obtains one or more resources- eecutes a statement- and t+en disposes o0 t+e resource.
!sing-state%ent.
u#i*+ ( reso!rce-ac8!isition ) e%,edded-state%ent
reso!rce-ac8!isition.
local-varia,le-declaration
e/pression
( reso-rce is a class or struct t+at implements System.$6is&osable- w+ic+ includes a single parameterless
met+od named 6is&ose. Code t+at is using a resource can call 6is&ose to indicate t+at t+e resource is no
longer needed. 10 6is&ose is not called- t+en automatic disposal eventually occurs as a conse9uence o0 garbage
collection.
10 t+e 0orm o0 reso!rce-ac8!isition is local-varia,le-declaration t+en t+e type o0 t+e local-varia,le-declaration
must be System.$6is&osable or a type t+at can be implicitly converted to System.$6is&osable. 10 t+e
0orm o0 reso!rce-ac8!isition is e/pression t+en t+is epression must be o0 type System.$6is&osable or a
type t+at can be implicitly converted to System.$6is&osable.
5ocal variables declared in a reso!rce-ac8!isition are read<only- and must include an initialiDer. ( compile<time
error occurs i0 t+e embedded statement attempts to modi0y t+ese local variables Jvia assignment or t+e << and
== operatorsM - ta7e t+e address o0 t+em- or pass t+em as re- or out parameters.
( using statement is translated into t+ree partsC ac9uisition- usage- and disposal. 8sage o0 t+e resource is
implicitly enclosed in a try statement t+at includes a -inally clause. T+is -inally clause disposes o0 t+e
resource. 10 a null resource is ac9uired- t+en no call to 6is&ose is made- and no eception is t+rown.
( using statement o0 t+e 0orm
using (Oesource1y&e resource + e#&ression) statement
corresponds to one o0 two possible epansions. 6+en Oesource1y&e is a value type- t+e epansion is
2$ Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
{
Oesource1y&e resource + e#&ression;
try {
statement;
!
-inally {
(($6is&osable)resource).6is&ose();
!
!
/t+erwise- w+en Oesource1y&e is a re0erence type- t+e epansion is
{
Oesource1y&e resource + e#&ression;
try {
statement;
!
-inally {
i- (resource @+ null) (($6is&osable)resource).6is&ose();
!
!
1n eit+er epansion- t+e resource variable is read<only in t+e embedded statement.
( using statement o0 t+e 0orm
using (e#&ression) statement
+as t+e same two possible epansions- but in t+is case Oesource1y&e is implicitly t+e compile<time type o0 t+e
e#&ression- and t+e resource variable is inaccessible in- and invisible to- t+e embedded statement.
6+en a reso!rce-ac8!isition ta7es t+e 0orm o0 a local-varia,le-declaration- it is possible to ac9uire multiple
resources o0 a given type. ( using statement o0 t+e 0orm
using (Oesource1y&e r2 + e2 r8 + e8 ... rN + eN) statement
is precisely e9uivalent to a se9uence o0 nested using statementsC
using (Oesource1y&e r2 + e2)
using (Oesource1y&e r8 + e8)
...
using (Oesource1y&e rN + eN)
statement
T+e eample below creates a 0ile named log.t#t and writes two lines o0 tet to t+e 0ile. T+e eample t+en
opens t+at same 0ile 0or reading and copies t+e contained lines o0 tet to t+e console.
using System;
using System.$%;
class 1est
{
static void Main() {
using (1e#tWriter , + Vile.Create1e#t("log.t#t")) {
,.WriteLine("1"is is line one");
,.WriteLine("1"is is line t,o");
!
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 2!
C# Language Specification
using (1e#tOeader r + Vile.%&en1e#t("log.t#t")) {
string s;
,"ile ((s + r.OeadLine()) @+ null) {
Console.WriteLine(s);
!
!
!
!
#ince t+e 1e#tWriter and 1e#tOeader classes implement t+e $6is&osable inter0ace- t+e eample can use
using statements to ensure t+at t+e underlying 0ile is properly closed 0ollowing t+e write or read operations.
0.1# T-e !ield stateent
T+e yield statement is used in an iterator bloc7 JV3.2M to yield a value to t+e enumerator ob&ect JV1..14.4M or
enumerable ob&ect JV1..14."M o0 an iterator or to signal t+e end o0 t+e iteration.
+ield-state%ent.
)ield %e$u%* e/pression A
)ield "%e!( A
yield is not a reserved wordQ it +as special meaning only w+en used immediately be0ore a return or brea(
7eyword. 1n ot+er contets- yield can be used as an identi0ier.
T+ere are several restrictions on w+ere a yield statement can appear- as described in t+e 0ollowing.
1t is a compile<time error 0or a yield statement Jo0 eit+er 0ormM to appear outside a %ethod-,od+- operator-
,od+ or accessor-,od+
1t is a compile<time error 0or a yield statement Jo0 eit+er 0ormM to appear inside an anonymous 0unction.
1t is a compile<time error 0or a yield statement Jo0 eit+er 0ormM to appear in t+e -inally clause o0 a try
statement.
1t is a compile<time error 0or a yield return statement to appear anyw+ere in a try statement t+at
contains any catc" clauses.
T+e 0ollowing eample s+ows some valid and invalid uses o0 yield statements.
delegate $)numerableDintE 6();
$)numeratorDintE Set)numerator() {
try {
yield return 2; .. %(
yield brea(; .. %(
!
-inally {
yield return 8; .. )rror yield in -inally
yield brea(; .. )rror yield in -inally
!
try {
yield return 9; .. )rror yield return in try...catc"
yield brea(; .. %(
!
catc" {
yield return J; .. )rror yield return in try...catc"
yield brea(; .. %(
!
2'* Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
6 d + delegate {
yield return K; .. )rror yield in an anonymous -unction
!;
!
int MyMet"od() {
yield return 2; .. )rror ,rong return ty&e -or an iterator bloc(
!
(n implicit conversion JV%.1M must eist 0rom t+e type o0 t+e epression in t+e yield return statement to t+e
yield type JV1..14.3M o0 t+e iterator.
( yield return statement is eecuted as 0ollowsC
T+e epression given in t+e statement is evaluated- implicitly converted to t+e yield type- and assigned to
t+e Current property o0 t+e enumerator ob&ect.
Eecution o0 t+e iterator bloc7 is suspended. 10 t+e yield return statement is wit+in one or more try
bloc7s- t+e associated -inally bloc7s are not eecuted at t+is time.
T+e MoveNe#t met+od o0 t+e enumerator ob&ect returns true to its caller- indicating t+at t+e enumerator
ob&ect success0ully advanced to t+e net item.
T+e net call to t+e enumerator ob&ectPs MoveNe#t met+od resumes eecution o0 t+e iterator bloc7 0rom w+ere
it was last suspended.
( yield brea( statement is eecuted as 0ollowsC
10 t+e yield brea( statement is enclosed by one or more try bloc7s wit+ associated -inally bloc7s-
control is initially trans0erred to t+e -inally bloc7 o0 t+e innermost try statement. 6+en and i0 control
reac+es t+e end point o0 a -inally bloc7- control is trans0erred to t+e -inally bloc7 o0 t+e net enclosing
try statement. T+is process is repeated until t+e -inally bloc7s o0 all enclosing try statements +ave been
eecuted.
Control is returned to t+e caller o0 t+e iterator bloc7. T+is is eit+er t+e MoveNe#t met+od or 6is&ose
met+od o0 t+e enumerator ob&ect.
)ecause a yield brea( statement unconditionally trans0ers control elsew+ere- t+e end point o0 a yield brea(
statement is never reac+able.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 2'1
C# Language Specification
1. ;aespaces
C# programs are organiDed using namespaces. =amespaces are used bot+ as an KinternalL organiDation system
0or a program- and as an KeternalL organiDation systemRa way o0 presenting program elements t+at are
eposed to ot+er programs.
8sing directives JV$.4M are provided to 0acilitate t+e use o0 namespaces.
1.1 Copilation units
( co%pilation-!nit de0ines t+e overall structure o0 a source 0ile. ( compilation unit consists o0 Dero or more
!sing-directives 0ollowed by Dero or more glo,al-attri,!tes 0ollowed by Dero or more na%espace-%e%,er-
declarations.
co%pilation-!nit.
e/tern-alias-directivesopt !sing-directivesopt glo,al-attri,!tesopt
na%espace-%e%,er-declarationsopt
( C# program consists o0 one or more compilation units- eac+ contained in a separate source 0ile. 6+en a C#
program is compiled- all o0 t+e compilation units are processed toget+er. T+us- compilation units can depend on
eac+ ot+er- possibly in a circular 0as+ion.
T+e !sing-directives o0 a compilation unit a00ect t+e glo,al-attri,!tes and na%espace-%e%,er-declarations o0
t+at compilation unit- but +ave no e00ect on ot+er compilation units.
T+e glo,al-attri,!tes JV1!M o0 a compilation unit permit t+e speci0ication o0 attributes 0or t+e target assembly
and module. (ssemblies and modules act as p+ysical containers 0or types. (n assembly may consist o0 several
p+ysically separate modules.
T+e na%espace-%e%,er-declarations o0 eac+ compilation unit o0 a program contribute members to a single
declaration space called t+e global namespace. *or eampleC
*ile '.csC
class ' {!
*ile :.csC
class : {!
T+e two compilation units contribute to t+e single global namespace- in t+is case declaring two classes wit+ t+e
0ully 9uali0ied names ' and :. )ecause t+e two compilation units contribute to t+e same declaration space- it
would +ave been an error i0 eac+ contained a declaration o0 a member wit+ t+e same name.
1.2 ;aespace declarations
( na%espace-declaration consists o0 t+e 7eyword names&ace- 0ollowed by a namespace name and body-
optionally 0ollowed by a semicolon.
na%espace-declaration.
*!me#.!&e 8!alified-identifier na%espace-,od+ Aopt
2'2 Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
8!alified-identifier.
identifier
8!alified-identifier 9 identifier
na%espace-,od+.
{ e/tern-alias-directivesopt !sing-directivesopt na%espace-%e%,er-declarationsopt }
( na%espace-declaration may occur as a top<level declaration in a co%pilation-!nit or as a member declaration
wit+in anot+er na%espace-declaration. 6+en a na%espace-declaration occurs as a top<level declaration in a
co%pilation-!nit- t+e namespace becomes a member o0 t+e global namespace. 6+en a na%espace-declaration
occurs wit+in anot+er na%espace-declaration- t+e inner namespace becomes a member o0 t+e outer namespace.
1n eit+er case- t+e name o0 a namespace must be uni9ue wit+in t+e containing namespace.
=amespaces are implicitly &ublic and t+e declaration o0 a namespace cannot include any access modi0iers.
6it+in a na%espace-,od+- t+e optional !sing-directives import t+e names o0 ot+er namespaces and types-
allowing t+em to be re0erenced directly instead o0 t+roug+ 9uali0ied names. T+e optional na%espace-%e%,er-
declarations contribute members to t+e declaration space o0 t+e namespace. =ote t+at all !sing-directives must
appear be0ore any member declarations.
T+e 8!alified-identifier o0 a na%espace-declaration may be a single identi0ier or a se9uence o0 identi0iers
separated by K.L to7ens. T+e latter 0orm permits a program to de0ine a nested namespace wit+out leically
nesting several namespace declarations. *or eample-
names&ace N2.N8
{
class ' {!
class : {!
!
is semantically e9uivalent to
names&ace N2
{
names&ace N8
{
class ' {!
class : {!
!
!
=amespaces are open<ended- and two namespace declarations wit+ t+e same 0ully 9uali0ied name contribute to
t+e same declaration space JV3.3M. 1n t+e eample
names&ace N2.N8
{
class ' {!
!
names&ace N2.N8
{
class : {!
!
t+e two namespace declarations above contribute to t+e same declaration space- in t+is case declaring two
classes wit+ t+e 0ully 9uali0ied names N2.N8.' and N2.N8.:. )ecause t+e two declarations contribute to t+e
same declaration space- it would +ave been an error i0 eac+ contained a declaration o0 a member wit+ t+e same
name.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 2'3
C# Language Specification
1.3 $%tern aliases
(n e/tern-alias-directive introduces an identi0ier t+at serves as an alias 0or a namespace. T+e speci0ication o0
t+e aliased namespace is eternal to t+e source code o0 t+e program and applies also to nested namespaces o0 t+e
aliased namespace.
e/tern-alias-directives.
e/tern-alias-directive
e/tern-alias-directives e/tern-alias-directive
e/tern-alias-directive.
e-$e%* !li!# identifier A
T+e scope o0 an e/tern-alias-directive etends over t+e !sing-directives- glo,al-attri,!tes and na%espace-
%e%,er-declarations o0 its immediately containing compilation unit or namespace body.
6it+in a compilation unit or namespace body t+at contains an e/tern-alias-directive- t+e identi0ier introduced by
t+e e/tern-alias-directive can be used to re0erence t+e aliased namespace. 1t is a compile<time error 0or t+e
identifier to be t+e word global.
(n e/tern-alias-directive ma7es an alias available wit+in a particular compilation unit or namespace body- but it
does not contribute any new members to t+e underlying declaration space. 1n ot+er words- an e/tern-alias-
directive is not transitive- but- rat+er- a00ects only t+e compilation unit or namespace body in w+ic+ it occurs.
T+e 0ollowing program declares and uses two etern aliases- I and `- eac+ o0 w+ic+ represent t+e root o0 a
distinct namespace +ierarc+yC
e#tern alias I;
e#tern alias `;
class 1est
{
I//N.' a;
I//N.: b2;
`//N.: b8;
`//N.C c;
!
T+e program declares t+e eistence o0 t+e etern aliases I and `- but t+e actual de0initions o0 t+e aliases are
eternal to t+e program. T+e identically named N.: classes can now be re0erenced as I.N.: and `.N.:- or-
using t+e namespace alias 9uali0ier- I//N.: and `//N.:. (n error occurs i0 a program declares an etern alias
0or w+ic+ no eternal de0inition is provided.
1.# 6sing directi"es
8sing directives 0acilitate t+e use o0 namespaces and types de0ined in ot+er namespaces. 8sing directives
impact t+e name resolution process o0 na%espace-or-t+pe-na%es JV3.3M and si%ple-na%es JV!.".2M- but unli7e
declarations- using directives do not contribute new members to t+e underlying declaration spaces o0 t+e
compilation units or namespaces wit+in w+ic+ t+ey are used.
!sing-directives.
!sing-directive
!sing-directives !sing-directive
!sing-directive.
!sing-alias-directive
!sing-na%espace-directive
( !sing-alias-directive JV$.4.1M introduces an alias 0or a namespace or type.
2'" Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
( !sing-na%espace-directive JV$.4.2M imports t+e type members o0 a namespace.
T+e scope o0 a !sing-directive etends over t+e na%espace-%e%,er-declarations o0 its immediately containing
compilation unit or namespace body. T+e scope o0 a !sing-directive speci0ically does not include its peer !sing-
directives. T+us- peer !sing-directives do not a00ect eac+ ot+er- and t+e order in w+ic+ t+ey are written is
insigni0icant.
1.#.1 6sing alias directi"es
( !sing-alias-directive introduces an identi0ier t+at serves as an alias 0or a namespace or type wit+in t+e
immediately enclosing compilation unit or namespace body.
!sing-alias-directive.
u#i*+ identifier H na%espace-or-t+pe-na%e A
6it+in member declarations in a compilation unit or namespace body t+at contains a !sing-alias-directive- t+e
identi0ier introduced by t+e !sing-alias-directive can be used to re0erence t+e given namespace or type. *or
eampleC
names&ace N2.N8
{
class ' {!
!
names&ace N9
{
using ' + N2.N8.';
class :/ ' {!
!
(bove- wit+in member declarations in t+e N9 namespace- ' is an alias 0or N2.N8.'- and t+us class N9.: derives
0rom class N2.N8.'. T+e same e00ect can be obtained by creating an alias O 0or N2.N8 and t+en re0erencing
O.'C
names&ace N9
{
using O + N2.N8;
class :/ O.' {!
!
T+e identifier o0 a !sing-alias-directive must be uni9ue wit+in t+e declaration space o0 t+e compilation unit or
namespace t+at immediately contains t+e !sing-alias-directive. *or eampleC
names&ace N9
{
class ' {!
!
names&ace N9
{
using ' + N2.N8.'; .. )rror ' already e#ists
!
(bove- N9 already contains a member '- so it is a compile<time error 0or a !sing-alias-directive to use t+at
identi0ier. 5i7ewise- it is a compile<time error 0or two or more !sing-alias-directives in t+e same compilation
unit or namespace body to declare aliases by t+e same name.
( !sing-alias-directive ma7es an alias available wit+in a particular compilation unit or namespace body- but it
does not contribute any new members to t+e underlying declaration space. 1n ot+er words- a !sing-alias-
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 2'
C# Language Specification
directive is not transitive but rat+er a00ects only t+e compilation unit or namespace body in w+ic+ it occurs. 1n
t+e eample
names&ace N9
{
using O + N2.N8;
!
names&ace N9
{
class :/ O.' {! .. )rror O un(no,n
!
t+e scope o0 t+e !sing-alias-directive t+at introduces O only etends to member declarations in t+e namespace
body in w+ic+ it is contained- so O is un7nown in t+e second namespace declaration. However- placing t+e
!sing-alias-directive in t+e containing compilation unit causes t+e alias to become available wit+in bot+
namespace declarationsC
using O + N2.N8;
names&ace N9
{
class :/ O.' {!
!
names&ace N9
{
class C/ O.' {!
!
Fust li7e regular members- names introduced by !sing-alias-directives are +idden by similarly named members
in nested scopes. 1n t+e eample
using O + N2.N8;
names&ace N9
{
class O {!
class :/ O.' {! .. )rror O "as no member '
!
t+e re0erence to O.' in t+e declaration o0 : causes a compile<time error because O re0ers to N9.O- not N2.N8.
T+e order in w+ic+ !sing-alias-directives are written +as no signi0icance- and resolution o0 t+e na%espace-or-
t+pe-na%e re0erenced by a !sing-alias-directive is not a00ected by t+e !sing-alias-directive itsel0 or by ot+er
!sing-directives in t+e immediately containing compilation unit or namespace body. 1n ot+er words- t+e
na%espace-or-t+pe-na%e o0 a !sing-alias-directive is resolved as i0 t+e immediately containing compilation unit
or namespace body +ad no !sing-directives. ( !sing-alias-directive may +owever be a00ected by e/tern-alias-
directives in t+e immediately containing compilation unit or namespace body. 1n t+e eample
names&ace N2.N8 {!
names&ace N9
{
e#tern alias );
using O2 + ).N; .. %a
using O8 + N2; .. %a
using O9 + N2.N8; .. %a
2'' Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
using OJ + O8.N8; .. )rror O8 un(no,n
!
t+e last !sing-alias-directive results in a compile<time error because it is not a00ected by t+e 0irst !sing-alias-
directive. T+e 0irst !sing-alias-directive does not result in an error since t+e scope o0 t+e etern alias ) includes
t+e !sing-alias-directive.
( !sing-alias-directive can create an alias 0or any namespace or type- including t+e namespace wit+in w+ic+ it
appears and any namespace or type nested wit+in t+at namespace.
(ccessing a namespace or type t+roug+ an alias yields eactly t+e same result as accessing t+at namespace or
type t+roug+ its declared name. *or eample- given
names&ace N2.N8
{
class ' {!
!
names&ace N9
{
using O2 + N2;
using O8 + N2.N8;
class :
{
N2.N8.' a; .. re-ers to N2.N8.'
O2.N8.' b; .. re-ers to N2.N8.'
O8.' c; .. re-ers to N2.N8.'
!
!
t+e names N2.N8.'- O2.N8.'- and O8.' are e9uivalent and all re0er to t+e class w+ose 0ully 9uali0ied name is
N2.N8.'.
8sing aliases can name a closed constructed type- but cannot name an unbound generic type declaration wit+out
supplying type arguments. *or eampleC
names&ace N2
{
class 'D1E
{
class : {!
!
!
names&ace N8
{
using W + N2.'; .. )rror cannot name unbound generic ty&e
using I + N2.'.:; .. )rror cannot name unbound generic ty&e
using ` + N2.'DintE; .. %( can name closed constructed ty&e
using PD1E + N2.'D1E; .. )rror using alias cannot "ave ty&e &arameters
!
1.#.2 6sing naespace directi"es
( !sing-na%espace-directive imports t+e types contained in a namespace into t+e immediately enclosing
compilation unit or namespace body- enabling t+e identi0ier o0 eac+ type to be used wit+out 9uali0ication.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 2'7
C# Language Specification
!sing-na%espace-directive.
u#i*+ na%espace-na%e A
6it+in member declarations in a compilation unit or namespace body t+at contains a !sing-na%espace-
directive- t+e types contained in t+e given namespace can be re0erenced directly. *or eampleC
names&ace N2.N8
{
class ' {!
!
names&ace N9
{
using N2.N8;
class :/ ' {!
!
(bove- wit+in member declarations in t+e N9 namespace- t+e type members o0 N2.N8 are directly available- and
t+us class N9.: derives 0rom class N2.N8.'.
( !sing-na%espace-directive imports t+e types contained in t+e given namespace- but speci0ically does not
import nested namespaces. 1n t+e eample
names&ace N2.N8
{
class ' {!
!
names&ace N9
{
using N2;
class :/ N8.' {! .. )rror N8 un(no,n
!
t+e !sing-na%espace-directive imports t+e types contained in N2- but not t+e namespaces nested in N2. T+us- t+e
re0erence to N8.' in t+e declaration o0 : results in a compile<time error because no members named N8 are in
scope.
8nli7e a !sing-alias-directive- a !sing-na%espace-directive may import types w+ose identi0iers are already
de0ined wit+in t+e enclosing compilation unit or namespace body. 1n e00ect- names imported by a !sing-
na%espace-directive are +idden by similarly named members in t+e enclosing compilation unit or namespace
body. *or eampleC
names&ace N2.N8
{
class ' {!
class : {!
!
names&ace N9
{
using N2.N8;
class ' {!
!
Here- wit+in member declarations in t+e N9 namespace- ' re0ers to N9.' rat+er t+an N2.N8.'.
2'$ Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
6+en more t+an one namespace imported by !sing-na%espace-directives in t+e same compilation unit or
namespace body contain types by t+e same name- re0erences to t+at name are considered ambiguous. 1n t+e
eample
names&ace N2
{
class ' {!
!
names&ace N8
{
class ' {!
!
names&ace N9
{
using N2;
using N8;
class :/ ' {! .. )rror ' is ambiguous
!
bot+ N2 and N8 contain a member '- and because N9 imports bot+- re0erencing ' in N9 is a compile<time error.
1n t+is situation- t+e con0lict can be resolved eit+er t+roug+ 9uali0ication o0 re0erences to '- or by introducing a
!sing-alias-directive t+at pic7s a particular '. *or eampleC
names&ace N9
{
using N2;
using N8;
using ' + N2.';
class :/ ' {! .. ' means N2.'
!
5i7e a !sing-alias-directive- a !sing-na%espace-directive does not contribute any new members to t+e
underlying declaration space o0 t+e compilation unit or namespace- but rat+er a00ects only t+e compilation unit
or namespace body in w+ic+ it appears.
T+e na%espace-na%e re0erenced by a !sing-na%espace-directive is resolved in t+e same way as t+e na%espace-
or-t+pe-na%e re0erenced by a !sing-alias-directive. T+us- !sing-na%espace-directives in t+e same compilation
unit or namespace body do not a00ect eac+ ot+er and can be written in any order.
1.& ;aespace ebers
( na%espace-%e%,er-declaration is eit+er a na%espace-declaration JV$.2M or a t+pe-declaration JV$.%M.
na%espace-%e%,er-declarations.
na%espace-%e%,er-declaration
na%espace-%e%,er-declarations na%espace-%e%,er-declaration
na%espace-%e%,er-declaration.
na%espace-declaration
t+pe-declaration
( compilation unit or a namespace body can contain na%espace-%e%,er-declarations- and suc+ declarations
contribute new members to t+e underlying declaration space o0 t+e containing compilation unit or namespace
body.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 2'!
C# Language Specification
1.' T!pe declarations
( t+pe-declaration is a class-declaration JV1..1M- a str!ct-declaration JV11.1M- an interface-declaration JV13.1M-
an en!%-declaration JV14.1M- or a delegate-declaration JV1".1M.
t+pe-declaration.
class-declaration
str!ct-declaration
interface-declaration
en!%-declaration
delegate-declaration
( t+pe-declaration can occur as a top<level declaration in a compilation unit or as a member declaration wit+in a
namespace- class- or struct.
6+en a type declaration 0or a type 1 occurs as a top<level declaration in a compilation unit- t+e 0ully 9uali0ied
name o0 t+e newly declared type is simply 1. 6+en a type declaration 0or a type 1 occurs wit+in a namespace-
class- or struct- t+e 0ully 9uali0ied name o0 t+e newly declared type is N.1- w+ere N is t+e 0ully 9uali0ied name o0
t+e containing namespace- class- or struct.
( type declared wit+in a class or struct is called a nested type JV1..3.3M.
T+e permitted access modi0iers and t+e de0ault access 0or a type declaration depend on t+e contet in w+ic+ t+e
declaration ta7es place JV3.".1MC
Types declared in compilation units or namespaces can +ave &ublic or internal access. T+e de0ault is
internal access.
Types declared in classes can +ave &ublic- &rotected internal- &rotected- internal- or &rivate
access. T+e de0ault is &rivate access.
Types declared in structs can +ave &ublic- internal- or &rivate access. T+e de0ault is &rivate access.
1.. ;aespace alias 7ualifiers
T+e naespace alias 4-alifier // ma7es it possible to guarantee t+at type name loo7ups are una00ected by t+e
introduction o0 new types and members. T+e namespace alias 9uali0ier always appears between two identi0iers
re0erred to as t+e le0t<+and and rig+t<+and identi0iers. 8nli7e t+e regular . 9uali0ier- t+e le0t<+and identi0ier o0
t+e // 9uali0ier is loo7ed up only as an etern or using alias.
( 8!alified-alias-%e%,er is de0ined as 0ollowsC
8!alified-alias-%e%,er.
identifier @@ identifier t+pe-arg!%ent-listopt
( 8!alified-alias-%e%,er can be used as a na%espace-or-t+pe-na%e JV3.3M or as t+e le0t operand in a %e%,er-
access JV!.".4M.
( 8!alified-alias-%e%,er +as one o0 two 0ormsC
N//$D'
2
... '
a
E- w+ere N and $ represent identi0iers- and D'
2
... '
a
E is a type argument list. Ja is
always at least one.M
N//$ w+ere N and $ represent identi0iers. J1n t+is case- a is considered to be Dero.M
8sing t+is notation- t+e meaning o0 a 8!alified-alias-%e%,er is determined as 0ollowsC
10 N is t+e identi0ier global- t+en t+e global namespace is searc+ed 0or $C
27* Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
o 10 t+e global namespace contains a namespace named $ and a is Dero- t+en t+e 8!alified-alias-%e%,er
re0ers to t+at namespace.
o /t+erwise- i0 t+e global namespace contains a non<generic type named $ and a is Dero- t+en t+e
8!alified-alias-%e%,er re0ers to t+at type.
o /t+erwise- i0 t+e global namespace contains a type named $ t+at +as a type parameters- t+en t+e
8!alified-alias-%e%,er re0ers to t+at type constructed wit+ t+e given type arguments.
o /t+erwise- t+e 8!alified-alias-%e%,er is unde0ined and a compile<time error occurs.
/t+erwise- starting wit+ t+e namespace declaration JV$.2M immediately containing t+e 8!alified-alias-
%e%,er Ji0 anyM- continuing wit+ eac+ enclosing namespace declaration Ji0 anyM- and ending wit+ t+e
compilation unit containing t+e 8!alified-alias-%e%,er- t+e 0ollowing steps are evaluated until an entity is
locatedC
o 10 t+e namespace declaration or compilation unit contains a !sing-alias-directive t+at associates N wit+ a
type- t+en t+e 8!alified-alias-%e%,er is unde0ined and a compile<time error occurs.
o /t+erwise- i0 t+e namespace declaration or compilation unit contains an e/tern-alias-directive or !sing-
alias-directive t+at associates N wit+ a namespace- t+enC
10 t+e namespace associated wit+ N contains a namespace named $ and a is Dero- t+en t+e 8!alified-
alias-%e%,er re0ers to t+at namespace.
/t+erwise- i0 t+e namespace associated wit+ N contains a non<generic type named $ and a is Dero-
t+en t+e 8!alified-alias-%e%,er re0ers to t+at type.
/t+erwise- i0 t+e namespace associated wit+ N contains a type named $ t+at +as a type parameters-
t+en t+e 8!alified-alias-%e%,er re0ers to t+at type constructed wit+ t+e given type arguments.
/t+erwise- t+e 8!alified-alias-%e%,er is unde0ined and a compile<time error occurs.
/t+erwise- t+e 8!alified-alias-%e%,er is unde0ined and a compile<time error occurs.
=ote t+at using t+e namespace alias 9uali0ier wit+ an alias t+at re0erences a type causes a compile<time error.
(lso note t+at i0 t+e identi0ier N is global- t+en loo7up is per0ormed in t+e global namespace- even i0 t+ere is a
using alias associating global wit+ a type or namespace.
1...1 6ni7ueness of aliases
Eac+ compilation unit and namespace body +as a separate declaration space 0or etern aliases and using aliases.
T+us- w+ile t+e name o0 an etern alias or using alias must be uni9ue wit+in t+e set o0 etern aliases and using
aliases declared in t+e immediately containing compilation unit or namespace body- an alias is permitted to +ave
t+e same name as a type or namespace as long as it is used only wit+ t+e // 9uali0ier.
1n t+e eample
names&ace N
{
&ublic class ' {!
&ublic class : {!
!
names&ace N
{
using ' + System.$%;
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 271
C# Language Specification
class I
{
'.Stream s2; .. )rror ' is ambiguous
'//Stream s8; .. %(
!
!
t+e name ' +as two possible meanings in t+e second namespace body because bot+ t+e class ' and t+e using
alias ' are in scope. *or t+is reason- use o0 ' in t+e 9uali0ied name '.Stream is ambiguous and causes a
compile<time error to occur. However- use o0 ' wit+ t+e // 9uali0ier is not an error because ' is loo7ed up only
as a namespace alias.
272 Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
10. Classes
( class is a data structure t+at may contain data members Jconstants and 0ieldsM- 0unction members Jmet+ods-
properties- events- indeers- operators- instance constructors- destructors and static constructorsM- and nested
types. Class types support in+eritance- a mec+anism w+ereby a derived class can etend and specialiDe a base
class.
10.1 Class declarations
( class-declaration is a t+pe-declaration JV$.%M t+at declares a new class.
class-declaration.
attri,!tesopt class-%odifiersopt .!%$i!lopt &l!## identifier t+pe-para%eter-listopt
class-,aseopt t+pe-para%eter-constraints-cla!sesopt class-,od+ Aopt
( class-declaration consists o0 an optional set o0 attri,!tes JV1!M- 0ollowed by an optional set o0 class-%odifiers
JV1..1.1M- 0ollowed by an optional &artial modi0ier- 0ollowed by t+e 7eyword class and an identifier t+at
names t+e class- 0ollowed by an optional t+pe-para%eter-list JV1..1.3M- 0ollowed by an optional class-,ase
speci0ication JV1..1.4M - 0ollowed by an optional set o0 t+pe-para%eter-constraints-cla!ses JV1..1."M- 0ollowed
by a class-,od+ JV1..1.%M- optionally 0ollowed by a semicolon.
( class declaration cannot supply t+pe-para%eter-constraints-cla!ses unless it also supplies a t+pe-para%eter-
list.
( class declaration t+at supplies a t+pe-para%eter-list is a generic class declaration. (dditionally- any class
nested inside a generic class declaration or a generic struct declaration is itsel0 a generic class declaration- since
type parameters 0or t+e containing type must be supplied to create a constructed type.
10.1.1 Class odifiers
( class-declaration may optionally include a se9uence o0 class modi0iersC
class-%odifiers.
class-%odifier
class-%odifiers class-%odifier
class-%odifier.
*ew
.u"li&
.%'$e&$ed
i*$e%*!l
.%i,!$e
!"#$%!&$
#e!led
#$!$i&
1t is a compile<time error 0or t+e same modi0ier to appear multiple times in a class declaration.
T+e ne, modi0ier is permitted on nested classes. 1t speci0ies t+at t+e class +ides an in+erited member by t+e
same name- as described in V1..3.4. 1t is a compile<time error 0or t+e ne, modi0ier to appear on a class
declaration t+at is not a nested class declaration.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 273
C# Language Specification
T+e &ublic- &rotected- internal- and &rivate modi0iers control t+e accessibility o0 t+e class. 2epending
on t+e contet in w+ic+ t+e class declaration occurs- some o0 t+ese modi0iers may not be permitted JV3.".1M.
T+e abstract- sealed and static modi0iers are discussed in t+e 0ollowing sections.
14.1.1.1 ?bstract classes
T+e abstract modi0ier is used to indicate t+at a class is incomplete and t+at it is intended to be used only as a
base class. (n abstract class di00ers 0rom a non<abstract class in t+e 0ollowing waysC
(n abstract class cannot be instantiated directly- and it is a compile<time error to use t+e ne, operator on an
abstract class. 6+ile it is possible to +ave variables and values w+ose compile<time types are abstract- suc+
variables and values will necessarily eit+er be null or contain re0erences to instances o0 non<abstract
classes derived 0rom t+e abstract types.
(n abstract class is permitted Jbut not re9uiredM to contain abstract members.
(n abstract class cannot be sealed.
6+en a non<abstract class is derived 0rom an abstract class- t+e non<abstract class must include actual
implementations o0 all in+erited abstract members- t+ereby overriding t+ose abstract members. 1n t+e eample
abstract class '
{
&ublic abstract void V();
!
abstract class :/ '
{
&ublic void S() {!
!
class C/ :
{
&ublic override void V() {
.. actual im&lementation o- V
!
!
t+e abstract class ' introduces an abstract met+od V. Class : introduces an additional met+od S- but since it
doesnPt provide an implementation o0 V- : must also be declared abstract. Class C overrides V and provides an
actual implementation. #ince t+ere are no abstract members in C- C is permitted Jbut not re9uiredM to be non<
abstract.
14.1.1.2 Sealed classes
T+e sealed modi0ier is used to prevent derivation 0rom a class. ( compile<time error occurs i0 a sealed class is
speci0ied as t+e base class o0 anot+er class.
( sealed class cannot also be an abstract class.
T+e sealed modi0ier is primarily used to prevent unintended derivation- but it also enables certain run<time
optimiDations. 1n particular- because a sealed class is 7nown to never +ave any derived classes- it is possible to
trans0orm virtual 0unction member invocations on sealed class instances into non<virtual invocations.
27" Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
14.1.1.3 Static classes
T+e static modi0ier is used to mar7 t+e class being declared as a static class.( static class cannot be
instantiated- cannot be used as a type and can contain only static members. /nly a static class can contain
declarations o0 etension met+ods JV1..%.$M.
( static class declaration is sub&ect to t+e 0ollowing restrictionsC
( static class may not include a sealed or abstract modi0ier. =ote- +owever- t+at since a static class
cannot be instantiated or derived 0rom- it be+aves as i0 it was bot+ sealed and abstract.
( static class may not include a class-,ase speci0ication JV1..1.4M and cannot eplicitly speci0y a base class
or a list o0 implemented inter0aces. ( static class implicitly in+erits 0rom type object.
( static class can only contain static members JV1..3.!M. =ote t+at constants and nested types are classi0ied
as static members.
( static class cannot +ave members wit+ &rotected or &rotected internal declared accessibility.
1t is a compile<time error to violate any o0 t+ese restrictions.
( static class +as no instance constructors. 1t is not possible to declare an instance constructor in a static class-
and no de0ault instance constructor JV1..11.4M is provided 0or a static class.
T+e members o0 a static class are not automatically static- and t+e member declarations must eplicitly include a
static modi0ier Jecept 0or constants and nested typesM. 6+en a class is nested wit+in a static outer class- t+e
nested class is not a static class unless it eplicitly includes a static modi0ier.
14.1.1.3.1 )e/erencing static class ty"es
( na%espace-or-t+pe-na%e JV3.3M is permitted to re0erence a static class i0
T+e na%espace-or-t+pe-na%e is t+e 1 in a na%espace-or-t+pe-na%e o0 t+e 0orm 1.$- or
T+e na%espace-or-t+pe-na%e is t+e 1 in a t+peof-e/pression JV!.".11M o0 t+e 0orm ty&eo-(1).
( pri%ar+-e/pression JV!."M is permitted to re0erence a static class i0
T+e pri%ar+-e/pression is t+e ) in a %e%,er-access JV!.".4M o0 t+e 0orm ).$.
1n any ot+er contet it is a compile<time error to re0erence a static class. *or eample- it is an error 0or a static
class to be used as a base class- a constituent type JV1..3.3M o0 a member- a generic type argument- or a type
parameter constraint. 5i7ewise- a static class cannot be used in an array type- a pointer type- a ne, epression- a
cast epression- an is epression- an as epression- a si?eo- epression- or a de0ault value epression.
10.1.2 Partial odifier
T+e &artial modi0ier is used to indicate t+at t+is class-declaration is a partial type declaration. 'ultiple
partial type declarations wit+ t+e same name wit+in an enclosing namespace or type declaration combine to
0orm one type declaration- 0ollowing t+e rules speci0ied in V1..2.
Having t+e declaration o0 a class distributed over separate segments o0 program tet can be use0ul i0 t+ese
segments are produced or maintained in di00erent contets. *or instance- one part o0 a class declaration may be
mac+ine generated- w+ereas t+e ot+er is manually aut+ored. Tetual separation o0 t+e two prevents updates by
one 0rom con0licting wit+ updates by t+e ot+er.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 27
C# Language Specification
10.1.3 T!pe paraeters
( type parameter is a simple identi0ier t+at denotes a place+older 0or a type argument supplied to create a
constructed type. ( type parameter is a 0ormal place+older 0or a type t+at will be supplied later. )y constrast- a
type argument JV4.4.1M is t+e actual type t+at is substituted 0or t+e type parameter w+en a constructed type is
created.
t+pe-para%eter-list.
I t+pe-para%eters J
t+pe-para%eters.
attri,!tesopt t+pe-para%eter
t+pe-para%eters ? attri,!tesopt t+pe-para%eter
t+pe-para%eter.
identifier
Eac+ type parameter in a class declaration de0ines a name in t+e declaration space JV3.3M o0 t+at class. T+us- it
cannot +ave t+e same name as anot+er type parameter or a member declared in t+at class. ( type parameter
cannot +ave t+e same name as t+e type itsel0.
10.1.# Class base specification
( class declaration may include a class-,ase speci0ication- w+ic+ de0ines t+e direct base class o0 t+e class and
t+e inter0aces JV13M implemented by t+e class.
class-,ase.
@ class-t+pe
@ interface-t+pe-list
@ class-t+pe ? interface-t+pe-list
interface-t+pe-list.
interface-t+pe
interface-t+pe-list ? interface-t+pe
T+e base class speci0ied in a class declaration can be a constructed class type JV4.4M. ( base class cannot be a
type parameter on its own- t+oug+ it can involve t+e type parameters t+at are in scope.
class )#tendDUE/ U {! .. )rror ty&e &arameter used as base class
14.1.4.1 (ase classes
6+en a class-t+pe is included in t+e class-,ase- it speci0ies t+e direct base class o0 t+e class being declared. 10 a
class declaration +as no class-,ase- or i0 t+e class-,ase lists only inter0ace types- t+e direct base class is assumed
to be object. ( class in+erits members 0rom its direct base class- as described in V1..3.3.
1n t+e eample
class ' {!
class :/ ' {!
class ' is said to be t+e direct base class o0 :- and : is said to be derived 0rom '. #ince ' does not eplicitly
speci0y a direct base class- its direct base class is implicitly object.
*or a constructed class type- i0 a base class is speci0ied in t+e generic class declaration- t+e base class o0 t+e
constructed type is obtained by substituting- 0or eac+ t+pe-para%eter in t+e base class declaration- t+e
corresponding t+pe-arg!%ent o0 t+e constructed type. 4iven t+e generic class declarations
class :D;UE {...!
27' Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
class SD1E/ :Dstring145E {...!
t+e base class o0 t+e constructed type SDintE would be :Dstringint45E.
T+e direct base class o0 a class type must be at least as accessible as t+e class type itsel0 JV3.".2M. *or eample- it
is a compile<time error 0or a &ublic class to derive 0rom a &rivate or internal class.
T+e direct base class o0 a class type must not be any o0 t+e 0ollowing typesC System.'rray-
System.6elegate- System.Multicast6elegate- System.)num- or System.Ualue1y&e. *urt+ermore- a
generic class declaration cannot use System.'ttribute as a direct or indirect base class.
T+e base classes o0 a class type are t+e direct base class and its base classes. 1n ot+er words- t+e set o0 base
classes is t+e transitive closure o0 t+e direct base class relations+ip. ;e0erring to t+e eample above- t+e base
classes o0 : are ' and object. 1n t+e eample
class ' {...!
class :D1E/ ' {...!
class CD1E/ :D$Com&arableD1EE {...!
class 6D1E/ CD145E {...!
t+e base classes o0 6DintE are CDint45E- :D$Com&arableDint45EE- '- and object.
Ecept 0or class object- every class type +as eactly one direct base class. T+e object class +as no direct base
class and is t+e ultimate base class o0 all ot+er classes.
6+en a class : derives 0rom a class '- it is a compile<time error 0or ' to depend on :. ( class directly depends
on its direct base class Ji0 anyM and directly depends on t+e class wit+in w+ic+ it is immediately nested Ji0 anyM.
4iven t+is de0inition- t+e complete set o0 classes upon w+ic+ a class depends is t+e transitive closure o0 t+e
directly depends on relations+ip.
T+e eample
class '/ : {!
class :/ C {!
class C/ ' {!
is in error because t+e classes circularly depend on t+emselves. 5i7ewise- t+e eample
class '/ :.C {!
class :/ '
{
&ublic class C {!
!
results in a compile<time error because ' depends on :.C Jits direct base classM- w+ic+ depends on : Jits
immediately enclosing classM- w+ic+ circularly depends on '.
=ote t+at a class does not depend on t+e classes t+at are nested wit+in it. 1n t+e eample
class '
{
class :/ ' {!
!
: depends on ' Jbecause ' is bot+ its direct base class and its immediately enclosing classM- but ' does not
depend on : Jsince : is neit+er a base class nor an enclosing class o0 'M. T+us- t+e eample is valid.
1t is not possible to derive 0rom a sealed class. 1n t+e eample
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 277
C# Language Specification
sealed class ' {!
class :/ ' {! .. )rror cannot derive -rom a sealed class
class : is in error because it attempts to derive 0rom t+e sealed class '.
14.1.4.2 #nter/ace im"lementations
( class-,ase speci0ication may include a list o0 inter0ace types- in w+ic+ case t+e class is said to implement t+e
given inter0ace types. 1nter0ace implementations are discussed 0urt+er in V13.4.
10.1.& T!pe paraeter constraints
4eneric type and met+od declarations can optionally speci0y type parameter constraints by including t+pe-
para%eter-constraints-cla!ses.
t+pe-para%eter-constraints-cla!ses.
t+pe-para%eter-constraints-cla!se
t+pe-para%eter-constraints-cla!ses t+pe-para%eter-constraints-cla!se
t+pe-para%eter-constraints-cla!se.
whe%e t+pe-para%eter @ t+pe-para%eter-constraints
t+pe-para%eter-constraints.
pri%ar+-constraint
secondar+-constraints
constr!ctor-constraint
pri%ar+-constraint ? secondar+-constraints
pri%ar+-constraint ? constr!ctor-constraint
secondar+-constraints ? constr!ctor-constraint
pri%ar+-constraint ? secondar+-constraints ? constr!ctor-constraint
pri%ar+-constraint.
class-t+pe
&l!##
#$%u&$
secondar+-constraints.
interface-t+pe
t+pe-para%eter
secondar+-constraints ? interface-t+pe
secondar+-constraints ? t+pe-para%eter
constr!ctor-constraint.
*ew ( )
Eac+ t+pe-para%eter-constraints-cla!se consists o0 t+e to7en ,"ere- 0ollowed by t+e name o0 a type parameter-
0ollowed by a colon and t+e list o0 constraints 0or t+at type parameter. T+ere can be at most one ,"ere clause
0or eac+ type parameter- and t+e ,"ere clauses can be listed in any order. 5i7e t+e get and set to7ens in a
property accessor- t+e ,"ere to7en is not a 7eyword.
T+e list o0 constraints given in a ,"ere clause can include any o0 t+e 0ollowing components- in t+is orderC a
single primary constraint- one or more secondary constraints- and t+e constructor constraint- ne,().
( primary constraint can be a class type or t+e reference type constraint class or t+e val-e type constraint
struct. ( secondary constraint can be a t+pe-para%eter or interface-t+pe.
27$ Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
T+e re0erence type constraint speci0ies t+at a type argument used 0or t+e type parameter must be a re0erence
type. (ll class types- inter0ace types- delegate types- array types- and type parameters 7nown to be a re0erence
type Jas de0ined belowM satis0y t+is constraint.
T+e value type constraint speci0ies t+at a type argument used 0or t+e type parameter must be a non<nullable
value type. (ll non<nullable struct types- enum types- and type parameters +aving t+e value type constraint
satis0y t+is constraint. =ote t+at alt+oug+ classi0ied as a value type- a nullable type JV4.1.1.M does not satis0y t+e
value type constraint. ( type parameter +aving t+e value type constraint cannot also +ave t+e constr!ctor-
constraint.
Pointer types are never allowed to be type arguments and are not considered to satis0y eit+er t+e re0erence type
or value type constraints.
10 a constraint is a class type- an inter0ace type- or a type parameter- t+at type speci0ies a minimal Kbase typeL
t+at every type argument used 0or t+at type parameter must support. 6+enever a constructed type or generic
met+od is used- t+e type argument is c+ec7ed against t+e constraints on t+e type parameter at compile<time. T+e
type argument supplied must derive 0rom or implement all o0 t+e constraints given 0or t+at type parameter.
( class-t+pe constraint must satis0y t+e 0ollowing rulesC
T+e type must be a class type.
T+e type must not be sealed.
T+e type must not be one o0 t+e 0ollowing typesC System.'rray- System.6elegate- System.)num- or
System.Ualue1y&e.
T+e type must not be object. )ecause all types derive 0rom object- suc+ a constraint would +ave no
e00ect i0 it were permitted.
(t most one constraint 0or a given type parameter can be a class type.
( type speci0ied as an interface-t+pe constraint must satis0y t+e 0ollowing rulesC
T+e type must be an inter0ace type.
( type must not be speci0ied more t+an once in a given ,"ere clause.
1n eit+er case- t+e constraint can involve any o0 t+e type parameters o0 t+e associated type or met+od declaration
as part o0 a constructed type- and can involve t+e type being declared.
(ny class or inter0ace type speci0ied as a type parameter constraint must be at least as accessible JV3.".4M as t+e
generic type or met+od being declared.
( type speci0ied as a t+pe-para%eter constraint must satis0y t+e 0ollowing rulesC
T+e type must be a type parameter.
( type must not be speci0ied more t+an once in a given ,"ere clause.
1n addition t+ere must be no cycles in t+e dependency grap+ o0 type parameters- w+ere dependency is a
transitive relation de0ined byC
10 a type parameter 1 is used as a constraint 0or type parameter S t+en S depends on 1.
10 a type parameter S depends on a type parameter 1 and 1 depends on a type parameter ; t+en S depends
on ;.
4iven t+is relation- it is a compile<time error 0or a type parameter to depend on itsel0 Jdirectly or indirectlyM.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 27!
C# Language Specification
(ny constraints must be consistent among dependent type parameters. 10 type parameter S depends on type
parameter 1 t+enC
1 must not +ave t+e value type constraint. /t+erwise- 1 is e00ectively sealed so S would be 0orced to be t+e
same type as 1- eliminating t+e need 0or two type parameters.
10 S +as t+e value type constraint t+en 1 must not +ave a class-t+pe constraint.
10 S +as a class-t+pe constraint ' and 1 +as a class-t+pe constraint : t+en t+ere must be an identity
conversion or implicit re0erence conversion 0rom ' to : or an implicit re0erence conversion 0rom : to '.
10 S also depends on type parameter ; and ; +as a class-t+pe constraint ' and 1 +as a class-t+pe constraint :
t+en t+ere must be an identity conversion or implicit re0erence conversion 0rom ' to : or an implicit
re0erence conversion 0rom : to '.
1t is valid 0or S to +ave t+e value type constraint and 1 to +ave t+e re0erence type constraint. E00ectively t+is
limits 1 to t+e types System.%bject- System.Ualue1y&e- System.)num- and any inter0ace type.
10 t+e ,"ere clause 0or a type parameter includes a constructor constraint Jw+ic+ +as t+e 0orm ne,()M- it is
possible to use t+e ne, operator to create instances o0 t+e type JV!.".1..1M. (ny type argument used 0or a type
parameter wit+ a constructor constraint must +ave a public parameterless constructor Jt+is constructor implicitly
eists 0or any value typeM or be a type parameter +aving t+e value type constraint or constructor constraint Jsee
V1..1." 0or detailsM.
T+e 0ollowing are eamples o0 constraintsC
inter-ace $*rintable
{
void *rint();
!
inter-ace $Com&arableD1E
{
int Com&are1o(1 value);
!
inter-ace $aey*roviderD1E
{
1 Setaey();
!
class *rinterD1E ,"ere 1/ $*rintable {...!
class SortedListD1E ,"ere 1/ $Com&arableD1E {...!
class 6ictionaryDaUE
,"ere a/ $Com&arableDaE
,"ere U/ $*rintable $aey*roviderDaE ne,()
{
...
!
T+e 0ollowing eample is in error because it causes a circularity in t+e dependency grap+ o0 t+e type parametersC
class CircularDS1E
,"ere S/ 1
,"ere 1/ S .. )rror circularity in de&endency gra&"
{
...
!
2$* Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
T+e 0ollowing eamples illustrate additional invalid situationsC
class SealedDS1E
,"ere S/ 1
,"ere 1/ struct .. )rror 1 is sealed
{
...
!
class ' {...!
class : {...!
class $ncom&atDS1E
,"ere S/ ' 1
,"ere 1/ : .. )rror incom&atible class=ty&e constraints
{
...
!
class StructWit"ClassDS1;E
,"ere S/ struct 1
,"ere 1/ ;
,"ere ;/ ' .. )rror ' incom&atible ,it" struct
{
...
!
T+e effective !ase class o0 a type parameter 1 is de0ined as 0ollowsC
10 1 +as no primary constraints or type parameter constraints- its e00ective base class is object.
10 1 +as t+e value type constraint- its e00ective base class is System.Ualue1y&e.
10 1 +as a class-t+pe constraint C but no t+pe-para%eter constraints- its e00ective base class is C.
10 1 +as no class-t+pe constraint but +as one or more t+pe-para%eter constraints- its e00ective base class is
t+e most encompassed type JV%.4.2M in t+e set o0 e00ective base classes o0 its t+pe-para%eter constraints. T+e
consistency rules ensure t+at suc+ a most encompassed type eists.
10 1 +as bot+ a class-t+pe constraint and one or more t+pe-para%eter constraints- its e00ective base class is
t+e most encompassed type JV%.4.2M in t+e set consisting o0 t+e class-t+pe constraint o0 1 and t+e e00ective
base classes o0 its t+pe-para%eter constraints. T+e consistency rules ensure t+at suc+ a most encompassed
type eists.
10 1 +as t+e re0erence type constraint but no class-t+pe constraints- its e00ective base class is object.
T+e effective interface set o0 a type parameter 1 is de0ined as 0ollowsC
10 1 +as no secondar+-constraints- its e00ective inter0ace set is empty.
10 1 +as interface-t+pe constraints but no t+pe-para%eter constraints- its e00ective inter0ace set is its set o0
interface-t+pe constraints.
10 1 +as no interface-t+pe constraints but +as t+pe-para%eter constraints- its e00ective inter0ace set is t+e
union o0 t+e e00ective inter0ace sets o0 its t+pe-para%eter constraints.
10 1 +as bot+ interface-t+pe constraints and t+pe-para%eter constraints- its e00ective inter0ace set is t+e union
o0 its set o0 interface-t+pe constraints and t+e e00ective inter0ace sets o0 its t+pe-para%eter constraints.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 2$1
C# Language Specification
( type parameter is "no2n to !e a reference type i0 it +as t+e re0erence type constraint or its e00ective base class
is not object or System.Ualue1y&e.
,alues o0 a constrained type parameter type can be used to access t+e instance members implied by t+e
constraints. 1n t+e eample
inter-ace $*rintable
{
void *rint();
!
class *rinterD1E ,"ere 1/ $*rintable
{
void *rint%ne(1 #) {
#.*rint();
!
!
t+e met+ods o0 $*rintable can be invo7ed directly on # because 1 is constrained to always implement
$*rintable.
10.1.' Class bod!
T+e class-,od+ o0 a class de0ines t+e members o0 t+at class.
class-,od+.
{ class-%e%,er-declarationsopt }
10.2 Partial t!pes
( type declaration can be split across multiple partial type declarations. T+e type declaration is constructed
0rom its parts by 0ollowing t+e rules in t+is section- w+ereupon it is treated as a single declaration during t+e
remainder o0 t+e compile<time and runtime processing o0 t+e program.
( class-declaration- str!ct-declaration or interface-declaration represents a partial type declaration i0 it
includes a &artial modi0ier. &artial is not a 7eyword- and only acts as a modi0ier i0 it appears immediately
be0ore one o0 t+e 7eywords class- struct or inter-ace in a type declaration- or be0ore t+e type void in a
met+od declaration. 1n ot+er contets it can be used as a normal identi0ier.
Eac+ part o0 a partial type declaration must include a &artial modi0ier. 1t must +ave t+e same name and be
declared in t+e same namespace or type declaration as t+e ot+er parts. T+e &artial modi0ier indicates t+at
additional parts o0 t+e type declaration may eist elsew+ere- but t+e eistence o0 suc+ additional parts is not a
re9uirementQ it is valid 0or a type wit+ a single declaration to include t+e &artial modi0ier.
(ll parts o0 a partial type must be compiled toget+er suc+ t+at t+e parts can be merged at compile<time into a
single type declaration. Partial types speci0ically do not allow already compiled types to be etended.
=ested types may be declared in multiple parts by using t+e &artial modi0ier. Typically- t+e containing type is
declared using &artial as well- and eac+ part o0 t+e nested type is declared in a di00erent part o0 t+e containing
type.
T+e &artial modi0ier is not permitted on delegate or enum declarations.
10.2.1 *ttributes
T+e attributes o0 a partial type are determined by combining- in an unspeci0ied order- t+e attributes o0 eac+ o0
t+e parts. 10 an attribute is placed on multiple parts- it is e9uivalent to speci0ying t+e attribute multiple times on
t+e type. *or eample- t+e two partsC
2$2 Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
4'ttr2 'ttr8(""ello")5
&artial class ' {!
4'ttr9 'ttr8("goodbye")5
&artial class ' {!
are e9uivalent to a declaration suc+ asC
4'ttr2 'ttr8(""ello") 'ttr9 'ttr8("goodbye")5
class ' {!
(ttributes on type parameters combine in a similar 0as+ion.
10.2.2 )odifiers
6+en a partial type declaration includes an accessibility speci0ication Jt+e &ublic- &rotected- internal-
and &rivate modi0iersM it must agree wit+ all ot+er parts t+at include an accessibility speci0ication. 10 no part o0
a partial type includes an accessibility speci0ication- t+e type is given t+e appropriate de0ault accessibility
JV3.".1M.
10 one or more partial declarations o0 a nested type include a ne, modi0ier- no warning is reported i0 t+e nested
type +ides an in+erited member JV3.!.1.2M.
10 one or more partial declarations o0 a class include an abstract modi0ier- t+e class is considered abstract
JV1..1.1.1M. /t+erwise- t+e class is considered non<abstract.
10 one or more partial declarations o0 a class include a sealed modi0ier- t+e class is considered sealed
JV1..1.1.2M. /t+erwise- t+e class is considered unsealed.
=ote t+at a class cannot be bot+ abstract and sealed.
6+en t+e unsa-e modi0ier is used on a partial type declaration- only t+at particular part is considered an unsa0e
contet JV13.1M.
10.2.3 T!pe paraeters and constraints
10 a generic type is declared in multiple parts- eac+ part must state t+e type parameters. Eac+ part must +ave t+e
same number o0 type parameters- and t+e same name 0or eac+ type parameter- in order.
6+en a partial generic type declaration includes constraints J,"ere clausesM- t+e constraints must agree wit+ all
ot+er parts t+at include constraints. #peci0ically- eac+ part t+at includes constraints must +ave constraints 0or t+e
same set o0 type parameters- and 0or eac+ type parameter t+e sets o0 primary- secondary- and constructor
constraints must be e9uivalent. Two sets o0 constraints are e9uivalent i0 t+ey contain t+e same members. 10 no
part o0 a partial generic type speci0ies type parameter constraints- t+e type parameters are considered
unconstrained.
T+e eample
&artial class 6ictionaryDaUE
,"ere a/ $Com&arableDaE
,"ere U/ $aey*roviderDaE $*ersistable
{
...
!
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 2$3
C# Language Specification
&artial class 6ictionaryDaUE
,"ere U/ $*ersistable $aey*roviderDaE
,"ere a/ $Com&arableDaE
{
...
!
&artial class 6ictionaryDaUE
{
...
!
is correct because t+ose parts t+at include constraints Jt+e 0irst twoM e00ectively speci0y t+e same set o0 primary-
secondary- and constructor constraints 0or t+e same set o0 type parameters- respectively.
10.2.# +ase class
6+en a partial class declaration includes a base class speci0ication it must agree wit+ all ot+er parts t+at include
a base class speci0ication. 10 no part o0 a partial class includes a base class speci0ication- t+e base class becomes
System.%bject JV1..1.4.1M.
10.2.& +ase interfaces
T+e set o0 base inter0aces 0or a type declared in multiple parts is t+e union o0 t+e base inter0aces speci0ied on
eac+ part. ( particular base inter0ace may only be named once on eac+ part- but it is permitted 0or multiple parts
to name t+e same base inter0aceJsM. T+ere must only be one implementation o0 t+e members o0 any given base
inter0ace.
1n t+e eample
&artial class C/ $' $: {...!
&artial class C/ $C {...!
&artial class C/ $' $: {...!
t+e set o0 base inter0aces 0or class C is $'- $:- and $C.
Typically- eac+ part provides an implementation o0 t+e inter0aceJsM declared on t+at partQ +owever- t+is is not a
re9uirement. ( part may provide t+e implementation 0or an inter0ace declared on a di00erent partC
&artial class I
{
int $Com&arable.Com&are1o(object o) {...!
!
&artial class I/ $Com&arable
{
...
!
10.2.' )ebers
6it+ t+e eception o0 partial met+ods JV1..2.!M- t+e set o0 members o0 a type declared in multiple parts is
simply t+e union o0 t+e set o0 members declared in eac+ part. T+e bodies o0 all parts o0 t+e type declaration
s+are t+e same declaration space JV3.3M- and t+e scope o0 eac+ member JV3.!M etends to t+e bodies o0 all t+e
parts. T+e accessibility domain o0 any member always includes all t+e parts o0 t+e enclosing typeQ a &rivate
member declared in one part is 0reely accessible 0rom anot+er part. 1t is a compile<time error to declare t+e same
member in more t+an one part o0 t+e type- unless t+at member is a type wit+ t+e &artial modi0ier.
2$" Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
&artial class '
{
int #; .. )rror cannot declare # more t"an once
&artial class $nner .. %( $nner is a &artial ty&e
{
int y;
!
!
&artial class '
{
int #; .. )rror cannot declare # more t"an once
&artial class $nner .. %( $nner is a &artial ty&e
{
int ?;
!
!
(lt+oug+ t+e ordering o0 members wit+in a type is not signi0icant to C# code- it may be signi0icant w+en
inter0acing wit+ ot+er languages and environments. 1n t+ese cases- t+e ordering o0 members wit+in a type
declared in multiple parts is unde0ined.
10.2.. Partial et-ods
Partial met+ods can be de0ined in one part o0 a type declaration and implemented in anot+er. T+e
implementation is optionalQ i0 no part implements t+e partial met+od- t+e partial met+od declaration and all calls
to it are removed 0rom t+e type declaration resulting 0rom t+e combination o0 t+e parts.
Partial met+ods cannot de0ine access modi0iers- but are implicitly &rivate. T+eir return type must be void-
and t+eir parameters cannot +ave t+e out modi0ier. T+e identi0ier &artial is recogniDed as a special 7eyword
in a met+od declaration only i0 it appears rig+t be0ore t+e void typeQ ot+erwise it can be used as a normal
identi0ier. ( partial met+od cannot eplicitly implement inter0ace met+ods.
T+ere are two 7inds o0 partial met+od declarationsC 10 t+e body o0 t+e met+od declaration is a semicolon- t+e
declaration is said to be a defining partial ethod declaration. 10 t+e body is given as a ,loc&- t+e declaration is
said to be an ipleenting partial ethod declaration. (cross t+e parts o0 a type declaration t+ere can be only
one de0ining partial met+od declaration wit+ a given signature- and t+ere can be only one implementing partial
met+od declaration wit+ a given signature. 10 an implementing partial met+od declaration is given- a
corresponding de0ining partial met+od declaration must eist- and t+e declarations must matc+ as speci0ied in
t+e 0ollowingC
T+e declarations must +ave t+e same modi0iers Jalt+oug+ not necessarily in t+e same orderM- met+od
name- number o0 type parameters and number o0 parameters.
Corresponding parameters in t+e declarations must +ave t+e same modi0iers Jalt+oug+ not necessarily in
t+e same orderM and t+e same types Jmodulo di00erences in type parameter namesM.
Corresponding type parameters in t+e declarations must +ave t+e same constraints Jmodulo di00erences
in type parameter namesM.
(n implementing partial met+od declaration can appear in t+e same part as t+e corresponding de0ining partial
met+od declaration.
/nly a de0ining partial met+od participates in overload resolution. T+us- w+et+er or not an implementing
declaration is given- invocation epressions may resolve to invocations o0 t+e partial met+od. )ecause a partial
met+od always returns void- suc+ invocation epressions will always be epression statements. *urt+ermore-
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 2$
C# Language Specification
because a partial met+od is implicitly &rivate- suc+ statements will always occur wit+in one o0 t+e parts o0 t+e
type declaration wit+in w+ic+ t+e partial met+od is declared.
10 no part o0 a partial type declaration contains an implementing declaration 0or a given partial met+od- any
epression statement invo7ing it is simply removed 0rom t+e combined type declaration. T+us t+e invocation
epression- including any constituent epressions- +as no e00ect at runtime. T+e partial met+od itsel0 is also
removed and will not be a member o0 t+e combined type declaration.
10 an implementing declaration eist 0or a given partial met+od- t+e invocations o0 t+e partial met+ods are
retained. T+e partial met+od gives rise to a met+od declaration similar to t+e implementing partial met+od
declaration ecept 0or t+e 0ollowingC
T+e &artial modi0ier is not included
T+e attributes in t+e resulting met+od declaration are t+e combined attributes o0 t+e de0ining and t+e
implementing partial met+od declaration in unspeci0ied order. 2uplicates are not removed.
T+e attributes on t+e parameters o0 t+e resulting met+od declaration are t+e combined attributes o0 t+e
corresponding parameters o0 t+e de0ining and t+e implementing partial met+od declaration in
unspeci0ied order. 2uplicates are not removed.
10 a de0ining declaration but not an implementing declaration is given 0or a partial met+od '- t+e 0ollowing
restrictions applyC
1t is a compile time error to create a delegate to met+od JV!.".1.."M.
1t is a compile time error to re0er to M inside an anonymous 0unction t+at is converted to an epression
tree type JV%.".2M.
Epressions occurring as part o0 an invocation o0 M do not a00ect t+e de0inite assignment state JV".3M-
w+ic+ can potentially lead to compile time errors.
M cannot be t+e entry point 0or an application JV3.1M.
Partial met+ods are use0ul 0or allowing one part o0 a type declaration to customiDe t+e be+avior o0 anot+er part-
e.g.- one t+at is generated by a tool. Consider t+e 0ollowing partial class declarationC
&artial class Customer
{
string name;
&ublic string Name {
get { return name; !
set {
%nNameC"anging(value);
name + value;
%nNameC"anged();
!
!
&artial void %nNameC"anging(string ne,Name);
&artial void %nNameC"anged();
!
10 t+is class is compiled wit+out any ot+er parts- t+e de0ining partial met+od declarations and t+eir invocations
will be removed- and t+e resulting combined class declaration will be e9uivalent to t+e 0ollowingC
2$' Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
class Customer
{
string name;
&ublic string Name {
get { return name; !
set { name + value; !
!
!
(ssume t+at anot+er part is given- +owever- w+ic+ provides implementing declarations o0 t+e partial met+odsC
&artial class Customer
{
&artial void %nNameC"anging(string ne,Name)
{
Console.WriteLine(RC"anging R < name < R to R < ne,Name);
!
&artial void %nNameC"anged()
{
Console.WriteLine(RC"anged to R < name);
!
!
T+en t+e resulting combined class declaration will be e9uivalent to t+e 0ollowingC
class Customer
{
string name;
&ublic string Name {
get { return name; !
set {
%nNameC"anging(value);
name + value;
%nNameC"anged();
!
!
void %nNameC"anging(string ne,Name)
{
Console.WriteLine(RC"anging R < name < R to R < ne,Name);
!
void %nNameC"anged()
{
Console.WriteLine(RC"anged to R < name);
!
!
10.2.0 ;ae binding
(lt+oug+ eac+ part o0 an etensible type must be declared wit+in t+e same namespace- t+e parts are typically
written wit+in di00erent namespace declarations. T+us- di00erent using directives JV$.4M may be present 0or eac+
part. 6+en interpreting simple names JV!.".2M wit+in one part- only t+e using directives o0 t+e namespace
declarationJsM enclosing t+at part are considered. T+is may result in t+e same identi0ier +aving di00erent
meanings in di00erent partsC
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 2$7
C# Language Specification
names&ace N
{
using List + System.Collections.'rrayList;
&artial class '
{
List #; .. # "as ty&e System.Collections.'rrayList
!
!
names&ace N
{
using List + Widgets.Lin(edList;
&artial class '
{
List y; .. y "as ty&e Widgets.Lin(edList
!
!
10.3 Class ebers
T+e members o0 a class consist o0 t+e members introduced by its class-%e%,er-declarations and t+e members
in+erited 0rom t+e direct base class.
class-%e%,er-declarations.
class-%e%,er-declaration
class-%e%,er-declarations class-%e%,er-declaration
class-%e%,er-declaration.
constant-declaration
field-declaration
%ethod-declaration
propert+-declaration
event-declaration
inde/er-declaration
operator-declaration
constr!ctor-declaration
destr!ctor-declaration
static-constr!ctor-declaration
t+pe-declaration
T+e members o0 a class type are divided into t+e 0ollowing categoriesC
Constants- w+ic+ represent constant values associated wit+ t+e class JV1..4M.
*ields- w+ic+ are t+e variables o0 t+e class JV1.."M.
'et+ods- w+ic+ implement t+e computations and actions t+at can be per0ormed by t+e class JV1..%M.
Properties- w+ic+ de0ine named c+aracteristics and t+e actions associated wit+ reading and writing t+ose
c+aracteristics JV1..!M.
Events- w+ic+ de0ine noti0ications t+at can be generated by t+e class JV1..3M.
1ndeers- w+ic+ permit instances o0 t+e class to be indeed in t+e same way JsyntacticallyM as arrays JV1..$M.
/perators- w+ic+ de0ine t+e epression operators t+at can be applied to instances o0 t+e class JV1..1.M.
2$$ Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
1nstance constructors- w+ic+ implement t+e actions re9uired to initialiDe instances o0 t+e class JV1..11M
2estructors- w+ic+ implement t+e actions to be per0ormed be0ore instances o0 t+e class are permanently
discarded JV1..13M.
#tatic constructors- w+ic+ implement t+e actions re9uired to initialiDe t+e class itsel0 JV1..12M.
Types- w+ic+ represent t+e types t+at are local to t+e class JV1..3.3M.
'embers t+at can contain eecutable code are collectively 7nown as t+e f!nction %e%,ers o0 t+e class type. T+e
0unction members o0 a class type are t+e met+ods- properties- events- indeers- operators- instance constructors-
destructors- and static constructors o0 t+at class type.
( class-declaration creates a new declaration space JV3.3M- and t+e class-%e%,er-declarations immediately
contained by t+e class-declaration introduce new members into t+is declaration space. T+e 0ollowing rules
apply to class-%e%,er-declarationsC
1nstance constructors- destructors and static constructors must +ave t+e same name as t+e immediately
enclosing class. (ll ot+er members must +ave names t+at di00er 0rom t+e name o0 t+e immediately enclosing
class.
T+e name o0 a constant- 0ield- property- event- or type must di00er 0rom t+e names o0 all ot+er members
declared in t+e same class.
T+e name o0 a met+od must di00er 0rom t+e names o0 all ot+er non<met+ods declared in t+e same class. 1n
addition- t+e signature JV3.%M o0 a met+od must di00er 0rom t+e signatures o0 all ot+er met+ods declared in
t+e same class- and two met+ods declared in t+e same class may not +ave signatures t+at di00er solely by
re- and out.
T+e signature o0 an instance constructor must di00er 0rom t+e signatures o0 all ot+er instance constructors
declared in t+e same class- and two constructors declared in t+e same class may not +ave signatures t+at
di00er solely by re- and out.
T+e signature o0 an indeer must di00er 0rom t+e signatures o0 all ot+er indeers declared in t+e same class.
T+e signature o0 an operator must di00er 0rom t+e signatures o0 all ot+er operators declared in t+e same class.
T+e in+erited members o0 a class type JV1..3.3M are not part o0 t+e declaration space o0 a class. T+us- a derived
class is allowed to declare a member wit+ t+e same name or signature as an in+erited member Jw+ic+ in e00ect
+ides t+e in+erited memberM.
10.3.1 T-e instance t!pe
Eac+ class declaration +as an associated bound type JV4.4.3M- t+e instance type. *or a generic class declaration-
t+e instance type is 0ormed by creating a constructed type JV4.4M 0rom t+e type declaration- wit+ eac+ o0 t+e
supplied type arguments being t+e corresponding type parameter. #ince t+e instance type uses t+e type
parameters- it can only be used w+ere t+e type parameters are in scopeQ t+at is- inside t+e class declaration. T+e
instance type is t+e type o0 t"is 0or code written inside t+e class declaration. *or non<generic classes- t+e
instance type is simply t+e declared class. T+e 0ollowing s+ows several class declarations along wit+ t+eir
instance typesC
class 'D1E .. instance ty&e/ 'D1E
{
class : {! .. instance ty&e/ 'D1E.:
class CD;E {! .. instance ty&e/ 'D1E.CD;E
!
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 2$!
C# Language Specification
class 6 {! .. instance ty&e/ 6
10.3.2 )ebers of constructed t!pes
T+e non<in+erited members o0 a constructed type are obtained by substituting- 0or eac+ t+pe-para%eter in t+e
member declaration- t+e corresponding t+pe-arg!%ent o0 t+e constructed type. T+e substitution process is based
on t+e semantic meaning o0 type declarations- and is not simply tetual substitution.
*or eample- given t+e generic class declaration
class SenD1;E
{
&ublic 145 a;
&ublic void S(int i 1 t SenD;1E gt) {...!
&ublic ; *ro& { get {...! set {...! !
&ublic int H(double d) {...!
!
t+e constructed type SenDint45$Com&arableDstringEE +as t+e 0ollowing membersC
&ublic int4545 a;
&ublic void S(int i int45 t SenD$Com&arableDstringEint45E gt) {...!
&ublic $Com&arableDstringE *ro& { get {...! set {...! !
&ublic int H(double d) {...!
T+e type o0 t+e member a in t+e generic class declaration Sen is Ktwo<dimensional array o0 1L- so t+e type o0
t+e member a in t+e constructed type above is Ktwo<dimensional array o0 one<dimensional array o0 intL- or
int4545.
6it+in instance 0unction members- t+e type o0 t"is is t+e instance type JV1..3.1M o0 t+e containing declaration.
(ll members o0 a generic class can use type parameters 0rom any enclosing class- eit+er directly or as part o0 a
constructed type. 6+en a particular closed constructed type JV4.4.2M is used at run<time- eac+ use o0 a type
parameter is replaced wit+ t+e actual type argument supplied to t+e constructed type. *or eampleC
class CDUE
{
&ublic U -2;
&ublic CDUE -8 + null;
&ublic C(U #) {
t"is.-2 + #;
t"is.-8 + t"is;
!
!
class '&&lication
{
static void Main() {
CDintE #2 + ne, CDintE(2);
Console.WriteLine(#2.-2); .. *rints 2
CDdoubleE #8 + ne, CDdoubleE(9.2J2K);
Console.WriteLine(#8.-2); .. *rints 9.2J2K
!
!
2!* Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
10.3.3 In-eritance
( class inherits t+e members o0 its direct base class type. 1n+eritance means t+at a class implicitly contains all
members o0 its direct base class type- ecept 0or t+e instance constructors- destructors and static constructors o0
t+e base class. #ome important aspects o0 in+eritance areC
1n+eritance is transitive. 10 C is derived 0rom :- and : is derived 0rom '- t+en C in+erits t+e members
declared in : as well as t+e members declared in '.
( derived class e/tends its direct base class. ( derived class can add new members to t+ose it in+erits- but it
cannot remove t+e de0inition o0 an in+erited member.
1nstance constructors- destructors- and static constructors are not in+erited- but all ot+er members are-
regardless o0 t+eir declared accessibility JV3."M. However- depending on t+eir declared accessibility-
in+erited members mig+t not be accessible in a derived class.
( derived class can hide JV3.!.1.2M in+erited members by declaring new members wit+ t+e same name or
signature. =ote +owever t+at +iding an in+erited member does not remove t+at memberRit merely ma7es
t+at member inaccessible directly t+roug+ t+e derived class.
(n instance o0 a class contains a set o0 all instance 0ields declared in t+e class and its base classes- and an
implicit conversion JV%.1.%M eists 0rom a derived class type to any o0 its base class types. T+us- a re0erence
to an instance o0 some derived class can be treated as a re0erence to an instance o0 any o0 its base classes.
( class can declare virtual met+ods- properties- and indeers- and derived classes can override t+e
implementation o0 t+ese 0unction members. T+is enables classes to e+ibit polymorp+ic be+avior w+erein
t+e actions per0ormed by a 0unction member invocation varies depending on t+e run<time type o0 t+e
instance t+roug+ w+ic+ t+at 0unction member is invo7ed.
T+e in+erited member o0 a constructed class type are t+e members o0 t+e immediate base class type
JV1..1.4.1M- w+ic+ is 0ound by substituting t+e type arguments o0 t+e constructed type 0or eac+ occurrence o0
t+e corresponding type parameters in t+e ,ase-class-specification. T+ese members- in turn- are trans0ormed
by substituting- 0or eac+ t+pe-para%eter in t+e member declaration- t+e corresponding t+pe-arg!%ent o0 t+e
,ase-class-specification.
class :D;E
{
&ublic ; V(long inde#) {...!
!
class 6D1E/ :D145E
{
&ublic 1 S(string s) {...!
!
1n t+e above eample- t+e constructed type 6DintE +as a non<in+erited member &ublic int S(string s)
obtained by substituting t+e type argument int 0or t+e type parameter 1. 6DintE also +as an in+erited member
0rom t+e class declaration :. T+is in+erited member is determined by 0irst determining t+e base class type
:Dint45E o0 6DintE by substituting int 0or 1 in t+e base class speci0ication :D145E. T+en- as a type
argument to :- int45 is substituted 0or ; in &ublic ; V(long inde#)- yielding t+e in+erited member &ublic
int45 V(long inde#).
10.3.# T-e new odifier
( class-%e%,er-declaration is permitted to declare a member wit+ t+e same name or signature as an in+erited
member. 6+en t+is occurs- t+e derived class member is said to hide t+e base class member. Hiding an in+erited
member is not considered an error- but it does cause t+e compiler to issue a warning. To suppress t+e warning-
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 2!1
C# Language Specification
t+e declaration o0 t+e derived class member can include a ne, modi0ier to indicate t+at t+e derived member is
intended to +ide t+e base member. T+is topic is discussed 0urt+er in V3.!.1.2.
10 a ne, modi0ier is included in a declaration t+at doesnPt +ide an in+erited member- a warning to t+at e00ect is
issued. T+is warning is suppressed by removing t+e ne, modi0ier.
10.3.& *ccess odifiers
( class-%e%,er-declaration can +ave any one o0 t+e 0ive possible 7inds o0 declared accessibility JV3.".1MC
&ublic- &rotected internal- &rotected- internal- or &rivate. Ecept 0or t+e &rotected internal
combination- it is a compile<time error to speci0y more t+an one access modi0ier. 6+en a class-%e%,er-
declaration does not include any access modi0iers- &rivate is assumed.
10.3.' Constituent t!pes
Types t+at are used in t+e declaration o0 a member are called t+e constituent types o0 t+at member. Possible
constituent types are t+e type o0 a constant- 0ield- property- event- or indeer- t+e return type o0 a met+od or
operator- and t+e parameter types o0 a met+od- indeer- operator- or instance constructor. T+e constituent types
o0 a member must be at least as accessible as t+at member itsel0 JV3.".4M.
10.3.. Static and instance ebers
'embers o0 a class are eit+er static e!ers or instance e!ers. 4enerally spea7ing- it is use0ul to t+in7 o0
static members as belonging to class types and instance members as belonging to ob&ects Jinstances o0 class
typesM.
6+en a 0ield- met+od- property- event- operator- or constructor declaration includes a static modi0ier- it
declares a static member. 1n addition- a constant or type declaration implicitly declares a static member. #tatic
members +ave t+e 0ollowing c+aracteristicsC
6+en a static member M is re0erenced in a %e%,er-access JV!.".4M o0 t+e 0orm ).M- ) must denote a type
containing M. 1t is a compile<time error 0or ) to denote an instance.
( static 0ield identi0ies eactly one storage location to be s+ared by all instances o0 a given closed class
type. =o matter +ow many instances o0 a given closed class type are created- t+ere is only ever one copy o0
a static 0ield.
( static 0unction member Jmet+od- property- event- operator- or constructorM does not operate on a speci0ic
instance- and it is a compile<time error to re0er to t"is in suc+ a 0unction member.
6+en a 0ield- met+od- property- event- indeer- constructor- or destructor declaration does not include a static
modi0ier- it declares an instance member. J(n instance member is sometimes called a non<static member.M
1nstance members +ave t+e 0ollowing c+aracteristicsC
6+en an instance member M is re0erenced in a %e%,er-access JV!.".4M o0 t+e 0orm ).M- ) must denote an
instance o0 a type containing M. 1t is a compile<time error 0or ) to denote a type.
Every instance o0 a class contains a separate set o0 all instance 0ields o0 t+e class.
(n instance 0unction member Jmet+od- property- indeer- instance constructor- or destructorM operates on a
given instance o0 t+e class- and t+is instance can be accessed as t"is JV!.".!M.
T+e 0ollowing eample illustrates t+e rules 0or accessing static and instance membersC
2!2 Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
class 1est
{
int #;
static int y;
void V() {
# + 2; .. %( same as t"is.# + 2
y + 2; .. %( same as 1est.y + 2
!
static void S() {
# + 2; .. )rror cannot access t"is.#
y + 2; .. %( same as 1est.y + 2
!
static void Main() {
1est t + ne, 1est();
t.# + 2; .. %(
t.y + 2; .. )rror cannot access static member t"roug" instance
1est.# + 2; .. )rror cannot access instance member t"roug" ty&e
1est.y + 2; .. %(
!
!
T+e V met+od s+ows t+at in an instance 0unction member- a si%ple-na%e JV!.".2M can be used to access bot+
instance members and static members. T+e S met+od s+ows t+at in a static 0unction member- it is a compile<
time error to access an instance member t+roug+ a si%ple-na%e. T+e Main met+od s+ows t+at in a %e%,er-
access JV!.".4M- instance members must be accessed t+roug+ instances- and static members must be accessed
t+roug+ types.
10.3.0 ;ested t!pes
( type declared wit+in a class or struct declaration is called a nested type. ( type t+at is declared wit+in a
compilation unit or namespace is called a non-nested type.
1n t+e eample
using System;
class '
{
class :
{
static void V() {
Console.WriteLine("'.:.V");
!
!
!
class : is a nested type because it is declared wit+in class '- and class ' is a non<nested type because it is
declared wit+in a compilation unit.
14.3.+.1 3ully Auali/ied name
T+e 0ully 9uali0ied name JV3.3.1M 0or a nested type is S.N w+ere S is t+e 0ully 9uali0ied name o0 t+e type in
w+ic+ type N is declared.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 2!3
C# Language Specification
14.3.+.2 'eclared accessibility
=on<nested types can +ave &ublic or internal declared accessibility and +ave internal declared
accessibility by de0ault. =ested types can +ave t+ese 0orms o0 declared accessibility too- plus one or more
additional 0orms o0 declared accessibility- depending on w+et+er t+e containing type is a class or structC
( nested type t+at is declared in a class can +ave any o0 0ive 0orms o0 declared accessibility J&ublic-
&rotected internal- &rotected- internal- or &rivateM and- li7e ot+er class members- de0aults to
&rivate declared accessibility.
( nested type t+at is declared in a struct can +ave any o0 t+ree 0orms o0 declared accessibility J&ublic-
internal- or &rivateM and- li7e ot+er struct members- de0aults to &rivate declared accessibility.
T+e eample
&ublic class List
{
.. *rivate data structure
&rivate class Node
{
&ublic object 6ata;
&ublic Node Ne#t;
&ublic Node(object data Node ne#t) {
t"is.6ata + data;
t"is.Ne#t + ne#t;
!
!
&rivate Node -irst + null;
&rivate Node last + null;
.. *ublic inter-ace
&ublic void 'dd1oVront(object o) {...!
&ublic void 'dd1o:ac((object o) {...!
&ublic object OemoveVromVront() {...!
&ublic object OemoveVrom:ac(() {...!
&ublic int Count { get {...! !
!
declares a private nested class Node.
14.3.+.3 -iding
( nested type may +ide JV3.!.1M a base member. T+e ne, modi0ier is permitted on nested type declarations so
t+at +iding can be epressed eplicitly. T+e eample
using System;
class :ase
{
&ublic static void M() {
Console.WriteLine(":ase.M");
!
!
2!" Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
class 6erived/ :ase
{
ne, &ublic class M
{
&ublic static void V() {
Console.WriteLine("6erived.M.V");
!
!
!
class 1est
{
static void Main() {
6erived.M.V();
!
!
s+ows a nested class M t+at +ides t+e met+od M de0ined in :ase.
14.3.+.4 this access
( nested type and its containing type do not +ave a special relations+ip wit+ regard to this-access JV!.".!M.
#peci0ically- t"is wit+in a nested type cannot be used to re0er to instance members o0 t+e containing type. 1n
cases w+ere a nested type needs access to t+e instance members o0 its containing type- access can be provided
by providing t+e t"is 0or t+e instance o0 t+e containing type as a constructor argument 0or t+e nested type. T+e
0ollowing eample
using System;
class C
{
int i + 289;
&ublic void V() {
Nested n + ne, Nested(t"is);
n.S();
!
&ublic class Nested
{
C t"is[c;
&ublic Nested(C c) {
t"is[c + c;
!
&ublic void S() {
Console.WriteLine(t"is[c.i);
!
!
!
class 1est
{
static void Main() {
C c + ne, C();
c.V();
!
!
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 2!
C# Language Specification
s+ows t+is tec+ni9ue. (n instance o0 C creates an instance o0 Nested and passes its own t"is to NestedPs
constructor in order to provide subse9uent access to CPs instance members.
14.3.+.5 ?ccess to "rivate and "rotected members o/ the containing ty"e
( nested type +as access to all o0 t+e members t+at are accessible to its containing type- including members o0
t+e containing type t+at +ave &rivate and &rotected declared accessibility. T+e eample
using System;
class C
{
&rivate static void V() {
Console.WriteLine("C.V");
!
&ublic class Nested
{
&ublic static void S() {
V();
!
!
!
class 1est
{
static void Main() {
C.Nested.S();
!
!
s+ows a class C t+at contains a nested class Nested. 6it+in Nested- t+e met+od S calls t+e static met+od V
de0ined in C- and V +as private declared accessibility.
( nested type also may access protected members de0ined in a base type o0 its containing type. 1n t+e eample
using System;
class :ase
{
&rotected void V() {
Console.WriteLine(":ase.V");
!
!
class 6erived/ :ase
{
&ublic class Nested
{
&ublic void S() {
6erived d + ne, 6erived();
d.V(); .. o(
!
!
!
2!' Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
class 1est
{
static void Main() {
6erived.Nested n + ne, 6erived.Nested();
n.S();
!
!
t+e nested class 6erived.Nested accesses t+e protected met+od V de0ined in 6erivedPs base class- :ase- by
calling t+roug+ an instance o0 6erived.
14.3.+.6 Bested ty"es in generic classes
( generic class declaration can contain nested type declarations. T+e type parameters o0 t+e enclosing class can
be used wit+in t+e nested types. ( nested type declaration can contain additional type parameters t+at apply only
to t+e nested type.
Every type declaration contained wit+in a generic class declaration is implicitly a generic type declaration.
6+en writing a re0erence to a type nested wit+in a generic type- t+e containing constructed type- including its
type arguments- must be named. However- 0rom wit+in t+e outer class- t+e nested type can be used wit+out
9uali0icationQ t+e instance type o0 t+e outer class can be implicitly used w+en constructing t+e nested type. T+e
0ollowing eample s+ows t+ree di00erent correct ways to re0er to a constructed type created 0rom $nnerQ t+e
0irst two are e9uivalentC
class %uterD1E
{
class $nnerD;E
{
&ublic static void V(1 t ; u) {...!
!
static void V(1 t) {
%uterD1E.$nnerDstringE.V(t "abc"); .. 1"ese t,o statements "ave
$nnerDstringE.V(t "abc"); .. t"e same e--ect
%uterDintE.$nnerDstringE.V(9 "abc"); .. 1"is ty&e is di--erent
%uter.$nnerDstringE.V(t "abc"); .. )rror %uter needs ty&e arg
!
!
(lt+oug+ it is bad programming style- a type parameter in a nested type can +ide a member or type parameter
declared in t+e outer typeC
class %uterD1E
{
class $nnerD1E .. Ualid "ides %uter_s 1
{
&ublic 1 t; .. Oe-ers to $nner_s 1
!
!
10.3.1 :eser"ed eber naes
To 0acilitate t+e underlying C# runtime implementation- 0or eac+ source member declaration t+at is a property-
event- or indeer- t+e implementation must reserve two met+od signatures based on t+e 7ind o0 t+e member
declaration- its name- and its type. 1t is a compile<time error 0or a program to declare a member w+ose signature
matc+es one o0 t+ese reserved signatures- even i0 t+e underlying runtime implementation does not ma7e use o0
t+ese reservations.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 2!7
C# Language Specification
T+e reserved names do not introduce declarations- t+us t+ey do not participate in member loo7up. However- a
declarationPs associated reserved met+od signatures do participate in in+eritance JV1..3.3M- and can be +idden
wit+ t+e ne, modi0ier JV1..3.4M.
T+e reservation o0 t+ese names serves t+ree purposesC
To allow t+e underlying implementation to use an ordinary identi0ier as a met+od name 0or get or set access
to t+e C# language 0eature.
To allow ot+er languages to interoperate using an ordinary identi0ier as a met+od name 0or get or set access
to t+e C# language 0eature.
To +elp ensure t+at t+e source accepted by one con0orming compiler is accepted by anot+er- by ma7ing t+e
speci0ics o0 reserved member names consistent across all C# implementations.
T+e declaration o0 a destructor JV1..13M also causes a signature to be reserved JV1..3.$.4M.
14.3.2.1 Member names reserved /or "ro"erties
*or a property * JV1..!M o0 type 1- t+e 0ollowing signatures are reservedC
1 get[*();
void set[*(1 value);
)ot+ signatures are reserved- even i0 t+e property is read<only or write<only.
1n t+e eample
using System;
class '
{
&ublic int * {
get { return 289; !
!
!
class :/ '
{
ne, &ublic int get[*() {
return JKX;
!
ne, &ublic void set[*(int value) {
!
!
class 1est
{
static void Main() {
: b + ne, :();
' a + b;
Console.WriteLine(a.*);
Console.WriteLine(b.*);
Console.WriteLine(b.get[*());
!
!
a class ' de0ines a read<only property *- t+us reserving signatures 0or get[* and set[* met+ods. ( class :
derives 0rom ' and +ides bot+ o0 t+ese reserved signatures. T+e eample produces t+e outputC
2!$ Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
289
289
JKX
14.3.2.2 Member names reserved /or events
*or an event ) JV1..3M o0 delegate type 1- t+e 0ollowing signatures are reservedC
void add[)(1 "andler);
void remove[)(1 "andler);
14.3.2.3 Member names reserved /or inde$ers
*or an indeer JV1..$M o0 type 1 wit+ parameter<list L- t+e 0ollowing signatures are reservedC
1 get[$tem(L);
void set[$tem(L 1 value);
)ot+ signatures are reserved- even i0 t+e indeer is read<only or write<only.
14.3.2.4 Member names reserved /or destructors
*or a class containing a destructor JV1..13M- t+e 0ollowing signature is reservedC
void Vinali?e();
10.# Constants
( constant is a class member t+at represents a constant valueC a value t+at can be computed at compile<time. (
constant-declaration introduces one or more constants o0 a given type.
constant-declaration.
attri,!tesopt constant-%odifiersopt &'*#$ t+pe constant-declarators A
constant-%odifiers.
constant-%odifier
constant-%odifiers constant-%odifier
constant-%odifier.
*ew
.u"li&
.%'$e&$ed
i*$e%*!l
.%i,!$e
constant-declarators.
constant-declarator
constant-declarators ? constant-declarator
constant-declarator.
identifier = constant-e/pression
( constant-declaration may include a set o0 attri,!tes JV1!M- a ne, modi0ier JV1..3.4M- and a valid combination
o0 t+e 0our access modi0iers JV1..3."M. T+e attributes and modi0iers apply to all o0 t+e members declared by t+e
constant-declaration. Even t+oug+ constants are considered static members- a constant-declaration neit+er
re9uires nor allows a static modi0ier. 1t is an error 0or t+e same modi0ier to appear multiple times in a constant
declaration.
T+e t+pe o0 a constant-declaration speci0ies t+e type o0 t+e members introduced by t+e declaration. T+e type is
0ollowed by a list o0 constant-declarators- eac+ o0 w+ic+ introduces a new member. ( constant-declarator
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 2!!
C# Language Specification
consists o0 an identifier t+at names t+e member- 0ollowed by an K+L to7en- 0ollowed by a constant-e/pression
JV!.13M t+at gives t+e value o0 t+e member.
T+e t+pe speci0ied in a constant declaration must be sbyte- byte- s"ort- us"ort- int- uint- long- ulong-
c"ar- -loat- double- decimal- bool- string- an en!%-t+pe- or a reference-t+pe. Eac+ constant-e/pression
must yield a value o0 t+e target type or o0 a type t+at can be converted to t+e target type by an implicit
conversion JV%.1M.
T+e t+pe o0 a constant must be at least as accessible as t+e constant itsel0 JV3.".4M.
T+e value o0 a constant is obtained in an epression using a si%ple-na%e JV!.".2M or a %e%,er-access JV!.".4M.
( constant can itsel0 participate in a constant-e/pression. T+us- a constant may be used in any construct t+at
re9uires a constant-e/pression. Eamples o0 suc+ constructs include case labels- goto case statements- enum
member declarations- attributes- and ot+er constant declarations.
(s described in V!.13- a constant-e/pression is an epression t+at can be 0ully evaluated at compile<time. #ince
t+e only way to create a non<null value o0 a reference-t+pe ot+er t+an string is to apply t+e ne, operator- and
since t+e ne, operator is not permitted in a constant-e/pression- t+e only possible value 0or constants o0
reference-t+pes ot+er t+an string is null.
6+en a symbolic name 0or a constant value is desired- but w+en t+e type o0 t+at value is not permitted in a
constant declaration- or w+en t+e value cannot be computed at compile<time by a constant-e/pression- a
readonly 0ield JV1..".2M may be used instead.
( constant declaration t+at declares multiple constants is e9uivalent to multiple declarations o0 single constants
wit+ t+e same attributes- modi0iers- and type. *or eample
class '
{
&ublic const double I + 2.3 ` + 8.3 P + 9.3;
!
is e9uivalent to
class '
{
&ublic const double I + 2.3;
&ublic const double ` + 8.3;
&ublic const double P + 9.3;
!
Constants are permitted to depend on ot+er constants wit+in t+e same program as long as t+e dependencies are
not o0 a circular nature. T+e compiler automatically arranges to evaluate t+e constant declarations in t+e
appropriate order. 1n t+e eample
class '
{
&ublic const int I + :.P < 2;
&ublic const int ` + 23;
!
class :
{
&ublic const int P + '.` < 2;
!
t+e compiler 0irst evaluates '.`- t+en evaluates :.P- and 0inally evaluates '.I- producing t+e values 23- 22-
and 28. Constant declarations may depend on constants 0rom ot+er programs- but suc+ dependencies are only
3** Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
possible in one direction. ;e0erring to t+e eample above- i0 ' and : were declared in separate programs- it
would be possible 0or '.I to depend on :.P- but :.P could t+en not simultaneously depend on '.`.
10.& ,ields
( field is a member t+at represents a variable associated wit+ an ob&ect or class. ( field-declaration introduces
one or more 0ields o0 a given type.
field-declaration.
attri,!tesopt field-%odifiersopt t+pe varia,le-declarators A
field-%odifiers.
field-%odifier
field-%odifiers field-%odifier
field-%odifier.
*ew
.u"li&
.%'$e&$ed
i*$e%*!l
.%i,!$e
#$!$i&
%e!d'*l)
,'l!$ile
varia,le-declarators.
varia,le-declarator
varia,le-declarators ? varia,le-declarator
varia,le-declarator.
identifier
identifier = varia,le-initiali-er
varia,le-initiali-er.
e/pression
arra+-initiali-er
( field-declaration may include a set o0 attri,!tes JV1!M- a ne, modi0ier JV1..3.4M- a valid combination o0 t+e
0our access modi0iers JV1..3."M- and a static modi0ier JV1..".1M. 1n addition- a field-declaration may include a
readonly modi0ier JV1..".2M or a volatile modi0ier JV1..".3M but not bot+. T+e attributes and modi0iers
apply to all o0 t+e members declared by t+e field-declaration. 1t is an error 0or t+e same modi0ier to appear
multiple times in a 0ield declaration.
T+e t+pe o0 a field-declaration speci0ies t+e type o0 t+e members introduced by t+e declaration. T+e type is
0ollowed by a list o0 varia,le-declarators- eac+ o0 w+ic+ introduces a new member. ( varia,le-declarator
consists o0 an identifier t+at names t+at member- optionally 0ollowed by an K+L to7en and a varia,le-initiali-er
JV1.."."M t+at gives t+e initial value o0 t+at member.
T+e t+pe o0 a 0ield must be at least as accessible as t+e 0ield itsel0 JV3.".4M.
T+e value o0 a 0ield is obtained in an epression using a si%ple-na%e JV!.".2M or a %e%,er-access JV!.".4M. T+e
value o0 a non<readonly 0ield is modi0ied using an assign%ent JV!.1%M. T+e value o0 a non<readonly 0ield can be
bot+ obtained and modi0ied using post0i increment and decrement operators JV!.".$M and pre0i increment and
decrement operators JV!.%."M.
( 0ield declaration t+at declares multiple 0ields is e9uivalent to multiple declarations o0 single 0ields wit+ t+e
same attributes- modi0iers- and type. *or eample
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 3*1
C# Language Specification
class '
{
&ublic static int I + 2 ` P + 233;
!
is e9uivalent to
class '
{
&ublic static int I + 2;
&ublic static int `;
&ublic static int P + 233;
!
10.&.1 Static and instance fields
6+en a 0ield declaration includes a static modi0ier- t+e 0ields introduced by t+e declaration are static fields.
6+en no static modi0ier is present- t+e 0ields introduced by t+e declaration are instance fields. #tatic 0ields
and instance 0ields are two o0 t+e several 7inds o0 variables JV"M supported by C#- and at times t+ey are re0erred
to as static varia!les and instance varia!les- respectively.
( static 0ield is not part o0 a speci0ic instanceQ instead- it is s+ared amongst all instances o0 a closed type
JV4.4.2M. =o matter +ow many instances o0 a closed class type are created- t+ere is only ever one copy o0 a static
0ield 0or t+e associated application domain.
*or eampleC
class CDUE
{
static int count + 3;
&ublic C() {
count<<;
!
&ublic static int Count {
get { return count; !
!
!
class '&&lication
{
static void Main() {
CDintE #2 + ne, CDintE();
Console.WriteLine(CDintE.Count); .. *rints 2
CDdoubleE #8 + ne, CDdoubleE();
Console.WriteLine(CDintE.Count); .. *rints 2
CDintE #9 + ne, CDintE();
Console.WriteLine(CDintE.Count); .. *rints 8
!
!
(n instance 0ield belongs to an instance. #peci0ically- every instance o0 a class contains a separate set o0 all t+e
instance 0ields o0 t+at class.
6+en a 0ield is re0erenced in a %e%,er-access JV!.".4M o0 t+e 0orm ).M- i0 M is a static 0ield- ) must denote a
type containing M- and i0 M is an instance 0ield- E must denote an instance o0 a type containing M.
3*2 Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
T+e di00erences between static and instance members are discussed 0urt+er in V1..3.!.
10.&.2 :eadonl! fields
6+en a field-declaration includes a readonly modi0ier- t+e 0ields introduced by t+e declaration are readonly
fields. 2irect assignments to readonly 0ields can only occur as part o0 t+at declaration or in an instance
constructor or static constructor in t+e same class. J( readonly 0ield can be assigned to multiple times in t+ese
contets.M #peci0ically- direct assignments to a readonly 0ield are permitted only in t+e 0ollowing contetsC
1n t+e varia,le-declarator t+at introduces t+e 0ield Jby including a varia,le-initiali-er in t+e declarationM.
*or an instance 0ield- in t+e instance constructors o0 t+e class t+at contains t+e 0ield declarationQ 0or a static
0ield- in t+e static constructor o0 t+e class t+at contains t+e 0ield declaration. T+ese are also t+e only contets
in w+ic+ it is valid to pass a readonly 0ield as an out or re- parameter.
(ttempting to assign to a readonly 0ield or pass it as an out or re- parameter in any ot+er contet is a
compile<time error.
14.5.2.1 6sing static readonly /ields /or constants
( static readonly 0ield is use0ul w+en a symbolic name 0or a constant value is desired- but w+en t+e type o0
t+e value is not permitted in a const declaration- or w+en t+e value cannot be computed at compile<time. 1n t+e
eample
&ublic class Color
{
&ublic static readonly Color :lac( + ne, Color(3 3 3);
&ublic static readonly Color W"ite + ne, Color(8KK 8KK 8KK);
&ublic static readonly Color Oed + ne, Color(8KK 3 3);
&ublic static readonly Color Sreen + ne, Color(3 8KK 3);
&ublic static readonly Color :lue + ne, Color(3 3 8KK);
&rivate byte red green blue;
&ublic Color(byte r byte g byte b) {
red + r;
green + g;
blue + b;
!
!
t+e :lac(- W"ite- Oed- Sreen- and :lue members cannot be declared as const members because t+eir values
cannot be computed at compile<time. However- declaring t+em static readonly instead +as muc+ t+e same
e00ect.
14.5.2.2 Versioning o/ constants and static readonly /ields
Constants and readonly 0ields +ave di00erent binary versioning semantics. 6+en an epression re0erences a
constant- t+e value o0 t+e constant is obtained at compile<time- but w+en an epression re0erences a readonly
0ield- t+e value o0 t+e 0ield is not obtained until run<time. Consider an application t+at consists o0 two separate
programsC
using System;
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 3*3
C# Language Specification
names&ace *rogram2
{
&ublic class ;tils
{
&ublic static readonly int I + 2;
!
!
names&ace *rogram8
{
class 1est
{
static void Main() {
Console.WriteLine(*rogram2.;tils.I);
!
!
!
T+e *rogram2 and *rogram8 namespaces denote two programs t+at are compiled separately. )ecause
*rogram2.;tils.I is declared as a static readonly 0ield- t+e value output by t+e Console.WriteLine
statement is not 7nown at compile<time- but rat+er is obtained at run<time. T+us- i0 t+e value o0 I is c+anged and
*rogram2 is recompiled- t+e Console.WriteLine statement will output t+e new value even i0 *rogram8
isnPt recompiled. However- +ad I been a constant- t+e value o0 I would +ave been obtained at t+e time
*rogram8 was compiled- and would remain una00ected by c+anges in *rogram2 until *rogram8 is
recompiled.
10.&.3 Volatile fields
6+en a field-declaration includes a volatile modi0ier- t+e 0ields introduced by t+at declaration are volatile
fields.
*or non<volatile 0ields- optimiDation tec+ni9ues t+at reorder instructions can lead to unepected and
unpredictable results in multi<t+readed programs t+at access 0ields wit+out sync+roniDation suc+ as t+at
provided by t+e loc&-state%ent JV3.12M. T+ese optimiDations can be per0ormed by t+e compiler- by t+e runtime
system- or by +ardware. *or volatile 0ields- suc+ reordering optimiDations are restrictedC
( read o0 a volatile 0ield is called a volatile read. ( volatile read +as Kac9uire semanticsLQ t+at is- it is
guaranteed to occur prior to any re0erences to memory t+at occur a0ter it in t+e instruction se9uence.
( write o0 a volatile 0ield is called a volatile 2rite. ( volatile write +as Krelease semanticsLQ t+at is- it is
guaranteed to +appen a0ter any memory re0erences prior to t+e write instruction in t+e instruction se9uence.
T+ese restrictions ensure t+at all t+reads will observe volatile writes per0ormed by any ot+er t+read in t+e order
in w+ic+ t+ey were per0ormed. ( con0orming implementation is not re9uired to provide a single total ordering
o0 volatile writes as seen 0rom all t+reads o0 eecution. T+e type o0 a volatile 0ield must be one o0 t+e 0ollowingC
( reference-t+pe.
T+e type byte- sbyte- s"ort- us"ort- int- uint- c"ar- -loat- bool- System.$nt*tr- or
System.;$nt*tr.
(n en!%-t+pe +aving an enum base type o0 byte- sbyte- s"ort- us"ort- int- or uint.
T+e eample
using System;
using System.1"reading;
3*" Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
class 1est
{
&ublic static int result;
&ublic static volatile bool -inis"ed;
static void 1"read8() {
result + 2J9;
-inis"ed + true;
!
static void Main() {
-inis"ed + -alse;
.. Oun 1"read8() in a ne, t"read
ne, 1"read(ne, 1"readStart(1"read8)).Start();
.. Wait -or 1"read8 to signal t"at it "as a result by setting
.. -inis"ed to true.
-or (;;) {
i- (-inis"ed) {
Console.WriteLine("result + {3!" result);
return;
!
!
!
!
produces t+e outputC
result + 2J9
1n t+is eample- t+e met+od Main starts a new t+read t+at runs t+e met+od 1"read8. T+is met+od stores a value
into a non<volatile 0ield called result- t+en stores true in t+e volatile 0ield -inis"ed. T+e main t+read waits
0or t+e 0ield -inis"ed to be set to true- t+en reads t+e 0ield result. #ince -inis"ed +as been declared
volatile- t+e main t+read must read t+e value 2J9 0rom t+e 0ield result. 10 t+e 0ield -inis"ed +ad not been
declared volatile- t+en it would be permissible 0or t+e store to result to be visible to t+e main t+read after
t+e store to -inis"ed- and +ence 0or t+e main t+read to read t+e value 3 0rom t+e 0ield result. 2eclaring
-inis"ed as a volatile 0ield prevents any suc+ inconsistency.
10.&.# ,ield initiali<ation
T+e initial value o0 a 0ield- w+et+er it be a static 0ield or an instance 0ield- is t+e de0ault value JV".2M o0 t+e
0ieldPs type. 1t is not possible to observe t+e value o0 a 0ield be0ore t+is de0ault initialiDation +as occurred- and a
0ield is t+us never KuninitialiDedL. T+e eample
using System;
class 1est
{
static bool b;
int i;
static void Main() {
1est t + ne, 1est();
Console.WriteLine("b + {3! i + {2!" b t.i);
!
!
produces t+e output
b + Valse i + 3
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 3*
C# Language Specification
because b and i are bot+ automatically initialiDed to de0ault values.
10.&.& Variable initiali<ers
*ield declarations may include varia,le-initiali-ers. *or static 0ields- variable initialiDers correspond to
assignment statements t+at are eecuted during class initialiDation. *or instance 0ields- variable initialiDers
correspond to assignment statements t+at are eecuted w+en an instance o0 t+e class is created.
T+e eample
using System;
class 1est
{
static double # + Mat".SQrt(8.3);
int i + 233;
string s + "Hello";
static void Main() {
1est a + ne, 1est();
Console.WriteLine("# + {3! i + {2! s + {8!" # a.i a.s);
!
!
produces t+e output
# + 2.J2J829KX89M92 i + 233 s + Hello
because an assignment to # occurs w+en static 0ield initialiDers eecute and assignments to i and s occur w+en
t+e instance 0ield initialiDers eecute.
T+e de0ault value initialiDation described in V1..".4 occurs 0or all 0ields- including 0ields t+at +ave variable
initialiDers. T+us- w+en a class is initialiDed- all static 0ields in t+at class are 0irst initialiDed to t+eir de0ault
values- and t+en t+e static 0ield initialiDers are eecuted in tetual order. 5i7ewise- w+en an instance o0 a class is
created- all instance 0ields in t+at instance are 0irst initialiDed to t+eir de0ault values- and t+en t+e instance 0ield
initialiDers are eecuted in tetual order.
1t is possible 0or static 0ields wit+ variable initialiDers to be observed in t+eir de0ault value state. However- t+is is
strongly discouraged as a matter o0 style. T+e eample
using System;
class 1est
{
static int a + b < 2;
static int b + a < 2;
static void Main() {
Console.WriteLine("a + {3! b + {2!" a b);
!
!
e+ibits t+is be+avior. 2espite t+e circular de0initions o0 a and b- t+e program is valid. 1t results in t+e output
a + 2 b + 8
because t+e static 0ields a and b are initialiDed to 3 Jt+e de0ault value 0or intM be0ore t+eir initialiDers are
eecuted. 6+en t+e initialiDer 0or a runs- t+e value o0 b is Dero- and so a is initialiDed to 2. 6+en t+e initialiDer
0or b runs- t+e value o0 a is already 2- and so b is initialiDed to 8.
3*' Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
14.5.5.1 Static /ield initiali@ation
T+e static 0ield variable initialiDers o0 a class correspond to a se9uence o0 assignments t+at are eecuted in t+e
tetual order in w+ic+ t+ey appear in t+e class declaration. 10 a static constructor JV1..12M eists in t+e class-
eecution o0 t+e static 0ield initialiDers occurs immediately prior to eecuting t+at static constructor. /t+erwise-
t+e static 0ield initialiDers are eecuted at an implementation<dependent time prior to t+e 0irst use o0 a static 0ield
o0 t+at class. T+e eample
using System;
class 1est
{
static void Main() {
Console.WriteLine("{3! {2!" :.` '.I);
!
&ublic static int V(string s) {
Console.WriteLine(s);
return 2;
!
!
class '
{
&ublic static int I + 1est.V("$nit '");
!
class :
{
&ublic static int ` + 1est.V("$nit :");
!
mig+t produce eit+er t+e outputC
$nit '
$nit :
2 2
or t+e outputC
$nit :
$nit '
2 2
because t+e eecution o0 IPs initialiDer and `Ps initialiDer could occur in eit+er orderQ t+ey are only constrained
to occur be0ore t+e re0erences to t+ose 0ields. However- in t+e eampleC
using System;
class 1est
{
static void Main() {
Console.WriteLine("{3! {2!" :.` '.I);
!
&ublic static int V(string s) {
Console.WriteLine(s);
return 2;
!
!
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 3*7
C# Language Specification
class '
{
static '() {!
&ublic static int I + 1est.V("$nit '");
!
class :
{
static :() {!
&ublic static int ` + 1est.V("$nit :");
!
t+e output must beC
$nit :
$nit '
2 2
because t+e rules 0or w+en static constructors eecute Jas de0ined in V1..12M provide t+at :Ps static constructor
Jand +ence :Ps static 0ield initialiDersM must run be0ore 'Ps static constructor and 0ield initialiDers.
14.5.5.2 #nstance /ield initiali@ation
T+e instance 0ield variable initialiDers o0 a class correspond to a se9uence o0 assignments t+at are eecuted
immediately upon entry to any one o0 t+e instance constructors JV1..11.1M o0 t+at class. T+e variable initialiDers
are eecuted in t+e tetual order in w+ic+ t+ey appear in t+e class declaration. T+e class instance creation and
initialiDation process is described 0urt+er in V1..11.
( variable initialiDer 0or an instance 0ield cannot re0erence t+e instance being created. T+us- it is a compile<time
error to re0erence t"is in a variable initialiDer- as it is a compile<time error 0or a variable initialiDer to re0erence
any instance member t+roug+ a si%ple-na%e. 1n t+e eample
class '
{
int # + 2;
int y + # < 2; .. )rror re-erence to instance member o- t"is
!
t+e variable initialiDer 0or y results in a compile<time error because it re0erences a member o0 t+e instance being
created.
10.' )et-ods
( ethod is a member t+at implements a computation or action t+at can be per0ormed by an ob&ect or class.
'et+ods are declared using %ethod-declarationsC
%ethod-declaration.
%ethod-header %ethod-,od+
%ethod-header.
attri,!tesopt %ethod-%odifiersopt .!%$i!lopt ret!rn-t+pe %e%,er-na%e t+pe-para%eter-listopt
( for%al-para%eter-listopt ) t+pe-para%eter-constraints-cla!sesopt
%ethod-%odifiers.
%ethod-%odifier
%ethod-%odifiers %ethod-%odifier
3*$ Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
%ethod-%odifier.
*ew
.u"li&
.%'$e&$ed
i*$e%*!l
.%i,!$e
#$!$i&
,i%$u!l
#e!led
',e%%ide
!"#$%!&$
e-$e%*
ret!rn-t+pe.
t+pe
,'id
%e%,er-na%e.
identifier
interface-t+pe 9 identifier
%ethod-,od+.
,loc&
A
( %ethod-declaration may include a set o0 attri,!tes JV1!M and a valid combination o0 t+e 0our access modi0iers
JV1..3."M- t+e ne, JV1..3.4M- static JV1..%.2M- virtual JV1..%.3M- override JV1..%.4M- sealed JV1..%."M-
abstract JV1..%.%M- and e#tern JV1..%.!M modi0iers.
( declaration +as a valid combination o0 modi0iers i0 all o0 t+e 0ollowing are trueC
T+e declaration includes a valid combination o0 access modi0iers JV1..3."M.
T+e declaration does not include t+e same modi0ier multiple times.
T+e declaration includes at most one o0 t+e 0ollowing modi0iersC static- virtual- and override.
T+e declaration includes at most one o0 t+e 0ollowing modi0iersC ne, and override.
10 t+e declaration includes t+e abstract modi0ier- t+en t+e declaration does not include any o0 t+e
0ollowing modi0iersC static- virtual- sealed or e#tern.
10 t+e declaration includes t+e &rivate modi0ier- t+en t+e declaration does not include any o0 t+e 0ollowing
modi0iersC virtual- override- or abstract.
10 t+e declaration includes t+e sealed modi0ier- t+en t+e declaration also includes t+e override modi0ier.
10 t+e declaration includes t+e &artial modi0ier- t+en it does not include any o0 t+e 0ollowing modi0iersC
ne,- &ublic- &rotected- internal- &rivate- virtual- sealed- override- abstract- or e#tern.
T+e ret!rn-t+pe o0 a met+od declaration speci0ies t+e type o0 t+e value computed and returned by t+e met+od.
T+e ret!rn-t+pe is void i0 t+e met+od does not return a value. 10 t+e declaration includes t+e &artial modi0ier-
t+en t+e return type must be void.
T+e %e%,er-na%e speci0ies t+e name o0 t+e met+od. 8nless t+e met+od is an eplicit inter0ace member
implementation JV13.4.1M- t+e %e%,er-na%e is simply an identifier. *or an eplicit inter0ace member
implementation- t+e %e%,er-na%e consists o0 an interface-t+pe 0ollowed by a K.L and an identifier.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 3*!
C# Language Specification
T+e optional t+pe-para%eter-list speci0ies t+e type parameters o0 t+e met+od JV1..1.3M. 10 a t+pe-para%eter-list
is speci0ied t+e met+od is a generic ethod. 10 t+e met+od +as an e#tern modi0ier- a t+pe-para%eter-list
cannot be speci0ied.
T+e optional for%al-para%eter-list speci0ies t+e parameters o0 t+e met+od JV1..%.1M.
T+e optional t+pe-para%eter-constraints-cla!ses speci0y constraints on individual type parameters JV1..1."M and
may only be speci0ied i0 a t+pe-para%eter-list is also supplied- and t+e met+od does not +ave an override
modi0ier.
T+e ret!rn-t+pe and eac+ o0 t+e types re0erenced in t+e for%al-para%eter-list o0 a met+od must be at least as
accessible as t+e met+od itsel0 JV3.".4M.
*or abstract and e#tern met+ods- t+e %ethod-,od+ consists simply o0 a semicolon. *or &artial met+ods
t+e %ethod-,od+ may consist o0 eit+er a semicolon or a ,loc&. *or all ot+er met+ods- t+e %ethod-,od+ consists
o0 a ,loc&- w+ic+ speci0ies t+e statements to eecute w+en t+e met+od is invo7ed.
T+e name- t+e type parameter list and t+e 0ormal parameter list o0 a met+od de0ine t+e signature JV3.%M o0 t+e
met+od. #peci0ically- t+e signature o0 a met+od consists o0 its name- t+e number o0 type parameters and t+e
number- modi0iers- and types o0 its 0ormal parameters. *or t+ese purposes- any type parameter o0 t+e met+od
t+at occurs in t+e type o0 a 0ormal parameter is identi0ied not by its name- but by its ordinal position in t+e type
argument list o0 t+e met+od.T+e return type is not part o0 a met+odPs signature- nor are t+e names o0 t+e type
parameters or t+e 0ormal parameters.
T+e name o0 a met+od must di00er 0rom t+e names o0 all ot+er non<met+ods declared in t+e same class. 1n
addition- t+e signature o0 a met+od must di00er 0rom t+e signatures o0 all ot+er met+ods declared in t+e same
class- and two met+ods declared in t+e same class may not +ave signatures t+at di00er solely by re- and out.
T+e met+odPs t+pe-para%eters are in scope t+roug+out t+e %ethod-declaration- and can be used to 0orm types
t+roug+out t+at scope in ret!rn-t+pe- %ethod-,od+- and t+pe-para%eter-constraints-cla!ses but not in attri,!tes.
(ll 0ormal parameters and type parameters must +ave di00erent names.
10.'.1 )et-od paraeters
T+e parameters o0 a met+od- i0 any- are declared by t+e met+odPs for%al-para%eter-list.
for%al-para%eter-list.
fi/ed-para%eters
fi/ed-para%eters ? para%eter-arra+
para%eter-arra+
fi/ed-para%eters.
fi/ed-para%eter
fi/ed-para%eters ? fi/ed-para%eter
fi/ed-para%eter.
attri,!tesopt para%eter-%odifieropt t+pe identifier
para%eter-%odifier.
%ef
'u$
$hi#
para%eter-arra+.
attri,!tesopt .!%!m# arra+-t+pe identifier
T+e 0ormal parameter list consists o0 one or more comma<separated parameters o0 w+ic+ only t+e last may be a
para%eter-arra+.
31* Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
( fi/ed-para%eter consists o0 an optional set o0 attri,!tes JV1!M- an optional re-- out or t"is modi0ier- a t+pe-
and an identifier. Eac+ fi/ed-para%eter declares a parameter o0 t+e given type wit+ t+e given name. T+e t"is
modi0ier designates t+e met+od as an etension met+od and is only allowed on t+e 0irst parameter o0 a static
met+od. Etension met+ods are 0urt+er described in V1..%.$.
( para%eter-arra+ consists o0 an optional set o0 attri,!tes JV1!M- a &arams modi0ier- an arra+-t+pe- and an
identifier. ( parameter array declares a single parameter o0 t+e given array type wit+ t+e given name. T+e
arra+-t+pe o0 a parameter array must be a single<dimensional array type JV12.1M. 1n a met+od invocation- a
parameter array permits eit+er a single argument o0 t+e given array type to be speci0ied- or it permits Dero or
more arguments o0 t+e array element type to be speci0ied. Parameter arrays are described 0urt+er in V1..%.1.4.
( met+od declaration creates a separate declaration space 0or parameters- type parameters and local variables.
=ames are introduced into t+is declaration space by t+e type parameter list and t+e 0ormal parameter list o0 t+e
met+od and by local variable declarations in t+e ,loc& o0 t+e met+od. 1t is an error 0or two members o0 a met+od
declaration space to +ave t+e same name. 1t is an error 0or t+e met+od declaration space and t+e local variable
declaration space o0 a nested declaration space to contain elements wit+ t+e same name.
( met+od invocation JV!.".".1M creates a copy- speci0ic to t+at invocation- o0 t+e 0ormal parameters and local
variables o0 t+e met+od- and t+e argument list o0 t+e invocation assigns values or variable re0erences to t+e
newly created 0ormal parameters. 6it+in t+e ,loc& o0 a met+od- 0ormal parameters can be re0erenced by t+eir
identi0iers in si%ple-na%e epressions JV!.".2M.
T+ere are 0our 7inds o0 0ormal parametersC
,alue parameters- w+ic+ are declared wit+out any modi0iers.
;e0erence parameters- w+ic+ are declared wit+ t+e re- modi0ier.
/utput parameters- w+ic+ are declared wit+ t+e out modi0ier.
Parameter arrays- w+ic+ are declared wit+ t+e &arams modi0ier.
(s described in V3.%- t+e re- and out modi0iers are part o0 a met+odPs signature- but t+e &arams modi0ier is
not.
14.6.1.1 Value "arameters
( parameter declared wit+ no modi0iers is a value parameter. ( value parameter corresponds to a local variable
t+at gets its initial value 0rom t+e corresponding argument supplied in t+e met+od invocation.
6+en a 0ormal parameter is a value parameter- t+e corresponding argument in a met+od invocation must be an
epression o0 a type t+at is implicitly convertible JV%.1M to t+e 0ormal parameter type.
( met+od is permitted to assign new values to a value parameter. #uc+ assignments only a00ect t+e local storage
location represented by t+e value parameterRt+ey +ave no e00ect on t+e actual argument given in t+e met+od
invocation.
14.6.1.2 )e/erence "arameters
( parameter declared wit+ a re- modi0ier is a re0erence parameter. 8nli7e a value parameter- a re0erence
parameter does not create a new storage location. 1nstead- a re0erence parameter represents t+e same storage
location as t+e variable given as t+e argument in t+e met+od invocation.
6+en a 0ormal parameter is a re0erence parameter- t+e corresponding argument in a met+od invocation must
consist o0 t+e 7eyword re- 0ollowed by a varia,le-reference JV".3.3M o0 t+e same type as t+e 0ormal parameter.
( variable must be de0initely assigned be0ore it can be passed as a re0erence parameter.
6it+in a met+od- a re0erence parameter is always considered de0initely assigned.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 311
C# Language Specification
( met+od declared as an iterator JV1..14M cannot +ave re0erence parameters.
T+e eample
using System;
class 1est
{
static void S,a&(re- int # re- int y) {
int tem& + #;
# + y;
y + tem&;
!
static void Main() {
int i + 2 j + 8;
S,a&(re- i re- j);
Console.WriteLine("i + {3! j + {2!" i j);
!
!
produces t+e output
i + 8 j + 2
*or t+e invocation o0 S,a& in Main- # represents i and y represents j. T+us- t+e invocation +as t+e e00ect o0
swapping t+e values o0 i and j.
1n a met+od t+at ta7es re0erence parameters it is possible 0or multiple names to represent t+e same storage
location. 1n t+e eample
class '
{
string s;
void V(re- string a re- string b) {
s + "%ne";
a + "1,o";
b + "1"ree";
!
void S() {
V(re- s re- s);
!
!
t+e invocation o0 V in S passes a re0erence to s 0or bot+ a and b. T+us- 0or t+at invocation- t+e names s- a- and b
all re0er to t+e same storage location- and t+e t+ree assignments all modi0y t+e instance 0ield s.
14.6.1.3 &ut"ut "arameters
( parameter declared wit+ an out modi0ier is an output parameter. #imilar to a re0erence parameter- an output
parameter does not create a new storage location. 1nstead- an output parameter represents t+e same storage
location as t+e variable given as t+e argument in t+e met+od invocation.
6+en a 0ormal parameter is an output parameter- t+e corresponding argument in a met+od invocation must
consist o0 t+e 7eyword out 0ollowed by a varia,le-reference JV".3.3M o0 t+e same type as t+e 0ormal parameter.
( variable need not be de0initely assigned be0ore it can be passed as an output parameter- but 0ollowing an
invocation w+ere a variable was passed as an output parameter- t+e variable is considered de0initely assigned.
312 Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
6it+in a met+od- &ust li7e a local variable- an output parameter is initially considered unassigned and must be
de0initely assigned be0ore its value is used.
Every output parameter o0 a met+od must be de0initely assigned be0ore t+e met+od returns.
( met+od declared as a partial met+od JV1..2.!M or an iterator JV1..14M cannot +ave output parameters.
/utput parameters are typically used in met+ods t+at produce multiple return values. *or eampleC
using System;
class 1est
{
static void S&lit*at"(string &at" out string dir out string name) {
int i + &at".Lengt";
,"ile (i E 3) {
c"ar c" + &at"4i C 25;
i- (c" ++ WZZW HH c" ++ W.W HH c" ++ W/W) brea(;
i==;
!
dir + &at".Substring(3 i);
name + &at".Substring(i);
!
static void Main() {
string dir name;
S&lit*at"("c/ZZWindo,sZZSystemZZ"ello.t#t" out dir out name);
Console.WriteLine(dir);
Console.WriteLine(name);
!
!
T+e eample produces t+e outputC
c/ZWindo,sZSystemZ
"ello.t#t
=ote t+at t+e dir and name variables can be unassigned be0ore t+ey are passed to S&lit*at"- and t+at t+ey are
considered de0initely assigned 0ollowing t+e call.
14.6.1.4 Parameter arrays
( parameter declared wit+ a &arams modi0ier is a parameter array. 10 a 0ormal parameter list includes a
parameter array- it must be t+e last parameter in t+e list and it must be o0 a single<dimensional array type. *or
eample- t+e types string45 and string4545 can be used as t+e type o0 a parameter array- but t+e type
string45 can not. 1t is not possible to combine t+e &arams modi0ier wit+ t+e modi0iers re- and out.
( parameter array permits arguments to be speci0ied in one o0 two ways in a met+od invocationC
T+e argument given 0or a parameter array can be a single epression o0 a type t+at is implicitly convertible
JV%.1M to t+e parameter array type. 1n t+is case- t+e parameter array acts precisely li7e a value parameter.
(lternatively- t+e invocation can speci0y Dero or more arguments 0or t+e parameter array- w+ere eac+
argument is an epression o0 a type t+at is implicitly convertible JV%.1M to t+e element type o0 t+e parameter
array. 1n t+is case- t+e invocation creates an instance o0 t+e parameter array type wit+ a lengt+ corresponding
to t+e number o0 arguments- initialiDes t+e elements o0 t+e array instance wit+ t+e given argument values-
and uses t+e newly created array instance as t+e actual argument.
Ecept 0or allowing a variable number o0 arguments in an invocation- a parameter array is precisely e9uivalent
to a value parameter JV1..%.1.1M o0 t+e same type.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 313
C# Language Specification
T+e eample
using System;
class 1est
{
static void V(&arams int45 args) {
Console.Write("'rray contains {3! elements/" args.Lengt");
-oreac" (int i in args)
Console.Write(" {3!" i);
Console.WriteLine();
!
static void Main() {
int45 arr + {2 8 9!;
V(arr);
V(23 83 93 J3);
V();
!
!
produces t+e output
'rray contains 9 elements/ 2 8 9
'rray contains J elements/ 23 83 93 J3
'rray contains 3 elements/
T+e 0irst invocation o0 V simply passes t+e array a as a value parameter. T+e second invocation o0 V
automatically creates a 0our<element int45 wit+ t+e given element values and passes t+at array instance as a
value parameter. 5i7ewise- t+e t+ird invocation o0 V creates a Dero<element int45 and passes t+at instance as a
value parameter. T+e second and t+ird invocations are precisely e9uivalent to writingC
V(ne, int45 {23 83 93 J3!);
V(ne, int45 {!);
6+en per0orming overload resolution- a met+od wit+ a parameter array may be applicable eit+er in its normal
0orm or in its epanded 0orm JV!.4.3.1M. T+e epanded 0orm o0 a met+od is available only i0 t+e normal 0orm o0
t+e met+od is not applicable and only i0 a met+od wit+ t+e same signature as t+e epanded 0orm is not already
declared in t+e same type.
T+e eample
using System;
class 1est
{
static void V(&arams object45 a) {
Console.WriteLine("V(object45)");
!
static void V() {
Console.WriteLine("V()");
!
static void V(object a3 object a2) {
Console.WriteLine("V(objectobject)");
!
31" Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
static void Main() {
V();
V(2);
V(2 8);
V(2 8 9);
V(2 8 9 J);
!
!
produces t+e output
V();
V(object45);
V(objectobject);
V(object45);
V(object45);
1n t+e eample- two o0 t+e possible epanded 0orms o0 t+e met+od wit+ a parameter array are already included in
t+e class as regular met+ods. T+ese epanded 0orms are t+ere0ore not considered w+en per0orming overload
resolution- and t+e 0irst and t+ird met+od invocations t+us select t+e regular met+ods. 6+en a class declares a
met+od wit+ a parameter array- it is not uncommon to also include some o0 t+e epanded 0orms as regular
met+ods. )y doing so it is possible to avoid t+e allocation o0 an array instance t+at occurs w+en an epanded
0orm o0 a met+od wit+ a parameter array is invo7ed.
6+en t+e type o0 a parameter array is object45- a potential ambiguity arises between t+e normal 0orm o0 t+e
met+od and t+e epended 0orm 0or a single object parameter. T+e reason 0or t+e ambiguity is t+at an
object45 is itsel0 implicitly convertible to type object. T+e ambiguity presents no problem- +owever- since it
can be resolved by inserting a cast i0 needed.
T+e eample
using System;
class 1est
{
static void V(&arams object45 args) {
-oreac" (object o in args) {
Console.Write(o.Set1y&e().VullName);
Console.Write(" ");
!
Console.WriteLine();
!
static void Main() {
object45 a + {2 "Hello" 289.JKX!;
object o + a;
V(a);
V((object)a);
V(o);
V((object45)o);
!
!
produces t+e output
System.$nt98 System.String System.6ouble
System.%bject45
System.%bject45
System.$nt98 System.String System.6ouble
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 31
C# Language Specification
1n t+e 0irst and last invocations o0 V- t+e normal 0orm o0 V is applicable because an implicit conversion eists
0rom t+e argument type to t+e parameter type Jbot+ are o0 type object45M. T+us- overload resolution selects t+e
normal 0orm o0 V- and t+e argument is passed as a regular value parameter. 1n t+e second and t+ird invocations-
t+e normal 0orm o0 V is not applicable because no implicit conversion eists 0rom t+e argument type to t+e
parameter type Jtype object cannot be implicitly converted to type object45M. However- t+e epanded 0orm
o0 V is applicable- so it is selected by overload resolution. (s a result- a one<element object45 is created by t+e
invocation- and t+e single element o0 t+e array is initialiDed wit+ t+e given argument value Jw+ic+ itsel0 is a
re0erence to an object45M.
10.'.2 Static and instance et-ods
6+en a met+od declaration includes a static modi0ier- t+at met+od is said to be a static met+od. 6+en no
static modi0ier is present- t+e met+od is said to be an instance met+od.
( static met+od does not operate on a speci0ic instance- and it is a compile<time error to re0er to t"is in a static
met+od.
(n instance met+od operates on a given instance o0 a class- and t+at instance can be accessed as t"is JV!.".!M.
6+en a met+od is re0erenced in a %e%,er-access JV!.".4M o0 t+e 0orm ).M- i0 M is a static met+od- ) must
denote a type containing M- and i0 M is an instance met+od- ) must denote an instance o0 a type containing M.
T+e di00erences between static and instance members are discussed 0urt+er in V1..3.!.
10.'.3 Virtual et-ods
6+en an instance met+od declaration includes a virtual modi0ier- t+at met+od is said to be a virtual met+od.
6+en no virtual modi0ier is present- t+e met+od is said to be a non<virtual met+od.
T+e implementation o0 a non<virtual met+od is invariantC T+e implementation is t+e same w+et+er t+e met+od is
invo7ed on an instance o0 t+e class in w+ic+ it is declared or an instance o0 a derived class. 1n contrast- t+e
implementation o0 a virtual met+od can be superseded by derived classes. T+e process o0 superseding t+e
implementation o0 an in+erited virtual met+od is 7nown as overriding t+at met+od JV1..%.4M.
1n a virtual met+od invocation- t+e r-n-tie type o0 t+e instance 0or w+ic+ t+at invocation ta7es place
determines t+e actual met+od implementation to invo7e. 1n a non<virtual met+od invocation- t+e copile-tie
type o0 t+e instance is t+e determining 0actor. 1n precise terms- w+en a met+od named N is invo7ed wit+ an
argument list ' on an instance wit+ a compile<time type C and a run<time type O Jw+ere O is eit+er C or a class
derived 0rom CM- t+e invocation is processed as 0ollowsC
*irst- overload resolution is applied to C- N- and '- to select a speci0ic met+od M 0rom t+e set o0 met+ods
declared in and in+erited by C. T+is is described in V!.".".1.
T+en- i0 M is a non<virtual met+od- M is invo7ed.
/t+erwise- M is a virtual met+od- and t+e most derived implementation o0 M wit+ respect to O is invo7ed.
*or every virtual met+od declared in or in+erited by a class- t+ere eists a ost derived ipleentation o0 t+e
met+od wit+ respect to t+at class. T+e most derived implementation o0 a virtual met+od M wit+ respect to a class
O is determined as 0ollowsC
10 O contains t+e introducing virtual declaration o0 M- t+en t+is is t+e most derived implementation o0 M.
/t+erwise- i0 O contains an override o0 M- t+en t+is is t+e most derived implementation o0 M.
/t+erwise- t+e most derived implementation o0 M wit+ respect to O is t+e same as t+e most derived
implementation o0 M wit+ respect to t+e direct base class o0 O.
31' Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
T+e 0ollowing eample illustrates t+e di00erences between virtual and non<virtual met+odsC
using System;
class '
{
&ublic void V() { Console.WriteLine("'.V"); !
&ublic virtual void S() { Console.WriteLine("'.S"); !
!
class :/ '
{
ne, &ublic void V() { Console.WriteLine(":.V"); !
&ublic override void S() { Console.WriteLine(":.S"); !
!
class 1est
{
static void Main() {
: b + ne, :();
' a + b;
a.V();
b.V();
a.S();
b.S();
!
!
1n t+e eample- ' introduces a non<virtual met+od V and a virtual met+od S. T+e class : introduces a new non<
virtual met+od V- t+us hiding t+e in+erited V- and also overrides t+e in+erited met+od S. T+e eample produces
t+e outputC
'.V
:.V
:.S
:.S
=otice t+at t+e statement a.S() invo7es :.S- not '.S. T+is is because t+e run<time type o0 t+e instance Jw+ic+
is :M- not t+e compile<time type o0 t+e instance Jw+ic+ is 'M- determines t+e actual met+od implementation to
invo7e.
)ecause met+ods are allowed to +ide in+erited met+ods- it is possible 0or a class to contain several virtual
met+ods wit+ t+e same signature. T+is does not present an ambiguity problem- since all but t+e most derived
met+od are +idden. 1n t+e eample
using System;
class '
{
&ublic virtual void V() { Console.WriteLine("'.V"); !
!
class :/ '
{
&ublic override void V() { Console.WriteLine(":.V"); !
!
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 317
C# Language Specification
class C/ :
{
ne, &ublic virtual void V() { Console.WriteLine("C.V"); !
!
class 6/ C
{
&ublic override void V() { Console.WriteLine("6.V"); !
!
class 1est
{
static void Main() {
6 d + ne, 6();
' a + d;
: b + d;
C c + d;
a.V();
b.V();
c.V();
d.V();
!
!
t+e C and 6 classes contain two virtual met+ods wit+ t+e same signatureC T+e one introduced by ' and t+e one
introduced by C. T+e met+od introduced by C +ides t+e met+od in+erited 0rom '. T+us- t+e override declaration
in 6 overrides t+e met+od introduced by C- and it is not possible 0or 6 to override t+e met+od introduced by '.
T+e eample produces t+e outputC
:.V
:.V
6.V
6.V
=ote t+at it is possible to invo7e t+e +idden virtual met+od by accessing an instance o0 6 t+roug+ a less derived
type in w+ic+ t+e met+od is not +idden.
10.'.# /"erride et-ods
6+en an instance met+od declaration includes an override modi0ier- t+e met+od is said to be an override
ethod. (n override met+od overrides an in+erited virtual met+od wit+ t+e same signature. 6+ereas a virtual
met+od declaration introd!ces a new met+od- an override met+od declaration speciali-es an eisting in+erited
virtual met+od by providing a new implementation o0 t+at met+od.
T+e met+od overridden by an override declaration is 7nown as t+e overridden !ase ethod. *or an override
met+od M declared in a class C- t+e overridden base met+od is determined by eamining eac+ base class type o0
C- starting wit+ t+e direct base class type o0 C and continuing wit+ eac+ successive direct base class type- until in
a given base class type at least one accessible met+od is located w+ic+ +as t+e same signature as M a0ter
substitution o0 type arguments. *or t+e purposes o0 locating t+e overridden base met+od- a met+od is considered
accessible i0 it is &ublic- i0 it is &rotected- i0 it is &rotected internal- or i0 it is internal and declared
in t+e same program as C.
( compile<time error occurs unless all o0 t+e 0ollowing are true 0or an override declarationC
(n overridden base met+od can be located as described above.
T+ere is eactly one suc+ overridden base met+od. T+is restriction +as e00ect only i0 t+e base class type is a
constructed type w+ere t+e substitution o0 type arguments ma7es t+e signature o0 two met+ods t+e same.
31$ Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
T+e overridden base met+od is a virtual- abstract- or override met+od. 1n ot+er words- t+e overridden base
met+od cannot be static or non<virtual.
T+e overridden base met+od is not a sealed met+od.
T+e override met+od and t+e overridden base met+od +ave t+e same return type.
T+e override declaration and t+e overridden base met+od +ave t+e same declared accessibility. 1n ot+er
words- an override declaration cannot c+ange t+e accessibility o0 t+e virtual met+od. However- i0 t+e
overridden base met+od is protected internal and it is declared in a di00erent assembly t+an t+e assembly
containing t+e override met+od t+en t+e override met+odPs declared accessibility must be protected.
T+e override declaration does not speci0y type<parameter<constraints<clauses. 1nstead t+e constraints are
in+erited 0rom t+e overridden base met+od.
T+e 0ollowing eample demonstrates +ow t+e overriding rules wor7 0or generic classesC
abstract class CD1E
{
&ublic virtual 1 V() {...!
&ublic virtual CD1E S() {...!
&ublic virtual void H(CD1E #) {...!
!
class 6/ CDstringE
{
&ublic override string V() {...! .. %(
&ublic override CDstringE S() {...! .. %(
&ublic override void H(CD1E #) {...! .. )rror s"ould be CDstringE
!
class )D1;E/ CD;E
{
&ublic override ; V() {...! .. %(
&ublic override CD;E S() {...! .. %(
&ublic override void H(CD1E #) {...! .. )rror s"ould be CD;E
!
(n override declaration can access t+e overridden base met+od using a ,ase-access JV!.".3M. 1n t+e eample
class '
{
int #;
&ublic virtual void *rintVields() {
Console.WriteLine("# + {3!" #);
!
!
class :/ '
{
int y;
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 31!
C# Language Specification
&ublic override void *rintVields() {
base.*rintVields();
Console.WriteLine("y + {3!" y);
!
!
t+e base.*rintVields() invocation in : invo7es t+e *rintVields met+od declared in '. ( ,ase-access
disables t+e virtual invocation mec+anism and simply treats t+e base met+od as a non<virtual met+od. Had t+e
invocation in : been written ((')t"is).*rintVields()- it would recursively invo7e t+e *rintVields
met+od declared in :- not t+e one declared in '- since *rintVields is virtual and t+e run<time type o0
((')t"is) is :.
/nly by including an override modi0ier can a met+od override anot+er met+od. 1n all ot+er cases- a met+od
wit+ t+e same signature as an in+erited met+od simply +ides t+e in+erited met+od. 1n t+e eample
class '
{
&ublic virtual void V() {!
!
class :/ '
{
&ublic virtual void V() {! .. Warning "iding in"erited V()
!
t+e V met+od in : does not include an override modi0ier and t+ere0ore does not override t+e V met+od in '.
;at+er- t+e V met+od in : +ides t+e met+od in '- and a warning is reported because t+e declaration does not
include a ne, modi0ier.
1n t+e eample
class '
{
&ublic virtual void V() {!
!
class :/ '
{
ne, &rivate void V() {! .. Hides '.V ,it"in body o- :
!
class C/ :
{
&ublic override void V() {! .. %( overrides '.V
!
t+e V met+od in : +ides t+e virtual V met+od in+erited 0rom '. #ince t+e new V in : +as private access- its scope
only includes t+e class body o0 : and does not etend to C. T+ere0ore- t+e declaration o0 V in C is permitted to
override t+e V in+erited 0rom '.
10.'.& Sealed et-ods
6+en an instance met+od declaration includes a sealed modi0ier- t+at met+od is said to be a sealed ethod. 10
an instance met+od declaration includes t+e sealed modi0ier- it must also include t+e override modi0ier. 8se
o0 t+e sealed modi0ier prevents a derived class 0rom 0urt+er overriding t+e met+od.
T+e eample
using System;
32* Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
class '
{
&ublic virtual void V() {
Console.WriteLine("'.V");
!
&ublic virtual void S() {
Console.WriteLine("'.S");
!
!
class :/ '
{
sealed override &ublic void V() {
Console.WriteLine(":.V");
!
override &ublic void S() {
Console.WriteLine(":.S");
!
!
class C/ :
{
override &ublic void S() {
Console.WriteLine("C.S");
!
!
t+e class : provides two override met+odsC an V met+od t+at +as t+e sealed modi0ier and a S met+od t+at does
not. :Ps use o0 t+e sealed modi-ier prevents C 0rom 0urt+er overriding V.
10.'.' *bstract et-ods
6+en an instance met+od declaration includes an abstract modi0ier- t+at met+od is said to be an a!stract
ethod. (lt+oug+ an abstract met+od is implicitly also a virtual met+od- it cannot +ave t+e modi0ier virtual.
(n abstract met+od declaration introduces a new virtual met+od but does not provide an implementation o0 t+at
met+od. 1nstead- non<abstract derived classes are re9uired to provide t+eir own implementation by overriding
t+at met+od. )ecause an abstract met+od provides no actual implementation- t+e %ethod-,od+ o0 an abstract
met+od simply consists o0 a semicolon.
(bstract met+od declarations are only permitted in abstract classes JV1..1.1.1M.
1n t+e eample
&ublic abstract class S"a&e
{
&ublic abstract void *aint(Sra&"ics g Oectangle r);
!
&ublic class )lli&se/ S"a&e
{
&ublic override void *aint(Sra&"ics g Oectangle r) {
g.6ra,)lli&se(r);
!
!
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 321
C# Language Specification
&ublic class :o#/ S"a&e
{
&ublic override void *aint(Sra&"ics g Oectangle r) {
g.6ra,Oect(r);
!
!
t+e S"a&e class de0ines t+e abstract notion o0 a geometrical s+ape ob&ect t+at can paint itsel0. T+e *aint
met+od is abstract because t+ere is no meaning0ul de0ault implementation. T+e )lli&se and :o# classes are
concrete S"a&e implementations. )ecause t+ese classes are non<abstract- t+ey are re9uired to override t+e
*aint met+od and provide an actual implementation.
1t is a compile<time error 0or a ,ase-access JV!.".3M to re0erence an abstract met+od. 1n t+e eample
abstract class '
{
&ublic abstract void V();
!
class :/ '
{
&ublic override void V() {
base.V(); .. )rror base.V is abstract
!
!
a compile<time error is reported 0or t+e base.V() invocation because it re0erences an abstract met+od.
(n abstract met+od declaration is permitted to override a virtual met+od. T+is allows an abstract class to 0orce
re<implementation o0 t+e met+od in derived classes- and ma7es t+e original implementation o0 t+e met+od
unavailable. 1n t+e eample
using System;
class '
{
&ublic virtual void V() {
Console.WriteLine("'.V");
!
!
abstract class :/ '
{
&ublic abstract override void V();
!
class C/ :
{
&ublic override void V() {
Console.WriteLine("C.V");
!
!
class ' declares a virtual met+od- class : overrides t+is met+od wit+ an abstract met+od- and class C overrides
t+e abstract met+od to provide its own implementation.
10.'.. $%ternal et-ods
6+en a met+od declaration includes an e#tern modi0ier- t+at met+od is said to be an e,ternal ethod.
Eternal met+ods are implemented eternally- typically using a language ot+er t+an C#. )ecause an eternal
322 Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
met+od declaration provides no actual implementation- t+e %ethod-,od+ o0 an eternal met+od simply consists
o0 a semicolon. (n eternal met+od may not be generic.
T+e e#tern modi0ier is typically used in con&unction wit+ a 6ll$m&ort attribute JV1!.".1M- allowing eternal
met+ods to be implemented by 255s J2ynamic 5in7 5ibrariesM. T+e eecution environment may support ot+er
mec+anisms w+ereby implementations o0 eternal met+ods can be provided.
6+en an eternal met+od includes a 6ll$m&ort attribute- t+e met+od declaration must also include a static
modi0ier. T+is eample demonstrates t+e use o0 t+e e#tern modi0ier and t+e 6ll$m&ort attributeC
using System.1e#t;
using System.Security.*ermissions;
using System.Ountime.$ntero&Services;
class *at"
{
46ll$m&ort("(ernel98" SetLast)rror+true)5
static e#tern bool Create6irectory(string name Security'ttribute sa);
46ll$m&ort("(ernel98" SetLast)rror+true)5
static e#tern bool Oemove6irectory(string name);
46ll$m&ort("(ernel98" SetLast)rror+true)5
static e#tern int SetCurrent6irectory(int bu-Si?e String:uilder bu-);
46ll$m&ort("(ernel98" SetLast)rror+true)5
static e#tern bool SetCurrent6irectory(string name);
!
10.'.0 Partial et-ods
6+en a met+od declaration includes a &artial modi0ier- t+at met+od is said to be a partial ethod. Partial
met+ods can only be declared as members o0 partial types JV1..2M- and are sub&ect to a number o0 restrictions.
Partial met+ods are 0urt+er described in V1..2.!.
10.'.1 $%tension et-ods
6+en t+e 0irst parameter o0 a met+od includes t+e t"is modi0ier- t+at met+od is said to be an e,tension
ethod. Etension met+ods can only be declared in non<generic- non<nested static classes. T+e 0irst parameter
o0 an etension met+od can +ave no modi0iers ot+er t+an t"is- and t+e parameter type cannot be a pointer type.
T+e 0ollowing is an eample o0 a static class t+at declares two etension met+odsC
&ublic static class )#tensions
{
&ublic static int 1o$nt98(t"is string s) {
return $nt98.*arse(s);
!
&ublic static 145 SliceD1E(t"is 145 source int inde# int count) {
i- (inde# D 3 HH count D 3 HH source.Lengt" C inde# D count)
t"ro, ne, 'rgument)#ce&tion();
145 result + ne, 14count5;
'rray.Co&y(source inde# result 3 count);
return result;
!
!
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 323
C# Language Specification
(n etension met+od is a regular static met+od. 1n addition- w+ere its enclosing static class is in scope- an
etension met+od can be invo7ed using instance met+od invocation synta JV!.".".2M- using t+e receiver
epression as t+e 0irst argument.
T+e 0ollowing program uses t+e etension met+ods declared aboveC
static class *rogram
{
static void Main() {
string45 strings + { "2" "88" "999" "JJJJ" !;
-oreac" (string s in strings.Slice(2 8)) {
Console.WriteLine(s.1o$nt98());
!
!
!
T+e #lice met+od is available on t+e string`a- and t+e To1nt32 met+od is available on string- because t+ey +ave
been declared as etension met+ods. T+e meaning o0 t+e program is t+e same as t+e 0ollowing- using ordinary
static met+od callsC
static class *rogram
{
static void Main() {
string45 strings + { "2" "88" "999" "JJJJ" !;
-oreac" (string s in )#tensions.Slice(strings 2 8)) {
Console.WriteLine()#tensions.1o$nt98(s));
!
!
!
10.'.10 )et-od bod!
T+e %ethod-,od+ o0 a met+od declaration consists o0 eit+er a ,loc& or a semicolon.
(bstract and eternal met+od declarations do not provide a met+od implementation- so t+eir met+od bodies
simply consist o0 a semicolon. *or any ot+er met+od- t+e met+od body is a bloc7 JV3.2M t+at contains t+e
statements to eecute w+en t+at met+od is invo7ed.
6+en t+e return type o0 a met+od is void- return statements JV3.$.4M in t+at met+odPs body are not permitted
to speci0y an epression. 10 eecution o0 t+e met+od body o0 a void met+od completes normally Jt+at is- control
0lows o00 t+e end o0 t+e met+od bodyM- t+at met+od simply returns to its caller.
6+en t+e return type o0 a met+od is not void- eac+ return statement in t+at met+odPs body must speci0y an
epression o0 a type t+at is implicitly convertible to t+e return type. T+e endpoint o0 t+e met+od body o0 a value<
returning met+od must not be reac+able. 1n ot+er words- in a value<returning met+od- control is not permitted to
0low o00 t+e end o0 t+e met+od body.
1n t+e eample
class '
{
&ublic int V() {! .. )rror return value reQuired
&ublic int S() {
return 2;
!
32" Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
&ublic int H(bool b) {
i- (b) {
return 2;
!
else {
return 3;
!
!
!
t+e value<returning V met+od results in a compile<time error because control can 0low o00 t+e end o0 t+e met+od
body. T+e S and H met+ods are correct because all possible eecution pat+s end in a return statement t+at
speci0ies a return value.
10.'.11 )et-od o"erloading
T+e met+od overload resolution rules are described in V!.4.2.
10.. Properties
( property is a member t+at provides access to a c+aracteristic o0 an ob&ect or a class. Eamples o0 properties
include t+e lengt+ o0 a string- t+e siDe o0 a 0ont- t+e caption o0 a window- t+e name o0 a customer- and so on.
Properties are a natural etension o0 0ieldsRbot+ are named members wit+ associated types- and t+e synta 0or
accessing 0ields and properties is t+e same. However- unli7e 0ields- properties do not denote storage locations.
1nstead- properties +ave accessors t+at speci0y t+e statements to be eecuted w+en t+eir values are read or
written. Properties t+us provide a mec+anism 0or associating actions wit+ t+e reading and writing o0 an ob&ectPs
attributesQ 0urt+ermore- t+ey permit suc+ attributes to be computed.
Properties are declared using propert+-declarationsC
propert+-declaration.
attri,!tesopt propert+-%odifiersopt t+pe %e%,er-na%e { accessor-declarations }
propert+-%odifiers.
propert+-%odifier
propert+-%odifiers propert+-%odifier
propert+-%odifier.
*ew
.u"li&
.%'$e&$ed
i*$e%*!l
.%i,!$e
#$!$i&
,i%$u!l
#e!led
',e%%ide
!"#$%!&$
e-$e%*
%e%,er-na%e.
identifier
interface-t+pe 9 identifier
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 32
C# Language Specification
( propert+-declaration may include a set o0 attri,!tes JV1!M and a valid combination o0 t+e 0our access
modi0iers JV1..3."M- t+e ne, JV1..3.4M- static JV1..%.2M- virtual JV1..%.3M- override JV1..%.4M- sealed
JV1..%."M- abstract JV1..%.%M- and e#tern JV1..%.!M modi0iers.
Property declarations are sub&ect to t+e same rules as met+od declarations JV1..%M wit+ regard to valid
combinations o0 modi0iers.
T+e t+pe o0 a property declaration speci0ies t+e type o0 t+e property introduced by t+e declaration- and t+e
%e%,er-na%e speci0ies t+e name o0 t+e property. 8nless t+e property is an eplicit inter0ace member
implementation- t+e %e%,er-na%e is simply an identifier. *or an eplicit inter0ace member implementation
JV13.4.1M- t+e %e%,er-na%e consists o0 an interface-t+pe 0ollowed by a K.L and an identifier.
T+e t+pe o0 a property must be at least as accessible as t+e property itsel0 JV3.".4M.
T+e accessor-declarations- w+ic+ must be enclosed in K{L and K!L to7ens- declare t+e accessors JV1..!.2M o0 t+e
property. T+e accessors speci0y t+e eecutable statements associated wit+ reading and writing t+e property.
Even t+oug+ t+e synta 0or accessing a property is t+e same as t+at 0or a 0ield- a property is not classi0ied as a
variable. T+us- it is not possible to pass a property as a re- or out argument.
6+en a property declaration includes an e#tern modi0ier- t+e property is said to be an e,ternal property.
)ecause an eternal property declaration provides no actual implementation- eac+ o0 its accessor-declarations
consists o0 a semicolon.
10...1 Static and instance properties
6+en a property declaration includes a static modi0ier- t+e property is said to be a static property. 6+en no
static modi0ier is present- t+e property is said to be an instance property.
( static property is not associated wit+ a speci0ic instance- and it is a compile<time error to re0er to t"is in t+e
accessors o0 a static property.
(n instance property is associated wit+ a given instance o0 a class- and t+at instance can be accessed as t"is
JV!.".!M in t+e accessors o0 t+at property.
6+en a property is re0erenced in a %e%,er-access JV!.".4M o0 t+e 0orm ).M- i0 M is a static property- ) must
denote a type containing M- and i0 M is an instance property- E must denote an instance o0 a type containing M.
T+e di00erences between static and instance members are discussed 0urt+er in V1..3.!.
10...2 *ccessors
T+e accessor-declarations o0 a property speci0y t+e eecutable statements associated wit+ reading and writing
t+at property.
accessor-declarations.
get-accessor-declaration set-accessor-declarationopt
set-accessor-declaration get-accessor-declarationopt
get-accessor-declaration.
attri,!tesopt accessor-%odifieropt +e$ accessor-,od+
set-accessor-declaration.
attri,!tesopt accessor-%odifieropt #e$ accessor-,od+
32' Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
accessor-%odifier.
.%'$e&$ed
i*$e%*!l
.%i,!$e
.%'$e&$ed i*$e%*!l
i*$e%*!l .%'$e&$ed
accessor-,od+.
,loc&
A
T+e accessor declarations consist o0 a get-accessor-declaration- a set-accessor-declaration- or bot+. Eac+
accessor declaration consists o0 t+e to7en get or set 0ollowed by an optional accessor-%odifier and an
accessor-,od+.
T+e use o0 accessor-%odifiers is governed by t+e 0ollowing restrictionsC
(n accessor-%odifier may not be used in an inter0ace or in an eplicit inter0ace member implementation.
*or a property or indeer t+at +as no override modi0er- an accessor-%odifier is permitted only i0 t+e
property or indeer +as bot+ a get and set accessor- and t+en is permitted only on one o0 t+ose accessors.
*or a property or indeer t+at includes an override modi0er- an accessor must matc+ t+e accessor-
%odifier- i0 any- o0 t+e accessor being overridden.
T+e accessor-%odifier must declare an accessibility t+at is strictly more restrictive t+an t+e declared
accessibility o0 t+e property or indeer itsel0. To be preciseC
o 10 t+e property or indeer +as a declared accessibility o0 &ublic- any accessor-%odifier may be used.
o 10 t+e property or indeer +as a declared accessibility o0 &rotected internal- t+e accessor-%odifier
may be eit+er internal- &rotected- or &rivate.
o 10 t+e property or indeer +as a declared accessibility o0 internal or &rotected- t+e accessor-
%odifier must be &rivate.
o 10 t+e property or indeer +as a declared accessibility o0 &rivate- no accessor-%odifier may be used.
*or abstract and e#tern properties- t+e accessor-,od+ 0or eac+ accessor speci0ied is simply a semicolon. (
non<abstract- non<etern property may be an a-toatically ipleented property- in w+ic+ case bot+ get and
set accessors must be given- bot+ wit+ a semicolon body JV1..!.3M. *or t+e accessors o0 any ot+er non<abstract-
non<etern property- t+e accessor-,od+ is a ,loc& w+ic+ speci0ies t+e statements to be eecuted w+en t+e
corresponding accessor is invo7ed.
( get accessor corresponds to a parameterless met+od wit+ a return value o0 t+e property type. Ecept as t+e
target o0 an assignment- w+en a property is re0erenced in an epression- t+e get accessor o0 t+e property is
invo7ed to compute t+e value o0 t+e property JV!.1.1M. T+e body o0 a get accessor must con0orm to t+e rules 0or
value<returning met+ods described in V1..%.1.. 1n particular- all return statements in t+e body o0 a get
accessor must speci0y an epression t+at is implicitly convertible to t+e property type. *urt+ermore- t+e endpoint
o0 a get accessor must not be reac+able.
( set accessor corresponds to a met+od wit+ a single value parameter o0 t+e property type and a void return
type. T+e implicit parameter o0 a set accessor is always named value. 6+en a property is re0erenced as t+e
target o0 an assignment JV!.1%M- or as t+e operand o0 << or == JV!.".$- V!.%."M- t+e set accessor is invo7ed wit+
an argument Jw+ose value is t+at o0 t+e rig+t<+and side o0 t+e assignment or t+e operand o0 t+e << or ==
operatorM t+at provides t+e new value JV!.1%.1M. T+e body o0 a set accessor must con0orm to t+e rules 0or void
met+ods described in V1..%.1.. 1n particular- return statements in t+e set accessor body are not permitted to
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 327
C# Language Specification
speci0y an epression. #ince a set accessor implicitly +as a parameter named value- it is a compile<time error
0or a local variable or constant declaration in a set accessor to +ave t+at name.
)ased on t+e presence or absence o0 t+e get and set accessors- a property is classi0ied as 0ollowsC
( property t+at includes bot+ a get accessor and a set accessor is said to be a read-2rite property.
( property t+at +as only a get accessor is said to be a read-only property. 1t is a compile<time error 0or a
read<only property to be t+e target o0 an assignment.
( property t+at +as only a set accessor is said to be a 2rite-only property. Ecept as t+e target o0 an
assignment- it is a compile<time error to re0erence a write<only property in an epression.
1n t+e eample
&ublic class :utton/ Control
{
&rivate string ca&tion;
&ublic string Ca&tion {
get {
return ca&tion;
!
set {
i- (ca&tion @+ value) {
ca&tion + value;
Oe&aint();
!
!
!
&ublic override void *aint(Sra&"ics g Oectangle r) {
.. *ainting code goes "ere
!
!
t+e :utton control declares a public Ca&tion property. T+e get accessor o0 t+e Ca&tion property returns t+e
string stored in t+e private ca&tion 0ield. T+e set accessor c+ec7s i0 t+e new value is di00erent 0rom t+e
current value- and i0 so- it stores t+e new value and repaints t+e control. Properties o0ten 0ollow t+e pattern
s+own aboveC T+e get accessor simply returns a value stored in a private 0ield- and t+e set accessor modi0ies
t+at private 0ield and t+en per0orms any additional actions re9uired to 0ully update t+e state o0 t+e ob&ect.
4iven t+e :utton class above- t+e 0ollowing is an eample o0 use o0 t+e Ca&tion propertyC
:utton o(:utton + ne, :utton();
o(:utton.Ca&tion + "%a"; .. $nvo(es set accessor
string s + o(:utton.Ca&tion; .. $nvo(es get accessor
Here- t+e set accessor is invo7ed by assigning a value to t+e property- and t+e get accessor is invo7ed by
re0erencing t+e property in an epression.
T+e get and set accessors o0 a property are not distinct members- and it is not possible to declare t+e accessors
o0 a property separately. (s suc+- it is not possible 0or t+e two accessors o0 a read<write property to +ave
di00erent accessibility. T+e eample
class '
{
&rivate string name;
32$ Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
&ublic string Name { .. )rror du&licate member name
get { return name; !
!
&ublic string Name { .. )rror du&licate member name
set { name + value; !
!
!
does not declare a single read<write property. ;at+er- it declares two properties wit+ t+e same name- one read<
only and one write<only. #ince two members declared in t+e same class cannot +ave t+e same name- t+e
eample causes a compile<time error to occur.
6+en a derived class declares a property by t+e same name as an in+erited property- t+e derived property +ides
t+e in+erited property wit+ respect to bot+ reading and writing. 1n t+e eample
class '
{
&ublic int * {
set {...!
!
!
class :/ '
{
ne, &ublic int * {
get {...!
!
!
t+e * property in : +ides t+e * property in ' wit+ respect to bot+ reading and writing. T+us- in t+e statements
: b + ne, :();
b.* + 2; .. )rror :.* is read=only
((')b).* + 2; .. %( re-erence to '.*
t+e assignment to b.* causes a compile<time error to be reported- since t+e read<only * property in : +ides t+e
write<only * property in '. =ote- +owever- t+at a cast can be used to access t+e +idden * property.
8nli7e public 0ields- properties provide a separation between an ob&ectPs internal state and its public inter0ace.
Consider t+e eampleC
class Label
{
&rivate int # y;
&rivate string ca&tion;
&ublic Label(int # int y string ca&tion) {
t"is.# + #;
t"is.y + y;
t"is.ca&tion + ca&tion;
!
&ublic int I {
get { return #; !
!
&ublic int ` {
get { return y; !
!
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 32!
C# Language Specification
&ublic *oint Location {
get { return ne, *oint(# y); !
!
&ublic string Ca&tion {
get { return ca&tion; !
!
!
Here- t+e Label class uses two int 0ields- # and y- to store its location. T+e location is publicly eposed bot+
as an I and a ` property and as a Location property o0 type *oint. 10- in a 0uture version o0 Label- it
becomes more convenient to store t+e location as a *oint internally- t+e c+ange can be made wit+out a00ecting
t+e public inter0ace o0 t+e classC
class Label
{
&rivate *oint location;
&rivate string ca&tion;
&ublic Label(int # int y string ca&tion) {
t"is.location + ne, *oint(# y);
t"is.ca&tion + ca&tion;
!
&ublic int I {
get { return location.#; !
!
&ublic int ` {
get { return location.y; !
!
&ublic *oint Location {
get { return location; !
!
&ublic string Ca&tion {
get { return ca&tion; !
!
!
Had # and y instead been &ublic readonly 0ields- it would +ave been impossible to ma7e suc+ a c+ange to
t+e Label class.
Eposing state t+roug+ properties is not necessarily any less e00icient t+an eposing 0ields directly. 1n particular-
w+en a property is non<virtual and contains only a small amount o0 code- t+e eecution environment may
replace calls to accessors wit+ t+e actual code o0 t+e accessors. T+is process is 7nown as inlining- and it ma7es
property access as e00icient as 0ield access- yet preserves t+e increased 0leibility o0 properties.
#ince invo7ing a get accessor is conceptually e9uivalent to reading t+e value o0 a 0ield- it is considered bad
programming style 0or get accessors to +ave observable side<e00ects. 1n t+e eample
class Counter
{
&rivate int ne#t;
&ublic int Ne#t {
get { return ne#t<<; !
!
!
33* Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
t+e value o0 t+e Ne#t property depends on t+e number o0 times t+e property +as previously been accessed. T+us-
accessing t+e property produces an observable side<e00ect- and t+e property s+ould be implemented as a met+od
instead.
T+e Kno side<e00ectsL convention 0or get accessors doesnPt mean t+at get accessors s+ould always be written to
simply return values stored in 0ields. 1ndeed- get accessors o0ten compute t+e value o0 a property by accessing
multiple 0ields or invo7ing met+ods. However- a properly designed get accessor per0orms no actions t+at cause
observable c+anges in t+e state o0 t+e ob&ect.
Properties can be used to delay initialiDation o0 a resource until t+e moment it is 0irst re0erenced. *or eampleC
using System.$%;
&ublic class Console
{
&rivate static 1e#tOeader reader;
&rivate static 1e#tWriter ,riter;
&rivate static 1e#tWriter error;
&ublic static 1e#tOeader $n {
get {
i- (reader ++ null) {
reader + ne, StreamOeader(Console.%&enStandard$n&ut());
!
return reader;
!
!
&ublic static 1e#tWriter %ut {
get {
i- (,riter ++ null) {
,riter + ne, StreamWriter(Console.%&enStandard%ut&ut());
!
return ,riter;
!
!
&ublic static 1e#tWriter )rror {
get {
i- (error ++ null) {
error + ne, StreamWriter(Console.%&enStandard)rror());
!
return error;
!
!
!
T+e Console class contains t+ree properties- $n- %ut- and )rror- t+at represent t+e standard input- output- and
error devices- respectively. )y eposing t+ese members as properties- t+e Console class can delay t+eir
initialiDation until t+ey are actually used. *or eample- upon 0irst re0erencing t+e %ut property- as in
Console.%ut.WriteLine(""ello ,orld");
t+e underlying 1e#tWriter 0or t+e output device is created. )ut i0 t+e application ma7es no re0erence to t+e $n
and )rror properties- t+en no ob&ects are created 0or t+ose devices.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 331
C# Language Specification
10...3 *utoaticall! ipleented properties
6+en a property is speci0ied as an automatically implemented property- a +idden bac7ing 0ield is automatically
available 0or t+e property- and t+e accessors are implemented to read 0rom and write to t+at bac7ing 0ield.
T+e 0ollowing eampleC
&ublic class *oint {
&ublic int I { get; set; ! .. automatically im&lemented
&ublic int ` { get; set; ! .. automatically im&lemented
!
is e9uivalent to t+e 0ollowing declarationC
&ublic class *oint {
&rivate int #;
&rivate int y;
&ublic int I { get { return #; ! set { # + value; ! !
&ublic int ` { get { return y; ! set { y + value; ! !
!
)ecause t+e bac7ing 0ield is inaccessible- it can be read and written only t+roug+ t+e property accessors. T+is
means t+at automatically implemented read<only or write<only properties do not ma7e sense- and are
disallowed. 1t is +owever possible to set t+e access level o0 eac+ accessor di00erently. T+us- t+e e00ect o0 a read<
only property wit+ a private bac7ing 0ield can be mimic7ed li7e t+isC
&ublic class Oead%nly*oint {
&ublic int I { get; &rivate set; !
&ublic int ` { get; &rivate set; !
&ublic Oead%nly*oint(int # int y) { I + #; ` + y; !
!
T+is restriction also means t+at de0inite assignment o0 struct types wit+ auto<implemented properties can only be
ac+ieved using t+e standard constructor o0 t+e struct- since assigning to t+e property itsel0 re9uires t+e struct to
be de0initely assigned. T+is means t+at user<de0ined constructors must call t+e de0ault constructor.
10...# *ccessibilit!
10 an accessor +as an accessor-%odifier- t+e accessibility domain JV3.".2M o0 t+e accessor is determined using t+e
declared accessibility o0 t+e accessor-%odifier. 10 an accessor does not +ave an accessor-%odifier- t+e
accessibility domain o0 t+e accessor is determined 0rom t+e declared accessibility o0 t+e property or indeer.
T+e presence o0 an accessor-%odifier never a00ects member loo7up JV!.3M or overload resolution JV!.4.3M. T+e
modi0iers on t+e property or indeer always determine w+ic+ property or indeer is bound to- regardless o0 t+e
contet o0 t+e access.
/nce a particular property or indeer +as been selected- t+e accessibility domains o0 t+e speci0ic accessors
involved are used to determine i0 t+at usage is validC
10 t+e usage is as a value JV!.1.1M- t+e get accessor must eist and be accessible.
10 t+e usage is as t+e target o0 a simple assignment JV!.1%.1M- t+e set accessor must eist and be accessible.
10 t+e usage is as t+e target o0 compound assignment JV!.1%.2M- or as t+e target o0 t+e << or == operators
JV!.".$- V!.%."M- bot+ t+e get accessors and t+e set accessor must eist and be accessible.
1n t+e 0ollowing eample- t+e property '.1e#t is +idden by t+e property :.1e#t- even in contets w+ere only
t+e set accessor is called. 1n contrast- t+e property :.Count is not accessible to class M- so t+e accessible
property '.Count is used instead.
332 Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
class '
{
&ublic string 1e#t {
get { return ""ello"; !
set { !
!
&ublic int Count {
get { return K; !
set { !
!
!
class :/ '
{
&rivate string te#t + "goodbye";
&rivate int count + 3;
ne, &ublic string 1e#t {
get { return te#t; !
&rotected set { te#t + value; !
!
ne, &rotected int Count {
get { return count; !
set { count + value; !
!
!
class M
{
static void Main() {
: b + ne, :();
b.Count + 28; .. Calls '.Count set accessor
int i + b.Count; .. Calls '.Count get accessor
b.1e#t + ""o,dy"; .. )rror :.1e#t set accessor not accessible
string s + b.1e#t; .. Calls :.1e#t get accessor
!
!
(n accessor t+at is used to implement an inter0ace may not +ave an accessor-%odifier. 10 only one accessor is
used to implement an inter0ace- t+e ot+er accessor may be declared wit+ an accessor-%odifierC
&ublic inter-ace $
{
string *ro& { get; !
!
&ublic class C/ $
{
&ublic *ro& {
get { return "'&ril"; ! .. Must not "ave a modi-ier "ere
internal set {...! .. %( because $.*ro& "as no set accessor
!
!
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 333
C# Language Specification
10...& Virtual? sealed? o"erride? and abstract accessors
( virtual property declaration speci0ies t+at t+e accessors o0 t+e property are virtual. T+e virtual modi0ier
applies to bot+ accessors o0 a read<write propertyRit is not possible 0or only one accessor o0 a read<write
property to be virtual.
(n abstract property declaration speci0ies t+at t+e accessors o0 t+e property are virtual- but does not provide
an actual implementation o0 t+e accessors. 1nstead- non<abstract derived classes are re9uired to provide t+eir
own implementation 0or t+e accessors by overriding t+e property. )ecause an accessor 0or an abstract property
declaration provides no actual implementation- its accessor-,od+ simply consists o0 a semicolon.
( property declaration t+at includes bot+ t+e abstract and override modi0iers speci0ies t+at t+e property is
abstract and overrides a base property. T+e accessors o0 suc+ a property are also abstract.
(bstract property declarations are only permitted in abstract classes JV1..1.1.1M.T+e accessors o0 an in+erited
virtual property can be overridden in a derived class by including a property declaration t+at speci0ies an
override directive. T+is is 7nown as an overriding property declaration. (n overriding property declaration
does not declare a new property. 1nstead- it simply specialiDes t+e implementations o0 t+e accessors o0 an
eisting virtual property.
(n overriding property declaration must speci0y t+e eact same accessibility modi0iers- type- and name as t+e
in+erited property. 10 t+e in+erited property +as only a single accessor Ji.e.- i0 t+e in+erited property is read<only
or write<onlyM- t+e overriding property must include only t+at accessor. 10 t+e in+erited property includes bot+
accessors Ji.e.- i0 t+e in+erited property is read<writeM- t+e overriding property can include eit+er a single
accessor or bot+ accessors.
(n overriding property declaration may include t+e sealed modi0ier. 8se o0 t+is modi0ier prevents a derived
class 0rom 0urt+er overriding t+e property. T+e accessors o0 a sealed property are also sealed.
Ecept 0or di00erences in declaration and invocation synta- virtual- sealed- override- and abstract accessors
be+ave eactly li7e virtual- sealed- override and abstract met+ods. #peci0ically- t+e rules described in V1..%.3-
V1..%.4- V1..%."- and V1..%.% apply as i0 accessors were met+ods o0 a corresponding 0ormC
( get accessor corresponds to a parameterless met+od wit+ a return value o0 t+e property type and t+e same
modi0iers as t+e containing property.
( set accessor corresponds to a met+od wit+ a single value parameter o0 t+e property type- a void return
type- and t+e same modi0iers as t+e containing property.
1n t+e eample
abstract class '
{
int y;
&ublic virtual int I {
get { return 3; !
!
&ublic virtual int ` {
get { return y; !
set { y + value; !
!
&ublic abstract int P { get; set; !
!
I is a virtual read<only property- ` is a virtual read<write property- and P is an abstract read<write property.
)ecause P is abstract- t+e containing class ' must also be declared abstract.
33" Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
( class t+at derives 0rom ' is s+ow belowC
class :/ '
{
int ?;
&ublic override int I {
get { return base.I < 2; !
!
&ublic override int ` {
set { base.` + value D 37 3/ value; !
!
&ublic override int P {
get { return ?; !
set { ? + value; !
!
!
Here- t+e declarations o0 I- `- and P are overriding property declarations. Eac+ property declaration eactly
matc+es t+e accessibility modi0iers- type- and name o0 t+e corresponding in+erited property. T+e get accessor
o0 I and t+e set accessor o0 ` use t+e base 7eyword to access t+e in+erited accessors. T+e declaration o0 P
overrides bot+ abstract accessorsRt+us- t+ere are no outstanding abstract 0unction members in :- and : is
permitted to be a non<abstract class.
6+en a property is declared as an override- any overridden accessors must be accessible to t+e overriding
code. 1n addition- t+e declared accessibility o0 bot+ t+e property or indeer itsel0- and o0 t+e accessors- must
matc+ t+at o0 t+e overridden member and accessors. *or eampleC
&ublic class :
{
&ublic virtual int * {
&rotected set {...!
get {...!
!
!
&ublic class 6/ :
{
&ublic override int * {
&rotected set {...! .. Must s&eci-y &rotected "ere
get {...! .. Must not "ave a modi-ier "ere
!
!
10.0 $"ents
(n event is a member t+at enables an ob&ect or class to provide noti0ications. Clients can attac+ eecutable code
0or events by supplying event handlers.
Events are declared using event-declarationsC
event-declaration.
attri,!tesopt event-%odifiersopt e,e*$ t+pe varia,le-declarators A
attri,!tesopt event-%odifiersopt e,e*$ t+pe %e%,er-na%e { event-accessor-declarations }
event-%odifiers.
event-%odifier
event-%odifiers event-%odifier
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 33
C# Language Specification
event-%odifier.
*ew
.u"li&
.%'$e&$ed
i*$e%*!l
.%i,!$e
#$!$i&
,i%$u!l
#e!led
',e%%ide
!"#$%!&$
e-$e%*
event-accessor-declarations.
add-accessor-declaration re%ove-accessor-declaration
re%ove-accessor-declaration add-accessor-declaration
add-accessor-declaration.
attri,!tesopt !dd ,loc&
re%ove-accessor-declaration.
attri,!tesopt %em',e ,loc&
(n event-declaration may include a set o0 attri,!tes JV1!M and a valid combination o0 t+e 0our access modi0iers
JV1..3."M- t+e ne, JV1..3.4M- static JV1..%.2M- virtual JV1..%.3M- override JV1..%.4M- sealed JV1..%."M-
abstract JV1..%.%M- and e#tern JV1..%.!M modi0iers.
Event declarations are sub&ect to t+e same rules as met+od declarations JV1..%M wit+ regard to valid
combinations o0 modi0iers.
T+e t+pe o0 an event declaration must be a delegate-t+pe JV4.2M- and t+at delegate-t+pe must be at least as
accessible as t+e event itsel0 JV3.".4M.
(n event declaration may include event-accessor-declarations. However- i0 it does not- 0or non<etern- non<
abstract events- t+e compiler supplies t+em automatically JV1..3.1MQ 0or etern events- t+e accessors are provided
eternally.
(n event declaration t+at omits event-accessor-declarations de0ines one or more eventsRone 0or eac+ o0 t+e
varia,le-declarators. T+e attributes and modi0iers apply to all o0 t+e members declared by suc+ an event-
declaration.
1t is a compile<time error 0or an event-declaration to include bot+ t+e abstract modi0ier and brace<delimited
event-accessor-declarations.
6+en an event declaration includes an e#tern modi0ier- t+e event is said to be an e,ternal event. )ecause an
eternal event declaration provides no actual implementation- it is an error 0or it to include bot+ t+e e#tern
modi0ier and event-accessor-declarations.
(n event can be used as t+e le0t<+and operand o0 t+e <+ and =+ operators JV!.1%.3M. T+ese operators are used-
respectively- to attac+ event +andlers to or to remove event +andlers 0rom an event- and t+e access modi0iers o0
t+e event control t+e contets in w+ic+ suc+ operations are permitted.
#ince <+ and =+ are t+e only operations t+at are permitted on an event outside t+e type t+at declares t+e event-
eternal code can add and remove +andlers 0or an event- but cannot in any ot+er way obtain or modi0y t+e
underlying list o0 event +andlers.
33' Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
1n an operation o0 t+e 0orm # <+ y or # =+ y- w+en # is an event and t+e re0erence ta7es place outside t+e type
t+at contains t+e declaration o0 #- t+e result o0 t+e operation +as type void Jas opposed to +aving t+e type o0 #-
wit+ t+e value o0 # a0ter t+e assignmentM. T+is rule pro+ibits eternal code 0rom indirectly eamining t+e
underlying delegate o0 an event.
T+e 0ollowing eample s+ows +ow event +andlers are attac+ed to instances o0 t+e :utton classC
&ublic delegate void )ventHandler(object sender )vent'rgs e);
&ublic class :utton/ Control
{
&ublic event )ventHandler Clic(;
!
&ublic class Login6ialog/ Vorm
{
:utton %(:utton;
:utton Cancel:utton;
&ublic Login6ialog() {
%(:utton + ne, :utton(...);
%(:utton.Clic( <+ ne, )ventHandler(%(:uttonClic();
Cancel:utton + ne, :utton(...);
Cancel:utton.Clic( <+ ne, )ventHandler(Cancel:uttonClic();
!
void %(:uttonClic((object sender )vent'rgs e) {
.. Handle %(:utton.Clic( event
!
void Cancel:uttonClic((object sender )vent'rgs e) {
.. Handle Cancel:utton.Clic( event
!
!
Here- t+e Login6ialog instance constructor creates two :utton instances and attac+es event +andlers to t+e
Clic( events.
10.0.1 ,ield9li5e e"ents
6it+in t+e program tet o0 t+e class or struct t+at contains t+e declaration o0 an event- certain events can be used
li7e 0ields. To be used in t+is way- an event must not be abstract or e#tern- and must not eplicitly include
event-accessor-declarations. #uc+ an event can be used in any contet t+at permits a 0ield. T+e 0ield contains a
delegate JV1"M w+ic+ re0ers to t+e list o0 event +andlers t+at +ave been added to t+e event. 10 no event +andlers
+ave been added- t+e 0ield contains null.
1n t+e eample
&ublic delegate void )ventHandler(object sender )vent'rgs e);
&ublic class :utton/ Control
{
&ublic event )ventHandler Clic(;
&rotected void %nClic(()vent'rgs e) {
i- (Clic( @+ null) Clic((t"is e);
!
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 337
C# Language Specification
&ublic void Oeset() {
Clic( + null;
!
!
Clic( is used as a 0ield wit+in t+e :utton class. (s t+e eample demonstrates- t+e 0ield can be eamined-
modi0ied- and used in delegate invocation epressions. T+e %nClic( met+od in t+e :utton class KraisesL t+e
Clic( event. T+e notion o0 raising an event is precisely e9uivalent to invo7ing t+e delegate represented by t+e
eventRt+us- t+ere are no special language constructs 0or raising events. =ote t+at t+e delegate invocation is
preceded by a c+ec7 t+at ensures t+e delegate is non<null.
/utside t+e declaration o0 t+e :utton class- t+e Clic( member can only be used on t+e le0t<+and side o0 t+e <+
and C+ operators- as in
b.Clic( <+ ne, )ventHandler(b);
w+ic+ appends a delegate to t+e invocation list o0 t+e Clic( event- and
b.Clic( C+ ne, )ventHandler(b);
w+ic+ removes a delegate 0rom t+e invocation list o0 t+e Clic( event.
6+en compiling a 0ield<li7e event- t+e compiler automatically creates storage to +old t+e delegate- and creates
accessors 0or t+e event t+at add or remove event +andlers to t+e delegate 0ield. 1n order to be t+read<sa0e- t+e
addition or removal operations are done w+ile +olding t+e loc7 JV3.12M on t+e containing ob&ect 0or an instance
event- or t+e type ob&ect JV!.".1..%M 0or a static event.
T+us- an instance event declaration o0 t+e 0ormC
class I
{
&ublic event 6 )v;
!
could be compiled to somet+ing e9uivalent toC
class I
{
&rivate 6 [[)v; .. -ield to "old t"e delegate
&ublic event 6 )v {
add {
loc((t"is) { [[)v + [[)v < value; !
!
remove {
loc((t"is) { [[)v + [[)v = value; !
!
!
!
6it+in t+e class I- re0erences to )v are compiled to re0erence t+e +idden 0ield [[)v instead. T+e name K[[)vL
is arbitraryQ t+e +idden 0ield could +ave any name or no name at all.
#imilarly- a static event declaration o0 t+e 0ormC
class I
{
&ublic static event 6 )v;
!
could be compiled to somet+ing e9uivalent toC
33$ Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
class I
{
&rivate static 6 [[)v; .. -ield to "old t"e delegate
&ublic static event 6 )v {
add {
loc((ty&eo-(I)) { [[)v + [[)v < value; !
!
remove {
loc((ty&eo-(I)) { [[)v + [[)v = value; !
!
!
!
10.0.2 $"ent accessors
Event declarations typically omit event-accessor-declarations- as in t+e :utton eample above. /ne situation
0or doing so involves t+e case in w+ic+ t+e storage cost o0 one 0ield per event is not acceptable. 1n suc+ cases- a
class can include event-accessor-declarations and use a private mec+anism 0or storing t+e list o0 event +andlers.
T+e event-accessor-declarations o0 an event speci0y t+e eecutable statements associated wit+ adding and
removing event +andlers.
T+e accessor declarations consist o0 an add-accessor-declaration and a re%ove-accessor-declaration. Eac+
accessor declaration consists o0 t+e to7en add or remove 0ollowed by a ,loc&. T+e ,loc& associated wit+ an
add-accessor-declaration speci0ies t+e statements to eecute w+en an event +andler is added- and t+e ,loc&
associated wit+ a re%ove-accessor-declaration speci0ies t+e statements to eecute w+en an event +andler is
removed.
Eac+ add-accessor-declaration and re%ove-accessor-declaration corresponds to a met+od wit+ a single value
parameter o0 t+e event type and a void return type. T+e implicit parameter o0 an event accessor is named
value. 6+en an event is used in an event assignment- t+e appropriate event accessor is used. #peci0ically- i0 t+e
assignment operator is <+ t+en t+e add accessor is used- and i0 t+e assignment operator is =+ t+en t+e remove
accessor is used. 1n eit+er case- t+e rig+t<+and operand o0 t+e assignment operator is used as t+e argument to t+e
event accessor. T+e bloc7 o0 an add-accessor-declaration or a re%ove-accessor-declaration must con0orm to
t+e rules 0or void met+ods described in V1..%.1.. 1n particular- return statements in suc+ a bloc7 are not
permitted to speci0y an epression.
#ince an event accessor implicitly +as a parameter named value- it is a compile<time error 0or a local variable
or constant declared in an event accessor to +ave t+at name.
1n t+e eample
class Control/ Com&onent
{
.. ;niQue (eys -or events
static readonly object mouse6o,n)ventaey + ne, object();
static readonly object mouse;&)ventaey + ne, object();
.. Oeturn event "andler associated ,it" (ey
&rotected 6elegate Set)ventHandler(object (ey) {...!
.. 'dd event "andler associated ,it" (ey
&rotected void 'dd)ventHandler(object (ey 6elegate "andler) {...!
.. Oemove event "andler associated ,it" (ey
&rotected void Oemove)ventHandler(object (ey 6elegate "andler) {...!
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 33!
C# Language Specification
.. Mouse6o,n event
&ublic event Mouse)ventHandler Mouse6o,n {
add { 'dd)ventHandler(mouse6o,n)ventaey value); !
remove { Oemove)ventHandler(mouse6o,n)ventaey value); !
!
.. Mouse;& event
&ublic event Mouse)ventHandler Mouse;& {
add { 'dd)ventHandler(mouse;&)ventaey value); !
remove { Oemove)ventHandler(mouse;&)ventaey value); !
!
.. $nvo(e t"e Mouse;& event
&rotected void %nMouse;&(Mouse)vent'rgs args) {
Mouse)ventHandler "andler;
"andler + (Mouse)ventHandler)Set)ventHandler(mouse;&)ventaey);
i- ("andler @+ null)
"andler(t"is args);
!
!
t+e Control class implements an internal storage mec+anism 0or events. T+e 'dd)ventHandler met+od
associates a delegate value wit+ a 7ey- t+e Set)ventHandler met+od returns t+e delegate currently associated
wit+ a 7ey- and t+e Oemove)ventHandler met+od removes a delegate as an event +andler 0or t+e speci0ied
event. Presumably- t+e underlying storage mec+anism is designed suc+ t+at t+ere is no cost 0or associating a
null delegate value wit+ a 7ey- and t+us un+andled events consume no storage.
10.0.3 Static and instance e"ents
6+en an event declaration includes a static modi0ier- t+e event is said to be a static event. 6+en no static
modi0ier is present- t+e event is said to be an instance event.
( static event is not associated wit+ a speci0ic instance- and it is a compile<time error to re0er to t"is in t+e
accessors o0 a static event.
(n instance event is associated wit+ a given instance o0 a class- and t+is instance can be accessed as t"is
JV!.".!M in t+e accessors o0 t+at event.
6+en an event is re0erenced in a %e%,er-access JV!.".4M o0 t+e 0orm ).M- i0 M is a static event- ) must denote a
type containing M- and i0 M is an instance event- E must denote an instance o0 a type containing M.
T+e di00erences between static and instance members are discussed 0urt+er in V1..3.!.
10.0.# Virtual? sealed? o"erride? and abstract accessors
( virtual event declaration speci0ies t+at t+e accessors o0 t+at event are virtual. T+e virtual modi0ier
applies to bot+ accessors o0 an event.
(n abstract event declaration speci0ies t+at t+e accessors o0 t+e event are virtual- but does not provide an
actual implementation o0 t+e accessors. 1nstead- non<abstract derived classes are re9uired to provide t+eir own
implementation 0or t+e accessors by overriding t+e event. )ecause an abstract event declaration provides no
actual implementation- it cannot provide brace<delimited event-accessor-declarations.
(n event declaration t+at includes bot+ t+e abstract and override modi0iers speci0ies t+at t+e event is
abstract and overrides a base event. T+e accessors o0 suc+ an event are also abstract.
(bstract event declarations are only permitted in abstract classes JV1..1.1.1M.
3"* Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
T+e accessors o0 an in+erited virtual event can be overridden in a derived class by including an event declaration
t+at speci0ies an override modi0ier. T+is is 7nown as an overriding event declaration. (n overriding event
declaration does not declare a new event. 1nstead- it simply specialiDes t+e implementations o0 t+e accessors o0
an eisting virtual event.
(n overriding event declaration must speci0y t+e eact same accessibility modi0iers- type- and name as t+e
overridden event.
(n overriding event declaration may include t+e sealed modi0ier. 8se o0 t+is modi0ier prevents a derived class
0rom 0urt+er overriding t+e event. T+e accessors o0 a sealed event are also sealed.
1t is a compile<time error 0or an overriding event declaration to include a ne, modi0ier.
Ecept 0or di00erences in declaration and invocation synta- virtual- sealed- override- and abstract accessors
be+ave eactly li7e virtual- sealed- override and abstract met+ods. #peci0ically- t+e rules described in V1..%.3-
V1..%.4- V1..%."- and V1..%.% apply as i0 accessors were met+ods o0 a corresponding 0orm. Eac+ accessor
corresponds to a met+od wit+ a single value parameter o0 t+e event type- a void return type- and t+e same
modi0iers as t+e containing event.
10.1 Inde%ers
(n inde,er is a member t+at enables an ob&ect to be indeed in t+e same way as an array. 1ndeers are declared
using inde/er-declarationsC
inde/er-declaration.
attri,!tesopt inde/er-%odifiersopt inde/er-declarator { accessor-declarations }
inde/er-%odifiers.
inde/er-%odifier
inde/er-%odifiers inde/er-%odifier
inde/er-%odifier.
*ew
.u"li&
.%'$e&$ed
i*$e%*!l
.%i,!$e
,i%$u!l
#e!led
',e%%ide
!"#$%!&$
e-$e%*
inde/er-declarator.
t+pe $hi# = for%al-para%eter-list >
t+pe interface-t+pe 9 $hi# = for%al-para%eter-list >
(n inde/er-declaration may include a set o0 attri,!tes JV1!M and a valid combination o0 t+e 0our access
modi0iers JV1..3."M- t+e ne, JV1..3.4M- virtual JV1..%.3M- override JV1..%.4M- sealed JV1..%."M- abstract
JV1..%.%M- and e#tern JV1..%.!M modi0iers.
1ndeer declarations are sub&ect to t+e same rules as met+od declarations JV1..%M wit+ regard to valid
combinations o0 modi0iers- wit+ t+e one eception being t+at t+e static modi0ier is not permitted on an indeer
declaration.
T+e modi0iers virtual- override- and abstract are mutually eclusive ecept in one case. T+e abstract
and override modi0iers may be used toget+er so t+at an abstract indeer can override a virtual one.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 3"1
C# Language Specification
T+e t+pe o0 an indeer declaration speci0ies t+e element type o0 t+e indeer introduced by t+e declaration.
8nless t+e indeer is an eplicit inter0ace member implementation- t+e t+pe is 0ollowed by t+e 7eyword t"is.
*or an eplicit inter0ace member implementation- t+e t+pe is 0ollowed by an interface-t+pe- a K.L- and t+e
7eyword t"is. 8nli7e ot+er members- indeers do not +ave user<de0ined names.
T+e for%al-para%eter-list speci0ies t+e parameters o0 t+e indeer. T+e 0ormal parameter list o0 an indeer
corresponds to t+at o0 a met+od JV1..%.1M- ecept t+at at least one parameter must be speci0ied- and t+at t+e re-
and out parameter modi0iers are not permitted.
T+e t+pe o0 an indeer and eac+ o0 t+e types re0erenced in t+e for%al-para%eter-list must be at least as
accessible as t+e indeer itsel0 JV3.".4M.
T+e accessor-declarations JV1..!.2M- w+ic+ must be enclosed in K{L and K!L to7ens- declare t+e accessors o0 t+e
indeer. T+e accessors speci0y t+e eecutable statements associated wit+ reading and writing indeer elements.
Even t+oug+ t+e synta 0or accessing an indeer element is t+e same as t+at 0or an array element- an indeer
element is not classi0ied as a variable. T+us- it is not possible to pass an indeer element as a re- or out
argument.
T+e 0ormal parameter list o0 an indeer de0ines t+e signature JV3.%M o0 t+e indeer. #peci0ically- t+e signature o0
an indeer consists o0 t+e number and types o0 its 0ormal parameters. T+e element type and names o0 t+e 0ormal
parameters are not part o0 an indeerPs signature.
T+e signature o0 an indeer must di00er 0rom t+e signatures o0 all ot+er indeers declared in t+e same class.
1ndeers and properties are very similar in concept- but di00er in t+e 0ollowing waysC
( property is identi0ied by its name- w+ereas an indeer is identi0ied by its signature.
( property is accessed t+roug+ a si%ple-na%e JV!.".2M or a %e%,er-access JV!.".4M- w+ereas an indeer
element is accessed t+roug+ an ele%ent-access JV!.".%.2M.
( property can be a static member- w+ereas an indeer is always an instance member.
( get accessor o0 a property corresponds to a met+od wit+ no parameters- w+ereas a get accessor o0 an
indeer corresponds to a met+od wit+ t+e same 0ormal parameter list as t+e indeer.
( set accessor o0 a property corresponds to a met+od wit+ a single parameter named value- w+ereas a
set accessor o0 an indeer corresponds to a met+od wit+ t+e same 0ormal parameter list as t+e indeer- plus
an additional parameter named value.
1t is a compile<time error 0or an indeer accessor to declare a local variable wit+ t+e same name as an
indeer parameter.
1n an overriding property declaration- t+e in+erited property is accessed using t+e synta base.*- w+ere *
is t+e property name. 1n an overriding indeer declaration- t+e in+erited indeer is accessed using t+e synta
base4)5- w+ere ) is a comma separated list o0 epressions.
(side 0rom t+ese di00erences- all rules de0ined in V1..!.2 and V1..!.3 apply to indeer accessors as well as to
property accessors.
6+en an indeer declaration includes an e#tern modi0ier- t+e indeer is said to be an e,ternal inde,er.
)ecause an eternal indeer declaration provides no actual implementation- eac+ o0 its accessor-declarations
consists o0 a semicolon.
T+e eample below declares a :it'rray class t+at implements an indeer 0or accessing t+e individual bits in
t+e bit array.
using System;
3"2 Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
class :it'rray
{
int45 bits;
int lengt";
&ublic :it'rray(int lengt") {
i- (lengt" D 3) t"ro, ne, 'rgument)#ce&tion();
bits + ne, int4((lengt" = 2) EE K) < 25;
t"is.lengt" + lengt";
!
&ublic int Lengt" {
get { return lengt"; !
!
&ublic bool t"is4int inde#5 {
get {
i- (inde# D 3 HH inde# E+ lengt") {
t"ro, ne, $nde#%ut%-Oange)#ce&tion();
!
return (bits4inde# EE K5 F 2 DD inde#) @+ 3;
!
set {
i- (inde# D 3 HH inde# E+ lengt") {
t"ro, ne, $nde#%ut%-Oange)#ce&tion();
!
i- (value) {
bits4inde# EE K5 H+ 2 DD inde#;
!
else {
bits4inde# EE K5 F+ A(2 DD inde#);
!
!
!
!
(n instance o0 t+e :it'rray class consumes substantially less memory t+an a corresponding bool45 Jsince
eac+ value o0 t+e 0ormer occupies only one bit instead o0 t+e latterPs one byteM- but it permits t+e same
operations as a bool45.
T+e 0ollowing Count*rimes class uses a :it'rray and t+e classical KsieveL algorit+m to compute t+e number
o0 primes between 1 and a given maimumC
class Count*rimes
{
static int Count(int ma#) {
:it'rray -lags + ne, :it'rray(ma# < 2);
int count + 2;
-or (int i + 8; i D+ ma#; i<<) {
i- (@-lags4i5) {
-or (int j + i > 8; j D+ ma#; j <+ i) -lags4j5 + true;
count<<;
!
!
return count;
!
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 3"3
C# Language Specification
static void Main(string45 args) {
int ma# + int.*arse(args435);
int count + Count(ma#);
Console.WriteLine("Vound {3! &rimes bet,een 2 and {2!" count ma#);
!
!
=ote t+at t+e synta 0or accessing elements o0 t+e :it'rray is precisely t+e same as 0or a bool45.
T+e 0ollowing eample s+ows a 2% 1. grid class t+at +as an indeer wit+ two parameters. T+e 0irst parameter
is re9uired to be an upper< or lowercase letter in t+e range (SW- and t+e second is re9uired to be an integer in t+e
range .S$.
using System;
class Srid
{
const int NumOo,s + 8X;
const int NumCols + 23;
int45 cells + ne, int4NumOo,s NumCols5;
&ublic int t"is4c"ar c int col5 {
get {
c + C"ar.1o;&&er(c);
i- (c D W'W HH c E WPW) {
t"ro, ne, 'rgument)#ce&tion();
!
i- (col D 3 HH col E+ NumCols) {
t"ro, ne, $nde#%ut%-Oange)#ce&tion();
!
return cells4c = W'W col5;
!
set {
c + C"ar.1o;&&er(c);
i- (c D W'W HH c E WPW) {
t"ro, ne, 'rgument)#ce&tion();
!
i- (col D 3 HH col E+ NumCols) {
t"ro, ne, $nde#%ut%-Oange)#ce&tion();
!
cells4c = W'W col5 + value;
!
!
!
10.1.1 Inde%er o"erloading
T+e indeer overload resolution rules are described in V!.4.2.
10.10 /perators
(n operator is a member t+at de0ines t+e meaning o0 an epression operator t+at can be applied to instances o0
t+e class. /perators are declared using operator-declarationsC
operator-declaration.
attri,!tesopt operator-%odifiers operator-declarator operator-,od+
3"" Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
operator-%odifiers.
operator-%odifier
operator-%odifiers operator-%odifier
operator-%odifier.
.u"li&
#$!$i&
e-$e%*
operator-declarator.
!nar+-operator-declarator
,inar+-operator-declarator
conversion-operator-declarator
!nar+-operator-declarator.
t+pe '.e%!$'% overloada,le-!nar+-operator ( t+pe identifier )
overloada,le-!nar+-operator. one of
+ : F G ++ :: $%ue f!l#e
,inar+-operator-declarator.
t+pe '.e%!$'% overloada,le-,inar+-operator ( t+pe identifier ? t+pe identifier )
overloada,le-,inar+-operator.
+
:
*
/
B
C
D
E
II
right-shift
HH
FH
J
I
JH
IH
conversion-operator-declarator.
im.li&i$ '.e%!$'% t+pe ( t+pe identifier )
e-.li&i$ '.e%!$'% t+pe ( t+pe identifier )
operator-,od+.
,loc&
A
T+ere are t+ree categories o0 overloadable operatorsC 8nary operators JV1..1..1M- binary operators JV1..1..2M-
and conversion operators JV1..1..3M.
6+en an operator declaration includes an e#tern modi0ier- t+e operator is said to be an e,ternal operator.
)ecause an eternal operator provides no actual implementation- its operator-,od+ consists o0 a semi<colon. *or
all ot+er operators- t+e operator-,od+ consists o0 a ,loc&- w+ic+ speci0ies t+e statements to eecute w+en t+e
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 3"
C# Language Specification
operator is invo7ed. T+e ,loc& o0 an operator must con0orm to t+e rules 0or value<returning met+ods described
in V1..%.1..
T+e 0ollowing rules apply to all operator declarationsC
(n operator declaration must include bot+ a &ublic and a static modi0ier.
T+e parameterJsM o0 an operator must be value parameters. 1t is a compile<time error 0or an operator
declaration to speci0y re- or out parameters.
T+e signature o0 an operator JV1..1..1- V1..1..2- V1..1..3M must di00er 0rom t+e signatures o0 all ot+er
operators declared in t+e same class.
(ll types re0erenced in an operator declaration must be at least as accessible as t+e operator itsel0 JV3.".4M.
1t is an error 0or t+e same modi0ier to appear multiple times in an operator declaration.
Eac+ operator category imposes additional restrictions- as described in t+e 0ollowing sections.
5i7e ot+er members- operators declared in a base class are in+erited by derived classes. )ecause operator
declarations always re9uire t+e class or struct in w+ic+ t+e operator is declared to participate in t+e signature o0
t+e operator- it is not possible 0or an operator declared in a derived class to +ide an operator declared in a base
class. T+us- t+e ne, modi0ier is never re9uired- and t+ere0ore never permitted- in an operator declaration.
(dditional in0ormation on unary and binary operators can be 0ound in V!.2.
(dditional in0ormation on conversion operators can be 0ound in V%.4.
10.10.1 6nar! operators
T+e 0ollowing rules apply to unary operator declarations- w+ere 1 denotes t+e instance type o0 t+e class or struct
t+at contains t+e operator declarationC
( unary <- =- @- or A operator must ta7e a single parameter o0 type 1 or 17 and can return any type.
( unary << or == operator must ta7e a single parameter o0 type 1 or 17 and must return t+at same type or a
type derived 0rom it.
( unary true or -alse operator must ta7e a single parameter o0 type 1 or 17 and must return type bool.
T+e signature o0 a unary operator consists o0 t+e operator to7en J<- =- @- A- <<- ==- true- or -alseM and t+e
type o0 t+e single 0ormal parameter. T+e return type is not part o0 a unary operatorPs signature- nor is t+e name
o0 t+e 0ormal parameter.
T+e true and -alse unary operators re9uire pair<wise declaration. ( compile<time error occurs i0 a class
declares one o0 t+ese operators wit+out also declaring t+e ot+er. T+e true and -alse operators are described
0urt+er in V!.11.2 and V!.1$.
T+e 0ollowing eample s+ows an implementation and subse9uent usage o0 o&erator << 0or an integer vector
classC
&ublic class $ntUector
{
&ublic $ntUector(int lengt") {...!
&ublic int Lengt" {...! .. read=only &ro&erty
&ublic int t"is4int inde#5 {...! .. read=,rite inde#er
3"' Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
&ublic static $ntUector o&erator <<($ntUector iv) {
$ntUector tem& + ne, $ntUector(iv.Lengt");
-or (int i + 3; i D iv.Lengt"; i<<)
tem&4i5 + iv4i5 < 2;
return tem&;
!
!
class 1est
{
static void Main() {
$ntUector iv2 + ne, $ntUector(J); .. vector o- J # 3
$ntUector iv8;
iv8 + iv2<<; .. iv8 contains J # 3 iv2 contains J # 2
iv8 + <<iv2; .. iv8 contains J # 8 iv2 contains J # 8
!
!
=ote +ow t+e operator met+od returns t+e value produced by adding 1 to t+e operand- &ust li7e t+e post0i
increment and decrement operators JV!.".$M- and t+e pre0i increment and decrement operators JV!.%."M. 8nli7e
in CNN- t+is met+od need not modi0y t+e value o0 its operand directly. 1n 0act- modi0ying t+e operand value
would violate t+e standard semantics o0 t+e post0i increment operator.
10.10.2 +inar! operators
T+e 0ollowing rules apply to binary operator declarations- w+ere 1 denotes t+e instance type o0 t+e class or
struct t+at contains t+e operator declarationC
( binary non<s+i0t operator must ta7e two parameters- at least one o0 w+ic+ must +ave type 1 or 17- and can
return any type.
( binary DD or EE operator must ta7e two parameters- t+e 0irst o0 w+ic+ must +ave type 1 or 17 and t+e
second o0 w+ic+ must +ave type int or int7- and can return any type.
T+e signature o0 a binary operator consists o0 t+e operator to7en J<- =- >- .- B- F- H- G- DD- EE- ++- @+- E- D- E+-
or D+M and t+e types o0 t+e two 0ormal parameters. T+e return type and t+e names o0 t+e 0ormal parameters are
not part o0 a binary operatorPs signature.
Certain binary operators re9uire pair<wise declaration. *or every declaration o0 eit+er operator o0 a pair- t+ere
must be a matc+ing declaration o0 t+e ot+er operator o0 t+e pair. Two operator declarations matc+ w+en t+ey
+ave t+e same return type and t+e same type 0or eac+ parameter. T+e 0ollowing operators re9uire pair<wise
declarationC
o&erator ++ and o&erator @+
o&erator E and o&erator D
o&erator E+ and o&erator D+
10.10.3 Con"ersion operators
( conversion operator declaration introduces a -ser-defined conversion JV%.4M w+ic+ augments t+e pre<de0ined
implicit and eplicit conversions.
( conversion operator declaration t+at includes t+e im&licit 7eyword introduces a user<de0ined implicit
conversion. 1mplicit conversions can occur in a variety o0 situations- including 0unction member invocations-
cast epressions- and assignments. T+is is described 0urt+er in V%.1.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 3"7
C# Language Specification
( conversion operator declaration t+at includes t+e e#&licit 7eyword introduces a user<de0ined eplicit
conversion. Eplicit conversions can occur in cast epressions- and are described 0urt+er in V%.2.
( conversion operator converts 0rom a source type- indicated by t+e parameter type o0 t+e conversion operator-
to a target type- indicated by t+e return type o0 t+e conversion operator.
*or a given source type S and target type 1- i0 S or 1 are nullable types- let S
3
and 1
3
re0er to t+eir underlying
types- ot+erwise S
3
and 1
3
are e9ual to S and 1 respectively. ( class or struct is permitted to declare a
conversion 0rom a source type S to a target type 1 only i0 all o0 t+e 0ollowing are trueC
S
3
and 1
3
are di00erent types.
Eit+er S
3
or 1
3
is t+e class or struct type in w+ic+ t+e operator declaration ta7es place.
=eit+er S
3
nor 1
3
is an interface-t+pe.
Ecluding user<de0ined conversions- a conversion does not eist 0rom S to 1 or 0rom 1 to S.
*or t+e purposes o0 t+ese rules- any type parameters associated wit+ S or 1 are considered to be uni9ue types
t+at +ave no in+eritance relations+ip wit+ ot+er types- and any constraints on t+ose type parameters are ignored.
1n t+e eample
class CD1E {...!
class 6D1E/ CD1E
{
&ublic static im&licit o&erator CDintE(6D1E value) {...! .. %(
&ublic static im&licit o&erator CDstringE(6D1E value) {...! .. %(
&ublic static im&licit o&erator CD1E(6D1E value) {...! .. )rror
!
t+e 0irst two operator declarations are permitted because- 0or t+e purposes o0 V1..$.3- 1 and int and string
respectively are considered uni9ue types wit+ no relations+ip. However- t+e t+ird operator is an error because
CD1E is t+e base class o0 6D1E.
*rom t+e second rule it 0ollows t+at a conversion operator must convert eit+er to or 0rom t+e class or struct type
in w+ic+ t+e operator is declared. *or eample- it is possible 0or a class or struct type C to de0ine a conversion
0rom C to int and 0rom int to C- but not 0rom int to bool.
1t is not possible to directly rede0ine a pre<de0ined conversion. T+us- conversion operators are not allowed to
convert 0rom or to object because implicit and eplicit conversions already eist between object and all
ot+er types. 5i7ewise- neit+er t+e source nor t+e target types o0 a conversion can be a base type o0 t+e ot+er-
since a conversion would t+en already eist.
However- it is possible to declare operators on generic types t+at- 0or particular type arguments- speci0y
conversions t+at already eist as pre<de0ined conversions. 1n t+e eample
struct ConvertibleD1E
{
&ublic static im&licit o&erator ConvertibleD1E(1 value) {...!
&ublic static e#&licit o&erator 1(ConvertibleD1E value) {...!
!
w+en type object is speci0ied as a type argument 0or 1- t+e second operator declares a conversion t+at already
eists Jan implicit- and t+ere0ore also an eplicit- conversion eists 0rom any type to type objectM.
3"$ Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
1n cases w+ere a pre<de0ined conversion eists between two types- any user<de0ined conversions between t+ose
types are ignored. #peci0icallyC
10 a pre<de0ined implicit conversion JV%.1M eists 0rom type S to type 1- all user<de0ined conversions
Jimplicit or eplicitM 0rom S to 1 are ignored.
10 a pre<de0ined eplicit conversion JV%.2M eists 0rom type S to type 1- any user<de0ined eplicit
conversions 0rom S to 1 are ignored. However- user<de0ined implicit conversions 0rom S to 1 are still
considered.
*or all types but object- t+e operators declared by t+e ConvertibleD1E type above do not con0lict wit+ pre<
de0ined conversions. *or eampleC
void V(int i ConvertibleDintE n) {
i + n; .. )rror
i + (int)n; .. ;ser=de-ined e#&licit conversion
n + i; .. ;ser=de-ined im&licit conversion
n + (ConvertibleDintE)i; .. ;ser=de-ined im&licit conversion
!
However- 0or type object- pre<de0ined conversions +ide t+e user<de0ined conversions in all cases but oneC
void V(object o ConvertibleDobjectE n) {
o + n; .. *re=de-ined bo#ing conversion
o + (object)n; .. *re=de-ined bo#ing conversion
n + o; .. ;ser=de-ined im&licit conversion
n + (ConvertibleDobjectE)o; .. *re=de-ined unbo#ing conversion
!
8ser<de0ined conversions are not allowed to convert 0rom or to interface-t+pes. 1n particular- t+is restriction
ensures t+at no user<de0ined trans0ormations occur w+en converting to an interface-t+pe- and t+at a conversion
to an interface-t+pe succeeds only i0 t+e ob&ect being converted actually implements t+e speci0ied interface-t+pe.
T+e signature o0 a conversion operator consists o0 t+e source type and t+e target type. J=ote t+at t+is is t+e only
0orm o0 member 0or w+ic+ t+e return type participates in t+e signature.M T+e im&licit or e#&licit
classi0ication o0 a conversion operator is not part o0 t+e operatorPs signature. T+us- a class or struct cannot
declare bot+ an im&licit and an e#&licit conversion operator wit+ t+e same source and target types.
1n general- user<de0ined implicit conversions s+ould be designed to never t+row eceptions and never lose
in0ormation. 10 a user<de0ined conversion can give rise to eceptions J0or eample- because t+e source argument
is out o0 rangeM or loss o0 in0ormation Jsuc+ as discarding +ig+<order bitsM- t+en t+at conversion s+ould be
de0ined as an eplicit conversion.
1n t+e eample
using System;
&ublic struct 6igit
{
byte value;
&ublic 6igit(byte value) {
i- (value D 3 HH value E L) t"ro, ne, 'rgument)#ce&tion();
t"is.value + value;
!
&ublic static im&licit o&erator byte(6igit d) {
return d.value;
!
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 3"!
C# Language Specification
&ublic static e#&licit o&erator 6igit(byte b) {
return ne, 6igit(b);
!
!
t+e conversion 0rom 6igit to byte is implicit because it never t+rows eceptions or loses in0ormation- but t+e
conversion 0rom byte to 6igit is eplicit since 6igit can only represent a subset o0 t+e possible values o0 a
byte.
10.11 Instance constructors
(n instance constr-ctor is a member t+at implements t+e actions re9uired to initialiDe an instance o0 a class.
1nstance constructors are declared using constr!ctor-declarationsC
constr!ctor-declaration.
attri,!tesopt constr!ctor-%odifiersopt constr!ctor-declarator constr!ctor-,od+
constr!ctor-%odifiers.
constr!ctor-%odifier
constr!ctor-%odifiers constr!ctor-%odifier
constr!ctor-%odifier.
.u"li&
.%'$e&$ed
i*$e%*!l
.%i,!$e
e-$e%*
constr!ctor-declarator.
identifier ( for%al-para%eter-listopt ) constr!ctor-initiali-eropt
constr!ctor-initiali-er.
@ "!#e ( arg!%ent-listopt )
@ $hi# ( arg!%ent-listopt )
constr!ctor-,od+.
,loc&
A
( constr!ctor-declaration may include a set o0 attri,!tes JV1!M- a valid combination o0 t+e 0our access modi0iers
JV1..3."M- and an e#tern JV1..%.!M modi0ier. ( constructor declaration is not permitted to include t+e same
modi0ier multiple times.
T+e identifier o0 a constr!ctor-declarator must name t+e class in w+ic+ t+e instance constructor is declared. 10
any ot+er name is speci0ied- a compile<time error occurs.
T+e optional for%al-para%eter-list o0 an instance constructor is sub&ect to t+e same rules as t+e for%al-
para%eter-list o0 a met+od JV1..%M. T+e 0ormal parameter list de0ines t+e signature JV3.%M o0 an instance
constructor and governs t+e process w+ereby overload resolution JV!.4.2M selects a particular instance
constructor in an invocation.
Eac+ o0 t+e types re0erenced in t+e for%al-para%eter-list o0 an instance constructor must be at least as
accessible as t+e constructor itsel0 JV3.".4M.
T+e optional constr!ctor-initiali-er speci0ies anot+er instance constructor to invo7e be0ore eecuting t+e
statements given in t+e constr!ctor-,od+ o0 t+is instance constructor. T+is is described 0urt+er in V1..11.1.
3* Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
6+en a constructor declaration includes an e#tern modi0ier- t+e constructor is said to be an e,ternal
constr-ctor. )ecause an eternal constructor declaration provides no actual implementation- its constr!ctor-
,od+ consists o0 a semicolon. *or all ot+er constructors- t+e constr!ctor-,od+ consists o0 a ,loc& w+ic+ speci0ies
t+e statements to initialiDe a new instance o0 t+e class. T+is corresponds eactly to t+e ,loc& o0 an instance
met+od wit+ a void return type JV1..%.1.M.
1nstance constructors are not in+erited. T+us- a class +as no instance constructors ot+er t+an t+ose actually
declared in t+e class. 10 a class contains no instance constructor declarations- a de0ault instance constructor is
automatically provided JV1..11.4M.
1nstance constructors are invo7ed by o,<ect-creation-e/pressions JV!.".1..1M and t+roug+ constr!ctor-
initiali-ers.
10.11.1 Constructor initiali<ers
(ll instance constructors Jecept t+ose 0or class objectM implicitly include an invocation o0 anot+er instance
constructor immediately be0ore t+e constr!ctor-,od+. T+e constructor to implicitly invo7e is determined by t+e
constr!ctor-initiali-erC
(n instance constructor initialiDer o0 t+e 0orm base(arg!%ent-listopt) causes an instance constructor 0rom
t+e direct base class to be invo7ed. T+at constructor is selected using arg!%ent-list and t+e overload
resolution rules o0 V!.4.3. T+e set o0 candidate instance constructors consists o0 all accessible instance
constructors contained in t+e direct base class- or t+e de0ault constructor JV1..11.4M- i0 no instance
constructors are declared in t+e direct base class. 10 t+is set is empty- or i0 a single best instance constructor
cannot be identi0ied- a compile<time error occurs.
(n instance constructor initialiDer o0 t+e 0orm t"is(arg!%ent-listopt) causes an instance constructor 0rom
t+e class itsel0 to be invo7ed. T+e constructor is selected using arg!%ent-list and t+e overload resolution
rules o0 V!.4.3. T+e set o0 candidate instance constructors consists o0 all accessible instance constructors
declared in t+e class itsel0. 10 t+is set is empty- or i0 a single best instance constructor cannot be identi0ied- a
compile<time error occurs. 10 an instance constructor declaration includes a constructor initialiDer t+at
invo7es t+e constructor itsel0- a compile<time error occurs.
10 an instance constructor +as no constructor initialiDer- a constructor initialiDer o0 t+e 0orm base() is implicitly
provided. T+us- an instance constructor declaration o0 t+e 0orm
C(...) {...!
is eactly e9uivalent to
C(...)/ base() {...!
T+e scope o0 t+e parameters given by t+e for%al-para%eter-list o0 an instance constructor declaration includes
t+e constructor initialiDer o0 t+at declaration. T+us- a constructor initialiDer is permitted to access t+e parameters
o0 t+e constructor. *or eampleC
class '
{
&ublic '(int # int y) {!
!
class :/ '
{
&ublic :(int # int y)/ base(# < y # = y) {!
!
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 31
C# Language Specification
(n instance constructor initialiDer cannot access t+e instance being created. T+ere0ore it is a compile<time error
to re0erence t"is in an argument epression o0 t+e constructor initialiDer- as is it a compile<time error 0or an
argument epression to re0erence any instance member t+roug+ a si%ple-na%e.
10.11.2 Instance "ariable initiali<ers
6+en an instance constructor +as no constructor initialiDer- or it +as a constructor initialiDer o0 t+e 0orm
base(...)- t+at constructor implicitly per0orms t+e initialiDations speci0ied by t+e varia,le-initiali-ers o0 t+e
instance 0ields declared in its class. T+is corresponds to a se9uence o0 assignments t+at are eecuted
immediately upon entry to t+e constructor and be0ore t+e implicit invocation o0 t+e direct base class constructor.
T+e variable initialiDers are eecuted in t+e tetual order in w+ic+ t+ey appear in t+e class declaration.
10.11.3 Constructor e%ecution
,ariable initialiDers are trans0ormed into assignment statements- and t+ese assignment statements are eecuted
be0ore t+e invocation o0 t+e base class instance constructor. T+is ordering ensures t+at all instance 0ields are
initialiDed by t+eir variable initialiDers be0ore any statements t+at +ave access to t+at instance are eecuted.
4iven t+e eample
using System;
class '
{
&ublic '() {
*rintVields();
!
&ublic virtual void *rintVields() {!
!
class :/ '
{
int # + 2;
int y;
&ublic :() {
y + =2;
!
&ublic override void *rintVields() {
Console.WriteLine("# + {3! y + {2!" # y);
!
!
w+en ne, :() is used to create an instance o0 :- t+e 0ollowing output is producedC
# + 2 y + 3
T+e value o0 # is 1 because t+e variable initialiDer is eecuted be0ore t+e base class instance constructor is
invo7ed. However- t+e value o0 y is . Jt+e de0ault value o0 an intM because t+e assignment to y is not eecuted
until a0ter t+e base class constructor returns.
1t is use0ul to t+in7 o0 instance variable initialiDers and constructor initialiDers as statements t+at are
automatically inserted be0ore t+e constr!ctor-,od+. T+e eample
using System;
using System.Collections;
32 Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
class '
{
int # + 2 y + =2 count;
&ublic '() {
count + 3;
!
&ublic '(int n) {
count + n;
!
!
class :/ '
{
double sQrt8 + Mat".SQrt(8.3);
'rrayList items + ne, 'rrayList(233);
int ma#;
&ublic :()/ t"is(233) {
items.'dd("de-ault");
!
&ublic :(int n)/ base(n C 2) {
ma# + n;
!
!
contains several variable initialiDersQ it also contains constructor initialiDers o0 bot+ 0orms Jbase and t"isM. T+e
eample corresponds to t+e code s+own below- w+ere eac+ comment indicates an automatically inserted
statement Jt+e synta used 0or t+e automatically inserted constructor invocations isnPt valid- but merely serves to
illustrate t+e mec+anismM.
using System.Collections;
class '
{
int # y count;
&ublic '() {
# + 2; .. Uariable initiali?er
y + =2; .. Uariable initiali?er
object(); .. $nvo(e object() constructor
count + 3;
!
&ublic '(int n) {
# + 2; .. Uariable initiali?er
y + =2; .. Uariable initiali?er
object(); .. $nvo(e object() constructor
count + n;
!
!
class :/ '
{
double sQrt8;
'rrayList items;
int ma#;
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 33
C# Language Specification
&ublic :()/ t"is(233) {
:(233); .. $nvo(e :(int) constructor
items.'dd("de-ault");
!
&ublic :(int n)/ base(n C 2) {
sQrt8 + Mat".SQrt(8.3); .. Uariable initiali?er
items + ne, 'rrayList(233); .. Uariable initiali?er
'(n C 2); .. $nvo(e '(int) constructor
ma# + n;
!
!
10.11.# 2efault constructors
10 a class contains no instance constructor declarations- a de0ault instance constructor is automatically provided.
T+at de0ault constructor simply invo7es t+e parameterless constructor o0 t+e direct base class. 10 t+e direct base
class does not +ave an accessible parameterless instance constructor- a compile<time error occurs. 10 t+e class is
abstract t+en t+e declared accessibility 0or t+e de0ault constructor is protected. /t+erwise- t+e declared
accessibility 0or t+e de0ault constructor is public. T+us- t+e de0ault constructor is always o0 t+e 0orm
&rotected C()/ base() {!
or
&ublic C()/ base() {!
w+ere C is t+e name o0 t+e class.
1n t+e eample
class Message
{
object sender;
string te#t;
!
a de0ault constructor is provided because t+e class contains no instance constructor declarations. T+us- t+e
eample is precisely e9uivalent to
class Message
{
object sender;
string te#t;
&ublic Message()/ base() {!
!
10.11.& Pri"ate constructors
6+en a class 1 declares only private instance constructors- it is not possible 0or classes outside t+e program tet
o0 1 to derive 0rom 1 or to directly create instances o0 1. T+us- i0 a class contains only static members and isnPt
intended to be instantiated- adding an empty private instance constructor will prevent instantiation. *or eampleC
&ublic class 1rig
{
&rivate 1rig() {! .. *revent instantiation
&ublic const double *$ + 9.2J2KL8XK9KYLML989YJX;
3" Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
&ublic static double Sin(double #) {...!
&ublic static double Cos(double #) {...!
&ublic static double 1an(double #) {...!
!
T+e 1rig class groups related met+ods and constants- but is not intended to be instantiated. T+ere0ore it
declares a single empty private instance constructor. (t least one instance constructor must be declared to
suppress t+e automatic generation o0 a de0ault constructor.
10.11.' /ptional instance constructor paraeters
T+e t"is(...) 0orm o0 constructor initialiDer is commonly used in con&unction wit+ overloading to implement
optional instance constructor parameters. 1n t+e eample
class 1e#t
{
&ublic 1e#t()/ t"is(3 3 null) {!
&ublic 1e#t(int # int y)/ t"is(# y null) {!
&ublic 1e#t(int # int y string s) {
.. 'ctual constructor im&lementation
!
!
t+e 0irst two instance constructors merely provide t+e de0ault values 0or t+e missing arguments. )ot+ use a
t"is(...) constructor initialiDer to invo7e t+e t+ird instance constructor- w+ic+ actually does t+e wor7 o0
initialiDing t+e new instance. T+e e00ect is t+at o0 optional constructor parametersC
1e#t t2 + ne, 1e#t(); .. Same as 1e#t(3 3 null)
1e#t t8 + ne, 1e#t(K 23); .. Same as 1e#t(K 23 null)
1e#t t9 + ne, 1e#t(K 83 "Hello");
10.12 Static constructors
( static constr-ctor is a member t+at implements t+e actions re9uired to initialiDe a closed class type. #tatic
constructors are declared using static-constr!ctor-declarationsC
static-constr!ctor-declaration.
attri,!tesopt static-constr!ctor-%odifiers identifier ( ) static-constr!ctor-,od+
static-constr!ctor-%odifiers.
e-$e%*opt #$!$i&
#$!$i& e-$e%*opt
static-constr!ctor-,od+.
,loc&
A
( static-constr!ctor-declaration may include a set o0 attri,!tes JV1!M and an e#tern modi0ier JV1..%.!M.
T+e identifier o0 a static-constr!ctor-declaration must name t+e class in w+ic+ t+e static constructor is declared.
10 any ot+er name is speci0ied- a compile<time error occurs.
6+en a static constructor declaration includes an e#tern modi0ier- t+e static constructor is said to be an
e,ternal static constr-ctor. )ecause an eternal static constructor declaration provides no actual
implementation- its static-constr!ctor-,od+ consists o0 a semicolon. *or all ot+er static constructor declarations-
t+e static-constr!ctor-,od+ consists o0 a ,loc& w+ic+ speci0ies t+e statements to eecute in order to initialiDe t+e
class. T+is corresponds eactly to t+e %ethod-,od+ o0 a static met+od wit+ a void return type JV1..%.1.M.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 3
C# Language Specification
#tatic constructors are not in+erited- and cannot be called directly.
T+e static constructor 0or a closed class type eecutes at most once in a given application domain. T+e eecution
o0 a static constructor is triggered by t+e 0irst o0 t+e 0ollowing events to occur wit+in an application domainC
(n instance o0 t+e class type is created.
(ny o0 t+e static members o0 t+e class type are re0erenced.
10 a class contains t+e Main met+od JV3.1M in w+ic+ eecution begins- t+e static constructor 0or t+at class
eecutes be0ore t+e Main met+od is called.
To initialiDe a new closed class type- 0irst a new set o0 static 0ields JV1..".1M 0or t+at particular closed type is
created. Eac+ o0 t+e static 0ields is initialiDed to its de0ault value JV".2M. =et- t+e static 0ield initialiDers
JV1..4.".1M are eecuted 0or t+ose static 0ields. *inally- t+e static constructor is eecuted.
T+e eample
using System;
class 1est
{
static void Main() {
'.V();
:.V();
!
!
class '
{
static '() {
Console.WriteLine("$nit '");
!
&ublic static void V() {
Console.WriteLine("'.V");
!
!
class :
{
static :() {
Console.WriteLine("$nit :");
!
&ublic static void V() {
Console.WriteLine(":.V");
!
!
must produce t+e outputC
$nit '
'.V
$nit :
:.V
because t+e eecution o0 'Ps static constructor is triggered by t+e call to '.V- and t+e eecution o0 :Ps static
constructor is triggered by t+e call to :.V.
3' Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
1t is possible to construct circular dependencies t+at allow static 0ields wit+ variable initialiDers to be observed in
t+eir de0ault value state.
T+e eample
using System;
class '
{
&ublic static int I;
static '() {
I + :.` < 2;
!
!
class :
{
&ublic static int ` + '.I < 2;
static :() {!
static void Main() {
Console.WriteLine("I + {3! ` + {2!" '.I :.`);
!
!
produces t+e output
I + 2 ` + 8
To eecute t+e Main met+od- t+e system 0irst runs t+e initialiDer 0or :.`- prior to class :Ps static constructor. `Ps
initialiDer causes 'Ps static constructor to be run because t+e value o0 '.I is re0erenced. T+e static constructor
o0 ' in turn proceeds to compute t+e value o0 I- and in doing so 0etc+es t+e de0ault value o0 `- w+ic+ is Dero.
'.I is t+us initialiDed to 1. T+e process o0 running 'Ps static 0ield initialiDers and static constructor t+en
completes- returning to t+e calculation o0 t+e initial value o0 `- t+e result o0 w+ic+ becomes 2.
)ecause t+e static constructor is eecuted eactly once 0or eac+ closed constructed class type- it is a convenient
place to en0orce run<time c+ec7s on t+e type parameter t+at cannot be c+ec7ed at compile<time via constraints
JV1..1."M. *or eample- t+e 0ollowing type uses a static constructor to en0orce t+at t+e type argument is an
enumC
class SenD1E ,"ere 1/ struct
{
static Sen() {
i- (@ty&eo-(1).$s)num) {
t"ro, ne, 'rgument)#ce&tion("1 must be an enum");
!
!
!
10.13 2estructors
( destr-ctor is a member t+at implements t+e actions re9uired to destruct an instance o0 a class. ( destructor is
declared using a destr!ctor-declarationC
destr!ctor-declaration.
attri,!tesopt e-$e%*opt G identifier ( ) destr!ctor-,od+
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 37
C# Language Specification
destr!ctor-,od+.
,loc&
A
( destr!ctor-declaration may include a set o0 attri,!tes JV1!M.
T+e identifier o0 a destr!ctor-declarator must name t+e class in w+ic+ t+e destructor is declared. 10 any ot+er
name is speci0ied- a compile<time error occurs.
6+en a destructor declaration includes an e#tern modi0ier- t+e destructor is said to be an e,ternal destr-ctor.
)ecause an eternal destructor declaration provides no actual implementation- its destr!ctor-,od+ consists o0 a
semicolon. *or all ot+er destructors- t+e destr!ctor-,od+ consists o0 a ,loc& w+ic+ speci0ies t+e statements to
eecute in order to destruct an instance o0 t+e class. ( destr!ctor-,od+ corresponds eactly to t+e %ethod-,od+
o0 an instance met+od wit+ a void return type JV1..%.1.M.
2estructors are not in+erited. T+us- a class +as no destructors ot+er t+an t+e one w+ic+ may be declared in t+at
class.
#ince a destructor is re9uired to +ave no parameters- it cannot be overloaded- so a class can +ave- at most- one
destructor.
2estructors are invo7ed automatically- and cannot be invo7ed eplicitly. (n instance becomes eligible 0or
destruction w+en it is no longer possible 0or any code to use t+at instance. Eecution o0 t+e destructor 0or t+e
instance may occur at any time a0ter t+e instance becomes eligible 0or destruction. 6+en an instance is
destructed- t+e destructors in t+at instancePs in+eritance c+ain are called- in order- 0rom most derived to least
derived. ( destructor may be eecuted on any t+read. *or 0urt+er discussion o0 t+e rules t+at govern w+en and
+ow a destructor is eecuted- see V3.$.
T+e output o0 t+e eample
using System;
class '
{
A'() {
Console.WriteLine("'Ws destructor");
!
!
class :/ '
{
A:() {
Console.WriteLine(":Ws destructor");
!
!
class 1est
{
static void Main() {
: b + ne, :();
b + null;
SC.Collect();
SC.WaitVor*endingVinali?ers();
!
!
is
:_s destructor
'_s destructor
3$ Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
since destructors in an in+eritance c+ain are called in order- 0rom most derived to least derived.
2estructors are implemented by overriding t+e virtual met+od Vinali?e on System.%bject. C# programs
are not permitted to override t+is met+od or call it Jor overrides o0 itM directly. *or instance- t+e program
class '
{
override &rotected void Vinali?e() {! .. error
&ublic void V() {
t"is.Vinali?e(); .. error
!
!
contains two errors.
T+e compiler be+aves as i0 t+is met+od- and overrides o0 it- do not eist at all. T+us- t+is programC
class '
{
void Vinali?e() {! .. &ermitted
!
is valid- and t+e met+od s+own +ides System.%bjectPs Vinali?e met+od.
*or a discussion o0 t+e be+avior w+en an eception is t+rown 0rom a destructor- see V1%.3.
10.1# Iterators
( 0unction member JV!.4M implemented using an iterator bloc7 JV3.2M is called an iterator.
(n iterator bloc7 may be used as t+e body o0 a 0unction member as long as t+e return type o0 t+e corresponding
0unction member is one o0 t+e enumerator inter0aces JV1..14.1M or one o0 t+e enumerable inter0aces JV1..14.2M.
1t can occur as a %ethod-,od+- operator-,od+ or accessor-,od+- w+ereas events- instance constructors- static
constructors and destructors cannot be implemented as iterators.
6+en a 0unction member is implemented using an iterator bloc7- it is a compile<time error 0or t+e 0ormal
parameter list o0 t+e 0unction member to speci0y any re- or out parameters.
10.1#.1 $nuerator interfaces
T+e en-erator interfaces are t+e non<generic inter0ace System.Collections.$)numerator and all
instantiations o0 t+e generic inter0ace System.Collections.Seneric.$)numeratorD1E. *or t+e sa7e o0
brevity- in t+is c+apter t+ese inter0aces are re0erenced as $)numerator and $)numeratorD1E- respectively.
10.1#.2 $nuerable interfaces
T+e en-era!le interfaces are t+e non<generic inter0ace System.Collections.$)numerable and all
instantiations o0 t+e generic inter0ace System.Collections.Seneric.$)numerableD1E. *or t+e sa7e o0
brevity- in t+is c+apter t+ese inter0aces are re0erenced as $)numerable and $)numerableD1E- respectively.
10.1#.3 @ield t!pe
(n iterator produces a se9uence o0 values- all o0 t+e same type. T+is type is called t+e yield type o0 t+e iterator.
T+e yield type o0 an iterator t+at returns $)numerator or $)numerable is object.
T+e yield type o0 an iterator t+at returns $)numeratorD1E or $)numerableD1E is 1.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 3!
C# Language Specification
10.1#.# $nuerator ob(ects
6+en a 0unction member returning an enumerator inter0ace type is implemented using an iterator bloc7-
invo7ing t+e 0unction member does not immediately eecute t+e code in t+e iterator bloc7. 1nstead- an
en-erator o!1ect is created and returned. T+is ob&ect encapsulates t+e code speci0ied in t+e iterator bloc7- and
eecution o0 t+e code in t+e iterator bloc7 occurs w+en t+e enumerator ob&ectPs MoveNe#t met+od is invo7ed.
(n enumerator ob&ect +as t+e 0ollowing c+aracteristicsC
1t implements $)numerator and $)numeratorD1E- w+ere 1 is t+e yield type o0 t+e iterator.
1t implements System.$6is&osable.
1t is initialiDed wit+ a copy o0 t+e argument values Ji0 anyM and instance value passed to t+e 0unction
member.
1t +as 0our potential states- !efore- r-nning- s-spended- and after- and is initially in t+e !efore state.
(n enumerator ob&ect is typically an instance o0 a compiler<generated enumerator class t+at encapsulates t+e
code in t+e iterator bloc7 and implements t+e enumerator inter0aces- but ot+er met+ods o0 implementation are
possible. 10 an enumerator class is generated by t+e compiler- t+at class will be nested- directly or indirectly- in
t+e class containing t+e 0unction member- it will +ave private accessibility- and it will +ave a name reserved 0or
compiler use JV2.4.2M.
(n enumerator ob&ect may implement more inter0aces t+an t+ose speci0ied above.
T+e 0ollowing sections describe t+e eact be+avior o0 t+e MoveNe#t- Current- and 6is&ose members o0 t+e
$)numerable and $)numerableD1E inter0ace implementations provided by an enumerator ob&ect.
=ote t+at enumerator ob&ects do not support t+e $)numerator.Oeset met+od. 1nvo7ing t+is met+od causes a
System.NotSu&&orted)#ce&tion to be t+rown.
14.14.4.1 *he MoveBe$t method
T+e MoveNe#t met+od o0 an enumerator ob&ect encapsulates t+e code o0 an iterator bloc7. 1nvo7ing t+e
MoveNe#t met+od eecutes code in t+e iterator bloc7 and sets t+e Current property o0 t+e enumerator ob&ect
as appropriate. T+e precise action per0ormed by MoveNe#t depends on t+e state o0 t+e enumerator ob&ect w+en
MoveNe#t is invo7edC
10 t+e state o0 t+e enumerator ob&ect is !efore- invo7ing MoveNe#tC
o C+anges t+e state to r-nning.
o 1nitialiDes t+e parameters Jincluding t"isM o0 t+e iterator bloc7 to t+e argument values and instance
value saved w+en t+e enumerator ob&ect was initialiDed.
o Eecutes t+e iterator bloc7 0rom t+e beginning until eecution is interrupted Jas described belowM.
10 t+e state o0 t+e enumerator ob&ect is r-nning- t+e result o0 invo7ing MoveNe#t is unspeci0ied.
10 t+e state o0 t+e enumerator ob&ect is s-spended- invo7ing MoveNe#tC
o C+anges t+e state to r-nning.
o ;estores t+e values o0 all local variables and parameters Jincluding t+isM to t+e values saved w+en
eecution o0 t+e iterator bloc7 was last suspended. =ote t+at t+e contents o0 any ob&ects re0erenced by
t+ese variables may +ave c+anged since t+e previous call to 'ove=et.
o ;esumes eecution o0 t+e iterator bloc7 immediately 0ollowing t+e yield return statement t+at
caused t+e suspension o0 eecution and continues until eecution is interrupted Jas described belowM.
3'* Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
10 t+e state o0 t+e enumerator ob&ect is after- invo7ing MoveNe#t returns -alse.
6+en MoveNe#t eecutes t+e iterator bloc7- eecution can be interrupted in 0our waysC )y a yield return
statement- by a yield brea( statement- by encountering t+e end o0 t+e iterator bloc7- and by an eception
being t+rown and propagated out o0 t+e iterator bloc7.
6+en a yield return statement is encountered JV3.14MC
o T+e epression given in t+e statement is evaluated- implicitly converted to t+e yield type- and assigned
to t+e Current property o0 t+e enumerator ob&ect.
o Eecution o0 t+e iterator body is suspended. T+e values o0 all local variables and parameters Jincluding
t"isM are saved- as is t+e location o0 t+is yield return statement. 10 t+e yield return statement is
wit+in one or more try bloc7s- t+e associated -inally bloc7s are not eecuted at t+is time.
o T+e state o0 t+e enumerator ob&ect is c+anged to s-spended.
o T+e MoveNe#t met+od returns true to its caller- indicating t+at t+e iteration success0ully advanced to
t+e net value.
6+en a yield brea( statement is encountered JV3.14MC
o 10 t+e yield brea( statement is wit+in one or more try bloc7s- t+e associated -inally bloc7s are
eecuted.
o T+e state o0 t+e enumerator ob&ect is c+anged to after.
o T+e MoveNe#t met+od returns -alse to its caller- indicating t+at t+e iteration is complete.
6+en t+e end o0 t+e iterator body is encounteredC
o T+e state o0 t+e enumerator ob&ect is c+anged to after.
o T+e MoveNe#t met+od returns -alse to its caller- indicating t+at t+e iteration is complete.
6+en an eception is t+rown and propagated out o0 t+e iterator bloc7C
o (ppropriate -inally bloc7s in t+e iterator body will +ave been eecuted by t+e eception propagation.
o T+e state o0 t+e enumerator ob&ect is c+anged to after.
o T+e eception propagation continues to t+e caller o0 t+e MoveNe#t met+od.
14.14.4.2 *he !urrent "ro"erty
(n enumerator ob&ectPs Current property is a00ected by yield return statements in t+e iterator bloc7.
6+en an enumerator ob&ect is in t+e s-spended state- t+e value o0 Current is t+e value set by t+e previous call
to MoveNe#t. 6+en an enumerator ob&ect is in t+e !efore- r-nning- or after states- t+e result o0 accessing
Current is unspeci0ied.
*or an iterator wit+ a yield type ot+er t+an object- t+e result o0 accessing Current t+roug+ t+e enumerator
ob&ectPs $)numerable implementation corresponds to accessing Current t+roug+ t+e enumerator ob&ectPs
$)numeratorD1E implementation and casting t+e result to object.
14.14.4.3 *he 'is"ose method
T+e 6is&ose met+od is used to clean up t+e iteration by bringing t+e enumerator ob&ect to t+e after state.
10 t+e state o0 t+e enumerator ob&ect is !efore- invo7ing 6is&ose c+anges t+e state to after.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 3'1
C# Language Specification
10 t+e state o0 t+e enumerator ob&ect is r-nning- t+e result o0 invo7ing 6is&ose is unspeci0ied.
10 t+e state o0 t+e enumerator ob&ect is s-spended- invo7ing 6is&oseC
o C+anges t+e state to r-nning.
o Eecutes any 0inally bloc7s as i0 t+e last eecuted yield return statement were a yield brea(
statement. 10 t+is causes an eception to be t+rown and propagated out o0 t+e iterator body- t+e state o0
t+e enumerator ob&ect is set to after and t+e eception is propagated to t+e caller o0 t+e 6is&ose
met+od.
o C+anges t+e state to after.
10 t+e state o0 t+e enumerator ob&ect is after- invo7ing 6is&ose +as no a00ect.
10.1#.& $nuerable ob(ects
6+en a 0unction member returning an enumerable inter0ace type is implemented using an iterator bloc7-
invo7ing t+e 0unction member does not immediately eecute t+e code in t+e iterator bloc7. 1nstead- an
en-era!le o!1ect is created and returned. T+e enumerable ob&ectPs Set)numerator met+od returns an
enumerator ob&ect t+at encapsulates t+e code speci0ied in t+e iterator bloc7- and eecution o0 t+e code in t+e
iterator bloc7 occurs w+en t+e enumerator ob&ectPs MoveNe#t met+od is invo7ed. (n enumerable ob&ect +as t+e
0ollowing c+aracteristicsC
1t implements $)numerable and $)numerableD1E- w+ere 1 is t+e yield type o0 t+e iterator.
1t is initialiDed wit+ a copy o0 t+e argument values Ji0 anyM and instance value passed to t+e 0unction
member.
(n enumerable ob&ect is typically an instance o0 a compiler<generated enumerable class t+at encapsulates t+e
code in t+e iterator bloc7 and implements t+e enumerable inter0aces- but ot+er met+ods o0 implementation are
possible. 10 an enumerable class is generated by t+e compiler- t+at class will be nested- directly or indirectly- in
t+e class containing t+e 0unction member- it will +ave private accessibility- and it will +ave a name reserved 0or
compiler use JV2.4.2M.
(n enumerable ob&ect may implement more inter0aces t+an t+ose speci0ied above. 1n particular- an enumerable
ob&ect may also implement $)numerator and $)numeratorD1E- enabling it to serve as bot+ an enumerable
and an enumerator. 1n t+at type o0 implementation- t+e 0irst time an enumerable ob&ectPs Set)numerator
met+od is invo7ed- t+e enumerable ob&ect itsel0 is returned. #ubse9uent invocations o0 t+e enumerable ob&ectPs
Set)numerator- i0 any- return a copy o0 t+e enumerable ob&ect. T+us- eac+ returned enumerator +as its own
state and c+anges in one enumerator will not a00ect anot+er.
14.14.5.1 *he .et%numerator method
(n enumerable ob&ect provides an implementation o0 t+e Set)numerator met+ods o0 t+e $)numerable and
$)numerableD1E inter0aces. T+e two Set)numerator met+ods s+are a common implementation t+at
ac9uires and returns an available enumerator ob&ect. T+e enumerator ob&ect is initialiDed wit+ t+e argument
values and instance value saved w+en t+e enumerable ob&ect was initialiDed- but ot+erwise t+e enumerator ob&ect
0unctions as described in V1..14.4.
10.1#.' Ipleentation e%aple
T+is section describes a possible implementation o0 iterators in terms o0 standard C# constructs. T+e
implementation described +ere is based on t+e same principles used by t+e 'icroso0t C# compiler- but it is by
no means a mandated implementation or t+e only one possible.
3'2 Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
T+e 0ollowing Stac(D1E class implements its Set)numerator met+od using an iterator. T+e iterator
enumerates t+e elements o0 t+e stac7 in top to bottom order.
using System;
using System.Collections;
using System.Collections.Seneric;
class Stac(D1E/ $)numerableD1E
{
145 items;
int count;
&ublic void *us"(1 item) {
i- (items ++ null) {
items + ne, 14J5;
!
else i- (items.Lengt" ++ count) {
145 ne,$tems + ne, 14count > 85;
'rray.Co&y(items 3 ne,$tems 3 count);
items + ne,$tems;
!
items4count<<5 + item;
!
&ublic 1 *o&() {
1 result + items4==count5;
items4count5 + de-ault(1);
return result;
!
&ublic $)numeratorD1E Set)numerator() {
-or (int i + count = 2; i E+ 3; ==i) yield return items4i5;
!
!
T+e Set)numerator met+od can be translated into an instantiation o0 a compiler<generated enumerator class
t+at encapsulates t+e code in t+e iterator bloc7- as s+own in t+e 0ollowing.
class Stac(D1E/ $)numerableD1E
{
...
&ublic $)numeratorD1E Set)numerator() {
return ne, [[)numerator2(t"is);
!
class [[)numerator2/ $)numeratorD1E $)numerator
{
int [[state;
1 [[current;
Stac(D1E [[t"is;
int i;
&ublic [[)numerator2(Stac(D1E [[t"is) {
t"is.[[t"is + [[t"is;
!
&ublic 1 Current {
get { return [[current; !
!
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 3'3
C# Language Specification
object $)numerator.Current {
get { return [[current; !
!
&ublic bool MoveNe#t() {
s,itc" ([[state) {
case 2/ goto [[state2;
case 8/ goto [[state8;
!
i + [[t"is.count = 2;
[[loo&/
i- (i D 3) goto [[state8;
[[current + [[t"is.items4i5;
[[state + 2;
return true;
[[state2/
==i;
goto [[loo&;
[[state8/
[[state + 8;
return -alse;
!
&ublic void 6is&ose() {
[[state + 8;
!
void $)numerator.Oeset() {
t"ro, ne, NotSu&&orted)#ce&tion();
!
!
!
1n t+e preceding translation- t+e code in t+e iterator bloc7 is turned into a state mac+ine and placed in t+e
MoveNe#t met+od o0 t+e enumerator class. *urt+ermore- t+e local variable i is turned into a 0ield in t+e
enumerator ob&ect so it can continue to eist across invocations o0 MoveNe#t.
T+e 0ollowing eample prints a simple multiplication table o0 t+e integers 1 t+roug+ 1.. T+e Vrom1o met+od in
t+e eample returns an enumerable ob&ect and is implemented using an iterator.
using System;
using System.Collections.Seneric;
class 1est
{
static $)numerableDintE Vrom1o(int -rom int to) {
,"ile (-rom D+ to) yield return -rom<<;
!
static void Main() {
$)numerableDintE e + Vrom1o(2 23);
-oreac" (int # in e) {
-oreac" (int y in e) {
Console.Write("{39! " # > y);
!
Console.WriteLine();
!
!
!
3'" Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
T+e Vrom1o met+od can be translated into an instantiation o0 a compiler<generated enumerable class t+at
encapsulates t+e code in t+e iterator bloc7- as s+own in t+e 0ollowing.
using System;
using System.1"reading;
using System.Collections;
using System.Collections.Seneric;
class 1est
{
...
static $)numerableDintE Vrom1o(int -rom int to) {
return ne, [[)numerable2(-rom to);
!
class [[)numerable2/
$)numerableDintE $)numerable
$)numeratorDintE $)numerator
{
int [[state;
int [[current;
int [[-rom;
int -rom;
int to;
int i;
&ublic [[)numerable2(int [[-rom int to) {
t"is.[[-rom + [[-rom;
t"is.to + to;
!
&ublic $)numeratorDintE Set)numerator() {
[[)numerable2 result + t"is;
i- ($nterloc(ed.Com&are)#c"ange(re- [[state 2 3) @+ 3) {
result + ne, [[)numerable2([[-rom to);
result.[[state + 2;
!
result.-rom + result.[[-rom;
return result;
!
$)numerator $)numerable.Set)numerator() {
return ($)numerator)Set)numerator();
!
&ublic int Current {
get { return [[current; !
!
object $)numerator.Current {
get { return [[current; !
!
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 3'
C# Language Specification
&ublic bool MoveNe#t() {
s,itc" ([[state) {
case 2/
i- (-rom E to) goto case 8;
[[current + -rom<<;
[[state + 2;
return true;
case 8/
[[state + 8;
return -alse;
de-ault/
t"ro, ne, $nvalid%&eration)#ce&tion();
!
!
&ublic void 6is&ose() {
[[state + 8;
!
void $)numerator.Oeset() {
t"ro, ne, NotSu&&orted)#ce&tion();
!
!
!
T+e enumerable class implements bot+ t+e enumerable inter0aces and t+e enumerator inter0aces- enabling it to
serve as bot+ an enumerable and an enumerator. T+e 0irst time t+e Set)numerator met+od is invo7ed- t+e
enumerable ob&ect itsel0 is returned. #ubse9uent invocations o0 t+e enumerable ob&ectPs Set)numerator- i0
any- return a copy o0 t+e enumerable ob&ect. T+us- eac+ returned enumerator +as its own state and c+anges in
one enumerator will not a00ect anot+er. T+e $nterloc(ed.Com&are)#c"ange met+od is used to ensure
t+read<sa0e operation.
T+e -rom and to parameters are turned into 0ields in t+e enumerable class. )ecause -rom is modi0ied in t+e
iterator bloc7- an additional [[-rom 0ield is introduced to +old t+e initial value given to -rom in eac+
enumerator.
T+e MoveNe#t met+od t+rows an $nvalid%&eration)#ce&tion i0 it is called w+en [[state is 3. T+is
protects against use o0 t+e enumerable ob&ect as an enumerator ob&ect wit+out 0irst calling Set)numerator.
T+e 0ollowing eample s+ows a simple tree class. T+e 1reeD1E class implements its Set)numerator met+od
using an iterator. T+e iterator enumerates t+e elements o0 t+e tree in in0i order.
using System;
using System.Collections.Seneric;
class 1reeD1E/ $)numerableD1E
{
1 value;
1reeD1E le-t;
1reeD1E rig"t;
&ublic 1ree(1 value 1reeD1E le-t 1reeD1E rig"t) {
t"is.value + value;
t"is.le-t + le-t;
t"is.rig"t + rig"t;
!
3'' Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
&ublic $)numeratorD1E Set)numerator() {
i- (le-t @+ null) -oreac" (1 # in le-t) yield #;
yield value;
i- (rig"t @+ null) -oreac" (1 # in rig"t) yield #;
!
!
class *rogram
{
static 1reeD1E Ma(e1reeD1E(145 items int le-t int rig"t) {
i- (le-t E rig"t) return null;
int i + (le-t < rig"t) . 8;
return ne, 1reeD1E(items4i5
Ma(e1ree(items le-t i = 2)
Ma(e1ree(items i < 2 rig"t));
!
static 1reeD1E Ma(e1reeD1E(&arams 145 items) {
return Ma(e1ree(items 3 items.Lengt" = 2);
!
.. 1"e out&ut o- t"e &rogram is/
.. 2 8 9 J K X M Y L
.. Mon 1ue Wed 1"u Vri Sat Sun
static void Main() {
1reeDintE ints + Ma(e1ree(2 8 9 J K X M Y L);
-oreac" (int i in ints) Console.Write("{3! " i);
Console.WriteLine();
1reeDstringE strings + Ma(e1ree(
"Mon" "1ue" "Wed" "1"u" "Vri" "Sat" "Sun");
-oreac" (string s in strings) Console.Write("{3! " s);
Console.WriteLine();
!
!
T+e Set)numerator met+od can be translated into an instantiation o0 a compiler<generated enumerator class
t+at encapsulates t+e code in t+e iterator bloc7- as s+own in t+e 0ollowing.
class 1reeD1E/ $)numerableD1E
{
...
&ublic $)numeratorD1E Set)numerator() {
return ne, [[)numerator2(t"is);
!
class [[)numerator2 / $)numeratorD1E $)numerator
{
NodeD1E [[t"is;
$)numeratorD1E [[le-t [[rig"t;
int [[state;
1 [[current;
&ublic [[)numerator2(NodeD1E [[t"is) {
t"is.[[t"is + [[t"is;
!
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 3'7
C# Language Specification
&ublic 1 Current {
get { return [[current; !
!
object $)numerator.Current {
get { return [[current; !
!
&ublic bool MoveNe#t() {
try {
s,itc" ([[state) {
case 3/
[[state + =2;
i- ([[t"is.le-t ++ null) goto [[yield[value;
[[le-t + [[t"is.le-t.Set)numerator();
goto case 2;
case 2/
[[state + =8;
i- (@[[le-t.MoveNe#t()) goto [[le-t[dis&ose;
[[current + [[le-t.Current;
[[state + 2;
return true;
[[le-t[dis&ose/
[[state + =2;
[[le-t.6is&ose();
[[yield[value/
[[current + [[t"is.value;
[[state + 8;
return true;
case 8/
[[state + =2;
i- ([[t"is.rig"t ++ null) goto [[end;
[[rig"t + [[t"is.rig"t.Set)numerator();
goto case 9;
case 9/
[[state + =9;
i- (@[[rig"t.MoveNe#t()) goto [[rig"t[dis&ose;
[[current + [[rig"t.Current;
[[state + 9;
return true;
[[rig"t[dis&ose/
[[state + =2;
[[rig"t.6is&ose();
[[end/
[[state + J;
brea(;
!
!
-inally {
i- ([[state D 3) 6is&ose();
!
return -alse;
!
3'$ Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
&ublic void 6is&ose() {
try {
s,itc" ([[state) {
case 2/
case =8/
[[le-t.6is&ose();
brea(;
case 9/
case =9/
[[rig"t.6is&ose();
brea(;
!
!
-inally {
[[state + J;
!
!
void $)numerator.Oeset() {
t"ro, ne, NotSu&&orted)#ce&tion();
!
!
!
T+e compiler generated temporaries used in t+e -oreac" statements are li0ted into t+e [[le-t and [[rig"t
0ields o0 t+e enumerator ob&ect. T+e [[state 0ield o0 t+e enumerator ob&ect is care0ully updated so t+at t+e
correct 6is&ose() met+od will be called correctly i0 an eception is t+rown. =ote t+at it is not possible to write
t+e translated code wit+ simple -oreac" statements.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 3'!
C# Language Specification
11. Structs
#tructs are similar to classes in t+at t+ey represent data structures t+at can contain data members and 0unction
members. However- unli7e classes- structs are value types and do not re9uire +eap allocation. ( variable o0 a
struct type directly contains t+e data o0 t+e struct- w+ereas a variable o0 a class type contains a re0erence to t+e
data- t+e latter 7nown as an ob&ect.
#tructs are particularly use0ul 0or small data structures t+at +ave value semantics. Comple numbers- points in a
coordinate system- or 7ey<value pairs in a dictionary are all good eamples o0 structs. :ey to t+ese data
structures is t+at t+ey +ave 0ew data members- t+at t+ey do not re9uire use o0 in+eritance or re0erential identity-
and t+at t+ey can be conveniently implemented using value semantics w+ere assignment copies t+e value instead
o0 t+e re0erence.
(s described in V4.1.4- t+e simple types provided by C#- suc+ as int- double- and bool- are in 0act all struct
types. Fust as t+ese prede0ined types are structs- it is also possible to use structs and operator overloading to
implement new KprimitiveL types in t+e C# language. Two eamples o0 suc+ types are given at t+e end o0 t+is
c+apter JV11.4M.
11.1 Struct declarations
( str!ct-declaration is a t+pe-declaration JV$.%M t+at declares a new structC
str!ct-declaration.
attri,!tesopt str!ct-%odifiersopt .!%$i!lopt #$%u&$ identifier t+pe-para%eter-listopt
str!ct-interfacesopt t+pe-para%eter-constraints-cla!sesopt str!ct-,od+ Aopt
( str!ct-declaration consists o0 an optional set o0 attri,!tes JV1!M- 0ollowed by an optional set o0 str!ct-
%odifiers JV11.1.1M- 0ollowed by an optional &artial modi0ier- 0ollowed by t+e 7eyword struct and an
identifier t+at names t+e struct- 0ollowed by an optional t+pe-para%eter-list speci0ication JV1..1.3M- 0ollowed by
an optional str!ct-interfaces speci0ication JV11.1.2M M- 0ollowed by an optional t+pe-para%eters-constraints-
cla!ses speci0ication JV1..1."M- 0ollowed by a str!ct-,od+ JV11.1.4M- optionally 0ollowed by a semicolon.
11.1.1 Struct odifiers
( str!ct-declaration may optionally include a se9uence o0 struct modi0iersC
str!ct-%odifiers.
str!ct-%odifier
str!ct-%odifiers str!ct-%odifier
str!ct-%odifier.
*ew
.u"li&
.%'$e&$ed
i*$e%*!l
.%i,!$e
1t is a compile<time error 0or t+e same modi0ier to appear multiple times in a struct declaration.
T+e modi0iers o0 a struct declaration +ave t+e same meaning as t+ose o0 a class declaration JV1..1M.
37* Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
11.1.2 Partial odifier
T+e &artial modi0ier indicates t+at t+is str!ct-declaration is a partial type declaration. 'ultiple partial struct
declarations wit+ t+e same name wit+in an enclosing namespace or type declaration combine to 0orm one struct
declaration- 0ollowing t+e rules speci0ied in V1..2.
11.1.3 Struct interfaces
( struct declaration may include a str!ct-interfaces speci0ication- in w+ic+ case t+e struct is said to implement
t+e given inter0ace types.
str!ct-interfaces.
@ interface-t+pe-list
1nter0ace implementations are discussed 0urt+er in V13.4.
11.1.# Struct bod!
T+e str!ct-,od+ o0 a struct de0ines t+e members o0 t+e struct.
str!ct-,od+.
{ str!ct-%e%,er-declarationsopt }
11.2 Struct ebers
T+e members o0 a struct consist o0 t+e members introduced by its str!ct-%e%,er-declarations and t+e members
in+erited 0rom t+e type System.Ualue1y&e.
str!ct-%e%,er-declarations.
str!ct-%e%,er-declaration
str!ct-%e%,er-declarations str!ct-%e%,er-declaration
str!ct-%e%,er-declaration.
constant-declaration
field-declaration
%ethod-declaration
propert+-declaration
event-declaration
inde/er-declaration
operator-declaration
constr!ctor-declaration
static-constr!ctor-declaration
t+pe-declaration
Ecept 0or t+e di00erences noted in V11.3- t+e descriptions o0 class members provided in V1..3 t+roug+ V1..14
apply to struct members as well.
11.3 Class and struct differences
#tructs di00er 0rom classes in several important waysC
#tructs are value types JV11.3.1M.
(ll struct types implicitly in+erit 0rom t+e class System.Ualue1y&e JV11.3.2M.
(ssignment to a variable o0 a struct type creates a cop+ o0 t+e value being assigned JV11.3.3M.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 371
C# Language Specification
T+e de0ault value o0 a struct is t+e value produced by setting all value type 0ields to t+eir de0ault value and
all re0erence type 0ields to null JV11.3.4M.
)oing and unboing operations are used to convert between a struct type and object JV11.3."M.
T+e meaning o0 t"is is di00erent 0or structs JV!.".!M.
1nstance 0ield declarations 0or a struct are not permitted to include variable initialiDers JV11.3.!M.
( struct is not permitted to declare a parameterless instance constructor JV11.3.3M.
( struct is not permitted to declare a destructor JV11.3.$M.
11.3.1 Value seantics
#tructs are value types JV4.1M and are said to +ave value semantics. Classes- on t+e ot+er +and- are re0erence
types JV4.2M and are said to +ave re0erence semantics.
( variable o0 a struct type directly contains t+e data o0 t+e struct- w+ereas a variable o0 a class type contains a
re0erence to t+e data- t+e latter 7nown as an ob&ect. 6+en a struct : contains an instance 0ield o0 type ' and ' is
a struct type- it is a compile<time error 0or ' to depend on :. ( struct I directly depends on a struct ` i0 I
contains an instance 0ield o0 type `. 4iven t+is de0inition- t+e complete set o0 structs upon w+ic+ a struct
depends is t+e transitive closure o0 t+e directly depends on relations+ip. *or eample
struct Node
{
int data;
Node ne#t; .. error Node directly de&ends on itsel-
!
is an error because Node contains an instance 0ield o0 its own type. (not+er eample
struct ' { : b; !
struct : { C c; !
struct C { ' a; !
is an error because eac+ o0 t+e types '- :- and C depend on eac+ ot+er.
6it+ classes- it is possible 0or two variables to re0erence t+e same ob&ect- and t+us possible 0or operations on
one variable to a00ect t+e ob&ect re0erenced by t+e ot+er variable. 6it+ structs- t+e variables eac+ +ave t+eir own
copy o0 t+e data Jecept in t+e case o0 re- and out parameter variablesM- and it is not possible 0or operations on
one to a00ect t+e ot+er. *urt+ermore- because structs are not re0erence types- it is not possible 0or values o0 a
struct type to be null.
4iven t+e declaration
struct *oint
{
&ublic int # y;
&ublic *oint(int # int y) {
t"is.# + #;
t"is.y + y;
!
!
t+e code 0ragment
372 Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
*oint a + ne, *oint(23 23);
*oint b + a;
a.# + 233;
System.Console.WriteLine(b.#);
outputs t+e value 23. T+e assignment o0 a to b creates a copy o0 t+e value- and b is t+us una00ected by t+e
assignment to a.#. Had *oint instead been declared as a class- t+e output would be 233 because a and b
would re0erence t+e same ob&ect.
11.3.2 In-eritance
(ll struct types implicitly in+erit 0rom t+e class System.Ualue1y&e- w+ic+- in turn- in+erits 0rom class
object. ( struct declaration may speci0y a list o0 implemented inter0aces- but it is not possible 0or a struct
declaration to speci0y a base class.
#truct types are never abstract and are always implicitly sealed. T+e abstract and sealed modi0iers are
t+ere0ore not permitted in a struct declaration.
#ince in+eritance isnPt supported 0or structs- t+e declared accessibility o0 a struct member cannot be &rotected
or &rotected internal.
*unction members in a struct cannot be abstract or virtual- and t+e override modi0ier is allowed only to
override met+ods in+erited 0rom System.Ualue1y&e.
11.3.3 *ssignent
(ssignment to a variable o0 a struct type creates a cop+ o0 t+e value being assigned. T+is di00ers 0rom
assignment to a variable o0 a class type- w+ic+ copies t+e re0erence but not t+e ob&ect identi0ied by t+e re0erence.
#imilar to an assignment- w+en a struct is passed as a value parameter or returned as t+e result o0 a 0unction
member- a copy o0 t+e struct is created. ( struct may be passed by re0erence to a 0unction member using a re-
or out parameter.
6+en a property or indeer o0 a struct is t+e target o0 an assignment- t+e instance epression associated wit+ t+e
property or indeer access must be classi0ied as a variable. 10 t+e instance epression is classi0ied as a value- a
compile<time error occurs. T+is is described in 0urt+er detail in V!.1%.1.
11.3.# 2efault "alues
(s described in V".2- several 7inds o0 variables are automatically initialiDed to t+eir de0ault value w+en t+ey are
created. *or variables o0 class types and ot+er re0erence types- t+is de0ault value is null. However- since structs
are value types t+at cannot be null- t+e de0ault value o0 a struct is t+e value produced by setting all value type
0ields to t+eir de0ault value and all re0erence type 0ields to null.
;e0erring to t+e *oint struct declared above- t+e eample
*oint45 a + ne, *oint42335;
initialiDes eac+ *oint in t+e array to t+e value produced by setting t+e # and y 0ields to Dero.
T+e de0ault value o0 a struct corresponds to t+e value returned by t+e de0ault constructor o0 t+e struct JV4.1.2M.
8nli7e a class- a struct is not permitted to declare a parameterless instance constructor. 1nstead- every struct
implicitly +as a parameterless instance constructor w+ic+ always returns t+e value t+at results 0rom setting all
value type 0ields to t+eir de0ault value and all re0erence type 0ields to null.
#tructs s+ould be designed to consider t+e de0ault initialiDation state a valid state. 1n t+e eample
using System;
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 373
C# Language Specification
struct aeyUalue*air
{
string (ey;
string value;
&ublic aeyUalue*air(string (ey string value) {
i- ((ey ++ null HH value ++ null) t"ro, ne, 'rgument)#ce&tion();
t"is.(ey + (ey;
t"is.value + value;
!
!
t+e user<de0ined instance constructor protects against null values only w+ere it is eplicitly called. 1n cases
w+ere a aeyUalue*air variable is sub&ect to de0ault value initialiDation- t+e (ey and value 0ields will be null-
and t+e struct must be prepared to +andle t+is state.
11.3.& +o%ing and unbo%ing
( value o0 a class type can be converted to type object or to an inter0ace type t+at is implemented by t+e class
simply by treating t+e re0erence as anot+er type at compile<time. 5i7ewise- a value o0 type object or a value o0
an inter0ace type can be converted bac7 to a class type wit+out c+anging t+e re0erence Jbut o0 course a run<time
type c+ec7 is re9uired in t+is caseM.
#ince structs are not re0erence types- t+ese operations are implemented di00erently 0or struct types. 6+en a value
o0 a struct type is converted to type object or to an inter0ace type t+at is implemented by t+e struct- a boing
operation ta7es place. 5i7ewise- w+en a value o0 type object or a value o0 an inter0ace type is converted bac7
to a struct type- an unboing operation ta7es place. ( 7ey di00erence 0rom t+e same operations on class types is
t+at boing and unboing copies t+e struct value eit+er into or out o0 t+e boed instance. T+us- 0ollowing a
boing or unboing operation- c+anges made to t+e unboed struct are not re0lected in t+e boed struct.
6+en a struct type overrides a virtual met+od in+erited 0rom System.%bject Jsuc+ as )Quals-
SetHas"Code- or 1oStringM- invocation o0 t+e virtual met+od t+roug+ an instance o0 t+e struct type does not
cause boing to occur. T+is is true even w+en t+e struct is used as a type parameter and t+e invocation occurs
t+roug+ an instance o0 t+e type parameter type. *or eampleC
using System;
struct Counter
{
int value;
&ublic override string 1oString() {
value<<;
return value.1oString();
!
!
class *rogram
{
static void 1estD1E() ,"ere 1/ ne,() {
1 # + ne, 1();
Console.WriteLine(#.1oString());
Console.WriteLine(#.1oString());
Console.WriteLine(#.1oString());
!
37" Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
static void Main() {
1estDCounterE();
!
!
T+e output o0 t+e program isC
2
8
9
(lt+oug+ it is bad style 0or 1oString to +ave side e00ects- t+e eample demonstrates t+at no boing occurred
0or t+e t+ree invocations o0 #.1oString().
#imilarly- boing never implicitly occurs w+en accessing a member on a constrained type parameter. *or
eample- suppose an inter0ace $Counter contains a met+od $ncrement w+ic+ can be used to modi0y a value.
10 $Counter is used as a constraint- t+e implementation o0 t+e $ncrement met+od is called wit+ a re0erence to
t+e variable t+at $ncrement was called on- never a boed copy.
using System;
inter-ace $Counter
{
void $ncrement();
!
struct Counter/ $Counter
{
int value;
&ublic override string 1oString() {
return value.1oString();
!
void $Counter.$ncrement() {
value<<;
!
!
class *rogram
{
static void 1estD1E() ,"ere 1/ $Counter ne,() {
1 # + ne, 1();
Console.WriteLine(#);
#.$ncrement(); .. Modi-y #
Console.WriteLine(#);
(($Counter)#).$ncrement(); .. Modi-y bo#ed co&y o- #
Console.WriteLine(#);
!
static void Main() {
1estDCounterE();
!
!
T+e 0irst call to $ncrement modi0ies t+e value in t+e variable #. T+is is not e9uivalent to t+e second call to
$ncrement- w+ic+ modi0ies t+e value in a boed copy o0 #. T+us- t+e output o0 t+e program isC
3
2
2
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 37
C# Language Specification
*or 0urt+er details on boing and unboing- see V4.3.
11.3.' )eaning of t-is
6it+in an instance constructor or instance 0unction member o0 a class- t"is is classi0ied as a value. T+us- w+ile
t"is can be used to re0er to t+e instance 0or w+ic+ t+e 0unction member was invo7ed- it is not possible to assign
to t"is in a 0unction member o0 a class.
6it+in an instance constructor o0 a struct- t"is corresponds to an out parameter o0 t+e struct type- and wit+in
an instance 0unction member o0 a struct- t"is corresponds to a re- parameter o0 t+e struct type. 1n bot+ cases-
t"is is classi0ied as a variable- and it is possible to modi0y t+e entire struct 0or w+ic+ t+e 0unction member was
invo7ed by assigning to t"is or by passing t+is as a re- or out parameter.
11.3.. ,ield initiali<ers
(s described in V11.3.4- t+e de0ault value o0 a struct consists o0 t+e value t+at results 0rom setting all value type
0ields to t+eir de0ault value and all re0erence type 0ields to null. *or t+is reason- a struct does not permit
instance 0ield declarations to include variable initialiDers. T+is restriction applies only to instance 0ields. #tatic
0ields o0 a struct are permitted to include variable initialiDers.
T+e eample
struct *oint
{
&ublic int # + 2; .. )rror initiali?er not &ermitted
&ublic int y + 2; .. )rror initiali?er not &ermitted
!
is in error because t+e instance 0ield declarations include variable initialiDers.
11.3.0 Constructors
8nli7e a class- a struct is not permitted to declare a parameterless instance constructor. 1nstead- every struct
implicitly +as a parameterless instance constructor w+ic+ always returns t+e value t+at results 0rom setting all
value type 0ields to t+eir de0ault value and all re0erence type 0ields to null JV4.1.2M. ( struct can declare instance
constructors +aving parameters. *or eample
struct *oint
{
int # y;
&ublic *oint(int # int y) {
t"is.# + #;
t"is.y + y;
!
!
4iven t+e above declaration- t+e statements
*oint &2 + ne, *oint();
*oint &8 + ne, *oint(3 3);
bot+ create a *oint wit+ # and y initialiDed to Dero.
( struct instance constructor is not permitted to include a constructor initialiDer o0 t+e 0orm base(...).
10 t+e struct instance constructor doesnPt speci0y a constructor initialiDer- t+e t"is variable corresponds to an
out parameter o0 t+e struct type- and similar to an out parameter- t"is must be de0initely assigned JV".3M at
every location w+ere t+e constructor returns. 10 t+e struct instance constructor speci0ies a constructor initialiDer-
37' Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
t+e t"is variable corresponds to a re- parameter o0 t+e struct type- and similar to a re- parameter- t"is is
considered de0initely assigned on entry to t+e constructor body. Consider t+e instance constructor
implementation belowC
struct *oint
{
int # y;
&ublic int I {
set { # + value; !
!
&ublic int ` {
set { y + value; !
!
&ublic *oint(int # int y) {
I + #; .. error t"is is not yet de-initely assigned
` + y; .. error t"is is not yet de-initely assigned
!
!
=o instance member 0unction Jincluding t+e set accessors 0or t+e properties I and `M can be called until all 0ields
o0 t+e struct being constructed +ave been de0initely assigned. =ote- +owever- t+at i0 *oint were a class instead
o0 a struct- t+e instance constructor implementation would be permitted.
11.3.1 2estructors
( struct is not permitted to declare a destructor.
11.3.10 Static constructors
#tatic constructors 0or structs 0ollow most o0 t+e same rules as 0or classes. T+e eecution o0 a static constructor
0or a struct type is triggered by t+e 0irst o0 t+e 0ollowing events to occur wit+in an application domainC
(n instance member o0 t+e struct type is re0erenced.
( static member o0 t+e struct type is re0erenced.
(n eplicitly declared constructor o0 t+e struct type is called.
T+e creation o0 de0ault values JV11.3.4M o0 struct types does not trigger t+e static constructor. J(n eample o0
t+is is t+e initial value o0 elements in an array.M
11.# Struct e%aples
T+e 0ollowing s+ows two signi0icant eamples o0 using struct types to create types t+at can be used similarly
to t+e built<in types o0 t+e language- but wit+ modi0ied semantics.
11.#.1 2atabase integer t!pe
T+e 6:$nt struct below implements an integer type t+at can represent t+e complete set o0 values o0 t+e int
type- plus an additional state t+at indicates an un7nown value. ( type wit+ t+ese c+aracteristics is commonly
used in databases.
using System;
&ublic struct 6:$nt
{
.. 1"e Null member re&resents an un(no,n 6:$nt value.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 377
C# Language Specification
&ublic static readonly 6:$nt Null + ne, 6:$nt();
.. W"en t"e de-ined -ield is true t"is 6:$nt re&resents a (no,n value
.. ,"ic" is stored in t"e value -ield. W"en t"e de-ined -ield is -alse
.. t"is 6:$nt re&resents an un(no,n value and t"e value -ield is 3.
int value;
bool de-ined;
.. *rivate instance constructor. Creates a 6:$nt ,it" a (no,n value.
6:$nt(int value) {
t"is.value + value;
t"is.de-ined + true;
!
.. 1"e $sNull &ro&erty is true i- t"is 6:$nt re&resents an un(no,n value.
&ublic bool $sNull { get { return @de-ined; ! !
.. 1"e Ualue &ro&erty is t"e (no,n value o- t"is 6:$nt or 3 i- t"is
.. 6:$nt re&resents an un(no,n value.
&ublic int Ualue { get { return value; ! !
.. $m&licit conversion -rom int to 6:$nt.
&ublic static im&licit o&erator 6:$nt(int #) {
return ne, 6:$nt(#);
!
.. )#&licit conversion -rom 6:$nt to int. 1"ro,s an e#ce&tion i- t"e
.. given 6:$nt re&resents an un(no,n value.
&ublic static e#&licit o&erator int(6:$nt #) {
i- (@#.de-ined) t"ro, ne, $nvalid%&eration)#ce&tion();
return #.value;
!
&ublic static 6:$nt o&erator <(6:$nt #) {
return #;
!
&ublic static 6:$nt o&erator =(6:$nt #) {
return #.de-ined 7 =#.value / Null;
!
&ublic static 6:$nt o&erator <(6:$nt # 6:$nt y) {
return #.de-ined FF y.de-ined7 #.value < y.value/ Null;
!
&ublic static 6:$nt o&erator =(6:$nt # 6:$nt y) {
return #.de-ined FF y.de-ined7 #.value = y.value/ Null;
!
&ublic static 6:$nt o&erator >(6:$nt # 6:$nt y) {
return #.de-ined FF y.de-ined7 #.value > y.value/ Null;
!
&ublic static 6:$nt o&erator .(6:$nt # 6:$nt y) {
return #.de-ined FF y.de-ined7 #.value . y.value/ Null;
!
&ublic static 6:$nt o&erator B(6:$nt # 6:$nt y) {
return #.de-ined FF y.de-ined7 #.value B y.value/ Null;
!
37$ Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
&ublic static 6::ool o&erator ++(6:$nt # 6:$nt y) {
return #.de-ined FF y.de-ined7 #.value ++ y.value/ 6::ool.Null;
!
&ublic static 6::ool o&erator @+(6:$nt # 6:$nt y) {
return #.de-ined FF y.de-ined7 #.value @+ y.value/ 6::ool.Null;
!
&ublic static 6::ool o&erator E(6:$nt # 6:$nt y) {
return #.de-ined FF y.de-ined7 #.value E y.value/ 6::ool.Null;
!
&ublic static 6::ool o&erator D(6:$nt # 6:$nt y) {
return #.de-ined FF y.de-ined7 #.value D y.value/ 6::ool.Null;
!
&ublic static 6::ool o&erator E+(6:$nt # 6:$nt y) {
return #.de-ined FF y.de-ined7 #.value E+ y.value/ 6::ool.Null;
!
&ublic static 6::ool o&erator D+(6:$nt # 6:$nt y) {
return #.de-ined FF y.de-ined7 #.value D+ y.value/ 6::ool.Null;
!
&ublic override bool )Quals(object obj) {
i- (@(obj is 6:$nt)) return -alse;
6:$nt # + (6:$nt)obj;
return value ++ #.value FF de-ined ++ #.de-ined;
!
&ublic override int SetHas"Code() {
return value;
!
&ublic override string 1oString() {
return de-ined7 value.1oString()/ R6:$nt.NullT;
!
!
11.#.2 2atabase boolean t!pe
T+e 6::ool struct below implements a t+ree<valued logical type. T+e possible values o0 t+is type are
6::ool.1rue- 6::ool.Valse- and 6::ool.Null- w+ere t+e Null member indicates an un7nown value.
#uc+ t+ree<valued logical types are commonly used in databases.
using System;
&ublic struct 6::ool
{
.. 1"e t"ree &ossible 6::ool values.
&ublic static readonly 6::ool Null + ne, 6::ool(3);
&ublic static readonly 6::ool Valse + ne, 6::ool(=2);
&ublic static readonly 6::ool 1rue + ne, 6::ool(2);
.. *rivate -ield t"at stores C2 3 2 -or Valse Null 1rue.
sbyte value;
.. *rivate instance constructor. 1"e value &arameter must be C2 3 or 2.
6::ool(int value) {
t"is.value + (sbyte)value;
!
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 37!
C# Language Specification
.. *ro&erties to e#amine t"e value o- a 6::ool. Oeturn true i- t"is
.. 6::ool "as t"e given value -alse ot"er,ise.
&ublic bool $sNull { get { return value ++ 3; ! !
&ublic bool $sValse { get { return value D 3; ! !
&ublic bool $s1rue { get { return value E 3; ! !
.. $m&licit conversion -rom bool to 6::ool. Ma&s true to 6::ool.1rue and
.. -alse to 6::ool.Valse.
&ublic static im&licit o&erator 6::ool(bool #) {
return #7 1rue/ Valse;
!
.. )#&licit conversion -rom 6::ool to bool. 1"ro,s an e#ce&tion i- t"e
.. given 6::ool is Null ot"er,ise returns true or -alse.
&ublic static e#&licit o&erator bool(6::ool #) {
i- (#.value ++ 3) t"ro, ne, $nvalid%&eration)#ce&tion();
return #.value E 3;
!
.. )Quality o&erator. Oeturns Null i- eit"er o&erand is Null ot"er,ise
.. returns 1rue or Valse.
&ublic static 6::ool o&erator ++(6::ool # 6::ool y) {
i- (#.value ++ 3 HH y.value ++ 3) return Null;
return #.value ++ y.value7 1rue/ Valse;
!
.. $neQuality o&erator. Oeturns Null i- eit"er o&erand is Null ot"er,ise
.. returns 1rue or Valse.
&ublic static 6::ool o&erator @+(6::ool # 6::ool y) {
i- (#.value ++ 3 HH y.value ++ 3) return Null;
return #.value @+ y.value7 1rue/ Valse;
!
.. Logical negation o&erator. Oeturns 1rue i- t"e o&erand is Valse Null
.. i- t"e o&erand is Null or Valse i- t"e o&erand is 1rue.
&ublic static 6::ool o&erator @(6::ool #) {
return ne, 6::ool(=#.value);
!
.. Logical 'N6 o&erator. Oeturns Valse i- eit"er o&erand is Valse
.. ot"er,ise Null i- eit"er o&erand is Null ot"er,ise 1rue.
&ublic static 6::ool o&erator F(6::ool # 6::ool y) {
return ne, 6::ool(#.value D y.value7 #.value/ y.value);
!
.. Logical %O o&erator. Oeturns 1rue i- eit"er o&erand is 1rue ot"er,ise
.. Null i- eit"er o&erand is Null ot"er,ise Valse.
&ublic static 6::ool o&erator H(6::ool # 6::ool y) {
return ne, 6::ool(#.value E y.value7 #.value/ y.value);
!
.. 6e-initely true o&erator. Oeturns true i- t"e o&erand is 1rue -alse
.. ot"er,ise.
3$* Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
&ublic static bool o&erator true(6::ool #) {
return #.value E 3;
!
.. 6e-initely -alse o&erator. Oeturns true i- t"e o&erand is Valse -alse
.. ot"er,ise.
&ublic static bool o&erator -alse(6::ool #) {
return #.value D 3;
!
&ublic override bool )Quals(object obj) {
i- (@(obj is 6::ool)) return -alse;
return value ++ ((6::ool)obj).value;
!
&ublic override int SetHas"Code() {
return value;
!
&ublic override string 1oString() {
i- (value E 3) return "6::ool.1rue";
i- (value D 3) return "6::ool.Valse";
return "6::ool.Null";
!
!
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 3$1
C0apter 1 Introduction
12. *rra!s
(n array is a data structure t+at contains a number o0 variables w+ic+ are accessed t+roug+ computed indices.
T+e variables contained in an array- also called t+e elements o0 t+e array- are all o0 t+e same type- and t+is type
is called t+e element type o0 t+e array.
(n array +as a ran7 w+ic+ determines t+e number o0 indices associated wit+ eac+ array element. T+e ran7 o0 an
array is also re0erred to as t+e dimensions o0 t+e array. (n array wit+ a ran7 o0 one is called a single-
diensional array. (n array wit+ a ran7 greater t+an one is called a -lti-diensional array. #peci0ic siDed
multi<dimensional arrays are o0ten re0erred to as two<dimensional arrays- t+ree<dimensional arrays- and so on.
Eac+ dimension o0 an array +as an associated lengt+ w+ic+ is an integral number greater t+an or e9ual to Dero.
T+e dimension lengt+s are not part o0 t+e type o0 t+e array- but rat+er are establis+ed w+en an instance o0 t+e
array type is created at run<time. T+e lengt+ o0 a dimension determines t+e valid range o0 indices 0or t+at
dimensionC *or a dimension o0 lengt+ N- indices can range 0rom 3 to N C 2 inclusive. T+e total number o0
elements in an array is t+e product o0 t+e lengt+s o0 eac+ dimension in t+e array. 10 one or more o0 t+e
dimensions o0 an array +ave a lengt+ o0 Dero- t+e array is said to be empty.
T+e element type o0 an array can be any type- including an array type.
12.1 *rra! t!pes
(n array type is written as a non-arra+-t+pe 0ollowed by one or more ran&-specifiersC
arra+-t+pe.
non-arra+-t+pe ran&-specifiers
non-arra+-t+pe.
t+pe
ran&-specifiers.
ran&-specifier
ran&-specifiers ran&-specifier
ran&-specifier.
= di%-separatorsopt >
di%-separators.
?
di%-separators ?
( non-arra+-t+pe is any t+pe t+at is not itsel0 an arra+-t+pe.
T+e ran7 o0 an array type is given by t+e le0tmost ran&-specifier in t+e arra+-t+peC ( ran&-specifier indicates
t+at t+e array is an array wit+ a ran7 o0 one plus t+e number o0 KL to7ens in t+e ran&-specifier.
T+e element type o0 an array type is t+e type t+at results 0rom deleting t+e le0tmost ran&-specifierC
(n array type o0 t+e 0orm 14O5 is an array wit+ ran7 O and a non<array element type 1.
(n array type o0 t+e 0orm 14O54O
2
5...4O
N
5 is an array wit+ ran7 O and an element type 14O
2
5...4O
N
5.
1n e00ect- t+e ran&-specifiers are read 0rom le0t to rig+t ,efore t+e 0inal non<array element type. T+e type int45
4545 is a single<dimensional array o0 t+ree<dimensional arrays o0 two<dimensional arrays o0 int.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 3$3
C# Language Specification
(t run<time- a value o0 an array type can be null or a re0erence to an instance o0 t+at array type.
12.1.1 T-e S!ste.*rra! t!pe
T+e type System.'rray is t+e abstract base type o0 all array types. (n implicit re0erence conversion JV%.1.%M
eists 0rom any array type to System.'rray- and an eplicit re0erence conversion JV%.2.4M eists 0rom
System.'rray to any array type. =ote t+at System.'rray is not itsel0 an arra+-t+pe. ;at+er- it is a class-t+pe
0rom w+ic+ all arra+-t+pes are derived.
(t run<time- a value o0 type System.'rray can be null or a re0erence to an instance o0 any array type.
12.1.2 *rra!s and t-e generic IList interface
( one<dimensional array 145 implements t+e inter0ace System.Collections.Seneric.$ListD1E
J$ListD1E 0or s+ortM and its base inter0aces. (ccordingly- t+ere is an implicit conversion 0rom 145 to
$ListD1E and its base inter0aces. 1n addition- i0 t+ere is an implicit re0erence conversion 0rom S to 1 t+en S45
implements $ListD1E and t+ere is an implicit re0erence conversion 0rom S45 to $ListD1E and its base
inter0aces JV%.1.%M. 10 t+ere is an eplicit re0erence conversion 0rom S to 1 t+en t+ere is an eplicit re0erence
conversion 0rom S45 to $ListD1E and its base inter0aces JV%.2.4M. *or eampleC
using System.Collections.Seneric;
class 1est
{
static void Main() {
string45 sa + ne, string4K5;
object45 oa2 + ne, object4K5;
object45 oa8 + sa;
$ListDstringE lst2 + sa; .. %(
$ListDstringE lst8 + oa2; .. )rror cast needed
$ListDobjectE lst9 + sa; .. %(
$ListDobjectE lstJ + oa2; .. %(
$ListDstringE lstK + ($ListDstringE)oa2; .. )#ce&tion
$ListDstringE lstX + ($ListDstringE)oa8; .. %(
!
!
T+e assignment lst8 + oa2 generates a compile<time error since t+e conversion 0rom object45 to
$ListDstringE is an eplicit conversion- not implicit. T+e cast ($ListDstringE)oa2 will cause an
eception to be t+rown at runtime since oa2 re0erences an object45 and not a string45. However t+e cast
($ListDstringE)oa8 will not cause an eception to be t+rown since oa8 re0erences a string45.
6+enever t+ere is an implicit or eplicit re0erence conversion 0rom S45 to $ListD1E- t+ere is also an eplicit
re0erence conversion 0rom $ListD1E and its base inter0aces to S45 JV%.2.4M.
6+en an array type S45 implements $ListD1E- some o0 t+e members o0 t+e implemented inter0ace may t+row
eceptions. T+e precise be+avior o0 t+e implementation o0 t+e inter0ace is beyond t+e scope o0 t+is speci0ication.
12.2 *rra! creation
(rray instances are created by arra+-creation-e/pressions JV!.".1..4M or by 0ield or local variable declarations
t+at include an arra+-initiali-er JV12.%M.
6+en an array instance is created- t+e ran7 and lengt+ o0 eac+ dimension are establis+ed and t+en remain
constant 0or t+e entire li0etime o0 t+e instance. 1n ot+er words- it is not possible to c+ange t+e ran7 o0 an eisting
array instance- nor is it possible to resiDe its dimensions.
3$" Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
(n array instance is always o0 an array type. T+e System.'rray type is an abstract type t+at cannot be
instantiated.
Elements o0 arrays created by arra+-creation-e/pressions are always initialiDed to t+eir de0ault value JV".2M.
12.3 *rra! eleent access
(rray elements are accessed using ele%ent-access epressions JV!.".%.1M o0 t+e 0orm '4$
2
$
8
... $
N
5-
w+ere ' is an epression o0 an array type and eac+ $
I
is an epression o0 type int- uint- long- ulong- or o0 a
type t+at can be implicitly converted to one or more o0 t+ese types. T+e result o0 an array element access is a
variable- namely t+e array element selected by t+e indices.
T+e elements o0 an array can be enumerated using a -oreac" statement JV3.3.4M.
12.# *rra! ebers
Every array type in+erits t+e members declared by t+e System.'rray type.
12.& *rra! co"ariance
*or any two reference-t+pes ' and :- i0 an implicit re0erence conversion JV%.1.%M or eplicit re0erence
conversion JV%.2.4M eists 0rom ' to :- t+en t+e same re0erence conversion also eists 0rom t+e array type '4O5
to t+e array type :4O5- w+ere O is any given ran&-specifier Jbut t+e same 0or bot+ array typesM. T+is relations+ip
is 7nown as array covariance. (rray covariance in particular means t+at a value o0 an array type '4O5 may
actually be a re0erence to an instance o0 an array type :4O5- provided an implicit re0erence conversion eists
0rom : to '.
)ecause o0 array covariance- assignments to elements o0 re0erence type arrays include a run<time c+ec7 w+ic+
ensures t+at t+e value being assigned to t+e array element is actually o0 a permitted type JV!.1%.1M. *or eampleC
class 1est
{
static void Vill(object45 array int inde# int count object value) {
-or (int i + inde#; i D inde# < count; i<<) array4i5 + value;
!
static void Main() {
string45 strings + ne, string42335;
Vill(strings 3 233 ";nde-ined");
Vill(strings 3 23 null);
Vill(strings L3 23 3);
!
!
T+e assignment to array4i5 in t+e Vill met+od implicitly includes a run<time c+ec7 w+ic+ ensures t+at t+e
ob&ect re0erenced by value is eit+er null or an instance o0 a type t+at is compatible wit+ t+e actual element
type o0 array. 1n Main- t+e 0irst two invocations o0 Vill succeed- but t+e t+ird invocation causes a
System.'rray1y&eMismatc")#ce&tion to be t+rown upon eecuting t+e 0irst assignment to array4i5.
T+e eception occurs because a boed int cannot be stored in a string array.
(rray covariance speci0ically does not etend to arrays o0 val!e-t+pes. *or eample- no conversion eists t+at
permits an int45 to be treated as an object45.
12.' *rra! initiali<ers
(rray initialiDers may be speci0ied in 0ield declarations JV1.."M- local variable declarations JV3.".1M- and array
creation epressions JV!.".1..4MC
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 3$
C# Language Specification
arra+-initiali-er.
{ varia,le-initiali-er-listopt }
{ varia,le-initiali-er-list ? }
varia,le-initiali-er-list.
varia,le-initiali-er
varia,le-initiali-er-list ? varia,le-initiali-er
varia,le-initiali-er.
e/pression
arra+-initiali-er
(n array initialiDer consists o0 a se9uence o0 variable initialiDers- enclosed by K{Land K!L to7ens and separated
by KL to7ens. Eac+ variable initialiDer is an epression or- in t+e case o0 a multi<dimensional array- a nested
array initialiDer.
T+e contet in w+ic+ an array initialiDer is used determines t+e type o0 t+e array being initialiDed. 1n an array
creation epression- t+e array type immediately precedes t+e initialiDer- or is in0erred 0rom t+e epressions in t+e
array initialiDer. 1n a 0ield or variable declaration- t+e array type is t+e type o0 t+e 0ield or variable being
declared. 6+en an array initialiDer is used in a 0ield or variable declaration- suc+ asC
int45 a + {3 8 J X Y!;
it is simply s+ort+and 0or an e9uivalent array creation epressionC
int45 a + ne, int45 {3 8 J X Y!;
*or a single<dimensional array- t+e array initialiDer must consist o0 a se9uence o0 epressions t+at are
assignment compatible wit+ t+e element type o0 t+e array. T+e epressions initialiDe array elements in
increasing order- starting wit+ t+e element at inde Dero. T+e number o0 epressions in t+e array initialiDer
determines t+e lengt+ o0 t+e array instance being created. *or eample- t+e array initialiDer above creates an
int45 instance o0 lengt+ " and t+en initialiDes t+e instance wit+ t+e 0ollowing valuesC
a435 + 3; a425 + 8; a485 + J; a495 + X; a4J5 + Y;
*or a multi<dimensional array- t+e array initialiDer must +ave as many levels o0 nesting as t+ere are dimensions
in t+e array. T+e outermost nesting level corresponds to t+e le0tmost dimension and t+e innermost nesting level
corresponds to t+e rig+tmost dimension. T+e lengt+ o0 eac+ dimension o0 t+e array is determined by t+e number
o0 elements at t+e corresponding nesting level in t+e array initialiDer. *or eac+ nested array initialiDer- t+e
number o0 elements must be t+e same as t+e ot+er array initialiDers at t+e same level. T+e eampleC
int45 b + {{3 2! {8 9! {J K! {X M! {Y L!!;
creates a two<dimensional array wit+ a lengt+ o0 0ive 0or t+e le0tmost dimension and a lengt+ o0 two 0or t+e
rig+tmost dimensionC
int45 b + ne, int4K 85;
and t+en initialiDes t+e array instance wit+ t+e 0ollowing valuesC
b43 35 + 3; b43 25 + 2;
b42 35 + 8; b42 25 + 9;
b48 35 + J; b48 25 + K;
b49 35 + X; b49 25 + M;
b4J 35 + Y; b4J 25 + L;
6+en an array creation epression includes bot+ eplicit dimension lengt+s and an array initialiDer- t+e lengt+s
must be constant epressions and t+e number o0 elements at eac+ nesting level must matc+ t+e corresponding
dimension lengt+. Here are some eamplesC
3$' Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
int i + 9;
int45 # + ne, int495 {3 2 8!; .. %a
int45 y + ne, int4i5 {3 2 8!; .. )rror i not a constant
int45 ? + ne, int495 {3 2 8 9!; .. )rror lengt".initiali?er mismatc"
Here- t+e initialiDer 0or y results in a compile<time error because t+e dimension lengt+ epression is not a
constant- and t+e initialiDer 0or ? results in a compile<time error because t+e lengt+ and t+e number o0 elements
in t+e initialiDer do not agree.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 3$7
C0apter 1 Introduction
13. Interfaces
(n inter0ace de0ines a contract. ( class or struct t+at implements an inter0ace must ad+ere to its contract. (n
inter0ace may in+erit 0rom multiple base inter0aces- and a class or struct may implement multiple inter0aces.
1nter0aces can contain met+ods- properties- events- and indeers. T+e inter0ace itsel0 does not provide
implementations 0or t+e members t+at it de0ines. T+e inter0ace merely speci0ies t+e members t+at must be
supplied by classes or structs t+at implement t+e inter0ace.
13.1 Interface declarations
(n interface-declaration is a t+pe-declaration JV$.%M t+at declares a new inter0ace type.
interface-declaration.
attri,!tesopt interface-%odifiersopt .!%$i!lopt i*$e%f!&e identifier t+pe-para%eter-listopt
interface-,aseopt t+pe-para%eter-constraints-cla!sesopt interface-,od+ Aopt
(n interface-declaration consists o0 an optional set o0 attri,!tes JV1!M- 0ollowed by an optional set o0 interface-
%odifiers JV13.1.1M- 0ollowed by an optional &artial modi0ier- 0ollowed by t+e 7eyword inter-ace and an
identifier t+at names t+e inter0ace- 0ollowed by an optional t+pe-para%eter-list speci0ication JV1..1.3M- 0ollowed
by an optional interface-,ase speci0ication JV13.1.2M- 0ollowed by an optional t+pe-para%eter-constraints-
cla!ses speci0ication JV1..1."M- 0ollowed by a interface-,od+ JV13.1.4M- optionally 0ollowed by a semicolon.
13.1.1 Interface odifiers
(n interface-declaration may optionally include a se9uence o0 inter0ace modi0iersC
interface-%odifiers.
interface-%odifier
interface-%odifiers interface-%odifier
interface-%odifier.
*ew
.u"li&
.%'$e&$ed
i*$e%*!l
.%i,!$e
1t is a compile<time error 0or t+e same modi0ier to appear multiple times in an inter0ace declaration.
T+e ne, modi0ier is only permitted on inter0aces de0ined wit+in a class. 1t speci0ies t+at t+e inter0ace +ides an
in+erited member by t+e same name- as described in V1..3.4.
T+e &ublic- &rotected- internal- and &rivate modi0iers control t+e accessibility o0 t+e inter0ace.
2epending on t+e contet in w+ic+ t+e inter0ace declaration occurs- only some o0 t+ese modi0iers may be
permitted JV3.".1M.
13.1.2 Partial odifier
T+e &artial modi0ier indicates t+at t+is interface-declaration is a partial type declaration. 'ultiple partial
inter0ace declarations wit+ t+e same name wit+in an enclosing namespace or type declaration combine to 0orm
one inter0ace declaration- 0ollowing t+e rules speci0ied in V1..2.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 3$!
C# Language Specification
13.1.3 +ase interfaces
(n inter0ace can in+erit 0rom Dero or more inter0ace types- w+ic+ are called t+e e,plicit !ase interfaces o0 t+e
inter0ace. 6+en an inter0ace +as one or more eplicit base inter0aces- t+en in t+e declaration o0 t+at inter0ace- t+e
inter0ace identi0ier is 0ollowed by a colon and a comma separated list o0 base inter0ace types.
interface-,ase.
@ interface-t+pe-list
*or a constructed inter0ace type- t+e eplicit base inter0aces are 0ormed by ta7ing t+e eplicit base inter0ace
declarations on t+e generic type declaration- and substituting- 0or eac+ t+pe-para%eter in t+e base inter0ace
declaration- t+e corresponding t+pe-arg!%ent o0 t+e constructed type.
T+e eplicit base inter0aces o0 an inter0ace must be at least as accessible as t+e inter0ace itsel0 JV3.".4M. *or
eample- it is a compile<time error to speci0y a &rivate or internal inter0ace in t+e interface-,ase o0 a
&ublic inter0ace.
1t is a compile<time error 0or an inter0ace to directly or indirectly in+erit 0rom itsel0.
T+e !ase interfaces o0 an inter0ace are t+e eplicit base inter0aces and t+eir base inter0aces. 1n ot+er words- t+e
set o0 base inter0aces is t+e complete transitive closure o0 t+e eplicit base inter0aces- t+eir eplicit base
inter0aces- and so on. (n inter0ace in+erits all members o0 its base inter0aces. 1n t+e eample
inter-ace $Control
{
void *aint();
!
inter-ace $1e#t:o#/ $Control
{
void Set1e#t(string te#t);
!
inter-ace $List:o#/ $Control
{
void Set$tems(string45 items);
!
inter-ace $Combo:o#/ $1e#t:o# $List:o# {!
t+e base inter0aces o0 $Combo:o# are $Control- $1e#t:o#- and $List:o#.
1n ot+er words- t+e $Combo:o# inter0ace above in+erits members Set1e#t and Set$tems as well as *aint.
( class or struct t+at implements an inter0ace also implicitly implements all o0 t+e inter0acePs base inter0aces.
13.1.# Interface bod!
T+e interface-,od+ o0 an inter0ace de0ines t+e members o0 t+e inter0ace.
interface-,od+.
{ interface-%e%,er-declarationsopt }
13.2 Interface ebers
T+e members o0 an inter0ace are t+e members in+erited 0rom t+e base inter0aces and t+e members declared by
t+e inter0ace itsel0.
interface-%e%,er-declarations.
interface-%e%,er-declaration
interface-%e%,er-declarations interface-%e%,er-declaration
3!* Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
interface-%e%,er-declaration.
interface-%ethod-declaration
interface-propert+-declaration
interface-event-declaration
interface-inde/er-declaration
(n inter0ace declaration may declare Dero or more members. T+e members o0 an inter0ace must be met+ods-
properties- events- or indeers. (n inter0ace cannot contain constants- 0ields- operators- instance constructors-
destructors- or types- nor can an inter0ace contain static members o0 any 7ind.
(ll inter0ace members implicitly +ave public access. 1t is a compile<time error 0or inter0ace member declarations
to include any modi0iers. 1n particular- inter0aces members cannot be declared wit+ t+e modi0iers abstract-
&ublic- &rotected- internal- &rivate- virtual- override- or static.
T+e eample
&ublic delegate void StringList)vent($StringList sender);
&ublic inter-ace $StringList
{
void 'dd(string s);
int Count { get; !
event StringList)vent C"anged;
string t"is4int inde#5 { get; set; !
!
declares an inter0ace t+at contains one eac+ o0 t+e possible 7inds o0 membersC ( met+od- a property- an event-
and an indeer.
(n interface-declaration creates a new declaration space JV3.3M- and t+e interface-%e%,er-declarations
immediately contained by t+e interface-declaration introduce new members into t+is declaration space. T+e
0ollowing rules apply to interface-%e%,er-declarationsC
T+e name o0 a met+od must di00er 0rom t+e names o0 all properties and events declared in t+e same
inter0ace. 1n addition- t+e signature JV3.%M o0 a met+od must di00er 0rom t+e signatures o0 all ot+er met+ods
declared in t+e same inter0ace- and two met+ods declared in t+e same inter0ace may not +ave signatures t+at
di00er solely by re- and out.
T+e name o0 a property or event must di00er 0rom t+e names o0 all ot+er members declared in t+e same
inter0ace.
T+e signature o0 an indeer must di00er 0rom t+e signatures o0 all ot+er indeers declared in t+e same
inter0ace.
T+e in+erited members o0 an inter0ace are speci0ically not part o0 t+e declaration space o0 t+e inter0ace. T+us- an
inter0ace is allowed to declare a member wit+ t+e same name or signature as an in+erited member. 6+en t+is
occurs- t+e derived inter0ace member is said to hide t+e base inter0ace member. Hiding an in+erited member is
not considered an error- but it does cause t+e compiler to issue a warning. To suppress t+e warning- t+e
declaration o0 t+e derived inter0ace member must include a ne, modi0ier to indicate t+at t+e derived member is
intended to +ide t+e base member. T+is topic is discussed 0urt+er in V3.!.1.2.
10 a ne, modi0ier is included in a declaration t+at doesnPt +ide an in+erited member- a warning is issued to t+at
e00ect. T+is warning is suppressed by removing t+e ne, modi0ier.
=ote t+at t+e members in class object are not- strictly spea7ing- members o0 any inter0ace JV13.2M. However-
t+e members in class object are available via member loo7up in any inter0ace type JV!.3M.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 3!1
C# Language Specification
13.2.1 Interface et-ods
1nter0ace met+ods are declared using interface-%ethod-declarationsC
interface-%ethod-declaration.
attri,!tesopt *ewopt ret!rn-t+pe identifier t+pe-para%eter-list
( for%al-para%eter-listopt ) t+pe-para%eter-constraints-cla!sesopt A
T+e attri,!tes- ret!rn-t+pe- identifier- and for%al-para%eter-list o0 an inter0ace met+od declaration +ave t+e
same meaning as t+ose o0 a met+od declaration in a class JV1..%M. (n inter0ace met+od declaration is not
permitted to speci0y a met+od body- and t+e declaration t+ere0ore always ends wit+ a semicolon.
13.2.2 Interface properties
1nter0ace properties are declared using interface-propert+-declarationsC
interface-propert+-declaration.
attri,!tesopt *ewopt t+pe identifier { interface-accessors }
interface-accessors.
attri,!tesopt +e$ A
attri,!tesopt #e$ A
attri,!tesopt +e$ A attri,!tesopt #e$ A
attri,!tesopt #e$ A attri,!tesopt +e$ A
T+e attri,!tes- t+pe- and identifier o0 an inter0ace property declaration +ave t+e same meaning as t+ose o0 a
property declaration in a class JV1..!M.
T+e accessors o0 an inter0ace property declaration correspond to t+e accessors o0 a class property declaration
JV1..!.2M- ecept t+at t+e accessor body must always be a semicolon. T+us- t+e accessors simply indicate
w+et+er t+e property is read<write- read<only- or write<only.
13.2.3 Interface e"ents
1nter0ace events are declared using interface-event-declarationsC
interface-event-declaration.
attri,!tesopt *ewopt e,e*$ t+pe identifier A
T+e attri,!tes- t+pe- and identifier o0 an inter0ace event declaration +ave t+e same meaning as t+ose o0 an event
declaration in a class JV1..3M.
13.2.# Interface inde%ers
1nter0ace indeers are declared using interface-inde/er-declarationsC
interface-inde/er-declaration.
attri,!tesopt *ewopt t+pe $hi# = for%al-para%eter-list > { interface-accessors }
T+e attri,!tes- t+pe- and for%al-para%eter-list o0 an inter0ace indeer declaration +ave t+e same meaning as
t+ose o0 an indeer declaration in a class JV1..$M.
T+e accessors o0 an inter0ace indeer declaration correspond to t+e accessors o0 a class indeer declaration
JV1..$M- ecept t+at t+e accessor body must always be a semicolon. T+us- t+e accessors simply indicate w+et+er
t+e indeer is read<write- read<only- or write<only.
3!2 Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
13.2.& Interface eber access
1nter0ace members are accessed t+roug+ member access JV!.".4M and indeer access JV!.".%.2M epressions o0
t+e 0orm $.M and $4'5- w+ere $ is an inter0ace type- M is a met+od- property- or event o0 t+at inter0ace type- and
' is an indeer argument list.
*or inter0aces t+at are strictly single<in+eritance Jeac+ inter0ace in t+e in+eritance c+ain +as eactly Dero or one
direct base inter0aceM- t+e e00ects o0 t+e member loo7up JV!.3M- met+od invocation JV!.".".1M- and indeer access
JV!.".%.2M rules are eactly t+e same as 0or classes and structsC 'ore derived members +ide less derived
members wit+ t+e same name or signature. However- 0or multiple<in+eritance inter0aces- ambiguities can occur
w+en two or more unrelated base inter0aces declare members wit+ t+e same name or signature. T+is section
s+ows several eamples o0 suc+ situations. 1n all cases- eplicit casts can be used to resolve t+e ambiguities.
1n t+e eample
inter-ace $List
{
int Count { get; set; !
!
inter-ace $Counter
{
void Count(int i);
!
inter-ace $ListCounter/ $List $Counter {!
class C
{
void 1est($ListCounter #) {
#.Count(2); .. )rror
#.Count + 2; .. )rror
(($List)#).Count + 2; .. %( invo(es $List.Count.set
(($Counter)#).Count(2); .. %( invo(es $Counter.Count
!
!
t+e 0irst two statements cause compile<time errors because t+e member loo7up JV!.3M o0 Count in
$ListCounter is ambiguous. (s illustrated by t+e eample- t+e ambiguity is resolved by casting # to t+e
appropriate base inter0ace type. #uc+ casts +ave no run<time costsRt+ey merely consist o0 viewing t+e instance
as a less derived type at compile<time.
1n t+e eample
inter-ace $$nteger
{
void 'dd(int i);
!
inter-ace $6ouble
{
void 'dd(double d);
!
inter-ace $Number/ $$nteger $6ouble {!
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 3!3
C# Language Specification
class C
{
void 1est($Number n) {
n.'dd(2); .. $nvo(es $$nteger.'dd
n.'dd(2.3); .. %nly $6ouble.'dd is a&&licable
(($$nteger)n).'dd(2); .. %nly $$nteger.'dd is a candidate
(($6ouble)n).'dd(2); .. %nly $6ouble.'dd is a candidate
!
!
t+e invocation n.'dd(2) selects $$nteger.'dd by applying t+e overload resolution rules o0 V!.4.3. #imilarly
t+e invocation n.'dd(2.3) selects $6ouble.'dd. 6+en eplicit casts are inserted- t+ere is only one candidate
met+od- and t+us no ambiguity.
1n t+e eample
inter-ace $:ase
{
void V(int i);
!
inter-ace $Le-t/ $:ase
{
ne, void V(int i);
!
inter-ace $Oig"t/ $:ase
{
void S();
!
inter-ace $6erived/ $Le-t $Oig"t {!
class '
{
void 1est($6erived d) {
d.V(2); .. $nvo(es $Le-t.V
(($:ase)d).V(2); .. $nvo(es $:ase.V
(($Le-t)d).V(2); .. $nvo(es $Le-t.V
(($Oig"t)d).V(2); .. $nvo(es $:ase.V
!
!
t+e $:ase.V member is +idden by t+e $Le-t.V member. T+e invocation d.V(2) t+us selects $Le-t.V- even
t+oug+ $:ase.V appears to not be +idden in t+e access pat+ t+at leads t+roug+ $Oig"t.
T+e intuitive rule 0or +iding in multiple<in+eritance inter0aces is simply t+isC 10 a member is +idden in any access
pat+- it is +idden in all access pat+s. )ecause t+e access pat+ 0rom $6erived to $Le-t to $:ase +ides
$:ase.V- t+e member is also +idden in t+e access pat+ 0rom $6erived to $Oig"t to $:ase.
13.3 ,ull! 7ualified interface eber naes
(n inter0ace member is sometimes re0erred to by its f-lly 4-alified nae. T+e 0ully 9uali0ied name o0 an
inter0ace member consists o0 t+e name o0 t+e inter0ace in w+ic+ t+e member is declared- 0ollowed by a dot-
0ollowed by t+e name o0 t+e member. T+e 0ully 9uali0ied name o0 a member re0erences t+e inter0ace in w+ic+
t+e member is declared. *or eample- given t+e declarations
3!" Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
inter-ace $Control
{
void *aint();
!
inter-ace $1e#t:o#/ $Control
{
void Set1e#t(string te#t);
!
t+e 0ully 9uali0ied name o0 *aint is $Control.*aint and t+e 0ully 9uali0ied name o0 Set1e#t is
$1e#t:o#.Set1e#t.
1n t+e eample above- it is not possible to re0er to *aint as $1e#t:o#.*aint.
6+en an inter0ace is part o0 a namespace- t+e 0ully 9uali0ied name o0 an inter0ace member includes t+e
namespace name. *or eample
names&ace System
{
&ublic inter-ace $Cloneable
{
object Clone();
!
!
Here- t+e 0ully 9uali0ied name o0 t+e Clone met+od is System.$Cloneable.Clone.
13.# Interface ipleentations
1nter0aces may be implemented by classes and structs. To indicate t+at a class or struct implements an inter0ace-
t+e inter0ace identi0ier is included in t+e base class list o0 t+e class or struct. *or eampleC
inter-ace $Cloneable
{
object Clone();
!
inter-ace $Com&arable
{
int Com&are1o(object ot"er);
!
class List)ntry/ $Cloneable $Com&arable
{
&ublic object Clone() {...!
&ublic int Com&are1o(object ot"er) {...!
!
( class or struct t+at implements an inter0ace also implicitly implements all o0 t+e inter0acePs base inter0aces.
T+is is true even i0 t+e class or struct doesnPt eplicitly list all base inter0aces in t+e base class list. *or eampleC
inter-ace $Control
{
void *aint();
!
inter-ace $1e#t:o#/ $Control
{
void Set1e#t(string te#t);
!
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 3!
C# Language Specification
class 1e#t:o#/ $1e#t:o#
{
&ublic void *aint() {...!
&ublic void Set1e#t(string te#t) {...!
!
Here- class 1e#t:o# implements bot+ $Control and $1e#t:o#.
T+e base inter0aces speci0ied in a class declaration can be constructed inter0ace types JV4.4M. ( base inter0ace
cannot be a type parameter on its own- t+oug+ it can involve t+e type parameters t+at are in scope. T+e
0ollowing code illustrates +ow a class can implement and etend constructed typesC
class CD;UE {!
inter-ace $2DUE {!
class 6/ CDstringintE $2DstringE {!
class )D1E/ CDint1E $2D1E {!
T+e base inter0aces o0 a generic class declaration must satis0y t+e uni9ueness rule described in V13.4.2.
13.#.1 $%plicit interface eber ipleentations
*or purposes o0 implementing inter0aces- a class or struct may declare e,plicit interface e!er
ipleentations. (n eplicit inter0ace member implementation is a met+od- property- event- or indeer
declaration t+at re0erences a 0ully 9uali0ied inter0ace member name. *or eample
inter-ace $ListD1E
{
145 Set)lements();
!
inter-ace $6ictionaryDaUE
{
U t"is4a (ey5;
void 'dd(a (ey U value);
!
class ListD1E/ $ListD1E $6ictionaryDint1E
{
145 $ListD1E.Set)lements() {...!
1 $6ictionaryDint1E.t"is4int inde#5 {...!
void $6ictionaryDint1E.'dd(int inde# 1 value) {...!
!
Here $6ictionaryDint1E.t"is and $6ictionaryDint1E.'dd are eplicit inter0ace member
implementations.
1n some cases- t+e name o0 an inter0ace member may not be appropriate 0or t+e implementing class- in w+ic+
case t+e inter0ace member may be implemented using eplicit inter0ace member implementation. ( class
implementing a 0ile abstraction- 0or eample- would li7ely implement a Close member 0unction t+at +as t+e
e00ect o0 releasing t+e 0ile resource- and implement t+e 6is&ose met+od o0 t+e $6is&osable inter0ace using
eplicit inter0ace member implementationC
inter-ace $6is&osable
{
void 6is&ose();
!
3!' Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
class MyVile/ $6is&osable
{
void $6is&osable.6is&ose() {
Close();
!
&ublic void Close() {
.. 6o ,"atWs necessary to close t"e -ile
System.SC.Su&&ressVinali?e(t"is);
!
!
1t is not possible to access an eplicit inter0ace member implementation t+roug+ its 0ully 9uali0ied name in a
met+od invocation- property access- or indeer access. (n eplicit inter0ace member implementation can only
be accessed t+roug+ an inter0ace instance- and is in t+at case re0erenced simply by its member name.
1t is a compile<time error 0or an eplicit inter0ace member implementation to include access modi0iers- and it is a
compile<time error to include t+e modi0iers abstract- virtual- override- or static.
Eplicit inter0ace member implementations +ave di00erent accessibility c+aracteristics t+an ot+er members.
)ecause eplicit inter0ace member implementations are never accessible t+roug+ t+eir 0ully 9uali0ied name in a
met+od invocation or a property access- t+ey are in a sense private. However- since t+ey can be accessed
t+roug+ an inter0ace instance- t+ey are in a sense also public.
Eplicit inter0ace member implementations serve two primary purposesC
)ecause eplicit inter0ace member implementations are not accessible t+roug+ class or struct instances- t+ey
allow inter0ace implementations to be ecluded 0rom t+e public inter0ace o0 a class or struct. T+is is
particularly use0ul w+en a class or struct implements an internal inter0ace t+at is o0 no interest to a consumer
o0 t+at class or struct.
Eplicit inter0ace member implementations allow disambiguation o0 inter0ace members wit+ t+e same
signature. 6it+out eplicit inter0ace member implementations it would be impossible 0or a class or struct to
+ave di00erent implementations o0 inter0ace members wit+ t+e same signature and return type- as would it be
impossible 0or a class or struct to +ave any implementation at all o0 inter0ace members wit+ t+e same
signature but wit+ di00erent return types.
*or an eplicit inter0ace member implementation to be valid- t+e class or struct must name an inter0ace in its
base class list t+at contains a member w+ose 0ully 9uali0ied name- type- and parameter types eactly matc+ t+ose
o0 t+e eplicit inter0ace member implementation. T+us- in t+e 0ollowing class
class S"a&e/ $Cloneable
{
object $Cloneable.Clone() {...!
int $Com&arable.Com&are1o(object ot"er) {...! .. invalid
!
t+e declaration o0 $Com&arable.Com&are1o results in a compile<time error because $Com&arable is not
listed in t+e base class list o0 S"a&e and is not a base inter0ace o0 $Cloneable. 5i7ewise- in t+e declarations
class S"a&e/ $Cloneable
{
object $Cloneable.Clone() {...!
!
class )lli&se/ S"a&e
{
object $Cloneable.Clone() {...! .. invalid
!
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 3!7
C# Language Specification
t+e declaration o0 $Cloneable.Clone in )lli&se results in a compile<time error because $Cloneable is not
eplicitly listed in t+e base class list o0 )lli&se.
T+e 0ully 9uali0ied name o0 an inter0ace member must re0erence t+e inter0ace in w+ic+ t+e member was
declared. T+us- in t+e declarations
inter-ace $Control
{
void *aint();
!
inter-ace $1e#t:o#/ $Control
{
void Set1e#t(string te#t);
!
class 1e#t:o#/ $1e#t:o#
{
void $Control.*aint() {...!
void $1e#t:o#.Set1e#t(string te#t) {...!
!
t+e eplicit inter0ace member implementation o0 *aint must be written as $Control.*aint.
13.#.2 6ni7ueness of ipleented interfaces
T+e inter0aces implemented by a generic type declaration must remain uni9ue 0or all possible constructed types.
6it+out t+is rule- it would be impossible to determine t+e correct met+od to call 0or certain constructed types.
*or eample- suppose a generic class declaration were permitted to be written as 0ollowsC
inter-ace $D1E
{
void V();
!
class ID;UE/ $D;E $DUE .. )rror/ $D;E and $DUE con-lict
{
void $D;E.V() {...!
void $DUE.V() {...!
!
6ere t+is permitted- it would be impossible to determine w+ic+ code to eecute in t+e 0ollowing caseC
$DintE # + ne, IDintintE();
#.V();
To determine i0 t+e inter0ace list o0 a generic type declaration is valid- t+e 0ollowing steps are per0ormedC
5et L be t+e list o0 inter0aces directly speci0ied in a generic class- struct- or inter0ace declaration C.
(dd to L any base inter0aces o0 t+e inter0aces already in L.
;emove any duplicates 0rom L.
10 any possible constructed type created 0rom C would- a0ter type arguments are substituted into L- cause two
inter0aces in L to be identical- t+en t+e declaration o0 C is invalid. Constraint declarations are not considered
w+en determining all possible constructed types.
3!$ Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
1n t+e class declaration I above- t+e inter0ace list L consists o0 $D;E and $DUE. T+e declaration is invalid
because any constructed type wit+ ; and U being t+e same type would cause t+ese two inter0aces to be identical
types.
1t is possible 0or inter0aces speci0ied at di00erent in+eritance levels to uni0yC
inter-ace $D1E
{
void V();
!
class :aseD;E/ $D;E
{
void $D;E.V() {b!
!
class 6erivedD;UE/ :aseD;E $DUE .. %(
{
void $DUE.V() {b!
!
T+is code is valid even t+oug+ 6erivedD;UE implements bot+ $D;E and $DUE. T+e code
$DintE # + ne, 6erivedDintintE();
#.V();
invo7es t+e met+od in 6erived- since 6erivedDintintE e00ectively re<implements $DintE JV13.4.%M.
13.#.3 Ipleentation of generic et-ods
6+en a generic met+od implicitly implements an inter0ace met+od- t+e constraints given 0or eac+ met+od type
parameter must be e9uivalent in bot+ declarations Ja0ter any inter0ace type parameters are replaced wit+ t+e
appropriate type argumentsM- w+ere met+od type parameters are identi0ied by ordinal positions- le0t to rig+t.
6+en a generic met+od eplicitly implements an inter0ace met+od- +owever- no constraints are allowed on t+e
implementing met+od. 1nstead- t+e constraints are in+erited 0rom t+e inter0ace met+od
inter-ace $D':CE
{
void VD1E(1 t) ,"ere 1/ ';
void SD1E(1 t) ,"ere 1/ :;
void HD1E(1 t) ,"ere 1/ C;
!
class C/ $DobjectCstringE
{
&ublic void VD1E(1 t) {...! .. %(
&ublic void SD1E(1 t) ,"ere 1/ C {...! .. %(
&ublic void HD1E(1 t) ,"ere 1/ string {...! .. )rror
!
T+e met+od C.VD1E implicitly implements $DobjectCstringE.VD1E. 1n t+is case- C.VD1E is not re9uired
Jnor permittedM to speci0y t+e constraint 1/ object since object is an implicit constraint on all type
parameters. T+e met+od C.SD1E implicitly implements $DobjectCstringE.SD1E because t+e constraints
matc+ t+ose in t+e inter0ace- a0ter t+e inter0ace type parameters are replaced wit+ t+e corresponding type
arguments. T+e constraint 0or met+od C.HD1E is an error because sealed types Jstring in t+is caseM cannot be
used as constraints. /mitting t+e constraint would also be an error since constraints o0 implicit inter0ace met+od
implementations are re9uired to matc+. T+us- it is impossible to implicitly implement
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 3!!
C# Language Specification
$DobjectCstringE.HD1E. T+is inter0ace met+od can only be implemented using an eplicit inter0ace
member implementationC
class C/ $DobjectCstringE
{
...
&ublic void HD;E(; u) ,"ere ;/ class {...!
void $DobjectCstringE.HD1E(1 t) {
string s + t; .. %(
HD1E(t);
!
!
1n t+is eample- t+e eplicit inter0ace member implementation invo7es a public met+od +aving strictly wea7er
constraints. =ote t+at t+e assignment 0rom t to s is valid since 1 in+erits a constraint o0 1/ string- even
t+oug+ t+is constraint is not epressible in source code.
13.#.# Interface apping
( class or struct must provide implementations o0 all members o0 t+e inter0aces t+at are listed in t+e base class
list o0 t+e class or struct. T+e process o0 locating implementations o0 inter0ace members in an implementing
class or struct is 7nown as interface apping.
1nter0ace mapping 0or a class or struct C locates an implementation 0or eac+ member o0 eac+ inter0ace speci0ied
in t+e base class list o0 C. T+e implementation o0 a particular inter0ace member $.M- w+ere $ is t+e inter0ace in
w+ic+ t+e member M is declared- is determined by eamining eac+ class or struct S- starting wit+ C and repeating
0or eac+ successive base class o0 C- until a matc+ is locatedC
10 S contains a declaration o0 an eplicit inter0ace member implementation t+at matc+es $ and M- t+en t+is
member is t+e implementation o0 $.M.
/t+erwise- i0 S contains a declaration o0 a non<static public member t+at matc+es M- t+en t+is member is t+e
implementation o0 $.M. 10 more t+an one member matc+es- it is unspeci0ied w+ic+ member is t+e
implementation o0 $.M. T+is situation can only occur i0 S is a constructed type w+ere t+e two members as
declared in t+e generic type +ave di00erent signatures- but t+e type arguments ma7e t+eir signatures
identical.
( compile<time error occurs i0 implementations cannot be located 0or all members o0 all inter0aces speci0ied in
t+e base class list o0 C. =ote t+at t+e members o0 an inter0ace include t+ose members t+at are in+erited 0rom base
inter0aces.
*or purposes o0 inter0ace mapping- a class member ' matc+es an inter0ace member : w+enC
' and : are met+ods- and t+e name- type- and 0ormal parameter lists o0 ' and : are identical.
' and : are properties- t+e name and type o0 ' and : are identical- and ' +as t+e same accessors as : J' is
permitted to +ave additional accessors i0 it is not an eplicit inter0ace member implementationM.
' and : are events- and t+e name and type o0 ' and : are identical.
' and : are indeers- t+e type and 0ormal parameter lists o0 ' and : are identical- and ' +as t+e same
accessors as : J' is permitted to +ave additional accessors i0 it is not an eplicit inter0ace member
implementationM.
=otable implications o0 t+e inter0ace mapping algorit+m areC
"** Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
Eplicit inter0ace member implementations ta7e precedence over ot+er members in t+e same class or struct
w+en determining t+e class or struct member t+at implements an inter0ace member.
=eit+er non<public nor static members participate in inter0ace mapping.
1n t+e eample
inter-ace $Cloneable
{
object Clone();
!
class C/ $Cloneable
{
object $Cloneable.Clone() {...!
&ublic object Clone() {...!
!
t+e $Cloneable.Clone member o0 C becomes t+e implementation o0 Clone in $Cloneable because eplicit
inter0ace member implementations ta7e precedence over ot+er members.
10 a class or struct implements two or more inter0aces containing a member wit+ t+e same name- type- and
parameter types- it is possible to map eac+ o0 t+ose inter0ace members onto a single class or struct member. *or
eample
inter-ace $Control
{
void *aint();
!
inter-ace $Vorm
{
void *aint();
!
class *age/ $Control $Vorm
{
&ublic void *aint() {...!
!
Here- t+e *aint met+ods o0 bot+ $Control and $Vorm are mapped onto t+e *aint met+od in *age. 1t is o0
course also possible to +ave separate eplicit inter0ace member implementations 0or t+e two met+ods.
10 a class or struct implements an inter0ace t+at contains +idden members- t+en some members must necessarily
be implemented t+roug+ eplicit inter0ace member implementations. *or eample
inter-ace $:ase
{
int * { get; !
!
inter-ace $6erived/ $:ase
{
ne, int *();
!
(n implementation o0 t+is inter0ace would re9uire at least one eplicit inter0ace member implementation- and
would ta7e one o0 t+e 0ollowing 0orms
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. "*1
C# Language Specification
class C/ $6erived
{
int $:ase.* { get {...! !
int $6erived.*() {...!
!
class C/ $6erived
{
&ublic int * { get {...! !
int $6erived.*() {...!
!
class C/ $6erived
{
int $:ase.* { get {...! !
&ublic int *() {...!
!
6+en a class implements multiple inter0aces t+at +ave t+e same base inter0ace- t+ere can be only one
implementation o0 t+e base inter0ace. 1n t+e eample
inter-ace $Control
{
void *aint();
!
inter-ace $1e#t:o#/ $Control
{
void Set1e#t(string te#t);
!
inter-ace $List:o#/ $Control
{
void Set$tems(string45 items);
!
class Combo:o#/ $Control $1e#t:o# $List:o#
{
void $Control.*aint() {...!
void $1e#t:o#.Set1e#t(string te#t) {...!
void $List:o#.Set$tems(string45 items) {...!
!
it is not possible to +ave separate implementations 0or t+e $Control named in t+e base class list- t+e $Control
in+erited by $1e#t:o#- and t+e $Control in+erited by $List:o#. 1ndeed- t+ere is no notion o0 a separate
identity 0or t+ese inter0aces. ;at+er- t+e implementations o0 $1e#t:o# and $List:o# s+are t+e same
implementation o0 $Control- and Combo:o# is simply considered to implement t+ree inter0aces- $Control-
$1e#t:o#- and $List:o#.
T+e members o0 a base class participate in inter0ace mapping. 1n t+e eample
inter-ace $nter-ace2
{
void V();
!
"*2 Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
class Class2
{
&ublic void V() {!
&ublic void S() {!
!
class Class8/ Class2 $nter-ace2
{
ne, &ublic void S() {!
!
t+e met+od V in Class2 is used in Class8Ys implementation o0 $nter-ace2.
13.#.& Interface ipleentation in-eritance
( class in+erits all inter0ace implementations provided by its base classes.
6it+out eplicitly re-ipleenting an inter0ace- a derived class cannot in any way alter t+e inter0ace mappings
it in+erits 0rom its base classes. *or eample- in t+e declarations
inter-ace $Control
{
void *aint();
!
class Control/ $Control
{
&ublic void *aint() {...!
!
class 1e#t:o#/ Control
{
ne, &ublic void *aint() {...!
!
t+e *aint met+od in 1e#t:o# +ides t+e *aint met+od in Control- but it does not alter t+e mapping o0
Control.*aint onto $Control.*aint- and calls to *aint t+roug+ class instances and inter0ace instances
will +ave t+e 0ollowing e00ects
Control c + ne, Control();
1e#t:o# t + ne, 1e#t:o#();
$Control ic + c;
$Control it + t;
c.*aint(); .. invo(es Control.*aint();
t.*aint(); .. invo(es 1e#t:o#.*aint();
ic.*aint(); .. invo(es Control.*aint();
it.*aint(); .. invo(es Control.*aint();
However- w+en an inter0ace met+od is mapped onto a virtual met+od in a class- it is possible 0or derived classes
to override t+e virtual met+od and alter t+e implementation o0 t+e inter0ace. *or eample- rewriting t+e
declarations above to
inter-ace $Control
{
void *aint();
!
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. "*3
C# Language Specification
class Control/ $Control
{
&ublic virtual void *aint() {...!
!
class 1e#t:o#/ Control
{
&ublic override void *aint() {...!
!
t+e 0ollowing e00ects will now be observed
Control c + ne, Control();
1e#t:o# t + ne, 1e#t:o#();
$Control ic + c;
$Control it + t;
c.*aint(); .. invo(es Control.*aint();
t.*aint(); .. invo(es 1e#t:o#.*aint();
ic.*aint(); .. invo(es Control.*aint();
it.*aint(); .. invo(es 1e#t:o#.*aint();
#ince eplicit inter0ace member implementations cannot be declared virtual- it is not possible to override an
eplicit inter0ace member implementation. However- it is per0ectly valid 0or an eplicit inter0ace member
implementation to call anot+er met+od- and t+at ot+er met+od can be declared virtual to allow derived classes to
override it. *or eample
inter-ace $Control
{
void *aint();
!
class Control/ $Control
{
void $Control.*aint() { *aintControl(); !
&rotected virtual void *aintControl() {...!
!
class 1e#t:o#/ Control
{
&rotected override void *aintControl() {...!
!
Here- classes derived 0rom Control can specialiDe t+e implementation o0 $Control.*aint by overriding t+e
*aintControl met+od.
13.#.' Interface re9ipleentation
( class t+at in+erits an inter0ace implementation is permitted to re-ipleent t+e inter0ace by including it in t+e
base class list.
( re<implementation o0 an inter0ace 0ollows eactly t+e same inter0ace mapping rules as an initial
implementation o0 an inter0ace. T+us- t+e in+erited inter0ace mapping +as no e00ect w+atsoever on t+e inter0ace
mapping establis+ed 0or t+e re<implementation o0 t+e inter0ace. *or eample- in t+e declarations
inter-ace $Control
{
void *aint();
!
"*" Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
class Control/ $Control
{
void $Control.*aint() {...!
!
class MyControl/ Control $Control
{
&ublic void *aint() {!
!
t+e 0act t+at Control maps $Control.*aint onto Control.$Control.*aint doesnPt a00ect t+e re<
implementation in MyControl- w+ic+ maps $Control.*aint onto MyControl.*aint.
1n+erited public member declarations and in+erited eplicit inter0ace member declarations participate in t+e
inter0ace mapping process 0or re<implemented inter0aces. *or eample
inter-ace $Met"ods
{
void V();
void S();
void H();
void $();
!
class :ase/ $Met"ods
{
void $Met"ods.V() {!
void $Met"ods.S() {!
&ublic void H() {!
&ublic void $() {!
!
class 6erived/ :ase $Met"ods
{
&ublic void V() {!
void $Met"ods.H() {!
!
Here- t+e implementation o0 $Met"ods in 6erived maps t+e inter0ace met+ods onto 6erived.V-
:ase.$Met"ods.S- 6erived.$Met"ods.H- and :ase.$.
6+en a class implements an inter0ace- it implicitly also implements all o0 t+at inter0acePs base inter0aces.
5i7ewise- a re<implementation o0 an inter0ace is also implicitly a re<implementation o0 all o0 t+e inter0acePs base
inter0aces. *or eample
inter-ace $:ase
{
void V();
!
inter-ace $6erived/ $:ase
{
void S();
!
class C/ $6erived
{
void $:ase.V() {...!
void $6erived.S() {...!
!
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. "*
C# Language Specification
class 6/ C $6erived
{
&ublic void V() {...!
&ublic void S() {...!
!
Here- t+e re<implementation o0 $6erived also re<implements $:ase- mapping $:ase.V onto 6.V.
13.#.. *bstract classes and interfaces
5i7e a non<abstract class- an abstract class must provide implementations o0 all members o0 t+e inter0aces t+at
are listed in t+e base class list o0 t+e class. However- an abstract class is permitted to map inter0ace met+ods
onto abstract met+ods. *or eample
inter-ace $Met"ods
{
void V();
void S();
!
abstract class C/ $Met"ods
{
&ublic abstract void V();
&ublic abstract void S();
!
Here- t+e implementation o0 $Met"ods maps V and S onto abstract met+ods- w+ic+ must be overridden in non<
abstract classes t+at derive 0rom C.
=ote t+at eplicit inter0ace member implementations cannot be abstract- but eplicit inter0ace member
implementations are o0 course permitted to call abstract met+ods. *or eample
inter-ace $Met"ods
{
void V();
void S();
!
abstract class C/ $Met"ods
{
void $Met"ods.V() { VV(); !
void $Met"ods.S() { SS(); !
&rotected abstract void VV();
&rotected abstract void SS();
!
Here- non<abstract classes t+at derive 0rom C would be re9uired to override VV and SS- t+us providing t+e actual
implementation o0 $Met"ods.
"*' Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
1#. $nus
(n en- type is a distinct value type JV4.1M t+at declares a set o0 named constants.
T+e eample
enum Color
{
Oed
Sreen
:lue
!
declares an enum type named Color wit+ members Oed- Sreen- and :lue.
1#.1 $nu declarations
(n enum declaration declares a new enum type. (n enum declaration begins wit+ t+e 7eyword enum- and
de0ines t+e name- accessibility- underlying type- and members o0 t+e enum.
en!%-declaration.
attri,!tesopt en!%-%odifiersopt e*um identifier en!%-,aseopt en!%-,od+ Aopt
en!%-,ase.
@ integral-t+pe
en!%-,od+.
{ en!%-%e%,er-declarationsopt }
{ en!%-%e%,er-declarations ? }
Eac+ enum type +as a corresponding integral type called t+e -nderlying type o0 t+e enum type. T+is underlying
type must be able to represent all t+e enumerator values de0ined in t+e enumeration. (n enum declaration may
eplicitly declare an underlying type o0 byte- sbyte- s"ort- us"ort- int- uint- long or ulong. =ote t+at
c"ar cannot be used as an underlying type. (n enum declaration t+at does not eplicitly declare an underlying
type +as an underlying type o0 int.
T+e eample
enum Color/ long
{
Oed
Sreen
:lue
!
declares an enum wit+ an underlying type o0 long. ( developer mig+t c+oose to use an underlying type o0
long- as in t+e eample- to enable t+e use o0 values t+at are in t+e range o0 long but not in t+e range o0 int- or
to preserve t+is option 0or t+e 0uture.
1#.2 $nu odifiers
(n en!%-declaration may optionally include a se9uence o0 enum modi0iersC
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. "*7
C# Language Specification
en!%-%odifiers.
en!%-%odifier
en!%-%odifiers en!%-%odifier
en!%-%odifier.
*ew
.u"li&
.%'$e&$ed
i*$e%*!l
.%i,!$e
1t is a compile<time error 0or t+e same modi0ier to appear multiple times in an enum declaration.
T+e modi0iers o0 an enum declaration +ave t+e same meaning as t+ose o0 a class declaration JV1..1.1M. =ote-
+owever- t+at t+e abstract and sealed modi0iers are not permitted in an enum declaration. Enums cannot be
abstract and do not permit derivation.
1#.3 $nu ebers
T+e body o0 an enum type declaration de0ines Dero or more enum members- w+ic+ are t+e named constants o0
t+e enum type. =o two enum members can +ave t+e same name.
en!%-%e%,er-declarations.
en!%-%e%,er-declaration
en!%-%e%,er-declarations ? en!%-%e%,er-declaration
en!%-%e%,er-declaration.
attri,!tesopt identifier
attri,!tesopt identifier H constant-e/pression
Eac+ enum member +as an associated constant value. T+e type o0 t+is value is t+e underlying type 0or t+e
containing enum. T+e constant value 0or eac+ enum member must be in t+e range o0 t+e underlying type 0or t+e
enum. T+e eample
enum Color/ uint
{
Oed + =2
Sreen + =8
:lue + =9
!
results in a compile<time error because t+e constant values =2- =8- and C9 are not in t+e range o0 t+e underlying
integral type uint.
'ultiple enum members may s+are t+e same associated value. T+e eample
enum Color
{
Oed
Sreen
:lue
Ma# + :lue
!
s+ows an enum in w+ic+ two enum membersR:lue and Ma#R+ave t+e same associated value.
T+e associated value o0 an enum member is assigned eit+er implicitly or eplicitly. 10 t+e declaration o0 t+e
enum member +as a constant-e/pression initialiDer- t+e value o0 t+at constant epression- implicitly converted to
"*$ Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
t+e underlying type o0 t+e enum- is t+e associated value o0 t+e enum member. 10 t+e declaration o0 t+e enum
member +as no initialiDer- its associated value is set implicitly- as 0ollowsC
10 t+e enum member is t+e 0irst enum member declared in t+e enum type- its associated value is Dero.
/t+erwise- t+e associated value o0 t+e enum member is obtained by increasing t+e associated value o0 t+e
tetually preceding enum member by one. T+is increased value must be wit+in t+e range o0 values t+at can
be represented by t+e underlying type- ot+erwise a compile<time error occurs.
T+e eample
using System;
enum Color
{
Oed
Sreen + 23
:lue
!
class 1est
{
static void Main() {
Console.WriteLine(StringVromColor(Color.Oed));
Console.WriteLine(StringVromColor(Color.Sreen));
Console.WriteLine(StringVromColor(Color.:lue));
!
static string StringVromColor(Color c) {
s,itc" (c) {
case Color.Oed/
return String.Vormat("Oed + {3!" (int) c);
case Color.Sreen/
return String.Vormat("Sreen + {3!" (int) c);
case Color.:lue/
return String.Vormat(":lue + {3!" (int) c);
de-ault/
return "$nvalid color";
!
!
!
prints out t+e enum member names and t+eir associated values. T+e output isC
Oed + 3
Sreen + 23
:lue + 22
0or t+e 0ollowing reasonsC
t+e enum member Oed is automatically assigned t+e value Dero Jsince it +as no initialiDer and is t+e 0irst
enum memberMQ
t+e enum member Sreen is eplicitly given t+e value 23Q
and t+e enum member :lue is automatically assigned t+e value one greater t+an t+e member t+at tetually
precedes it.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. "*!
C# Language Specification
T+e associated value o0 an enum member may not- directly or indirectly- use t+e value o0 its own associated
enum member. /t+er t+an t+is circularity restriction- enum member initialiDers may 0reely re0er to ot+er enum
member initialiDers- regardless o0 t+eir tetual position. 6it+in an enum member initialiDer- values o0 ot+er
enum members are always treated as +aving t+e type o0 t+eir underlying type- so t+at casts are not necessary
w+en re0erring to ot+er enum members.
T+e eample
enum Circular
{
' + :
:
!
results in a compile<time error because t+e declarations o0 ' and : are circular. ' depends on : eplicitly- and :
depends on ' implicitly.
Enum members are named and scoped in a manner eactly analogous to 0ields wit+in classes. T+e scope o0 an
enum member is t+e body o0 its containing enum type. 6it+in t+at scope- enum members can be re0erred to by
t+eir simple name. *rom all ot+er code- t+e name o0 an enum member must be 9uali0ied wit+ t+e name o0 its
enum type. Enum members do not +ave any declared accessibilityRan enum member is accessible i0 its
containing enum type is accessible.
1#.# T-e S!ste.$nu t!pe
T+e type System.)num is t+e abstract base class o0 all enum types Jt+is is distinct and di00erent 0rom t+e
underlying type o0 t+e enum typeM- and t+e members in+erited 0rom System.)num are available in any enum
type. ( boing conversion JV4.3.1M eists 0rom any enum type to System.)num- and an unboing conversion
JV4.3.2M eists 0rom System.)num to any enum type.
=ote t+at System.)num is not itsel0 an en!%-t+pe. ;at+er- it is a class-t+pe 0rom w+ic+ all en!%-t+pes are
derived. T+e type System.)num in+erits 0rom t+e type System.Ualue1y&e JV4.1.1M- w+ic+- in turn- in+erits
0rom type object. (t run<time- a value o0 type System.)num can be null or a re0erence to a boed value o0
any enum type.
1#.& $nu "alues and operations
Eac+ enum type de0ines a distinct typeQ an eplicit enumeration conversion JV%.2.2M is re9uired to convert
between an enum type and an integral type- or between two enum types. T+e set o0 values t+at an enum type can
ta7e on is not limited by its enum members. 1n particular- any value o0 t+e underlying type o0 an enum can be
cast to t+e enum type- and is a distinct valid value o0 t+at enum type.
Enum members +ave t+e type o0 t+eir containing enum type Jecept wit+in ot+er enum member initialiDersC see
V14.3M. T+e value o0 an enum member declared in enum type ) wit+ associated value v is ())v.
T+e 0ollowing operators can be used on values o0 enum typesC ++- @+- D- E- D+- E+ JV!.$."M- binary < JV!.!.4M-
binary = JV!.!."M- G- F- H JV!.1..2M- A JV!.%.4M- <<- == JV!.".$ and V!.%."M- and si?eo- JV13.".4M.
Every enum type automatically derives 0rom t+e class System.)num Jw+ic+- in turn- derives 0rom
System.Ualue1y&e and objectM. T+us- in+erited met+ods and properties o0 t+is class can be used on values
o0 an enum type.
"1* Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
1&. 2elegates
2elegates enable scenarios t+at ot+er languagesRsuc+ as CNN- Pascal- and 'odulaR+ave addressed wit+
0unction pointers. 8nli7e CNN 0unction pointers- +owever- delegates are 0ully ob&ect oriented- and unli7e CNN
pointers to member 0unctions- delegates encapsulate bot+ an ob&ect instance and a met+od.
( delegate declaration de0ines a class t+at is derived 0rom t+e class System.6elegate. ( delegate instance
encapsulates an invocation list- w+ic+ is a list o0 one or more met+ods- eac+ o0 w+ic+ is re0erred to as a callable
entity. *or instance met+ods- a callable entity consists o0 an instance and a met+od on t+at instance. *or static
met+ods- a callable entity consists o0 &ust a met+od. 1nvo7ing a delegate instance wit+ an appropriate set o0
arguments causes eac+ o0 t+e delegatePs callable entities to be invo7ed wit+ t+e given set o0 arguments.
(n interesting and use0ul property o0 a delegate instance is t+at it does not 7now or care about t+e classes o0 t+e
met+ods it encapsulatesQ all t+at matters is t+at t+ose met+ods be compatible JV1".1M wit+ t+e delegatePs type.
T+is ma7es delegates per0ectly suited 0or KanonymousL invocation.
1&.1 2elegate declarations
( delegate-declaration is a t+pe-declaration JV$.%M t+at declares a new delegate type.
delegate-declaration.
attri,!tesopt delegate-%odifiersopt dele+!$e ret!rn-t+pe identifier t+pe-para%eter-listopt
( for%al-para%eter-listopt ) t+pe-para%eter-constraints-cla!sesopt A
delegate-%odifiers.
delegate-%odifier
delegate-%odifiers delegate-%odifier
delegate-%odifier.
*ew
.u"li&
.%'$e&$ed
i*$e%*!l
.%i,!$e
1t is a compile<time error 0or t+e same modi0ier to appear multiple times in a delegate declaration.
T+e ne, modi0ier is only permitted on delegates declared wit+in anot+er type- in w+ic+ case it speci0ies t+at
suc+ a delegate +ides an in+erited member by t+e same name- as described in V1..3.4.
T+e &ublic- &rotected- internal- and &rivate modi0iers control t+e accessibility o0 t+e delegate type.
2epending on t+e contet in w+ic+ t+e delegate declaration occurs- some o0 t+ese modi0iers may not be
permitted JV3.".1M.
T+e delegatePs type name is identifier.
T+e optional for%al-para%eter-list speci0ies t+e parameters o0 t+e delegate- and ret!rn-t+pe indicates t+e return
type o0 t+e delegate.
T+e optional t+pe-para%eter-list speci0ies t+e type parameters to t+e delegate itsel0.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. "11
C# Language Specification
2elegate types in C# are name e9uivalent- not structurally e9uivalent. #peci0ically- two di00erent delegate types
t+at +ave t+e same parameter lists and return type are considered di00erent delegate types. However- instances o0
two distinct but structurally e9uivalent delegate types may compare as e9ual JV!.$.3M.
*or eampleC
delegate int 62(int i double d);
class '
{
&ublic static int M2(int a double b) {...!
!
class :
{
delegate int 68(int c double d);
&ublic static int M2(int - double g) {...!
&ublic static void M8(int ( double l) {...!
&ublic static int M9(int g) {...!
&ublic static void MJ(int g) {...!
!
T+e delegate types 62 and 68 are bot+ compatible wit+ t+e met+ods '.M2 and :.M2- since t+ey +ave t+e same
return type and parameter listQ +owever- t+ese delegate types are two di00erent types- so t+ey are not
interc+angeable. T+e delegate types 62 and 68 are incompatible wit+ t+e met+ods :.M8- :.M9- and :.MJ- since
t+ey +ave di00erent return types or parameter lists.
5i7e ot+er generic type declarations- type arguments must be given to create a constructed delegate type. T+e
parameter types and return type o0 a constructed delegate type are created by substituting- 0or eac+ type
parameter in t+e delegate declaration- t+e corresponding type argument o0 t+e constructed delegate type. T+e
resulting return type and parameter types are used in determining w+at met+ods are compatible wit+ a
constructed delegate type. *or eampleC
delegate bool *redicateD1E(1 value);
class I
{
static bool V(int i) {...!
static bool S(string s) {...!
!
T+e delegate type *redicateDintE is compatible wit+ t+e met+od I.V and t+e delegate type
*redicateDstringE is compatible wit+ t+e met+od I.S.
T+e only way to declare a delegate type is via a delegate-declaration. ( delegate type is a class type t+at is
derived 0rom System.6elegate. 2elegate types are implicitly sealed- so it is not permissible to derive any
type 0rom a delegate type. 1t is also not permissible to derive a non<delegate class type 0rom
System.6elegate. =ote t+at System.6elegate is not itsel0 a delegate typeQ it is a class type 0rom w+ic+ all
delegate types are derived.
C# provides special synta 0or delegate instantiation and invocation. Ecept 0or instantiation- any operation t+at
can be applied to a class or class instance can also be applied to a delegate class or instance- respectively. 1n
particular- it is possible to access members o0 t+e System.6elegate type via t+e usual member access synta.
T+e set o0 met+ods encapsulated by a delegate instance is called an invocation list. 6+en a delegate instance is
created JV1".2M 0rom a single met+od- it encapsulates t+at met+od- and its invocation list contains only one entry.
"12 Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
However- w+en two non<null delegate instances are combined- t+eir invocation lists are concatenatedRin t+e
order le0t operand t+en rig+t operandRto 0orm a new invocation list- w+ic+ contains two or more entries.
2elegates are combined using t+e binary < JV!.!.4M and <+ operators JV!.1%.2M. ( delegate can be removed 0rom
a combination o0 delegates- using t+e binary = JV!.!."M and =+ operators JV!.1%.2M. 2elegates can be compared
0or e9uality JV!.$.3M.
T+e 0ollowing eample s+ows t+e instantiation o0 a number o0 delegates- and t+eir corresponding invocation
listsC
delegate void 6(int #);
class C
{
&ublic static void M2(int i) {...!
&ublic static void M8(int i) {...!
!
class 1est
{
static void Main() {
6 cd2 + ne, 6(C.M2); .. M2
6 cd8 + ne, 6(C.M8); .. M8
6 cd9 + cd2 < cd8; .. M2 < M8
6 cdJ + cd9 < cd2; .. M2 < M8 < M2
6 cdK + cdJ < cd9; .. M2 < M8 < M2 < M2 < M8
!
!
6+en cd2 and cd8 are instantiated- t+ey eac+ encapsulate one met+od. 6+en cd9 is instantiated- it +as an
invocation list o0 two met+ods- M2 and M8- in t+at order. cdJPs invocation list contains M2- M8- and M2- in t+at
order. *inally- cdKPs invocation list contains M2- M8- M2- M2- and M8- in t+at order. *or more eamples o0
combining Jas well as removingM delegates- see V1".4.
1&.2 2elegate copatibilit!
( met+od or delegate M is copati!le wit+ a delegate type 6 i0 all o0 t+e 0ollowing are trueC
6 and M +ave t+e same number o0 parameters- and eac+ parameter in 6 +as t+e same re- or out modi0iers as
t+e corresponding parameter in M.
*or eac+ value parameter Ja parameter wit+ no re- or out modi0ierM- an identity conversion JV%.1.1M or
implicit re0erence conversion JV%.1.%M eists 0rom t+e parameter type in 6 to t+e corresponding parameter
type in M.
*or eac+ re- or out parameter- t+e parameter type in 6 is t+e same as t+e parameter type in M.
(n identity or implicit re0erence conversion eists 0rom t+e return type o0 M to t+e return type o0 6.
1&.3 2elegate instantiation
(n instance o0 a delegate is created by a delegate-creation-e/pression JV!.".1.."M or a conversion to a delegate
type. T+e newly created delegate instance t+en re0ers to eit+erC
T+e static met+od re0erenced in t+e delegate-creation-e/pression- or
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. "13
C# Language Specification
T+e target ob&ect Jw+ic+ cannot be nullM and instance met+od re0erenced in t+e delegate-creation-
e/pression- or
(not+er delegate.
*or eampleC
delegate void 6(int #);
class C
{
&ublic static void M2(int i) {...!
&ublic void M8(int i) {...!
!
class 1est
{
static void Main() {
6 cd2 + ne, 6(C.M2); .. static met"od
C t + ne, C();
6 cd8 + ne, 6(t.M8); .. instance met"od
6 cd9 + ne, 6(cd8); .. anot"er delegate
!
!
/nce instantiated- delegate instances always re0er to t+e same target ob&ect and met+od. ;emember- w+en two
delegates are combined- or one is removed 0rom anot+er- a new delegate results wit+ its own invocation listQ t+e
invocation lists o0 t+e delegates combined or removed remain unc+anged.
1&.# 2elegate in"ocation
C# provides special synta 0or invo7ing a delegate. 6+en a non<null delegate instance w+ose invocation list
contains one entry is invo7ed- it invo7es t+e one met+od wit+ t+e same arguments it was given- and returns t+e
same value as t+e re0erred to met+od. J#ee V!.".".3 0or detailed in0ormation on delegate invocation.M 10 an
eception occurs during t+e invocation o0 suc+ a delegate- and t+at eception is not caug+t wit+in t+e met+od
t+at was invo7ed- t+e searc+ 0or an eception catc+ clause continues in t+e met+od t+at called t+e delegate- as i0
t+at met+od +ad directly called t+e met+od to w+ic+ t+at delegate re0erred.
1nvocation o0 a delegate instance w+ose invocation list contains multiple entries proceeds by invo7ing eac+ o0
t+e met+ods in t+e invocation list- sync+ronously- in order. Eac+ met+od so called is passed t+e same set o0
arguments as was given to t+e delegate instance. 10 suc+ a delegate invocation includes re0erence parameters
JV1..%.1.2M- eac+ met+od invocation will occur wit+ a re0erence to t+e same variableQ c+anges to t+at variable by
one met+od in t+e invocation list will be visible to met+ods 0urt+er down t+e invocation list. 10 t+e delegate
invocation includes output parameters or a return value- t+eir 0inal value will come 0rom t+e invocation o0 t+e
last delegate in t+e list.
10 an eception occurs during processing o0 t+e invocation o0 suc+ a delegate- and t+at eception is not caug+t
wit+in t+e met+od t+at was invo7ed- t+e searc+ 0or an eception catc+ clause continues in t+e met+od t+at called
t+e delegate- and any met+ods 0urt+er down t+e invocation list are not invo7ed.
(ttempting to invo7e a delegate instance w+ose value is null results in an eception o0 type
System.NullOe-erence)#ce&tion.
T+e 0ollowing eample s+ows +ow to instantiate- combine- remove- and invo7e delegatesC
using System;
delegate void 6(int #);
"1" Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
class C
{
&ublic static void M2(int i) {
Console.WriteLine("C.M2/ " < i);
!
&ublic static void M8(int i) {
Console.WriteLine("C.M8/ " < i);
!
&ublic void M9(int i) {
Console.WriteLine("C.M9/ " < i);
!
!
class 1est
{
static void Main() {
6 cd2 + ne, 6(C.M2);
cd2(=2); .. call M2
6 cd8 + ne, 6(C.M8);
cd8(=8); .. call M8
6 cd9 + cd2 < cd8;
cd9(23); .. call M2 t"en M8
cd9 <+ cd2;
cd9(83); .. call M2 M8 t"en M2
C c + ne, C();
6 cdJ + ne, 6(c.M9);
cd9 <+ cdJ;
cd9(93); .. call M2 M8 M2 t"en M9
cd9 =+ cd2; .. remove last M2
cd9(J3); .. call M2 M8 t"en M9
cd9 =+ cdJ;
cd9(K3); .. call M2 t"en M8
cd9 =+ cd8;
cd9(X3); .. call M2
cd9 =+ cd8; .. im&ossible removal is benign
cd9(X3); .. call M2
cd9 =+ cd2; .. invocation list is em&ty so cd9 is null
.. cd9(M3); .. System.NullOe-erence)#ce&tion t"ro,n
cd9 =+ cd2; .. im&ossible removal is benign
!
!
(s s+own in t+e statement cd9 <+ cd2;- a delegate can be present in an invocation list multiple times. 1n t+is
case- it is simply invo7ed once per occurrence. 1n an invocation list suc+ as t+is- w+en t+at delegate is removed-
t+e last occurrence in t+e invocation list is t+e one actually removed.
1mmediately prior to t+e eecution o0 t+e 0inal statement- cd9 =+ cd2;- t+e delegate cd9 re0ers to an empty
invocation list. (ttempting to remove a delegate 0rom an empty list Jor to remove a non<eistent delegate 0rom a
non<empty listM is not an error.
T+e output produced isC
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. "1
C# Language Specification
C.M2/ =2
C.M8/ =8
C.M2/ 23
C.M8/ 23
C.M2/ 83
C.M8/ 83
C.M2/ 83
C.M2/ 93
C.M8/ 93
C.M2/ 93
C.M9/ 93
C.M2/ J3
C.M8/ J3
C.M9/ J3
C.M2/ K3
C.M8/ K3
C.M2/ X3
C.M2/ X3
"1' Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
1'. $%ceptions
Eceptions in C# provide a structured- uni0orm- and type<sa0e way o0 +andling bot+ system level and application
level error conditions. T+e eception mec+anism in C# is 9uite similar to t+at o0 CNN- wit+ a 0ew important
di00erencesC
1n C#- all eceptions must be represented by an instance o0 a class type derived 0rom System.)#ce&tion.
1n CNN- any value o0 any type can be used to represent an eception.
1n C#- a 0inally bloc7 JV3.1.M can be used to write termination code t+at eecutes in bot+ normal eecution
and eceptional conditions. #uc+ code is di00icult to write in CNN wit+out duplicating code.
1n C#- system<level eceptions suc+ as over0low- divide<by<Dero- and null dere0erences +ave well de0ined
eception classes and are on a par wit+ application<level error conditions.
1'.1 Causes of e%ceptions
Eception can be t+rown in two di00erent ways.
( t"ro, statement JV3.$."M t+rows an eception immediately and unconditionally. Control never reac+es
t+e statement immediately 0ollowing t+e t"ro,.
Certain eceptional conditions t+at arise during t+e processing o0 C# statements and epression cause an
eception in certain circumstances w+en t+e operation cannot be completed normally. *or eample- an
integer division operation JV!.!.2M t+rows a System.6ivide:yPero)#ce&tion i0 t+e denominator is
Dero. #ee V1%.4 0or a list o0 t+e various eceptions t+at can occur in t+is way.
1'.2 T-e S!ste.$%ception class
T+e System.)#ce&tion class is t+e base type o0 all eceptions. T+is class +as a 0ew notable properties t+at all
eceptions s+areC
Message is a read<only property o0 type string t+at contains a +uman<readable description o0 t+e reason
0or t+e eception.
$nner)#ce&tion is a read<only property o0 type )#ce&tion. 10 its value is non<null- it re0ers to t+e
eception t+at caused t+e current eceptionRt+at is- t+e current eception was raised in a catc+ bloc7
+andling t+e $nner)#ce&tion. /t+erwise- its value is null- indicating t+at t+is eception was not caused
by anot+er eception. T+e number o0 eception ob&ects c+ained toget+er in t+is manner can be arbitrary.
T+e value o0 t+ese properties can be speci0ied in calls to t+e instance constructor 0or System.)#ce&tion.
1'.3 How e%ceptions are -andled
Eceptions are +andled by a try statement JV3.1.M.
6+en an eception occurs- t+e system searc+es 0or t+e nearest catc" clause t+at can +andle t+e eception- as
determined by t+e run<time type o0 t+e eception. *irst- t+e current met+od is searc+ed 0or a leically enclosing
try statement- and t+e associated catc+ clauses o0 t+e try statement are considered in order. 10 t+at 0ails- t+e
met+od t+at called t+e current met+od is searc+ed 0or a leically enclosing try statement t+at encloses t+e point
o0 t+e call to t+e current met+od. T+is searc+ continues until a catc" clause is 0ound t+at can +andle t+e current
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. "17
C# Language Specification
eception- by naming an eception class t+at is o0 t+e same class- or a base class- o0 t+e run<time type o0 t+e
eception being t+rown. ( catc" clause t+at doesnPt name an eception class can +andle any eception.
/nce a matc+ing catc+ clause is 0ound- t+e system prepares to trans0er control to t+e 0irst statement o0 t+e catc+
clause. )e0ore eecution o0 t+e catc+ clause begins- t+e system 0irst eecutes- in order- any -inally clauses
t+at were associated wit+ try statements more nested t+at t+an t+e one t+at caug+t t+e eception.
10 no matc+ing catc+ clause is 0ound- one o0 two t+ings occursC
10 t+e searc+ 0or a matc+ing catc+ clause reac+es a static constructor JV1..12M or static 0ield initialiDer- t+en a
System.1y&e$nitiali?ation)#ce&tion is t+rown at t+e point t+at triggered t+e invocation o0 t+e
static constructor. T+e inner eception o0 t+e System.1y&e$nitiali?ation)#ce&tion contains t+e
eception t+at was originally t+rown.
10 t+e searc+ 0or matc+ing catc+ clauses reac+es t+e code t+at initially started t+e t+read- t+en eecution o0
t+e t+read is terminated. T+e impact o0 suc+ termination is implementation<de0ined.
Eceptions t+at occur during destructor eecution are wort+ special mention. 10 an eception occurs during
destructor eecution- and t+at eception is not caug+t- t+en t+e eecution o0 t+at destructor is terminated and t+e
destructor o0 t+e base class Ji0 anyM is called. 10 t+ere is no base class Jas in t+e case o0 t+e object typeM or i0
t+ere is no base class destructor- t+en t+e eception is discarded.
1'.# Coon $%ception Classes
T+e 0ollowing eceptions are t+rown by certain C# operations.
"1$ Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
System.'rit"metic)#ce&tion
( base class 0or eceptions t+at occur during
arit+metic operations- suc+ as
System.6ivide:yPero)#ce&tion and
System.%ver-lo,)#ce&tion.
System.'rray1y&eMismatc")#ce&tion
T+rown w+en a store into an array 0ails because t+e
actual type o0 t+e stored element is incompatible
wit+ t+e actual type o0 t+e array.
System.6ivide:yPero)#ce&tion
T+rown w+en an attempt to divide an integral
value by Dero occurs.
System.$nde#%ut%-Oange)#ce&tion
T+rown w+en an attempt to inde an array via an
inde t+at is less t+an Dero or outside t+e bounds o0
t+e array.
System.$nvalidCast)#ce&tion
T+rown w+en an eplicit conversion 0rom a base
type or inter0ace to a derived type 0ails at run time.
System.NullOe-erence)#ce&tion
T+rown w+en a null re0erence is used in a way
t+at causes t+e re0erenced ob&ect to be re9uired.
System.%ut%-Memory)#ce&tion
T+rown w+en an attempt to allocate memory Jvia
ne,M 0ails.
System.%ver-lo,)#ce&tion
T+rown w+en an arit+metic operation in a
c"ec(ed contet over0lows.
System.Stac(%ver-lo,)#ce&tion
T+rown w+en t+e eecution stac7 is e+austed by
+aving too many pending met+od callsQ typically
indicative o0 very deep or unbounded recursion.
System.1y&e$nitiali?ation)#ce&tion
T+rown w+en a static constructor t+rows an
eception- and no catc" clauses eists to catc+ it.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. "1!
C0apter 1 Introduction
1.. *ttributes
'uc+ o0 t+e C# language enables t+e programmer to speci0y declarative in0ormation about t+e entities de0ined
in t+e program. *or eample- t+e accessibility o0 a met+od in a class is speci0ied by decorating it wit+ t+e
%ethod-%odifiers &ublic- &rotected- internal- and &rivate.
C# enables programmers to invent new 7inds o0 declarative in0ormation- called attri!-tes. Programmers can
t+en attac+ attributes to various program entities- and retrieve attribute in0ormation in a run<time environment.
*or instance- a 0ramewor7 mig+t de0ine a Hel&'ttribute attribute t+at can be placed on certain program
elements Jsuc+ as classes and met+odsM to provide a mapping 0rom t+ose program elements to t+eir
documentation.
(ttributes are de0ined t+roug+ t+e declaration o0 attribute classes JV1!.1M- w+ic+ may +ave positional and named
parameters JV1!.1.2M. (ttributes are attac+ed to entities in a C# program using attribute speci0ications JV1!.2M-
and can be retrieved at run<time as attribute instances JV1!.3M.
1..1 *ttribute classes
( class t+at derives 0rom t+e abstract class System.'ttribute- w+et+er directly or indirectly- is an attri!-te
class. T+e declaration o0 an attribute class de0ines a new 7ind o0 attri!-te t+at can be placed on a declaration. )y
convention- attribute classes are named wit+ a su00i o0 'ttribute. 8ses o0 an attribute may eit+er include or
omit t+is su00i.
1..1.1 *ttribute usage
T+e attribute 'ttribute;sage JV1!.4.1M is used to describe +ow an attribute class can be used.
'ttribute;sage +as a positional parameter JV1!.1.2M t+at enables an attribute class to speci0y t+e 7inds o0
declarations on w+ic+ it can be used. T+e eample
using System;
4'ttribute;sage('ttribute1argets.Class H 'ttribute1argets.$nter-ace)5
&ublic class Sim&le'ttribute/ 'ttribute
{
...
!
de0ines an attribute class named Sim&le'ttribute t+at can be placed on class-declarations and interface-
declarations only. T+e eample
4Sim&le5 class Class2 {...!
4Sim&le5 inter-ace $nter-ace2 {...!
s+ows several uses o0 t+e Sim&le attribute. (lt+oug+ t+is attribute is de0ined wit+ t+e name
Sim&le'ttribute- w+en t+is attribute is used- t+e 'ttribute su00i may be omitted- resulting in t+e s+ort
name Sim&le. T+us- t+e eample above is semantically e9uivalent to t+e 0ollowingC
4Sim&le'ttribute5 class Class2 {...!
4Sim&le'ttribute5 inter-ace $nter-ace2 {...!
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. "21
C# Language Specification
'ttribute;sage +as a named parameter JV1!.1.2M called 'llo,Multi&le- w+ic+ indicates w+et+er t+e
attribute can be speci0ied more t+an once 0or a given entity. 10 'llo,Multi&le 0or an attribute class is true-
t+en t+at attribute class is a -lti--se attri!-te class- and can be speci0ied more t+an once on an entity. 10
'llo,Multi&le 0or an attribute class is 0alse or it is unspeci0ied- t+en t+at attribute class is a single--se
attri!-te class- and can be speci0ied at most once on an entity.
T+e eample
using System;
4'ttribute;sage('ttribute1argets.Class 'llo,Multi&le + true)5
&ublic class 'ut"or'ttribute/ 'ttribute
{
&rivate string name;
&ublic 'ut"or'ttribute(string name) {
t"is.name + name;
!
&ublic string Name {
get { return name; !
!
!
de0ines a multi<use attribute class named 'ut"or'ttribute. T+e eample
4'ut"or(":rian aernig"an") 'ut"or("6ennis Oitc"ie")5
class Class2
{
...
!
s+ows a class declaration wit+ two uses o0 t+e 'ut"or attribute.
'ttribute;sage +as anot+er named parameter called $n"erited- w+ic+ indicates w+et+er t+e attribute-
w+en speci0ied on a base class- is also in+erited by classes t+at derive 0rom t+at base class. 10 $n"erited 0or an
attribute class is true- t+en t+at attribute is in+erited. 10 $n"erited 0or an attribute class is 0alse t+en t+at
attribute is not in+erited. 10 it is unspeci0ied- its de0ault value is true.
(n attribute class I not +aving an 'ttribute;sage attribute attac+ed to it- as in
using System;
class I/ 'ttribute {...!
is e9uivalent to t+e 0ollowingC
using System;
4'ttribute;sage(
'ttribute1argets.'ll
'llo,Multi&le + -alse
$n"erited + true)
5
class I/ 'ttribute {...!
1..1.2 Positional and naed paraeters
(ttribute classes can +ave positional paraeters and naed paraeters. Eac+ public instance constructor 0or
an attribute class de0ines a valid se9uence o0 positional parameters 0or t+at attribute class. Eac+ non<static public
read<write 0ield and property 0or an attribute class de0ines a named parameter 0or t+e attribute class.
"22 Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
T+e eample
using System;
4'ttribute;sage('ttribute1argets.Class)5
&ublic class Hel&'ttribute/ 'ttribute
{
&ublic Hel&'ttribute(string url) { .. *ositional &arameter
...
!
&ublic string 1o&ic { .. Named &arameter
get {...!
set {...!
!
&ublic string ;rl {
get {...!
!
!
de0ines an attribute class named Hel&'ttribute t+at +as one positional parameter- url- and one named
parameter- 1o&ic. (lt+oug+ it is non<static and public- t+e property ;rl does not de0ine a named parameter-
since it is not read<write.
T+is attribute class mig+t be used as 0ollowsC
4Hel&(""tt&/..,,,.mycom&any.com.....Class2."tm")5
class Class2
{
...
!
4Hel&(""tt&/..,,,.mycom&any.com.....Misc."tm" 1o&ic + "Class8")5
class Class8
{
...
!
1..1.3 *ttribute paraeter t!pes
T+e types o0 positional and named parameters 0or an attribute class are limited to t+e attri!-te paraeter types-
w+ic+ areC
/ne o0 t+e 0ollowing typesC bool- byte- c"ar- double- -loat- int- long- sbyte- s"ort- string-
uint- ulong- us"ort.
T+e type object.
T+e type System.1y&e.
(n enum type- provided it +as public accessibility and t+e types in w+ic+ it is nested Ji0 anyM also +ave
public accessibility JV1!.2M.
#ingle<dimensional arrays o0 t+e above types.
( constructor argument or public 0ield w+ic+ does not +ave one o0 t+ese types- cannot be used as a
positional or named parameter in an attribute speci0ication.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. "23
C# Language Specification
1..2 *ttribute specification
Attri!-te specification is t+e application o0 a previously de0ined attribute to a declaration. (n attribute is a piece
o0 additional declarative in0ormation t+at is speci0ied 0or a declaration. (ttributes can be speci0ied at global
scope Jto speci0y attributes on t+e containing assembly or moduleM and 0or t+pe-declarations JV$.%M- class-
%e%,er-declarations JV1..1."M- interface-%e%,er-declarations JV13.2M- str!ct-%e%,er-declarations JV11.2M-
en!%-%e%,er-declarations JV14.3M- accessor-declarations JV1..!.2M- event-accessor-declarations JV1..3.1M- and
for%al-para%eter-lists JV1..%.1M.
(ttributes are speci0ied in attri!-te sections. (n attribute section consists o0 a pair o0 s9uare brac7ets- w+ic+
surround a comma<separated list o0 one or more attributes. T+e order in w+ic+ attributes are speci0ied in suc+ a
list- and t+e order in w+ic+ sections attac+ed to t+e same program entity are arranged- is not signi0icant. *or
instance- t+e attribute speci0ications 4'54:5- 4:54'5- 4' :5- and 4: '5 are e9uivalent.
glo,al-attri,!tes.
glo,al-attri,!te-sections
glo,al-attri,!te-sections.
glo,al-attri,!te-section
glo,al-attri,!te-sections glo,al-attri,!te-section
glo,al-attri,!te-section.
= glo,al-attri,!te-target-specifier attri,!te-list >
= glo,al-attri,!te-target-specifier attri,!te-list ? >
glo,al-attri,!te-target-specifier.
glo,al-attri,!te-target @
glo,al-attri,!te-target.
!##em"l)
m'dule
attri,!tes.
attri,!te-sections
attri,!te-sections.
attri,!te-section
attri,!te-sections attri,!te-section
attri,!te-section.
= attri,!te-target-specifieropt attri,!te-list >
= attri,!te-target-specifieropt attri,!te-list ? >
attri,!te-target-specifier.
attri,!te-target @
attri,!te-target.
field
e,e*$
me$h'd
.!%!m
.%'.e%$)
%e$u%*
$).e
attri,!te-list.
attri,!te
attri,!te-list ? attri,!te
"2" Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
attri,!te.
attri,!te-na%e attri,!te-arg!%entsopt
attri,!te-na%e.
t+pe-na%e
attri,!te-arg!%ents.
( positional-arg!%ent-listopt )
( positional-arg!%ent-list ? na%ed-arg!%ent-list )
( na%ed-arg!%ent-list )
positional-arg!%ent-list.
positional-arg!%ent
positional-arg!%ent-list ? positional-arg!%ent
positional-arg!%ent.
attri,!te-arg!%ent-e/pression
na%ed-arg!%ent-list.
na%ed-arg!%ent
na%ed-arg!%ent-list ? na%ed-arg!%ent
na%ed-arg!%ent.
identifier H attri,!te-arg!%ent-e/pression
attri,!te-arg!%ent-e/pression.
e/pression
(n attribute consists o0 an attri,!te-na%e and an optional list o0 positional and named arguments. T+e positional
arguments Ji0 anyM precede t+e named arguments. ( positional argument consists o0 an attri,!te-arg!%ent-
e/pressionQ a named argument consists o0 a name- 0ollowed by an e9ual sign- 0ollowed by an attri,!te-
arg!%ent-e/pression- w+ic+- toget+er- are constrained by t+e same rules as simple assignment. T+e order o0
named arguments is not signi0icant.
T+e attri,!te-na%e identi0ies an attribute class. 10 t+e 0orm o0 attri,!te-na%e is t+pe-na%e t+en t+is name must
re0er to an attribute class. /t+erwise- a compile<time error occurs. T+e eample
class Class2 {!
4Class25 class Class8 {! .. )rror
results in a compile<time error because it attempts to use Class2 as an attribute class w+en Class2 is not an
attribute class.
Certain contets permit t+e speci0ication o0 an attribute on more t+an one target. ( program can eplicitly
speci0y t+e target by including an attri,!te-target-specifier. 6+en an attribute is placed at t+e global level- a
glo,al-attri,!te-target-specifier is re9uired. 1n all ot+er locations- a reasonable de0ault is applied- but an
attri,!te-target-specifier can be used to a00irm or override t+e de0ault in certain ambiguous cases Jor to &ust
a00irm t+e de0ault in non<ambiguous casesM. T+us- typically- attri,!te-target-specifiers can be omitted ecept at
t+e global level. T+e potentially ambiguous contets are resolved as 0ollowsC
(n attribute speci0ied at global scope can apply eit+er to t+e target assembly or t+e target module. =o
de0ault eists 0or t+is contet- so an attri,!te-target-specifier is always re9uired in t+is contet. T+e
presence o0 t+e assembly attri,!te-target-specifier indicates t+at t+e attribute applies to t+e target
assemblyQ t+e presence o0 t+e module attri,!te-target-specifier indicates t+at t+e attribute applies to t+e
target module.
(n attribute speci0ied on a delegate declaration can apply eit+er to t+e delegate being declared or to its
return value. 1n t+e absence o0 an attri,!te-target-specifier- t+e attribute applies to t+e delegate. T+e
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. "2
C# Language Specification
presence o0 t+e ty&e attri,!te-target-specifier indicates t+at t+e attribute applies to t+e delegateQ t+e
presence o0 t+e return attri,!te-target-specifier indicates t+at t+e attribute applies to t+e return value.
(n attribute speci0ied on a met+od declaration can apply eit+er to t+e met+od being declared or to its return
value. 1n t+e absence o0 an attri,!te-target-specifier- t+e attribute applies to t+e met+od. T+e presence o0 t+e
met"od attri,!te-target-specifier indicates t+at t+e attribute applies to t+e met+odQ t+e presence o0 t+e
return attri,!te-target-specifier indicates t+at t+e attribute applies to t+e return value.
(n attribute speci0ied on an operator declaration can apply eit+er to t+e operator being declared or to its
return value. 1n t+e absence o0 an attri,!te-target-specifier- t+e attribute applies to t+e operator. T+e
presence o0 t+e met"od attri,!te-target-specifier indicates t+at t+e attribute applies to t+e operatorQ t+e
presence o0 t+e return attri,!te-target-specifier indicates t+at t+e attribute applies to t+e return value.
(n attribute speci0ied on an event declaration t+at omits event accessors can apply to t+e event being
declared- to t+e associated 0ield Ji0 t+e event is not abstractM- or to t+e associated add and remove met+ods.
1n t+e absence o0 an attri,!te-target-specifier- t+e attribute applies to t+e event. T+e presence o0 t+e event
attri,!te-target-specifier indicates t+at t+e attribute applies to t+e eventQ t+e presence o0 t+e -ield
attri,!te-target-specifier indicates t+at t+e attribute applies to t+e 0ieldQ and t+e presence o0 t+e met"od
attri,!te-target-specifier indicates t+at t+e attribute applies to t+e met+ods.
(n attribute speci0ied on a get accessor declaration 0or a property or indeer declaration can apply eit+er to
t+e associated met+od or to its return value. 1n t+e absence o0 an attri,!te-target-specifier- t+e attribute
applies to t+e met+od. T+e presence o0 t+e met"od attri,!te-target-specifier indicates t+at t+e attribute
applies to t+e met+odQ t+e presence o0 t+e return attri,!te-target-specifier indicates t+at t+e attribute
applies to t+e return value.
(n attribute speci0ied on a set accessor 0or a property or indeer declaration can apply eit+er to t+e
associated met+od or to its lone implicit parameter. 1n t+e absence o0 an attri,!te-target-specifier- t+e
attribute applies to t+e met+od. T+e presence o0 t+e met"od attri,!te-target-specifier indicates t+at t+e
attribute applies to t+e met+odQ t+e presence o0 t+e &aram attri,!te-target-specifier indicates t+at t+e
attribute applies to t+e parameterQ t+e presence o0 t+e return attri,!te-target-specifier indicates t+at t+e
attribute applies to t+e return value.
(n attribute speci0ied on an add or remove accessor declaration 0or an event declaration can apply eit+er to
t+e associated met+od or to its lone parameter. 1n t+e absence o0 an attri,!te-target-specifier- t+e attribute
applies to t+e met+od. T+e presence o0 t+e met"od attri,!te-target-specifier indicates t+at t+e attribute
applies to t+e met+odQ t+e presence o0 t+e &aram attri,!te-target-specifier indicates t+at t+e attribute applies
to t+e parameterQ t+e presence o0 t+e return attri,!te-target-specifier indicates t+at t+e attribute applies to
t+e return value.
1n ot+er contets- inclusion o0 an attri,!te-target-specifier is permitted but unnecessary. *or instance- a class
declaration may eit+er include or omit t+e speci0ier ty&eC
4ty&e/ 'ut"or(":rian aernig"an")5
class Class2 {!
4'ut"or("6ennis Oitc"ie")5
class Class8 {!
1t is an error to speci0y an invalid attri,!te-target-specifier. *or instance- t+e speci0ier &aram cannot be used on
a class declarationC
4&aram/ 'ut"or(":rian aernig"an")5 .. )rror
class Class2 {!
"2' Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
)y convention- attribute classes are named wit+ a su00i o0 'ttribute. (n attri,!te-na%e o0 t+e 0orm t+pe-
na%e may eit+er include or omit t+is su00i. 10 an attribute class is 0ound bot+ wit+ and wit+out t+is su00i- an
ambiguity is present- and a compile<time error results. 10 t+e attri,!te-na%e is spelled suc+ t+at its rig+t<most
identifier is a verbatim identi0ier JV2.4.2M- t+en only an attribute wit+out a su00i is matc+ed- t+us enabling suc+
an ambiguity to be resolved. T+e eample
using System;
4'ttribute;sage('ttribute1argets.'ll)5
&ublic class I/ 'ttribute
{!
4'ttribute;sage('ttribute1argets.'ll)5
&ublic class I'ttribute/ 'ttribute
{!
4I5 .. )rror/ ambiguity
class Class2 {!
4I'ttribute5 .. Oe-ers to I'ttribute
class Class8 {!
4\I5 .. Oe-ers to I
class Class9 {!
4\I'ttribute5 .. Oe-ers to I'ttribute
class ClassJ {!
s+ows two attribute classes named I and I'ttribute. T+e attribute 4I5 is ambiguous- since it could re0er to
eit+er I or I'ttribute. 8sing a verbatim identi0ier allows t+e eact intent to be speci0ied in suc+ rare cases.
T+e attribute 4I'ttribute5 is not ambiguous Jalt+oug+ it would be i0 t+ere was an attribute class named
I'ttribute'ttributeAM. 10 t+e declaration 0or class I is removed- t+en bot+ attributes re0er to t+e attribute
class named I'ttribute- as 0ollowsC
using System;
4'ttribute;sage('ttribute1argets.'ll)5
&ublic class I'ttribute/ 'ttribute
{!
4I5 .. Oe-ers to I'ttribute
class Class2 {!
4I'ttribute5 .. Oe-ers to I'ttribute
class Class8 {!
4\I5 .. )rror/ no attribute named "I"
class Class9 {!
1t is a compile<time error to use a single<use attribute class more t+an once on t+e same entity. T+e eample
using System;
4'ttribute;sage('ttribute1argets.Class)5
&ublic class Hel&String'ttribute/ 'ttribute
{
string value;
&ublic Hel&String'ttribute(string value) {
t"is.value + value;
!
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. "27
C# Language Specification
&ublic string Ualue {
get {...!
!
!
4Hel&String("6escri&tion o- Class2")5
4Hel&String("'not"er descri&tion o- Class2")5
&ublic class Class2 {!
results in a compile<time error because it attempts to use Hel&String- w+ic+ is a single<use attribute class-
more t+an once on t+e declaration o0 Class2.
(n epression ) is an attri,!te-arg!%ent-e/pression i0 all o0 t+e 0ollowing statements are trueC
T+e type o0 ) is an attribute parameter type JV1!.1.3M.
(t compile<time- t+e value o0 ) can be resolved to one o0 t+e 0ollowingC
o ( constant value.
o ( System.1y&e ob&ect.
o ( one<dimensional array o0 attri,!te-arg!%ent-e/pressions.
*or eampleC
using System;
4'ttribute;sage('ttribute1argets.Class)5
&ublic class 1est'ttribute/ 'ttribute
{
&ublic int *2 {
get {...!
set {...!
!
&ublic 1y&e *8 {
get {...!
set {...!
!
&ublic object *9 {
get {...!
set {...!
!
!
41est(*2 + 289J *9 + ne, int45 {2 9 K! *8 + ty&eo-(-loat))5
class MyClass {!
( t+peof-e/pression JV!.".11M used as an attribute argument epression can re0erence a non<generic type- a
closed constructed type- or an unbound generic type- but it cannot re0erence an open type. T+is is to ensure t+at
t+e epression can be resolved at compile time.
class '/ 'ttribute
{
&ublic '(1y&e t) {...!
!
class SD1E
{
4'(ty&eo-(1))5 1 t; .. )rror o&en ty&e in attribute
!
"2$ Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
class I
{
4'(ty&eo-(ListDintE))5 int #; .. %( closed constructed ty&e
4'(ty&eo-(ListDE))5 int y; .. %( unbound generic ty&e
!
1..3 *ttribute instances
(n attri!-te instance is an instance t+at represents an attribute at run<time. (n attribute is de0ined wit+ an
attribute class- positional arguments- and named arguments. (n attribute instance is an instance o0 t+e attribute
class t+at is initialiDed wit+ t+e positional and named arguments.
;etrieval o0 an attribute instance involves bot+ compile<time and run<time processing- as described in t+e
0ollowing sections.
1..3.1 Copilation of an attribute
T+e compilation o0 an attri,!te wit+ attribute class 1- positional-arg!%ent-list * and na%ed-arg!%ent-list N-
consists o0 t+e 0ollowing stepsC
*ollow t+e compile<time processing steps 0or compiling an o,<ect-creation-e/pression o0 t+e 0orm ne,
1(*). T+ese steps eit+er result in a compile<time error- or determine an instance constructor C on 1 t+at can
be invo7ed at run<time.
10 C does not +ave public accessibility- t+en a compile<time error occurs.
*or eac+ na%ed-arg!%ent 'rg in NC
o 5et Name be t+e identifier o0 t+e na%ed-arg!%ent 'rg.
o Name must identi0y a non<static read<write public 0ield or property on 1. 10 1 +as no suc+ 0ield or
property- t+en a compile<time error occurs.
:eep t+e 0ollowing in0ormation 0or run<time instantiation o0 t+e attributeC t+e attribute class 1- t+e instance
constructor C on 1- t+e positional-arg!%ent-list * and t+e na%ed-arg!%ent-list N.
1..3.2 :un9tie retrie"al of an attribute instance
Compilation o0 an attri,!te yields an attribute class 1- an instance constructor C on 1- a positional-arg!%ent-list
*- and a na%ed-arg!%ent-list N. 4iven t+is in0ormation- an attribute instance can be retrieved at run<time using
t+e 0ollowing stepsC
*ollow t+e run<time processing steps 0or eecuting an o,<ect-creation-e/pression o0 t+e 0orm ne, 1(*)-
using t+e instance constructor C as determined at compile<time. T+ese steps eit+er result in an eception- or
produce an instance % o0 1.
*or eac+ na%ed-arg!%ent 'rg in N- in orderC
o 5et Name be t+e identifier o0 t+e na%ed-arg!%ent 'rg. 10 Name does not identi0y a non<static public
read<write 0ield or property on %- t+en an eception is t+rown.
o 5et Ualue be t+e result o0 evaluating t+e attri,!te-arg!%ent-e/pression o0 'rg.
o 10 Name identi0ies a 0ield on %- t+en set t+is 0ield to Ualue.
o /t+erwise- Name identi0ies a property on %. #et t+is property to Ualue.
o T+e result is %- an instance o0 t+e attribute class 1 t+at +as been initialiDed wit+ t+e positional-
arg!%ent-list * and t+e na%ed-arg!%ent-list N.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. "2!
C# Language Specification
1..# :eser"ed attributes
( small number o0 attributes a00ect t+e language in some way. T+ese attributes includeC
System.'ttribute;sage'ttribute JV1!.4.1M- w+ic+ is used to describe t+e ways in w+ic+ an attribute
class can be used.
System.6iagnostics.Conditional'ttribute JV1!.4.2M- w+ic+ is used to de0ine conditional
met+ods.
System.%bsolete'ttribute JV1!.4.3M- w+ic+ is used to mar7 a member as obsolete.
1..#.1 T-e *ttribute6sage attribute
T+e attribute 'ttribute;sage is used to describe t+e manner in w+ic+ t+e attribute class can be used.
( class t+at is decorated wit+ t+e 'ttribute;sage attribute must derive 0rom System.'ttribute- eit+er
directly or indirectly. /t+erwise- a compile<time error occurs.
names&ace System
{
4'ttribute;sage('ttribute1argets.Class)5
&ublic class 'ttribute;sage'ttribute/ 'ttribute
{
&ublic 'ttribute;sage'ttribute('ttribute1argets valid%n) {...!
&ublic virtual bool 'llo,Multi&le { get {...! set {...! !
&ublic virtual bool $n"erited { get {...! set {...! !
&ublic virtual 'ttribute1argets Ualid%n { get {...! !
!
&ublic enum 'ttribute1argets
{
'ssembly + 3#3332
Module + 3#3338
Class + 3#333J
Struct + 3#333Y
)num + 3#3323
Constructor + 3#3383
Met"od + 3#33J3
*ro&erty + 3#33Y3
Vield + 3#3233
)vent + 3#3833
$nter-ace + 3#3J33
*arameter + 3#3Y33
6elegate + 3#2333
OeturnUalue + 3#8333
'll + 'ssembly H Module H Class H Struct H )num H Constructor H
Met"od H *ro&erty H Vield H )vent H $nter-ace H *arameter H
6elegate H OeturnUalue
!
!
1..#.2 T-e Conditional attribute
T+e attribute Conditional enables t+e de0inition o0 conditional ethods and conditional attri!-te classes.
"3* Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
names&ace System.6iagnostics
{
4'ttribute;sage('ttribute1argets.Met"od H 'ttribute1argets.Class
'llo,Multi&le + true)5
&ublic class Conditional'ttribute/ 'ttribute
{
&ublic Conditional'ttribute(string conditionString) {...!
&ublic string ConditionString { get {...! !
!
!
1.4.2.1 !onditional methods
( met+od decorated wit+ t+e Conditional attribute is a conditional met+od. T+e Conditional attribute
indicates a condition by testing a conditional compilation symbol. Calls to a conditional met+od are eit+er
included or omitted depending on w+et+er t+is symbol is de0ined at t+e point o0 t+e call. 10 t+e symbol is
de0ined- t+e call is includedQ ot+erwise- t+e call Jincluding evaluation o0 t+e parameters o0 t+e callM is omitted.
( conditional met+od is sub&ect to t+e 0ollowing restrictionsC
T+e conditional met+od must be a met+od in a class-declaration or str!ct-declaration. ( compile<time error
occurs i0 t+e Conditional attribute is speci0ied on a met+od in an inter0ace declaration.
T+e conditional met+od must +ave a return type o0 void.
T+e conditional met+od must not be mar7ed wit+ t+e override modi0ier. ( conditional met+od may be
mar7ed wit+ t+e virtual modi0ier- +owever. /verrides o0 suc+ a met+od are implicitly conditional- and
must not be eplicitly mar7ed wit+ a Conditional attribute.
T+e conditional met+od must not be an implementation o0 an inter0ace met+od. /t+erwise- a compile<time
error occurs.
1n addition- a compile<time error occurs i0 a conditional met+od is used in a delegate-creation-e/pression. T+e
eample
0de-ine 6):;S
using System;
using System.6iagnostics;
class Class2
{
4Conditional("6):;S")5
&ublic static void M() {
Console.WriteLine(")#ecuted Class2.M");
!
!
class Class8
{
&ublic static void 1est() {
Class2.M();
!
!
declares Class2.M as a conditional met+od. Class8Ys 1est met+od calls t+is met+od. #ince t+e conditional
compilation symbol 6):;S is de0ined- i0 Class8.1est is called- it will call M. 10 t+e symbol 6):;S +ad not
been de0ined- t+en Class8.1est would not call Class2.M.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. "31
C# Language Specification
1t is important to note t+at t+e inclusion or eclusion o0 a call to a conditional met+od is controlled by t+e
conditional compilation symbols at t+e point o0 t+e call. 1n t+e eample
*ile class2.csC
using System.6iagnostics;
class Class2
{
4Conditional("6):;S")5
&ublic static void V() {
Console.WriteLine(")#ecuted Class2.V");
!
!
*ile class8.csC
0de-ine 6):;S
class Class8
{
&ublic static void S() {
Class2.V(); .. V is called
!
!
*ile class9.csC
0unde- 6):;S
class Class9
{
&ublic static void H() {
Class2.V(); .. V is not called
!
!
t+e classes Class8 and Class9 eac+ contain calls to t+e conditional met+od Class2.V- w+ic+ is conditional
based on w+et+er or not 6):;S is de0ined. #ince t+is symbol is de0ined in t+e contet o0 Class8 but not
Class9- t+e call to V in Class8 is included- w+ile t+e call to V in Class9 is omitted.
T+e use o0 conditional met+ods in an in+eritance c+ain can be con0using. Calls made to a conditional met+od
t+roug+ base- o0 t+e 0orm base.M- are sub&ect to t+e normal conditional met+od call rules. 1n t+e eample
*ile class2.csC
using System;
using System.6iagnostics;
class Class2
{
4Conditional("6):;S")5
&ublic virtual void M() {
Console.WriteLine("Class2.M e#ecuted");
!
!
*ile class8.csC
using System;
"32 Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
class Class8/ Class2
{
&ublic override void M() {
Console.WriteLine("Class8.M e#ecuted");
base.M(); .. base.M is not called@
!
!
*ile class9.csC
0de-ine 6):;S
using System;
class Class9
{
&ublic static void 1est() {
Class8 c + ne, Class8();
c.M(); .. M is called
!
!
Class8 includes a call to t+e M de0ined in its base class. T+is call is omitted because t+e base met+od is
conditional based on t+e presence o0 t+e symbol 6):;S- w+ic+ is unde0ined. T+us- t+e met+od writes to t+e
console KClass8.M e#ecutedL only. Fudicious use o0 pp-declarations can eliminate suc+ problems.
1.4.2.2 !onditional attribute classes
(n attribute class JV1!.1M decorated wit+ one or more Conditional attributes is a conditional attri!-te class.
( conditional attribute class is t+us associated wit+ t+e conditional compilation symbols declared in its
Conditional attributes. T+is eampleC
using System;
using System.6iagnostics;
4Conditional("'L*H'")5
4Conditional(":)1'")5
&ublic class 1est'ttribute / 'ttribute {!
declares 1est'ttribute as a conditional attribute class associated wit+ t+e conditional compilations symbols
'L*H' and :)1'.
(ttribute speci0ications JV1!.2M o0 a conditional attribute are included i0 one or more o0 its associated conditional
compilation symbols is de0ined at t+e point o0 speci0ication- ot+erwise t+e attribute speci0ication is omitted.
1t is important to note t+at t+e inclusion or eclusion o0 an attribute speci0ication o0 a conditional attribute class
is controlled by t+e conditional compilation symbols at t+e point o0 t+e speci0ication. 1n t+e eample
*ile test.csC
using System;
using System.6iagnostics;
4Conditional(R6):;ST)5
&ublic class 1est'ttribute / 'ttribute {!
*ile class2.csC
0de-ine 6):;S
41est5 .. 1est'ttribute is s&eci-ied
class Class2 {!
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. "33
C# Language Specification
*ile class8.csC
0unde- 6):;S
41est5 .. 1est'ttribute is not s&eci-ied
class Class8 {!
t+e classes Class2 and Class8 are eac+ decorated wit+ attribute 1est- w+ic+ is conditional based on w+et+er
or not 6):;S is de0ined. #ince t+is symbol is de0ined in t+e contet o0 Class2 but not Class8- t+e
speci0ication o0 t+e 1est attribute on Class2 is included- w+ile t+e speci0ication o0 t+e 1est attribute on
Class8 is omitted.
1..#.3 T-e /bsolete attribute
T+e attribute %bsolete is used to mar7 types and members o0 types t+at s+ould no longer be used.
names&ace System
{
4'ttribute;sage(
'ttribute1argets.Class H
'ttribute1argets.Struct H
'ttribute1argets.)num H
'ttribute1argets.$nter-ace H
'ttribute1argets.6elegate H
'ttribute1argets.Met"od H
'ttribute1argets.Constructor H
'ttribute1argets.*ro&erty H
'ttribute1argets.Vield H
'ttribute1argets.)vent
$n"erited + -alse)
5
&ublic class %bsolete'ttribute/ 'ttribute
{
&ublic %bsolete'ttribute() {...!
&ublic %bsolete'ttribute(string message) {...!
&ublic %bsolete'ttribute(string message bool error) {...!
&ublic string Message { get {...! !
&ublic bool $s)rror { get {...! !
!
!
10 a program uses a type or member t+at is decorated wit+ t+e %bsolete attribute- t+e compiler issues a warning
or an error. #peci0ically- t+e compiler issues a warning i0 no error parameter is provided- or i0 t+e error
parameter is provided and +as t+e value -alse. T+e compiler issues an error i0 t+e error parameter is speci0ied
and +as t+e value true.
1n t+e eample
4%bsolete("1"is class is obsolete; use class : instead")5
class '
{
&ublic void V() {!
!
"3" Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
class :
{
&ublic void V() {!
!
class 1est
{
static void Main() {
' a + ne, '(); .. Warning
a.V();
!
!
t+e class ' is decorated wit+ t+e %bsolete attribute. Eac+ use o0 ' in Main results in a warning t+at includes
t+e speci0ied message- KT+is class is obsoleteQ use class ) instead.L
1..& *ttributes for Interoperation
3ote. 9his section is applica,le onl+ to the Microsoft .3@9 i%ple%entation of C#.
1..&.1 Interoperation wit- C/) and 4in32 coponents
T+e .=ET runtime provides a large number o0 attributes t+at enable C# programs to interoperate wit+
components written using C/' and 6in32 255s. *or eample- t+e 6ll$m&ort attribute can be used on a
static e#tern met+od to indicate t+at t+e implementation o0 t+e met+od is to be 0ound in a 6in32 255.
T+ese attributes are 0ound in t+e System.Ountime.$ntero&Services namespace- and detailed
documentation 0or t+ese attributes is 0ound in t+e .=ET runtime documentation.
1..&.2 Interoperation wit- ot-er .;$T languages
1.5.2.1 *he #nde$erBame attribute
1ndeers are implemented in .=ET using indeed properties- and +ave a name in t+e .=ET metadata. 10 no
$nde#erName attribute is present 0or an indeer- t+en t+e name $tem is used by de0ault. T+e $nde#erName
attribute enables a developer to override t+is de0ault and speci0y a di00erent name.
names&ace System.Ountime.Com&ilerServices.CS"ar&
{
4'ttribute;sage('ttribute1argets.*ro&erty)5
&ublic class $nde#erName'ttribute/ 'ttribute
{
&ublic $nde#erName'ttribute(string inde#erName) {...!
&ublic string Ualue { get {...! !
!
!
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. "3
C0apter 1 Introduction
10. 6nsafe code
T+e core C# language- as de0ined in t+e preceding c+apters- di00ers notably 0rom C and CNN in its omission o0
pointers as a data type. 1nstead- C# provides re0erences and t+e ability to create ob&ects t+at are managed by a
garbage collector. T+is design- coupled wit+ ot+er 0eatures- ma7es C# a muc+ sa0er language t+an C or CNN. 1n
t+e core C# language it is simply not possible to +ave an uninitialiDed variable- a KdanglingL pointer- or an
epression t+at indees an array beyond its bounds. 6+ole categories o0 bugs t+at routinely plague C and CNN
programs are t+us eliminated.
6+ile practically every pointer type construct in C or CNN +as a re0erence type counterpart in C#- nonet+eless-
t+ere are situations w+ere access to pointer types becomes a necessity. *or eample- inter0acing wit+ t+e
underlying operating system- accessing a memory<mapped device- or implementing a time<critical algorit+m
may not be possible or practical wit+out access to pointers. To address t+is need- C# provides t+e ability to write
-nsafe code.
1n unsa0e code it is possible to declare and operate on pointers- to per0orm conversions between pointers and
integral types- to ta7e t+e address o0 variables- and so 0ort+. 1n a sense- writing unsa0e code is muc+ li7e writing
C code wit+in a C# program.
8nsa0e code is in 0act a Ksa0eL 0eature 0rom t+e perspective o0 bot+ developers and users. 8nsa0e code must be
clearly mar7ed wit+ t+e modi0ier unsa-e- so developers canPt possibly use unsa0e 0eatures accidentally- and t+e
eecution engine wor7s to ensure t+at unsa0e code cannot be eecuted in an untrusted environment.
10.1 6nsafe conte%ts
T+e unsa0e 0eatures o0 C# are available only in !nsafe conte/ts. (n unsa0e contet is introduced by including an
unsa-e modi0ier in t+e declaration o0 a type or member- or by employing an !nsafe-state%entC
( declaration o0 a class- struct- inter0ace- or delegate may include an unsa-e modi0ier- in w+ic+ case t+e
entire tetual etent o0 t+at type declaration Jincluding t+e body o0 t+e class- struct- or inter0aceM is
considered an unsa0e contet.
( declaration o0 a 0ield- met+od- property- event- indeer- operator- instance constructor- destructor- or static
constructor may include an unsa-e modi0ier- in w+ic+ case t+e entire tetual etent o0 t+at member
declaration is considered an unsa0e contet.
(n !nsafe-state%ent enables t+e use o0 an unsa0e contet wit+in a ,loc&. T+e entire tetual etent o0 t+e
associated ,loc& is considered an unsa0e contet.
T+e associated grammar etensions are s+own below. *or brevity- ellipses J...M are used to represent productions
t+at appear in preceding c+apters.
class-%odifier.
...
u*#!fe
str!ct-%odifier.
...
u*#!fe
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. "37
C# Language Specification
interface-%odifier.
...
u*#!fe
delegate-%odifier.
...
u*#!fe
field-%odifier.
...
u*#!fe
%ethod-%odifier.
...
u*#!fe
propert+-%odifier.
...
u*#!fe
event-%odifier.
...
u*#!fe
inde/er-%odifier.
...
u*#!fe
operator-%odifier.
...
u*#!fe
constr!ctor-%odifier.
...
u*#!fe
destr!ctor-declaration.
attri,!tesopt e-$e%*opt u*#!feopt G identifier ( ) destr!ctor-,od+
attri,!tesopt u*#!feopt e-$e%*opt G identifier ( ) destr!ctor-,od+
static-constr!ctor-%odifiers.
e-$e%*opt u*#!feopt #$!$i&
u*#!feopt e-$e%*opt #$!$i&
e-$e%*opt #$!$i& u*#!feopt
u*#!feopt #$!$i& e-$e%*opt
#$!$i& e-$e%*opt u*#!feopt
#$!$i& u*#!feopt e-$e%*opt
e%,edded-state%ent.
...
!nsafe-state%ent
!nsafe-state%ent.
u*#!fe ,loc&
1n t+e eample
"3$ Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
&ublic unsa-e struct Node
{
&ublic int Ualue;
&ublic Node> Le-t;
&ublic Node> Oig"t;
!
t+e unsa-e modi0ier speci0ied in t+e struct declaration causes t+e entire tetual etent o0 t+e struct declaration
to become an unsa0e contet. T+us- it is possible to declare t+e Le-t and Oig"t 0ields to be o0 a pointer type.
T+e eample above could also be written
&ublic struct Node
{
&ublic int Ualue;
&ublic unsa-e Node> Le-t;
&ublic unsa-e Node> Oig"t;
!
Here- t+e unsa-e modi0iers in t+e 0ield declarations cause t+ose declarations to be considered unsa0e contets.
/t+er t+an establis+ing an unsa0e contet- t+us permitting t+e use o0 pointer types- t+e unsa-e modi0ier +as no
e00ect on a type or a member. 1n t+e eample
&ublic class '
{
&ublic unsa-e virtual void V() {
c"ar> &;
...
!
!
&ublic class :/ '
{
&ublic override void V() {
base.V();
...
!
!
t+e unsa-e modi0ier on t+e V met+od in ' simply causes t+e tetual etent o0 V to become an unsa0e contet in
w+ic+ t+e unsa0e 0eatures o0 t+e language can be used. 1n t+e override o0 V in :- t+ere is no need to re<speci0y
t+e unsa-e modi0ierRunless- o0 course- t+e V met+od in : itsel0 needs access to unsa0e 0eatures.
T+e situation is slig+tly di00erent w+en a pointer type is part o0 t+e met+odPs signature
&ublic unsa-e class '
{
&ublic virtual void V(c"ar> &) {...!
!
&ublic class :/ '
{
&ublic unsa-e override void V(c"ar> &) {...!
!
Here- because VPs signature includes a pointer type- it can only be written in an unsa0e contet. However- t+e
unsa0e contet can be introduced by eit+er ma7ing t+e entire class unsa0e- as is t+e case in '- or by including an
unsa-e modi0ier in t+e met+od declaration- as is t+e case in :.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. "3!
C# Language Specification
10.2 Pointer t!pes
1n an unsa0e contet- a t+pe JV4M may be a pointer-t+pe as well as a val!e-t+pe or a reference-t+pe. However- a
pointer-t+pe may also be used in a ty&eo- epression JV!.".1..%M outside o0 an unsa0e contet as suc+ usage is
not unsa0e.
t+pe.
...
pointer-t+pe
( pointer-t+pe is written as an !n%anaged-t+pe or t+e 7eyword void- 0ollowed by a > to7enC
pointer-t+pe.
!n%anaged-t+pe *
,'id *
!n%anaged-t+pe.
t+pe
T+e type speci0ied be0ore t+e > in a pointer type is called t+e referent type o0 t+e pointer type. 1t represents t+e
type o0 t+e variable to w+ic+ a value o0 t+e pointer type points.
8nli7e re0erences Jvalues o0 re0erence typesM- pointers are not trac7ed by t+e garbage collectorRt+e garbage
collector +as no 7nowledge o0 pointers and t+e data to w+ic+ t+ey point. *or t+is reason a pointer is not
permitted to point to a re0erence or to a struct t+at contains re0erences- and t+e re0erent type o0 a pointer must be
an !n%anaged-t+pe.
(n !n%anaged-t+pe is any type t+at isnPt a reference-t+pe and doesnPt contain reference-t+pe 0ields at any level
o0 nesting. 1n ot+er words- an !n%anaged-t+pe is one o0 t+e 0ollowingC
sbyte- byte- s"ort- us"ort- int- uint- long- ulong- c"ar- -loat- double- decimal- or bool.
(ny en!%-t+pe.
(ny pointer-t+pe.
(ny user<de0ined str!ct-t+pe t+at contains 0ields o0 !n%anaged-t+pes only.
T+e intuitive rule 0or miing o0 pointers and re0erences is t+at re0erents o0 re0erences Job&ectsM are permitted to
contain pointers- but re0erents o0 pointers are not permitted to contain re0erences.
#ome eamples o0 pointer types are given in t+e table belowC
(xa)ple ,escription
byte>
Pointer to byte
c"ar>
Pointer to c"ar
int>>
Pointer to pointer to int
int>45
#ingle<dimensional array o0 pointers to int
void>
Pointer to un7nown type
*or a given implementation- all pointer types must +ave t+e same siDe and representation.
8nli7e C and CNN- w+en multiple pointers are declared in t+e same declaration- in C# t+e > is written along
wit+ t+e underlying type only- not as a pre0i punctuator on eac+ pointer name. *or eample
""* Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
int> &i &j; .. N%1 as int >&i >&j;
T+e value o0 a pointer +aving type 1> represents t+e address o0 a variable o0 type 1. T+e pointer indirection
operator > JV13.".1M may be used to access t+is variable. *or eample- given
a variable * o0 type int>- t+e epression >* denotes t+e int variable 0ound at t+e address contained in *.
5i7e an ob&ect re0erence- a pointer may be null. (pplying t+e indirection operator to a null pointer results in
implementation<de0ined be+avior. ( pointer wit+ value null is represented by all<bits<Dero.
T+e void> type represents a pointer to an un7nown type. )ecause t+e re0erent type is un7nown- t+e indirection
operator cannot be applied to a pointer o0 type void>- nor can any arit+metic be per0ormed on suc+ a pointer.
However- a pointer o0 type void> can be cast to any ot+er pointer type Jand vice versaM.
Pointer types are a separate category o0 types. 8nli7e re0erence types and value types- pointer types do not
in+erit 0rom object and no conversions eist between pointer types and object. 1n particular- boing and
unboing JV4.3M are not supported 0or pointers. However- conversions are permitted between di00erent pointer
types and between pointer types and t+e integral types. T+is is described in V13.4.
( pointer-t+pe may be used as t+e type o0 a volatile 0ield JV1..".3M.
(lt+oug+ pointers can be passed as re- or out parameters- doing so can cause unde0ined be+avior- since t+e
pointer may well be set to point to a local variable w+ic+ no longer eists w+en t+e called met+od returns- or t+e
0ied ob&ect to w+ic+ it used to point- is no longer 0ied. *or eampleC
using System;
class 1est
{
static int value + 83;
unsa-e static void V(out int> &i2 re- int> &i8) {
int i + 23;
&i2 + Fi;
-i#ed (int> &j + Fvalue) {
.. ...
&i8 + &j;
!
!
static void Main() {
int i + 23;
unsa-e {
int> &#2;
int> &#8 + Fi;
V(out &#2 re- &#8);
Console.WriteLine(">&#2 + {3! >&#8 + {2!"
>&#2 >&#8); .. unde-ined be"avior
!
!
!
( met+od can return a value o0 some type- and t+at type can be a pointer. *or eample- w+en given a pointer to
a contiguous se9uence o0 ints- t+at se9uencePs element count- and some ot+er int value- t+e 0ollowing met+od
returns t+e address o0 t+at value in t+at se9uence- i0 a matc+ occursQ ot+erwise it returns nullC
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. ""1
C# Language Specification
unsa-e static int> Vind(int> &i int si?e int value) {
-or (int i + 3; i D si?e; <<i) {
i- (>&i ++ value)
return &i;
<<&i;
!
return null;
!
1n an unsa0e contet- several constructs are available 0or operating on pointersC
T+e > operator may be used to per0orm pointer indirection JV13.".1M.
T+e =E operator may be used to access a member o0 a struct t+roug+ a pointer JV13.".2M.
T+e 45 operator may be used to inde a pointer JV13.".3M.
T+e F operator may be used to obtain t+e address o0 a variable JV13.".4M.
T+e << and == operators may be used to increment and decrement pointers JV13."."M.
T+e < and = operators may be used to per0orm pointer arit+metic JV13.".%M.
T+e ++- @+- D- E- D+- and +E operators may be used to compare pointers JV13.".!M.
T+e stac(alloc operator may be used to allocate memory 0rom t+e call stac7 JV13.!M.
T+e -i#ed statement may be used to temporarily 0i a variable so its address can be obtained JV13.%M.
10.3 ,i%ed and o"eable "ariables
T+e address<o0 operator JV13.".4M and t+e -i#ed statement JV13.%M divide variables into two categoriesC 9i,ed
varia!les and ovea!le varia!les.
*ied variables reside in storage locations t+at are una00ected by operation o0 t+e garbage collector. JEamples
o0 0ied variables include local variables- value parameters- and variables created by dere0erencing pointers.M /n
t+e ot+er +and- moveable variables reside in storage locations t+at are sub&ect to relocation or disposal by t+e
garbage collector. JEamples o0 moveable variables include 0ields in ob&ects and elements o0 arrays.M
T+e F operator JV13.".4M permits t+e address o0 a 0ied variable to be obtained wit+out restrictions. However-
because a moveable variable is sub&ect to relocation or disposal by t+e garbage collector- t+e address o0 a
moveable variable can only be obtained using a -i#ed statement JV13.%M- and t+at address remains valid only
0or t+e duration o0 t+at -i#ed statement.
1n precise terms- a 0ied variable is one o0 t+e 0ollowingC
( variable resulting 0rom a si%ple-na%e JV!.".2M t+at re0ers to a local variable or a value parameter- unless
t+e variable is captured by an anonymous 0unction.
( variable resulting 0rom a %e%,er-access JV!.".4M o0 t+e 0orm U.$- w+ere U is a 0ied variable o0 a str!ct-
t+pe.
( variable resulting 0rom a pointer-indirection-e/pression JV13.".1M o0 t+e 0orm >*- a pointer-%e%,er-
access JV13.".2M o0 t+e 0orm *=E$- or a pointer-ele%ent-access JV13.".3M o0 t+e 0orm *4)5.
(ll ot+er variables are classi0ied as moveable variables.
=ote t+at a static 0ield is classi0ied as a moveable variable. (lso note t+at a re- or out parameter is classi0ied as
a moveable variable- even i0 t+e argument given 0or t+e parameter is a 0ied variable. *inally- note t+at a
variable produced by dere0erencing a pointer is always classi0ied as a 0ied variable.
""2 Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
10.# Pointer con"ersions
1n an unsa0e contet- t+e set o0 available implicit conversions JV%.1M is etended to include t+e 0ollowing implicit
pointer conversionsC
*rom any pointer-t+pe to t+e type void>.
*rom t+e null literal to any pointer-t+pe.
(dditionally- in an unsa0e contet- t+e set o0 available eplicit conversions JV%.2M is etended to include t+e
0ollowing eplicit pointer conversionsC
*rom any pointer-t+pe to any ot+er pointer-t+pe.
*rom sbyte- byte- s"ort- us"ort- int- uint- long- or ulong to any pointer-t+pe.
*rom any pointer-t+pe to sbyte- byte- s"ort- us"ort- int- uint- long- or ulong.
*inally- in an unsa0e contet- t+e set o0 standard implicit conversions JV%.3.1M includes t+e 0ollowing pointer
conversionC
*rom any pointer-t+pe to t+e type void>.
Conversions between two pointer types never c+ange t+e actual pointer value. 1n ot+er words- a conversion 0rom
one pointer type to anot+er +as no e00ect on t+e underlying address given by t+e pointer.
6+en one pointer type is converted to anot+er- i0 t+e resulting pointer is not correctly aligned 0or t+e pointed<to
type- t+e be+avior is unde0ined i0 t+e result is dere0erenced. 1n general- t+e concept Kcorrectly alignedL is
transitiveC i0 a pointer to type ' is correctly aligned 0or a pointer to type :- w+ic+- in turn- is correctly aligned 0or
a pointer to type C- t+en a pointer to type ' is correctly aligned 0or a pointer to type C.
Consider t+e 0ollowing case in w+ic+ a variable +aving one type is accessed via a pointer to a di00erent typeC
c"ar c + W'W;
c"ar> &c + Fc;
void> &v + &c;
int> &i + (int>)&v;
int i + >&i; .. unde-ined
>&i + 289JKX; .. unde-ined
6+en a pointer type is converted to a pointer to byte- t+e result points to t+e lowest addressed byte o0 t+e
variable. #uccessive increments o0 t+e result- up to t+e siDe o0 t+e variable- yield pointers to t+e remaining bytes
o0 t+at variable. *or eample- t+e 0ollowing met+od displays eac+ o0 t+e eig+t bytes in a double as a
+eadecimal valueC
using System;
class 1est
{
unsa-e static void Main() {
double d + 289.JKXe89;
unsa-e {
byte> &b + (byte>)Fd;
-or (int i + 3; i D si?eo-(double); <<i)
Console.Write("{3/I8! " >&b<<);
Console.WriteLine();
!
!
!
/0 course- t+e output produced depends on endianness.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. ""3
C# Language Specification
'appings between pointers and integers are implementation<de0ined. However- on 32< and %4<bit CP8
arc+itectures wit+ a linear address space- conversions o0 pointers to or 0rom integral types typically be+ave
eactly li7e conversions o0 uint or ulong values- respectively- to or 0rom t+ose integral types.
10.& Pointers in e%pressions
1n an unsa0e contet- an epression may yield a result o0 a pointer type- but outside an unsa0e contet it is a
compile<time error 0or an epression to be o0 a pointer type. 1n precise terms- outside an unsa0e contet a
compile<time error occurs i0 any si%ple-na%e JV!.".2M- %e%,er-access JV!.".4M- invocation-e/pression JV!."."M-
or ele%ent-access JV!.".%M is o0 a pointer type.
1n an unsa0e contet- t+e pri%ar+-no-arra+-creation-e/pression JV!."M and !nar+-e/pression JV!.%M productions
permit t+e 0ollowing additional constructsC
pri%ar+-no-arra+-creation-e/pression.
...
pointer-%e%,er-access
pointer-ele%ent-access
si-eof-e/pression
!nar+-e/pression.
...
pointer-indirection-e/pression
addressof-e/pression
T+ese constructs are described in t+e 0ollowing sections. T+e precedence and associativity o0 t+e unsa0e
operators is implied by t+e grammar.
10.&.1 Pointer indirection
( pointer-indirection-e/pression consists o0 an asteris7 J>M 0ollowed by a !nar+-e/pression.
pointer-indirection-e/pression.
* !nar+-e/pression
T+e unary > operator denotes pointer indirection and is used to obtain t+e variable to w+ic+ a pointer points.
T+e result o0 evaluating >*- w+ere * is an epression o0 a pointer type 1>- is a variable o0 type 1. 1t is a compile<
time error to apply t+e unary > operator to an epression o0 type void> or to an epression t+at isnPt o0 a pointer
type.
T+e e00ect o0 applying t+e unary > operator to a null pointer is implementation<de0ined. 1n particular- t+ere is
no guarantee t+at t+is operation t+rows a System.NullOe-erence)#ce&tion.
10 an invalid value +as been assigned to t+e pointer- t+e be+avior o0 t+e unary > operator is unde0ined. (mong
t+e invalid values 0or dere0erencing a pointer by t+e unary > operator are an address inappropriately aligned 0or
t+e type pointed to Jsee eample in V13.4M- and t+e address o0 a variable a0ter t+e end o0 its li0etime.
*or purposes o0 de0inite assignment analysis- a variable produced by evaluating an epression o0 t+e 0orm >* is
considered initially assigned JV".3.1M.
10.&.2 Pointer eber access
( pointer-%e%,er-access consists o0 a pri%ar+-e/pression- 0ollowed by a K=EL to7en- 0ollowed by an identifier.
pointer-%e%,er-access.
pri%ar+-e/pression :J identifier
""" Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
1n a pointer member access o0 t+e 0orm *=E$- * must be an epression o0 a pointer type ot+er t+an void>- and $
must denote an accessible member o0 t+e type to w+ic+ * points.
( pointer member access o0 t+e 0orm *=E$ is evaluated eactly as (>*).$. *or a description o0 t+e pointer
indirection operator J>M- see V13.".1. *or a description o0 t+e member access operator J.M- see V!.".4.
1n t+e eample
using System;
struct *oint
{
&ublic int #;
&ublic int y;
&ublic override string 1oString() {
return "(" < # < "" < y < ")";
!
!
class 1est
{
static void Main() {
*oint &oint;
unsa-e {
*oint> & + F&oint;
&=E# + 23;
&=Ey + 83;
Console.WriteLine(&=E1oString());
!
!
!
t+e =E operator is used to access 0ields and invo7e a met+od o0 a struct t+roug+ a pointer. )ecause t+e operation
*=E$ is precisely e9uivalent to (>*).$- t+e Main met+od could e9ually well +ave been writtenC
class 1est
{
static void Main() {
*oint &oint;
unsa-e {
*oint> & + F&oint;
(>&).# + 23;
(>&).y + 83;
Console.WriteLine((>&).1oString());
!
!
!
10.&.3 Pointer eleent access
( pointer-ele%ent-access consists o0 a pri%ar+-no-arra+-creation-e/pression 0ollowed by an epression
enclosed in K4L and K5L.
pointer-ele%ent-access.
pri%ar+-no-arra+-creation-e/pression = e/pression >
1n a pointer element access o0 t+e 0orm *4)5- * must be an epression o0 a pointer type ot+er t+an void>- and )
must be an epression o0 a type t+at can be implicitly converted to int- uint- long- or ulong.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. ""
C# Language Specification
( pointer element access o0 t+e 0orm *4)5 is evaluated eactly as >(* < )). *or a description o0 t+e pointer
indirection operator J>M- see V13.".1. *or a description o0 t+e pointer addition operator J<M- see V13.".%.
1n t+e eample
class 1est
{
static void Main() {
unsa-e {
c"ar> & + stac(alloc c"ar48KX5;
-or (int i + 3; i D 8KX; i<<) &4i5 + (c"ar)i;
!
!
!
a pointer element access is used to initialiDe t+e c+aracter bu00er in a -or loop. )ecause t+e operation *4)5 is
precisely e9uivalent to >(* < ))- t+e eample could e9ually well +ave been writtenC
class 1est
{
static void Main() {
unsa-e {
c"ar> & + stac(alloc c"ar48KX5;
-or (int i + 3; i D 8KX; i<<) >(& < i) + (c"ar)i;
!
!
!
T+e pointer element access operator does not c+ec7 0or out<o0<bounds errors and t+e be+avior w+en accessing an
out<o0<bounds element is unde0ined. T+is is t+e same as C and CNN.
10.&.# T-e address9of operator
(n addressof-e/pression consists o0 an ampersand JFM 0ollowed by a !nar+-e/pression.
addressof-e/pression.
C !nar+-e/pression
4iven an epression ) w+ic+ is o0 a type 1 and is classi0ied as a 0ied variable JV13.3M- t+e construct F)
computes t+e address o0 t+e variable given by ). T+e type o0 t+e result is 1> and is classi0ied as a value. (
compile<time error occurs i0 ) is not classi0ied as a variable- i0 ) is classi0ied as a read<only local variable- or i0 )
denotes a moveable variable. 1n t+e last case- a 0ied statement JV13.%M can be used to temporarily K0iL t+e
variable be0ore obtaining its address. (s stated in V!.".4- outside an instance constructor or static constructor 0or
a struct or class t+at de0ines a readonly 0ield- t+at 0ield is considered a value- not a variable. (s suc+- its
address cannot be ta7en. #imilarly- t+e address o0 a constant cannot be ta7en.
T+e F operator does not re9uire its argument to be de0initely assigned- but 0ollowing an F operation- t+e variable
to w+ic+ t+e operator is applied is considered de0initely assigned in t+e eecution pat+ in w+ic+ t+e operation
occurs. 1t is t+e responsibility o0 t+e programmer to ensure t+at correct initialiDation o0 t+e variable actually does
ta7e place in t+is situation.
1n t+e eample
using System;
""' Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
class 1est
{
static void Main() {
int i;
unsa-e {
int> & + Fi;
>& + 289;
!
Console.WriteLine(i);
!
!
i is considered de0initely assigned 0ollowing t+e Fi operation used to initialiDe &. T+e assignment to >& in
e00ect initialiDes i- but t+e inclusion o0 t+is initialiDation is t+e responsibility o0 t+e programmer- and no
compile<time error would occur i0 t+e assignment was removed.
T+e rules o0 de0inite assignment 0or t+e F operator eist suc+ t+at redundant initialiDation o0 local variables can
be avoided. *or eample- many eternal (P1s ta7e a pointer to a structure w+ic+ is 0illed in by t+e (P1. Calls to
suc+ (P1s typically pass t+e address o0 a local struct variable- and wit+out t+e rule- redundant initialiDation o0
t+e struct variable would be re9uired.
10.&.& Pointer increent and decreent
1n an unsa0e contet- t+e << and == operators JV!.".$ and V!.%."M can be applied to pointer variables o0 all types
ecept void>. T+us- 0or every pointer type 1>- t+e 0ollowing operators are implicitly de0inedC
1> o&erator <<(1> #);
1> o&erator ==(1> #);
T+e operators produce t+e same results as # < 2 and # = 2- respectively JV13.".%M. 1n ot+er words- 0or a pointer
variable o0 type 1>- t+e << operator adds si?eo-(1) to t+e address contained in t+e variable- and t+e ==
operator subtracts si?eo-(1) 0rom t+e address contained in t+e variable.
10 a pointer increment or decrement operation over0lows t+e domain o0 t+e pointer type- t+e result is
implementation<de0ined- but no eceptions are produced.
10.&.' Pointer arit-etic
1n an unsa0e contet- t+e < and = operators JV!.!.4 and V!.!."M can be applied to values o0 all pointer types
ecept void>. T+us- 0or every pointer type 1>- t+e 0ollowing operators are implicitly de0inedC
1> o&erator <(1> # int y);
1> o&erator <(1> # uint y);
1> o&erator <(1> # long y);
1> o&erator <(1> # ulong y);
1> o&erator <(int # 1> y);
1> o&erator <(uint # 1> y);
1> o&erator <(long # 1> y);
1> o&erator <(ulong # 1> y);
1> o&erator C(1> # int y);
1> o&erator C(1> # uint y);
1> o&erator C(1> # long y);
1> o&erator C(1> # ulong y);
long o&erator C(1> # 1> y);
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. ""7
C# Language Specification
4iven an epression * o0 a pointer type 1> and an epression N o0 type int- uint- long- or ulong- t+e
epressions * < N and N < * compute t+e pointer value o0 type 1> t+at results 0rom adding N > si?eo-(1) to
t+e address given by *. 5i7ewise- t+e epression * = N computes t+e pointer value o0 type 1> t+at results 0rom
subtracting N > si?eo-(1) 0rom t+e address given by *.
4iven two epressions- * and ^- o0 a pointer type 1>- t+e epression * C ^ computes t+e di00erence between t+e
addresses given by * and ^ and t+en divides t+at di00erence by si?eo-(1). T+e type o0 t+e result is always
long. 1n e00ect- * = ^ is computed as ((long)(*) = (long)(^)) . si?eo-(1).
*or eampleC
using System;
class 1est
{
static void Main() {
unsa-e {
int> values + stac(alloc int4835;
int> & + Fvalues425;
int> Q + Fvalues42K5;
Console.WriteLine("& = Q + {3!" & = Q);
Console.WriteLine("Q = & + {3!" Q = &);
!
!
!
w+ic+ produces t+e outputC
& = Q + =2J
Q = & + 2J
10 a pointer arit+metic operation over0lows t+e domain o0 t+e pointer type- t+e result is truncated in an
implementation<de0ined 0as+ion- but no eceptions are produced.
10.&.. Pointer coparison
1n an unsa0e contet- t+e ++- @+- D- E- D+- and +E operators JV!.$M can be applied to values o0 all pointer types.
T+e pointer comparison operators areC
bool o&erator ++(void> # void> y);
bool o&erator @+(void> # void> y);
bool o&erator D(void> # void> y);
bool o&erator E(void> # void> y);
bool o&erator D+(void> # void> y);
bool o&erator E+(void> # void> y);
)ecause an implicit conversion eists 0rom any pointer type to t+e void> type- operands o0 any pointer type can
be compared using t+ese operators. T+e comparison operators compare t+e addresses given by t+e two operands
as i0 t+ey were unsigned integers.
10.&.0 T-e si<eof operator
T+e si?eo- operator returns t+e number o0 bytes occupied by a variable o0 a given type. T+e type speci0ied as
an operand to si?eo- must be an !n%anaged-t+pe JV13.2M.
""$ Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
si-eof-e/pression.
#i0e'f ( !n%anaged-t+pe )
T+e result o0 t+e si?eo- operator is a value o0 type int. *or certain prede0ined types- t+e si?eo- operator
yields a constant value as s+own in t+e table below.
(xpression /esult
si?eo-(sbyte) 2
si?eo-(byte) 2
si?eo-(s"ort) 8
si?eo-(us"ort) 8
si?eo-(int) J
si?eo-(uint) J
si?eo-(long) Y
si?eo-(ulong) Y
si?eo-(c"ar) 8
si?eo-(-loat) J
si?eo-(double) Y
si?eo-(bool) 2
*or all ot+er types- t+e result o0 t+e si?eo- operator is implementation<de0ined and is classi0ied as a value- not
a constant.
T+e order in w+ic+ members are pac7ed into a struct is unspeci0ied.
*or alignment purposes- t+ere may be unnamed padding at t+e beginning o0 a struct- wit+in a struct- and at t+e
end o0 t+e struct. T+e contents o0 t+e bits used as padding are indeterminate.
6+en applied to an operand t+at +as struct type- t+e result is t+e total number o0 bytes in a variable o0 t+at type-
including any padding.
10.' T-e fi%ed stateent
1n an unsa0e contet- t+e e%,edded-state%ent JV3M production permits an additional construct- t+e -i#ed
statement- w+ic+ is used to K0iL a moveable variable suc+ t+at its address remains constant 0or t+e duration o0
t+e statement.
e%,edded-state%ent.
...
fi/ed-state%ent
fi/ed-state%ent.
fi-ed ( pointer-t+pe fi/ed-pointer-declarators ) e%,edded-state%ent
fi/ed-pointer-declarators.
fi/ed-pointer-declarator
fi/ed-pointer-declarators ? fi/ed-pointer-declarator
fi/ed-pointer-declarator.
identifier H fi/ed-pointer-initiali-er
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. ""!
C# Language Specification
fi/ed-pointer-initiali-er.
C varia,le-reference
e/pression
Eac+ fi/ed-pointer-declarator declares a local variable o0 t+e given pointer-t+pe and initialiDes t+at local
variable wit+ t+e address computed by t+e corresponding fi/ed-pointer-initiali-er. ( local variable declared in a
-i#ed statement is accessible in any fi/ed-pointer-initiali-ers occurring to t+e rig+t o0 t+at variablePs
declaration- and in t+e e%,edded-state%ent o0 t+e -i#ed statement. ( local variable declared by a -i#ed
statement is considered read<only. ( compile<time error occurs i0 t+e embedded statement attempts to modi0y
t+is local variable Jvia assignment or t+e << and == operatorsM or pass it as a re- or out parameter.
( fi/ed-pointer-initiali-er can be one o0 t+e 0ollowingC
T+e to7en KFL 0ollowed by a varia,le-reference JV".3.3M to a moveable variable JV13.3M o0 an unmanaged
type 1- provided t+e type 1> is implicitly convertible to t+e pointer type given in t+e -i#ed statement. 1n
t+is case- t+e initialiDer computes t+e address o0 t+e given variable- and t+e variable is guaranteed to remain
at a 0ied address 0or t+e duration o0 t+e -i#ed statement.
(n epression o0 an arra+-t+pe wit+ elements o0 an unmanaged type 1- provided t+e type 1> is implicitly
convertible to t+e pointer type given in t+e -i#ed statement. 1n t+is case- t+e initialiDer computes t+e
address o0 t+e 0irst element in t+e array- and t+e entire array is guaranteed to remain at a 0ied address 0or
t+e duration o0 t+e -i#ed statement. T+e be+avior o0 t+e -i#ed statement is implementation<de0ined i0 t+e
array epression is null or i0 t+e array +as Dero elements.
(n epression o0 type string- provided t+e type c"ar> is implicitly convertible to t+e pointer type given
in t+e -i#ed statement. 1n t+is case- t+e initialiDer computes t+e address o0 t+e 0irst c+aracter in t+e string-
and t+e entire string is guaranteed to remain at a 0ied address 0or t+e duration o0 t+e -i#ed statement. T+e
be+avior o0 t+e -i#ed statement is implementation<de0ined i0 t+e string epression is null.
( si%ple-na%e or %e%,er-access t+at re0erences a 0ied siDe bu00er member o0 a moveable variable-
provided t+e type o0 t+e 0ied siDe bu00er member is implicitly convertible to t+e pointer type given in t+e
-i#ed statement. 1n t+is case- t+e initialiDer computes a pointer to t+e 0irst element o0 t+e 0ied siDe bu00er
JV13.!.2M- and t+e 0ied siDe bu00er is guaranteed to remain at a 0ied address 0or t+e duration o0 t+e -i#ed
statement.
*or eac+ address computed by a fi/ed-pointer-initiali-er t+e -i#ed statement ensures t+at t+e variable
re0erenced by t+e address is not sub&ect to relocation or disposal by t+e garbage collector 0or t+e duration o0 t+e
-i#ed statement. *or eample- i0 t+e address computed by a fi/ed-pointer-initiali-er re0erences a 0ield o0 an
ob&ect or an element o0 an array instance- t+e -i#ed statement guarantees t+at t+e containing ob&ect instance is
not relocated or disposed o0 during t+e li0etime o0 t+e statement.
1t is t+e programmerPs responsibility to ensure t+at pointers created by -i#ed statements do not survive beyond
eecution o0 t+ose statements. *or eample- w+en pointers created by -i#ed statements are passed to eternal
(P1s- it is t+e programmerPs responsibility to ensure t+at t+e (P1s retain no memory o0 t+ese pointers.
*ied ob&ects may cause 0ragmentation o0 t+e +eap Jbecause t+ey canPt be movedM. *or t+at reason- ob&ects
s+ould be 0ied only w+en absolutely necessary and t+en only 0or t+e s+ortest amount o0 time possible.
T+e eample
class 1est
{
static int #;
int y;
"* Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
unsa-e static void V(int> &) {
>& + 2;
!
static void Main() {
1est t + ne, 1est();
int45 a + ne, int4235;
unsa-e {
-i#ed (int> & + F#) V(&);
-i#ed (int> & + Ft.y) V(&);
-i#ed (int> & + Fa435) V(&);
-i#ed (int> & + a) V(&);
!
!
!
demonstrates several uses o0 t+e -i#ed statement. T+e 0irst statement 0ies and obtains t+e address o0 a static
0ield- t+e second statement 0ies and obtains t+e address o0 an instance 0ield- and t+e t+ird statement 0ies and
obtains t+e address o0 an array element. 1n eac+ case it would +ave been an error to use t+e regular F operator
since t+e variables are all classi0ied as moveable variables.
T+e t+ird and 0ourt+ -i#ed statements in t+e eample above produce identical results. 1n general- 0or an array
instance a- speci0ying Fa435 in a -i#ed statement is t+e same as simply speci0ying a.
T+is eample o0 t+e -i#ed statement uses stringC
class 1est
{
static string name + "##";
unsa-e static void V(c"ar> &) {
-or (int i + 3; &4i5 @+ WZ3W; <<i)
Console.WriteLine(&4i5);
!
static void Main() {
unsa-e {
-i#ed (c"ar> & + name) V(&);
-i#ed (c"ar> & + "##") V(&);
!
!
!
1n an unsa0e contet array elements o0 single<dimensional arrays are stored in increasing inde order- starting
wit+ inde 3 and ending wit+ inde Lengt" C 2. *or multi<dimensional arrays- array elements are stored suc+
t+at t+e indices o0 t+e rig+tmost dimension are increased 0irst- t+en t+e net le0t dimension- and so on to t+e le0t.
6it+in a -i#ed statement t+at obtains a pointer & to an array instance a- t+e pointer values ranging 0rom & to
& < a.Lengt" = 2 represent addresses o0 t+e elements in t+e array. 5i7ewise- t+e variables ranging 0rom &435
to &4a.Lengt" = 25 represent t+e actual array elements. 4iven t+e way in w+ic+ arrays are stored- we can treat
an array o0 any dimension as t+oug+ it were linear.
*or eampleC
using System;
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. "1
C# Language Specification
class 1est
{
static void Main() {
int45 a + ne, int489J5;
unsa-e {
-i#ed (int> & + a) {
-or (int i + 3; i D a.Lengt"; <<i) .. treat as linear
&4i5 + i;
!
!
-or (int i + 3; i D 8; <<i)
-or (int j + 3; j D 9; <<j) {
-or (int ( + 3; ( D J; <<()
Console.Write("4{3!{2!{8!5 + {98! " i j ( a4ij(5);
Console.WriteLine();
!
!
!
w+ic+ produces t+e outputC
43335 + 3 43325 + 2 43385 + 8 43395 + 9
43235 + J 43225 + K 43285 + X 43295 + M
43835 + Y 43825 + L 43885 + 23 43895 + 22
42335 + 28 42325 + 29 42385 + 2J 42395 + 2K
42235 + 2X 42225 + 2M 42285 + 2Y 42295 + 2L
42835 + 83 42825 + 82 42885 + 88 42895 + 89
1n t+e eample
class 1est
{
unsa-e static void Vill(int> & int count int value) {
-or (; count @+ 3; count==) >&<< + value;
!
static void Main() {
int45 a + ne, int42335;
unsa-e {
-i#ed (int> & + a) Vill(& 233 =2);
!
!
!
a -i#ed statement is used to 0i an array so its address can be passed to a met+od t+at ta7es a pointer.
1n t+e eampleC
unsa-e struct Vont
{
&ublic int si?e;
&ublic -i#ed c"ar name4985;
!
"2 Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
class 1est
{
unsa-e static void *utString(string s c"ar> bu--er int bu-Si?e) {
int len + s.Lengt";
i- (len E bu-Si?e) len + bu-Si?e;
-or (int i + 3; i D len; i<<) bu--er4i5 + s4i5;
-or (int i + len; i D bu-Si?e; i<<) bu--er4i5 + (c"ar)3;
!
Vont -;
unsa-e static void Main()
{
1est test + ne, 1est();
test.-.si?e + 23;
-i#ed (c"ar> & + test.-.name) {
*utString("1imes Ne, Ooman" & 98);
!
!
!
a 0ied statement is used to 0i a 0ied siDe bu00er o0 a struct so its address can be used as a pointer.
( c"ar> value produced by 0iing a string instance always points to a null<terminated string. 6it+in a 0ied
statement t+at obtains a pointer & to a string instance s- t+e pointer values ranging 0rom & to & < s.Lengt" = 2
represent addresses o0 t+e c+aracters in t+e string- and t+e pointer value & < s.Lengt" always points to a null
c+aracter Jt+e c+aracter wit+ value WZ3WM.
'odi0ying ob&ects o0 managed type t+roug+ 0ied pointers can results in unde0ined be+avior. *or eample-
because strings are immutable- it is t+e programmerPs responsibility to ensure t+at t+e c+aracters re0erenced by a
pointer to a 0ied string are not modi0ied.
T+e automatic null<termination o0 strings is particularly convenient w+en calling eternal (P1s t+at epect KC<
styleL strings. =ote- +owever- t+at a string instance is permitted to contain null c+aracters. 10 suc+ null c+aracters
are present- t+e string will appear truncated w+en treated as a null<terminated c"ar>.
10.. ,i%ed si<e buffers
*ied siDe bu00ers are used to declare KC styleL in<line arrays as members o0 structs- and are primarily use0ul 0or
inter0acing wit+ unmanaged (P1s.
10...1 ,i%ed si<e buffer declarations
( fi,ed si3e !-ffer is a member t+at represents storage 0or a 0ied lengt+ bu00er o0 variables o0 a given type. (
0ied siDe bu00er declaration introduces one or more 0ied siDe bu00ers o0 a given element type. *ied siDe
bu00ers are only permitted in struct declarations and can only occur in unsa0e contets JV13.1M.
str!ct-%e%,er-declaration.
>
fi/ed-si-e-,!ffer-declaration
fi/ed-si-e-,!ffer-declaration.
attri,!tesopt fi/ed-si-e-,!ffer-%odifiersopt fi-ed ,!ffer-ele%ent-t+pe
fi/ed-si-e-,!ffer-declarators A
fi/ed-si-e-,!ffer-%odifiers.
fi/ed-si-e-,!ffer-%odifier
fi/ed-si-e-,!ffer-%odifier fi/ed-si-e-,!ffer-%odifiers
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. "3
C# Language Specification
fi/ed-si-e-,!ffer-%odifier.
*ew
.u"li&
.%'$e&$ed
i*$e%*!l
.%i,!$e
u*#!fe
,!ffer-ele%ent-t+pe.
t+pe
fi/ed-si-e-,!ffer-declarators.
fi/ed-si-e-,!ffer-declarator
fi/ed-si-e-,!ffer-declarator fi/ed-si-e-,!ffer-declarators
fi/ed-si-e-,!ffer-declarator.
identifier = const-e/pression >
( 0ied siDe bu00er declaration may include a set o0 attributes JV1!M- a ne, modi0ier JV1..2.2M- a valid
combination o0 t+e 0our access modi0iers JV1..2.3M and an unsa-e modi0ier JV13.1M. T+e attributes and
modi0iers apply to all o0 t+e members declared by t+e 0ied siDe bu00er declaration. 1t is an error 0or t+e same
modi0ier to appear multiple times in a 0ied siDe bu00er declaration.
( 0ied siDe bu00er declaration is not permitted to include t+e static modi0ier.
T+e bu00er element type o0 a 0ied siDe bu00er declaration speci0ies t+e element type o0 t+e bu00erJsM introduced
by t+e declaration. T+e bu00er element type must be one o0 t+e prede0ined types sbyte- byte- s"ort- us"ort-
int- uint- long- ulong- c"ar- -loat- double- or bool.
T+e bu00er element type is 0ollowed by a list o0 0ied siDe bu00er declarators- eac+ o0 w+ic+ introduces a new
member. ( 0ied siDe bu00er declarator consists o0 an identi0ier t+at names t+e member- 0ollowed by a constant
epression enclosed in 4 and 5 to7ens. T+e constant epression denotes t+e number o0 elements in t+e member
introduced by t+at 0ied siDe bu00er declarator. T+e type o0 t+e constant epression must be implicitly
convertible to type int- and t+e value must be a non<Dero positive integer.
T+e elements o0 a 0ied siDe bu00er are guaranteed to be laid out se9uentially in memory.
( 0ied siDe bu00er declaration t+at declares multiple 0ied siDe bu00ers is e9uivalent to multiple declarations o0 a
single 0ied siDe bu00er declation wit+ t+e same attributes- and element types. *or eample
unsa-e struct '
{
&ublic -i#ed int #4K5 y4235 ?42335;
!
is e9uivalent to
unsa-e struct '
{
&ublic -i#ed int #4K5;
&ublic -i#ed int y4235;
&ublic -i#ed int ?42335;
!
10...2 ,i%ed si<e buffers in e%pressions
'ember loo7up JV!.3M o0 a 0ied siDe bu00er member proceeds eactly li7e member loo7up o0 a 0ield.
"" Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
( 0ied siDe bu00er can be re0erenced in an epression using a si%ple-na%e JV!.".2M or a %e%,er-access
JV!.".4M.
6+en a 0ied siDe bu00er member is re0erenced as a simple name- t+e e00ect is t+e same as a member access o0
t+e 0orm t"is.$- w+ere $ is t+e 0ied siDe bu00er member.
1n a member access o0 t+e 0orm ).$- i0 ) is o0 a struct type and a member loo7up o0 $ in t+at struct type
identi0ies a 0ied siDe member- t+en ).$ is evaluated an classi0ied as 0ollowsC
10 t+e epression ).$ does not occur in an unsa0e contet- a compile<time error occurs.
10 ) is classi0ied as a value- a compile<time error occurs.
/t+erwise- i0 ) is a moveable variable JV13.3M and t+e epression ).$ is not a fi/ed-pointer-initiali-er
JV13.%M- a compile<time error occurs.
/t+erwise- ) re0erences a 0ied variable and t+e result o0 t+e epression is a pointer to t+e 0irst element o0
t+e 0ied siDe bu00er member $ in ). T+e result is o0 type S>- w+ere S is t+e element type o0 $- and is
classi0ied as a value.
T+e subse9uent elements o0 t+e 0ied siDe bu00er can be accessed using pointer operations 0rom t+e 0irst element.
8nli7e access to arrays- access to t+e elements o0 a 0ied siDe bu00er is an unsa0e operation and is not range
c+ec7ed.
T+e 0ollowing eample declares and uses a struct wit+ a 0ied siDe bu00er member.
unsa-e struct Vont
{
&ublic int si?e;
&ublic -i#ed c"ar name4985;
!
class 1est
{
unsa-e static void *utString(string s c"ar> bu--er int bu-Si?e) {
int len + s.Lengt";
i- (len E bu-Si?e) len + bu-Si?e;
-or (int i + 3; i D len; i<<) bu--er4i5 + s4i5;
-or (int i + len; i D bu-Si?e; i<<) bu--er4i5 + (c"ar)3;
!
unsa-e static void Main()
{
Vont -;
-.si?e + 23;
*utString("1imes Ne, Ooman" -.name 98);
!
!
10...3 2efinite assignent c-ec5ing
*ied siDe bu00ers are not sub&ect to de0inite assignment c+ec7ing JV".3M- and 0ied siDe bu00er members are
ignored 0or purposes o0 de0inite assignment c+ec7ing o0 struct type variables.
6+en t+e outermost containing struct variable o0 a 0ied siDe bu00er member is a static variable- an instance
variable o0 a class instance- or an array element- t+e elements o0 t+e 0ied siDe bu00er are automatically
initialiDed to t+eir de0ault values JV".2M. 1n all ot+er cases- t+e initial content o0 a 0ied siDe bu00er is unde0ined.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. "
C# Language Specification
10.0 Stac5 allocation
1n an unsa0e contet- a local variable declaration JV3.".1M may include a stac7 allocation initialiDer w+ic+
allocates memory 0rom t+e call stac7.
local-varia,le-initiali-er.
>
stac&alloc-initiali-er
stac&alloc-initiali-er.
#$!&(!ll'& !n%anaged-t+pe = e/pression >
T+e !n%anaged-t+pe indicates t+e type o0 t+e items t+at will be stored in t+e newly allocated location- and t+e
e/pression indicates t+e number o0 t+ese items. Ta7en toget+er- t+ese speci0y t+e re9uired allocation siDe. #ince
t+e siDe o0 a stac7 allocation cannot be negative- it is a compile<time error to speci0y t+e number o0 items as a
constant-e/pression t+at evaluates to a negative value.
( stac7 allocation initialiDer o0 t+e 0orm stac(alloc 14)5 re9uires 1 to be an unmanaged type JV13.2M and )
to be an epression o0 type int. T+e construct allocates ) > si?eo-(1) bytes 0rom t+e call stac7 and returns a
pointer- o0 type 1>- to t+e newly allocated bloc7. 10 ) is a negative value- t+en t+e be+avior is unde0ined. 10 ) is
Dero- t+en no allocation is made- and t+e pointer returned is implementation<de0ined. 10 t+ere is not enoug+
memory available to allocate a bloc7 o0 t+e given siDe- a System.Stac(%ver-lo,)#ce&tion is t+rown.
T+e content o0 t+e newly allocated memory is unde0ined.
#tac7 allocation initialiDers are not permitted in catc" or -inally bloc7s JV3.1.M.
T+ere is no way to eplicitly 0ree memory allocated using stac(alloc. (ll stac7 allocated memory bloc7s
created during t+e eecution o0 a 0unction member are automatically discarded w+en t+at 0unction member
returns. T+is corresponds to t+e alloca 0unction- an etension commonly 0ound in C and CNN
implementations.
1n t+e eample
using System;
class 1est
{
static string $nt1oString(int value) {
int n + value E+ 37 value/ =value;
unsa-e {
c"ar> bu--er + stac(alloc c"ar42X5;
c"ar> & + bu--er < 2X;
do {
>==& + (c"ar)(n B 23 < W3W);
n .+ 23;
! ,"ile (n @+ 3);
i- (value D 3) >==& + W=W;
return ne, string(& 3 (int)(bu--er < 2X = &));
!
!
static void Main() {
Console.WriteLine($nt1oString(289JK));
Console.WriteLine($nt1oString(=LLL));
!
!
"' Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
C0apter 1 Introduction
a stac(alloc initialiDer is used in t+e $nt1oString met+od to allocate a bu00er o0 1% c+aracters on t+e stac7.
T+e bu00er is automatically discarded w+en t+e met+od returns.
10.1 2!naic eor! allocation
Ecept 0or t+e stac(alloc operator- C# provides no prede0ined constructs 0or managing non<garbage collected
memory. #uc+ services are typically provided by supporting class libraries or imported directly 0rom t+e
underlying operating system. *or eample- t+e Memory class below illustrates +ow t+e +eap 0unctions o0 an
underlying operating system mig+t be accessed 0rom C#C
using System;
using System.Ountime.$ntero&Services;
&ublic unsa-e class Memory
{
.. Handle -or t"e &rocess "ea&. 1"is "andle is used in all calls to t"e
.. Hea&III '*$s in t"e met"ods belo,.
static int &" + Set*rocessHea&();
.. *rivate instance constructor to &revent instantiation.
&rivate Memory() {!
.. 'llocates a memory bloc( o- t"e given si?e. 1"e allocated memory is
.. automatically initiali?ed to ?ero.
&ublic static void> 'lloc(int si?e) {
void> result + Hea&'lloc(&" H)'*[P)O%[M)M%O` si?e);
i- (result ++ null) t"ro, ne, %ut%-Memory)#ce&tion();
return result;
!
.. Co&ies count bytes -rom src to dst. 1"e source and destination
.. bloc(s are &ermitted to overla&.
&ublic static void Co&y(void> src void> dst int count) {
byte> &s + (byte>)src;
byte> &d + (byte>)dst;
i- (&s E &d) {
-or (; count @+ 3; count==) >&d<< + >&s<<;
!
else i- (&s D &d) {
-or (&s <+ count &d <+ count; count @+ 3; count==) >==&d + >==&s;
!
!
.. Vrees a memory bloc(.
&ublic static void Vree(void> bloc() {
i- (@Hea&Vree(&" 3 bloc()) t"ro, ne, $nvalid%&eration)#ce&tion();
!
.. Oe=allocates a memory bloc(. $- t"e reallocation reQuest is -or a
.. larger si?e t"e additional region o- memory is automatically
.. initiali?ed to ?ero.
&ublic static void> Oe'lloc(void> bloc( int si?e) {
void> result + Hea&Oe'lloc(&" H)'*[P)O%[M)M%O` bloc( si?e);
i- (result ++ null) t"ro, ne, %ut%-Memory)#ce&tion();
return result;
!
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. "7
C# Language Specification
.. Oeturns t"e si?e o- a memory bloc(.
&ublic static int Si?e%-(void> bloc() {
int result + Hea&Si?e(&" 3 bloc();
i- (result ++ =2) t"ro, ne, $nvalid%&eration)#ce&tion();
return result;
!
.. Hea& '*$ -lags
const int H)'*[P)O%[M)M%O` + 3#3333333Y;
.. Hea& '*$ -unctions
46ll$m&ort("(ernel98")5
static e#tern int Set*rocessHea&();
46ll$m&ort("(ernel98")5
static e#tern void> Hea&'lloc(int "Hea& int -lags int si?e);
46ll$m&ort("(ernel98")5
static e#tern bool Hea&Vree(int "Hea& int -lags void> bloc();
46ll$m&ort("(ernel98")5
static e#tern void> Hea&Oe'lloc(int "Hea& int -lags
void> bloc( int si?e);
46ll$m&ort("(ernel98")5
static e#tern int Hea&Si?e(int "Hea& int -lags void> bloc();
!
(n eample t+at uses t+e Memory class is given belowC
class 1est
{
static void Main() {
unsa-e {
byte> bu--er + (byte>)Memory.'lloc(8KX);
try {
-or (int i + 3; i D 8KX; i<<) bu--er4i5 + (byte)i;
byte45 array + ne, byte48KX5;
-i#ed (byte> & + array) Memory.Co&y(bu--er & 8KX);
!
-inally {
Memory.Vree(bu--er);
!
-or (int i + 3; i D 8KX; i<<) Console.WriteLine(array4i5);
!
!
!
T+e eample allocates 2"% bytes o0 memory t+roug+ Memory.'lloc and initialiDes t+e memory bloc7 wit+
values increasing 0rom . to 2"". 1t t+en allocates a 2"% element byte array and uses Memory.Co&y to copy t+e
contents o0 t+e memory bloc7 into t+e byte array. *inally- t+e memory bloc7 is 0reed using Memory.Vree and
t+e contents o0 t+e byte array are output on t+e console.
"$ Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
+ppendix + ,ocu)entation co))ents
*. 2ocuentation coents
C# provides a mec+anism 0or programmers to document t+eir code using a special comment synta t+at contains
I'5 tet. 1n source code 0iles- comments +aving a certain 0orm can be used to direct a tool to produce I'5
0rom t+ose comments and t+e source code elements- w+ic+ t+ey precede. Comments using suc+ synta are
called doc-entation coents. T+ey must immediately precede a user<de0ined type Jsuc+ as a class- delegate-
or inter0aceM or a member Jsuc+ as a 0ield- event- property- or met+odM. T+e I'5 generation tool is called t+e
doc-entation generator. JT+is generator could be- but need not be- t+e C# compiler itsel0.M T+e output
produced by t+e documentation generator is called t+e doc-entation file. ( documentation 0ile is used as input
to a doc-entation vie2erQ a tool intended to produce some sort o0 visual display o0 type in0ormation and its
associated documentation.
T+is speci0ication suggests a set o0 tags to be used in documentation comments- but use o0 t+ese tags is not
re9uired- and ot+er tags may be used i0 desired- as long t+e rules o0 well<0ormed I'5 are 0ollowed.
*.1 Introduction
Comments +aving a special 0orm can be used to direct a tool to produce I'5 0rom t+ose comments and t+e
source code elements- w+ic+ t+ey precede. #uc+ comments are single<line comments t+at start wit+ t+ree slas+es
J...M- or delimited comments t+at start wit+ a slas+ and two stars J.>>M. T+ey must immediately precede a user<
de0ined type Jsuc+ as a class- delegate- or inter0aceM or a member Jsuc+ as a 0ield- event- property- or met+odM
t+at t+ey annotate. (ttribute sections JV1!.2M are considered part o0 declarations- so documentation comments
must precede attributes applied to a type or member.
S#ntax8
single-line-doc-co%%ent.
/// inp!t-charactersopt
deli%ited-doc-co%%ent.
/** deli%ited-co%%ent-charactersopt */
1n a single-line-doc-co%%ent- i0 t+ere is a whitespace c+aracter 0ollowing t+e ... c+aracters on eac+ o0 t+e
single-line-doc-co%%ents ad&acent to t+e current single-line-doc-co%%ent- t+en t+at whitespace c+aracter is not
included in t+e I'5 output.
1n a deli%ited-doc-co%%ent- i0 t+e 0irst non<whitespace c+aracter on t+e second line is an asteris& and t+e same
pattern o0 optional whitespace c+aracters and an asteris& c+aracter is repeated at t+e beginning o0 eac+ o0 t+e
line wit+in t+e deli%ited-doc-co%%ent- t+en t+e c+aracters o0 t+e repeated pattern are not included in t+e I'5
output. T+e pattern may include whitespace c+aracters a0ter- as well as be0ore- t+e asteris& c+aracter.
(xa)ple8
... DsummaryEClass DcE*ointD.cE models a &oint in a t,o=dimensional
... &lane.D.summaryE
...
&ublic class *oint
{
... DsummaryEmet"od DcEdra,D.cE renders t"e &oint.D.summaryE
void dra,() {b!
!
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. "!
C# Language Specification
T+e tet wit+in documentation comments must be well 0ormed according to t+e rules o0 I'5
J+ttpCOOwww.w3.orgOT;O;EC<mlM. 10 t+e I'5 is ill 0ormed- a warning is generated and t+e documentation 0ile
will contain a comment saying t+at an error was encountered.
(lt+oug+ developers are 0ree to create t+eir own set o0 tags- a recommended set is de0ined in V(.2. #ome o0 t+e
recommended tags +ave special meaningsC
T+e D&aramE tag is used to describe parameters. 10 suc+ a tag is used- t+e documentation generator must
veri0y t+at t+e speci0ied parameter eists and t+at all parameters are described in documentation comments.
10 suc+ veri0ication 0ails- t+e documentation generator issues a warning.
T+e cre- attribute can be attac+ed to any tag to provide a re0erence to a code element. T+e documentation
generator must veri0y t+at t+is code element eists. 10 t+e veri0ication 0ails- t+e documentation generator
issues a warning. 6+en loo7ing 0or a name described in a cre- attribute- t+e documentation generator must
respect namespace visibility according to using statements appearing wit+in t+e source code. *or code
elements t+at are generic- t+e normal generic synta Jie KListD1ELM cannot be used because it produces
invalid I'5. )races can be used instead o0 brac7ets Jie KList{1!LM- or t+e I'5 escape synta can be
used Jie KListFlt;1Fgt;LM.
T+e DsummaryE tag is intended to be used by a documentation viewer to display additional in0ormation
about a type or member.
T+e DincludeE tag includes in0ormation 0rom an eternal I'5 0ile.
=ote care0ully t+at t+e documentation 0ile does not provide 0ull in0ormation about t+e type and members J0or
eample- it does not contain any type in0ormationM. To get suc+ in0ormation about a type or member- t+e
documentation 0ile must be used in con&unction wit+ re0lection on t+e actual type or member.
*.2 :ecoended tags
T+e documentation generator must accept and process any tag t+at is valid according to t+e rules o0 I'5. T+e
0ollowing tags provide commonly used 0unctionality in user documentation. J/0 course- ot+er tags are possible.M
"'* Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
+ppendix + ,ocu)entation co))ents
Tag Section 2urpose
DcE '.8.2
#et tet in a code<li7e 0ont
DcodeE '.8.8
#et one or more lines o0 source code or program output
De#am&leE '.8.9
1ndicate an eample
De#ce&tionE '.8.J
1denti0ies t+e eceptions a met+od can t+row
DincludeE '.8.K
1ncludes I'5 0rom an eternal 0ile
DlistE '.8.X
Create a list or table
D&araE '.8.M
Permit structure to be added to tet
D&aramE '.8.Y
2escribe a parameter 0or a met+od or constructor
D&aramre-E '.8.L
1denti0y t+at a word is a parameter name
D&ermissionE '.8.23
2ocument t+e security accessibility o0 a member
DsummaryE '.8.22
2escribe a type
DreturnsE '.8.28
2escribe t+e return value o0 a met+od
DseeE '.8.29
#peci0y a lin7
DseealsoE '.8.2J
4enerate a (ee Also entry
DsummaryE '.8.2K
2escribe a member o0 a type
DvalueE '.8.2X
2escribe a property
Dty&e&aramE
2escribe a generic type parameter
Dty&e&aramre-E
1denti0y t+at a word is a type parameter name
*.2.1 AcB
T+is tag provides a mec+anism to indicate t+at a 0ragment o0 tet wit+in a description s+ould be set in a special
0ont suc+ as t+at used 0or a bloc7 o0 code. *or lines o0 actual code- use DcodeE JV(.2.2M.
S#ntax8
DcE$e-$D.cE
(xa)ple8
... DsummaryEClass DcE*ointD.cE models a &oint in a t,o=dimensional
... &lane.D.summaryE
&ublic class *oint
{
.. ...
!
*.2.2 AcodeB
T+is tag is used to set one or more lines o0 source code or program output in some special 0ont. *or small code
0ragments in narrative- use DcE JV(.2.1M.
S#ntax8
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. "'1
C# Language Specification
DcodeE#'u%&e &'de '% .%'+%!m 'u$.u$D.codeE
(xa)ple8
... DsummaryE1"is met"od c"anges t"e &ointWs location by
... t"e given #= and y=o--sets.
... De#am&leEVor e#am&le/
... DcodeE
... *oint & + ne, *oint(9K);
... &.1ranslate(=29);
... D.codeE
... results in DcE&D.cEWs "aving t"e value (8Y).
... D.e#am&leE
... D.summaryE
&ublic void 1ranslate(int #or int yor) {
I <+ #or;
` <+ yor;
!
*.2.3 Ae%apleB
T+is tag allows eample code wit+in a comment- to speci0y +ow a met+od or ot+er library member may be used.
/rdinarily- t+is would also involve use o0 t+e tag DcodeE JV(.2.2M as well.
S#ntax8
De#am&leEde#&%i.$i'*D.e#am&leE
(xa)ple8
#ee DcodeE (V(.2.2) 0or an eample.
*.2.# Ae%ceptionB
T+is tag provides a way to document t+e eceptions a met+od can t+row.
S#ntax8
De#ce&tion cre-+"mem"e%"Ede#&%i.$i'*D.e#ce&tionE
w+ere
cre-+"mem"e%"
T+e name o0 a member. T+e documentation generator c+ec7s t+at t+e given member eists and
translates %e%,er to t+e canonical element name in t+e documentation 0ile.
de#&%i.$i'*
( description o0 t+e circumstances in w+ic+ t+e eception is t+rown.
(xa)ple8
"'2 Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
+ppendix + ,ocu)entation co))ents
&ublic class 6ata:ase%&erations
{
... De#ce&tion cre-+"MasterVileVormatCorru&t)#ce&tion"ED.e#ce&tionE
... De#ce&tion cre-+"MasterVileLoc(ed%&en)#ce&tion"ED.e#ce&tionE
&ublic static void OeadOecord(int -lag) {
i- (-lag ++ 2)
t"ro, ne, MasterVileVormatCorru&t)#ce&tion();
else i- (-lag ++ 8)
t"ro, ne, MasterVileLoc(ed%&en)#ce&tion();
.. b
!
!
*.2.& AincludeB
T+is tag allows including in0ormation 0rom an I'5 document t+at is eternal to t+e source code 0ile. T+e
eternal 0ile must be a well<0ormed I'5 document- and an IPat+ epression is applied to t+at document to
speci0y w+at I'5 0rom t+at document to include. T+e DincludeE tag is t+en replaced wit+ t+e selected I'5
0rom t+e eternal document.
S#ntax8
Dinclude -ile+"file*!me" &at"+"-.!$h" .E
w+ere
-ile+"file*!me"
T+e 0ile name o0 an eternal I'5 0ile. T+e 0ile name is interpreted relative to t+e 0ile t+at contains t+e
include tag.
&at"+"-.!$h"
(n IPat+ epression t+at selects some o0 t+e I'5 in t+e eternal I'5 0ile.
(xa)ple8
10 t+e source code contained a declaration li7eC
... Dinclude -ile+"docs.#ml" &at"+We#tradoc.class4\name+"$ntList"5.>W .E
&ublic class $ntList { b !
and t+e eternal 0ile Kdocs.#mlL +ad t+e 0ollowing contentsC
D7#ml version+"2.3"7E
De#tradocE
Dclass name+"$ntList"E
DsummaryE
Contains a list o- integers.
D.summaryE
D.classE
Dclass name+"StringList"E
DsummaryE
Contains a list o- integers.
D.summaryE
D.classE
D.e#tradocE
t+en t+e same documentation is output as i0 t+e source code containedC
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. "'3
C# Language Specification
... DsummaryE
... Contains a list o- integers.
... D.summaryE
&ublic class $ntList { b !
*.2.' AlistB
T+is tag is used to create a list or table o0 items. 1t may contain a Dlist"eaderE bloc7 to de0ine t+e +eading
row o0 eit+er a table or de0inition list. J6+en de0ining a table- only an entry 0or $e%m in t+e +eading need be
supplied.M
Eac+ item in t+e list is speci0ied wit+ an DitemE bloc7. 6+en creating a de0inition list- bot+ $e%m and
de#&%i.$i'* must be speci0ied. However- 0or a table- bulleted list- or numbered list- only de#&%i.$i'* need
be speci0ied.
S#ntax8
Dlist ty&e+"bullet" H "number" H "table"E
Dlist"eaderE
DtermE$e%mD.termE
Ddescri&tionEde#&%i.$i'*D.descri&tionE
D.list"eaderE
DitemE
DtermE$e%mD.termE
Ddescri&tionEde#&%i.$i'*D.descri&tionE
D.itemE
b
DitemE
DtermE$e%mD.termE
Ddescri&tionEde#&%i.$i'*D.descri&tionE
D.itemE
D.listE
w+ere
$e%m
T+e term to de0ine- w+ose de0inition is in de#&%i.$i'*.
de#&%i.$i'*
Eit+er an item in a bullet or numbered list- or t+e de0inition o0 a $e%m.
(xa)ple8
"'" Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
+ppendix + ,ocu)entation co))ents
&ublic class MyClass
{
... DsummaryEHere is an e#am&le o- a bulleted list/
... Dlist ty&e+"bullet"E
... DitemE
... Ddescri&tionE$tem 2.D.descri&tionE
... D.itemE
... DitemE
... Ddescri&tionE$tem 8.D.descri&tionE
... D.itemE
... D.listE
... D.summaryE
&ublic static void Main () {
.. ...
!
!
*.2.. AparaB
T+is tag is 0or use inside ot+er tags- suc+ as DsummaryE JV(.2.11M or DreturnsE JV(.2.12M- and permits
structure to be added to tet.
S#ntax8
D&araE&'*$e*$D.&araE
w+ere
&'*$e*$
T+e tet o0 t+e paragrap+.
(xa)ple8
... DsummaryE1"is is t"e entry &oint o- t"e *oint class testing &rogram.
... D&araE1"is &rogram tests eac" met"od and o&erator and
... is intended to be run a-ter any non=trvial maintenance "as
... been &er-ormed on t"e *oint class.D.&araED.summaryE
&ublic static void Main() {
.. ...
!
*.2.0 AparaB
T+is tag is used to describe a parameter 0or a met+od- constructor- or indeer.
S#ntax8
D&aram name+"*!me"Ede#&%i.$i'*D.&aramE
w+ere
*!me
T+e name o0 t+e parameter.
de#&%i.$i'*
( description o0 t+e parameter.
(xa)ple8
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. "'
C# Language Specification
... DsummaryE1"is met"od c"anges t"e &ointWs location to
... t"e given coordinates.D.summaryE
... D&aram name+"#or"Et"e ne, #=coordinate.D.&aramE
... D&aram name+"yor"Et"e ne, y=coordinate.D.&aramE
&ublic void Move(int #or int yor) {
I + #or;
` + yor;
!
*.2.1 ApararefB
T+is tag is used to indicate t+at a word is a parameter. T+e documentation 0ile can be processed to 0ormat t+is
parameter in some distinct way.
S#ntax8
D&aramre- name+"*!me".E
w+ere
*!me
T+e name o0 t+e parameter.
(xa)ple8
... DsummaryE1"is constructor initiali?es t"e ne, *oint to
... (D&aramre- name+"#or".ED&aramre- name+"yor".E).D.summaryE
... D&aram name+"#or"Et"e ne, *ointWs #=coordinate.D.&aramE
... D&aram name+"yor"Et"e ne, *ointWs y=coordinate.D.&aramE
&ublic *oint(int #or int yor) {
I + #or;
` + yor;
!
*.2.10 AperissionB
T+is tag allows t+e security accessibility o0 a member to be documented.
S#ntax8
D&ermission cre-+"mem"e%"Ede#&%i.$i'*D.&ermissionE
w+ere
cre-+"mem"e%"
T+e name o0 a member. T+e documentation generator c+ec7s t+at t+e given code element eists and
translates %e%,er to t+e canonical element name in t+e documentation 0ile.
de#&%i.$i'*
( description o0 t+e access to t+e member.
(xa)ple8
... D&ermission cre-+"System.Security.*ermissionSet"E)veryone can
... access t"is met"od.D.&ermissionE
&ublic static void 1est() {
.. ...
!
"'' Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
+ppendix + ,ocu)entation co))ents
*.2.11 Asuar!B
T+is tag is used to speci0y overview in0ormation about a type. J8se DsummaryE JV(.2.1"M to describe t+e
members o0 a type.M
S#ntax8
DsummaryEde#&%i.$i'*D.summaryE
w+ere
de#&%i.$i'*
T+e tet o0 t+e summary.
(xa)ple8
... DsummaryEClass DcE*ointD.cE models a &oint in a
... t,o=dimensional &lane.D.summaryE
&ublic class *oint
{
.. ...
!
*.2.12 AreturnsB
T+is tag is used to describe t+e return value o0 a met+od.
S#ntax8
DreturnsEde#&%i.$i'*D.returnsE
w+ere
de#&%i.$i'*
( description o0 t+e return value.
(xa)ple8
... DsummaryEOe&ort a &ointWs location as a string.D.summaryE
... DreturnsE' string re&resenting a &ointWs location in t"e -orm (#y)
... ,it"out any leading trailing or embedded ,"ites&ace.D.returnsE
&ublic override string 1oString() {
return "(" < I < "" < ` < ")";
!
*.2.13 AseeB
T+is tag allows a lin7 to be speci0ied wit+in tet. 8se DseealsoE JV(.2.14M to indicate tet t+at is to appear in a
(ee Also section.
S#ntax8
Dsee cre-+"mem"e%".E
w+ere
cre-+"mem"e%"
T+e name o0 a member. T+e documentation generator c+ec7s t+at t+e given code element eists and
c+anges %e%,er to t+e element name in t+e generated documentation 0ile.
(xa)ple8
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. "'7
C# Language Specification
... DsummaryE1"is met"od c"anges t"e &ointWs location to
... t"e given coordinates.D.summaryE
... Dsee cre-+"1ranslate".E
&ublic void Move(int #or int yor) {
I + #or;
` + yor;
!
... DsummaryE1"is met"od c"anges t"e &ointWs location by
... t"e given #= and y=o--sets.
... D.summaryE
... Dsee cre-+"Move".E
&ublic void 1ranslate(int #or int yor) {
I <+ #or;
` <+ yor;
!
*.2.1# AseealsoB
T+is tag allows an entry to be generated 0or t+e (ee Also section. 8se DseeE JV(.2.13M to speci0y a lin7 0rom
wit+in tet.
S#ntax8
Dseealso cre-+"mem"e%".E
w+ere
cre-+"mem"e%"
T+e name o0 a member. T+e documentation generator c+ec7s t+at t+e given code element eists and
c+anges %e%,er to t+e element name in t+e generated documentation 0ile.
(xa)ple8
... DsummaryE1"is met"od determines ,"et"er t,o *oints "ave t"e same
... location.D.summaryE
... Dseealso cre-+"o&erator++".E
... Dseealso cre-+"o&erator@+".E
&ublic override bool )Quals(object o) {
.. ...
!
*.2.1& Asuar!B
T+is tag can be used to describe a member 0or a type. 8se DsummaryE JV(.2.11M to describe t+e type itsel0.
S#ntax8
DsummaryEde#&%i.$i'*D.summaryE
w+ere
de#&%i.$i'*
( summary o0 t+e member.
(xa)ple8
... DsummaryE1"is constructor initiali?es t"e ne, *oint to (33).D.summaryE
&ublic *oint() / t"is(33) {
!
"'$ Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
+ppendix + ,ocu)entation co))ents
*.2.1' A"alueB
T+is tag allows a property to be described.
S#ntax8
DvalueE.%'.e%$) de#&%i.$i'*D.valueE
w+ere
.%'.e%$) de#&%i.$i'*
( description 0or t+e property.
(xa)ple8
... DvalueE*ro&erty DcEID.cE re&resents t"e &ointWs #=coordinate.D.valueE
&ublic int I
{
get { return #; !
set { # + value; !
!
*.2.1. At!peparaB
T+is tag is used to describe a generic type parameter 0or a class- struct- inter0ace- delegate- or met+od.
S#ntax8
Dty&e&aram name+"*!me"Ede#&%i.$i'*D.ty&e&aramE
w+ere
*!me
T+e name o0 t+e type parameter.
de#&%i.$i'*
( description o0 t+e type parameter.
(xa)ple8
... DsummaryE' generic list class.D.summaryE
... Dty&e&aram name+"1"E1"e ty&e stored by t"e list.D.ty&e&aramE
&ublic class MyListD1E {
...
!
*.2.10 At!pepararefB
T+is tag is used to indicate t+at a word is a type parameter. T+e documentation 0ile can be processed to 0ormat
t+is type parameter in some distinct way.
S#ntax8
Dty&e&aramre- name+"*!me".E
w+ere
*!me
T+e name o0 t+e type parameter.
(xa)ple8
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. "'!
C# Language Specification
... DsummaryE1"is met"od -etc"es data and returns a list o- Dty&e&aramre-
name+T1TE T.ETE .D.summaryE
... D&aram name+"string"EQuery to e#ecuteD.&aramE
&ublic ListD1E Vetc"6ataD1E(string Query) {
...
!
*.3 Processing t-e docuentation file
T+e documentation generator generates an 12 string 0or eac+ element in t+e source code t+at is tagged wit+ a
documentation comment. T+is 12 string uni9uely identi0ies a source element. ( documentation viewer can use
an 12 string to identi0y t+e corresponding metadataOre0lection item to w+ic+ t+e documentation applies.
T+e documentation 0ile is not a +ierarc+ical representation o0 t+e source codeQ rat+er- it is a 0lat list wit+ a
generated 12 string 0or eac+ element.
*.3.1 I2 string forat
T+e documentation generator observes t+e 0ollowing rules w+en it generates t+e 12 stringsC
=o w+ite space is placed in t+e string.
T+e 0irst part o0 t+e string identi0ies t+e 7ind o0 member being documented- via a single c+aracter 0ollowed
by a colon. T+e 0ollowing 7inds o0 members are de0inedC
C0aracter ,escription
E Event
* *ield
' 'et+od Jincluding constructors- destructors- and operatorsM
= =amespace
P Property Jincluding indeersM
T Type Jsuc+ as class- delegate- enum- inter0ace- and structM
A Error stringQ t+e rest o0 t+e string provides in0ormation about t+e
error. *or eample- t+e documentation generator generates error
in0ormation 0or lin7s t+at cannot be resolved.
T+e second part o0 t+e string is t+e 0ully 9uali0ied name o0 t+e element- starting at t+e root o0 t+e namespace.
T+e name o0 t+e element- its enclosing typeJsM- and namespace are separated by periods. 10 t+e name o0 t+e
item itsel0 +as periods- t+ey are replaced by 0 J;<3389M c+aracters. J1t is assumed t+at no element +as t+is
c+aracter in its name.M
*or met+ods and properties wit+ arguments- t+e argument list 0ollows- enclosed in parent+eses. *or t+ose
wit+out arguments- t+e parent+eses are omitted. T+e arguments are separated by commas. T+e encoding o0
eac+ argument is t+e same as a C51 signature- as 0ollowsC
o (rguments are represented by t+eir documentation name- w+ic+ is based on t+eir 0ully 9uali0ied name-
modi0ied as 0ollowsC
(rguments t+at represent generic types +ave an appended KPL c+aracter 0ollowed by t+e number o0
type parameters
"7* Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
+ppendix + ,ocu)entation co))ents
(rguments +aving t+e out or re- modi0ier +ave an \ 0ollowing t+eir type name. (rguments passed
by value or via &arams +ave no special notation.
(rguments t+at are arrays are represented as 4 lower,o!nd / si-e _ lower,o!nd / si-e 5 w+ere
t+e number o0 commas is t+e ran7 less one- and t+e lower bounds and siDe o0 eac+ dimension- i0
7nown- are represented in decimal. 10 a lower bound or siDe is not speci0ied- it is omitted. 10 t+e
lower bound and siDe 0or a particular dimension are omitted- t+e K/L is omitted as well. Fagged
arrays are represented by one K45L per level.
(rguments t+at +ave pointer types ot+er t+an void are represented using a > 0ollowing t+e type
name. ( void pointer is represented using a type name o0 System.Uoid.
(rguments t+at re0er to generic type parameters de0ined on types are encoded using t+e KbL
c+aracter 0ollowed by t+e Dero<based inde o0 t+e type parameter.
(rguments t+at use generic type parameters de0ined in met+ods use a double<bac7tic7 KbbL instead
o0 t+e KbL used 0or types.
(rguments t+at re0er to constructed generic types are encoded using t+e generic type- 0ollowed by
K]K- 0ollowed by a comma<separated list o0 type arguments- 0ollowed by K^L.
*.3.2 I2 string e%aples
T+e 0ollowing eamples eac+ s+ow a 0ragment o0 C# code- along wit+ t+e 12 string produced 0rom eac+ source
element capable o0 +aving a documentation commentC
Types are represented using t+eir 0ully 9uali0ied name- augmented wit+ generic in0ormationC
enum Color { Oed :lue Sreen !
names&ace 'cme
{
inter-ace $*rocess {...!
struct Ualue1y&e {...!
class Widget/ $*rocess
{
&ublic class NestedClass {...!
&ublic inter-ace $Menu$tem {...!
&ublic delegate void 6el(int i);
&ublic enum 6irection { Nort" Sout" )ast West !
!
class MyListD1E
{
class Hel&erD;UE {...!
!
!
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. "71
C# Language Specification
"1/Color"
"1/'cme.$*rocess"
"1/'cme.Ualue1y&e"
"1/'cme.Widget"
"1/'cme.Widget.NestedClass"
"1/'cme.Widget.$Menu$tem"
"1/'cme.Widget.6el"
"1/'cme.Widget.6irection"
T1/'cme.MyListd2T
T1/'cme.MyListd2.Hel&erd8T
*ields are represented by t+eir 0ully 9uali0ied nameC
names&ace 'cme
{
struct Ualue1y&e
{
&rivate int total;
!
class Widget/ $*rocess
{
&ublic class NestedClass
{
&rivate int value;
!
&rivate string message;
&rivate static Color de-aultColor;
&rivate const double *$ + 9.2J2KL;
&rotected readonly double mont"ly'verage;
&rivate long45 array2;
&rivate Widget45 array8;
&rivate unsa-e int >&Count;
&rivate unsa-e -loat >>&&Ualues;
!
!
"V/'cme.Ualue1y&e.total"
"V/'cme.Widget.NestedClass.value"
"V/'cme.Widget.message"
"V/'cme.Widget.de-aultColor"
"V/'cme.Widget.*$"
"V/'cme.Widget.mont"ly'verage"
"V/'cme.Widget.array2"
"V/'cme.Widget.array8"
"V/'cme.Widget.&Count"
"V/'cme.Widget.&&Ualues"
Constructors.
names&ace 'cme
{
class Widget/ $*rocess
{
static Widget() {...!
&ublic Widget() {...!
"72 Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
+ppendix + ,ocu)entation co))ents
&ublic Widget(string s) {...!
!
!
"M/'cme.Widget.0cctor"
"M/'cme.Widget.0ctor"
"M/'cme.Widget.0ctor(System.String)"
2estructors.
names&ace 'cme
{
class Widget/ $*rocess
{
AWidget() {...!
!
!
"M/'cme.Widget.Vinali?e"
'et+ods.
names&ace 'cme
{
struct Ualue1y&e
{
&ublic void M(int i) {...!
!
class Widget/ $*rocess
{
&ublic class NestedClass
{
&ublic void M(int i) {...!
!
&ublic static void M3() {...!
&ublic void M2(c"ar c out -loat - re- Ualue1y&e v) {...!
&ublic void M8(s"ort45 #2 int45 #8 long4545 #9) {...!
&ublic void M9(long4545 #9 Widget4545 #J) {...!
&ublic unsa-e void MJ(c"ar >&c Color >>&-) {...!
&ublic unsa-e void MK(void >&v double >4545 &d) {...!
&ublic void MX(int i &arams object45 args) {...!
!
class MyListD1E
{
&ublic void 1est(1 t) { !
!
class ;seList
{
&ublic void *rocess(MyListDintE list) { !
&ublic MyListD1E SetUaluesD1E(1 in&utUalue) { return null; !
!
!
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. "73
C# Language Specification
"M/'cme.Ualue1y&e.M(System.$nt98)"
"M/'cme.Widget.NestedClass.M(System.$nt98)"
"M/'cme.Widget.M3"
"M/'cme.Widget.M2(System.C"arSystem.Single\'cme.Ualue1y&e\)"
"M/'cme.Widget.M8(System.$nt2X45System.$nt9843/3/5System.$ntXJ4545)"
"M/'cme.Widget.M9(System.$ntXJ4545'cme.Widget43/3/3/545)"
"M/'cme.Widget.MJ(System.C"ar>Color>>)"
"M/'cme.Widget.MK(System.Uoid>System.6ouble>43/3/545)"
"M/'cme.Widget.MX(System.$nt98System.%bject45)"
TM/'cme.MyListd2.1est(d3)T
TM/'cme.;seList.*rocess('cme.MyList{System.$nt98!)T
TM/'cme.;seList.SetUaluesdd(dd3)T
Properties and indeers.
names&ace 'cme
{
class Widget/ $*rocess
{
&ublic int Widt" { get {...! set {...! !
&ublic int t"is4int i5 { get {...! set {...! !
&ublic int t"is4string s int i5 { get {...! set {...! !
!
!
"*/'cme.Widget.Widt""
"*/'cme.Widget.$tem(System.$nt98)"
"*/'cme.Widget.$tem(System.StringSystem.$nt98)"
Events.
names&ace 'cme
{
class Widget/ $*rocess
{
&ublic event 6el 'n)vent;
!
!
")/'cme.Widget.'n)vent"
8nary operators.
names&ace 'cme
{
class Widget/ $*rocess
{
&ublic static Widget o&erator<(Widget #) {...!
!
!
"M/'cme.Widget.o&[;nary*lus('cme.Widget)"
T+e complete set o0 unary operator 0unction names used is as 0ollowsC o&[;nary*lus-
o&[;naryNegation- o&[LogicalNot- o&[%nesCom&lement- o&[$ncrement- o&[6ecrement-
o&[1rue- and o&[Valse.
)inary operators.
"7" Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
+ppendix + ,ocu)entation co))ents
names&ace 'cme
{
class Widget/ $*rocess
{
&ublic static Widget o&erator<(Widget #2 Widget #8) {...!
!
!
"M/'cme.Widget.o&['ddition('cme.Widget'cme.Widget)"
T+e complete set o0 binary operator 0unction names used is as 0ollowsC o&['ddition- o&[Subtraction-
o&[Multi&ly- o&[6ivision- o&[Modulus- o&[:it,ise'nd- o&[:it,ise%r- o&[)#clusive%r-
o&[Le-tS"i-t- o&[Oig"tS"i-t- o&[)Quality- o&[$neQuality- o&[Less1"an-
o&[Less1"an%r)Qual- o&[Sreater1"an- and o&[Sreater1"an%r)Qual.
Conversion operators +ave a trailing KAL 0ollowed by t+e return type.
names&ace 'cme
{
class Widget/ $*rocess
{
&ublic static e#&licit o&erator int(Widget #) {...!
&ublic static im&licit o&erator long(Widget #) {...!
!
!
"M/'cme.Widget.o&[)#&licit('cme.Widget)ASystem.$nt98"
"M/'cme.Widget.o&[$m&licit('cme.Widget)ASystem.$ntXJ"
*.# *n e%aple
*.#.1 CC source code
T+e 0ollowing eample s+ows t+e source code o0 a *oint classC
names&ace Sra&"ics
{
... DsummaryEClass DcE*ointD.cE models a &oint in a t,o=dimensional &lane.
... D.summaryE
&ublic class *oint
{
... DsummaryE$nstance variable DcE#D.cE re&resents t"e &ointWs
... #=coordinate.D.summaryE
&rivate int #;
... DsummaryE$nstance variable DcEyD.cE re&resents t"e &ointWs
... y=coordinate.D.summaryE
&rivate int y;
... DvalueE*ro&erty DcEID.cE re&resents t"e &ointWs #=coordinate.D.valueE
&ublic int I
{
get { return #; !
set { # + value; !
!
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. "7
C# Language Specification
... DvalueE*ro&erty DcE`D.cE re&resents t"e &ointWs y=coordinate.D.valueE
&ublic int `
{
get { return y; !
set { y + value; !
!
... DsummaryE1"is constructor initiali?es t"e ne, *oint to
... (33).D.summaryE
&ublic *oint() / t"is(33) {!
... DsummaryE1"is constructor initiali?es t"e ne, *oint to
... (D&aramre- name+"#or".ED&aramre- name+"yor".E).D.summaryE
... D&aramEDcE#orD.cE is t"e ne, *ointWs #=coordinate.D.&aramE
... D&aramEDcEyorD.cE is t"e ne, *ointWs y=coordinate.D.&aramE
&ublic *oint(int #or int yor) {
I + #or;
` + yor;
!
... DsummaryE1"is met"od c"anges t"e &ointWs location to
... t"e given coordinates.D.summaryE
... D&aramEDcE#orD.cE is t"e ne, #=coordinate.D.&aramE
... D&aramEDcEyorD.cE is t"e ne, y=coordinate.D.&aramE
... Dsee cre-+"1ranslate".E
&ublic void Move(int #or int yor) {
I + #or;
` + yor;
!
... DsummaryE1"is met"od c"anges t"e &ointWs location by
... t"e given #= and y=o--sets.
... De#am&leEVor e#am&le/
... DcodeE
... *oint & + ne, *oint(9K);
... &.1ranslate(=29);
... D.codeE
... results in DcE&D.cEWs "aving t"e value (8Y).
... D.e#am&leE
... D.summaryE
... D&aramEDcE#orD.cE is t"e relative #=o--set.D.&aramE
... D&aramEDcEyorD.cE is t"e relative y=o--set.D.&aramE
... Dsee cre-+"Move".E
&ublic void 1ranslate(int #or int yor) {
I <+ #or;
` <+ yor;
!
"7' Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
+ppendix + ,ocu)entation co))ents
... DsummaryE1"is met"od determines ,"et"er t,o *oints "ave t"e same
... location.D.summaryE
... D&aramEDcEoD.cE is t"e object to be com&ared to t"e current object.
... D.&aramE
... DreturnsE1rue i- t"e *oints "ave t"e same location and t"ey "ave
... t"e e#act same ty&e; ot"er,ise -alse.D.returnsE
... Dseealso cre-+"o&erator++".E
... Dseealso cre-+"o&erator@+".E
&ublic override bool )Quals(object o) {
i- (o ++ null) {
return -alse;
!
i- (t"is ++ o) {
return true;
!
i- (Set1y&e() ++ o.Set1y&e()) {
*oint & + (*oint)o;
return (I ++ &.I) FF (` ++ &.`);
!
return -alse;
!
... DsummaryEOe&ort a &ointWs location as a string.D.summaryE
... DreturnsE' string re&resenting a &ointWs location in t"e -orm (#y)
... ,it"out any leading training or embedded ,"ites&ace.D.returnsE
&ublic override string 1oString() {
return "(" < I < "" < ` < ")";
!
... DsummaryE1"is o&erator determines ,"et"er t,o *oints "ave t"e same
... location.D.summaryE
... D&aramEDcE&2D.cE is t"e -irst *oint to be com&ared.D.&aramE
... D&aramEDcE&8D.cE is t"e second *oint to be com&ared.D.&aramE
... DreturnsE1rue i- t"e *oints "ave t"e same location and t"ey "ave
... t"e e#act same ty&e; ot"er,ise -alse.D.returnsE
... Dseealso cre-+")Quals".E
... Dseealso cre-+"o&erator@+".E
&ublic static bool o&erator++(*oint &2 *oint &8) {
i- ((object)&2 ++ null HH (object)&8 ++ null) {
return -alse;
!
i- (&2.Set1y&e() ++ &8.Set1y&e()) {
return (&2.I ++ &8.I) FF (&2.` ++ &8.`);
!
return -alse;
!
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. "77
C# Language Specification
... DsummaryE1"is o&erator determines ,"et"er t,o *oints "ave t"e same
... location.D.summaryE
... D&aramEDcE&2D.cE is t"e -irst *oint to be com&ared.D.&aramE
... D&aramEDcE&8D.cE is t"e second *oint to be com&ared.D.&aramE
... DreturnsE1rue i- t"e *oints do not "ave t"e same location and t"e
... e#act same ty&e; ot"er,ise -alse.D.returnsE
... Dseealso cre-+")Quals".E
... Dseealso cre-+"o&erator++".E
&ublic static bool o&erator@+(*oint &2 *oint &8) {
return @(&2 ++ &8);
!
... DsummaryE1"is is t"e entry &oint o- t"e *oint class testing
... &rogram.
... D&araE1"is &rogram tests eac" met"od and o&erator and
... is intended to be run a-ter any non=trvial maintenance "as
... been &er-ormed on t"e *oint class.D.&araED.summaryE
&ublic static void Main() {
.. class test code goes "ere
!
!
!
*.#.2 :esulting D)L
Here is t+e output produced by one documentation generator w+en given t+e source code 0or class *oint-
s+own aboveC
D7#ml version+"2.3"7E
DdocE
DassemblyE
DnameE*ointD.nameE
D.assemblyE
DmembersE
Dmember name+"1/Sra&"ics.*oint"E
DsummaryEClass DcE*ointD.cE models a &oint in a t,o=dimensional
&lane.
D.summaryE
D.memberE
Dmember name+"V/Sra&"ics.*oint.#"E
DsummaryE$nstance variable DcE#D.cE re&resents t"e &ointWs
#=coordinate.D.summaryE
D.memberE
Dmember name+"V/Sra&"ics.*oint.y"E
DsummaryE$nstance variable DcEyD.cE re&resents t"e &ointWs
y=coordinate.D.summaryE
D.memberE
Dmember name+"M/Sra&"ics.*oint.0ctor"E
DsummaryE1"is constructor initiali?es t"e ne, *oint to
(33).D.summaryE
D.memberE
"7$ Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
+ppendix + ,ocu)entation co))ents
Dmember name+"M/Sra&"ics.*oint.0ctor(System.$nt98System.$nt98)"E
DsummaryE1"is constructor initiali?es t"e ne, *oint to
(D&aramre- name+"#or".ED&aramre- name+"yor".E).D.summaryE
D&aramEDcE#orD.cE is t"e ne, *ointWs #=coordinate.D.&aramE
D&aramEDcEyorD.cE is t"e ne, *ointWs y=coordinate.D.&aramE
D.memberE
Dmember name+"M/Sra&"ics.*oint.Move(System.$nt98System.$nt98)"E
DsummaryE1"is met"od c"anges t"e &ointWs location to
t"e given coordinates.D.summaryE
D&aramEDcE#orD.cE is t"e ne, #=coordinate.D.&aramE
D&aramEDcEyorD.cE is t"e ne, y=coordinate.D.&aramE
Dsee
cre-+"M/Sra&"ics.*oint.1ranslate(System.$nt98System.$nt98)".E
D.memberE
Dmember
name+"M/Sra&"ics.*oint.1ranslate(System.$nt98System.$nt98)"E
DsummaryE1"is met"od c"anges t"e &ointWs location by
t"e given #= and y=o--sets.
De#am&leEVor e#am&le/
DcodeE
*oint & + ne, *oint(9K);
&.1ranslate(=29);
D.codeE
results in DcE&D.cEWs "aving t"e value (8Y).
D.e#am&leE
D.summaryE
D&aramEDcE#orD.cE is t"e relative #=o--set.D.&aramE
D&aramEDcEyorD.cE is t"e relative y=o--set.D.&aramE
Dsee cre-+"M/Sra&"ics.*oint.Move(System.$nt98System.$nt98)".E
D.memberE
Dmember name+"M/Sra&"ics.*oint.)Quals(System.%bject)"E
DsummaryE1"is met"od determines ,"et"er t,o *oints "ave t"e same
location.D.summaryE
D&aramEDcEoD.cE is t"e object to be com&ared to t"e current
object.
D.&aramE
DreturnsE1rue i- t"e *oints "ave t"e same location and t"ey "ave
t"e e#act same ty&e; ot"er,ise -alse.D.returnsE
Dseealso
cre-+"M/Sra&"ics.*oint.o&[)Quality(Sra&"ics.*ointSra&"ics.*oint)".E
Dseealso
cre-+"M/Sra&"ics.*oint.o&[$neQuality(Sra&"ics.*ointSra&"ics.*oint)".E
D.memberE
Dmember name+"M/Sra&"ics.*oint.1oString"E
DsummaryEOe&ort a &ointWs location as a string.D.summaryE
DreturnsE' string re&resenting a &ointWs location in t"e -orm
(#y)
,it"out any leading training or embedded ,"ites&ace.D.returnsE
D.memberE
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. "7!
C# Language Specification
Dmember
name+"M/Sra&"ics.*oint.o&[)Quality(Sra&"ics.*ointSra&"ics.*oint)"E
DsummaryE1"is o&erator determines ,"et"er t,o *oints "ave t"e
same
location.D.summaryE
D&aramEDcE&2D.cE is t"e -irst *oint to be com&ared.D.&aramE
D&aramEDcE&8D.cE is t"e second *oint to be com&ared.D.&aramE
DreturnsE1rue i- t"e *oints "ave t"e same location and t"ey "ave
t"e e#act same ty&e; ot"er,ise -alse.D.returnsE
Dseealso cre-+"M/Sra&"ics.*oint.)Quals(System.%bject)".E
Dseealso
cre-+"M/Sra&"ics.*oint.o&[$neQuality(Sra&"ics.*ointSra&"ics.*oint)".E
D.memberE
Dmember
name+"M/Sra&"ics.*oint.o&[$neQuality(Sra&"ics.*ointSra&"ics.*oint)"E
DsummaryE1"is o&erator determines ,"et"er t,o *oints "ave t"e
same
location.D.summaryE
D&aramEDcE&2D.cE is t"e -irst *oint to be com&ared.D.&aramE
D&aramEDcE&8D.cE is t"e second *oint to be com&ared.D.&aramE
DreturnsE1rue i- t"e *oints do not "ave t"e same location and
t"e
e#act same ty&e; ot"er,ise -alse.D.returnsE
Dseealso cre-+"M/Sra&"ics.*oint.)Quals(System.%bject)".E
Dseealso
cre-+"M/Sra&"ics.*oint.o&[)Quality(Sra&"ics.*ointSra&"ics.*oint)".E
D.memberE
Dmember name+"M/Sra&"ics.*oint.Main"E
DsummaryE1"is is t"e entry &oint o- t"e *oint class testing
&rogram.
D&araE1"is &rogram tests eac" met"od and o&erator and
is intended to be run a-ter any non=trvial maintenance "as
been &er-ormed on t"e *oint class.D.&araED.summaryE
D.memberE
Dmember name+"*/Sra&"ics.*oint.I"E
DvalueE*ro&erty DcEID.cE re&resents t"e &ointWs
#=coordinate.D.valueE
D.memberE
Dmember name+"*/Sra&"ics.*oint.`"E
DvalueE*ro&erty DcE`D.cE re&resents t"e &ointWs
y=coordinate.D.valueE
D.memberE
D.membersE
D.docE
"$* Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
+ppendix C /eferences
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. "$1
C# Language Specification
+. 3raar
T+is appendi contains summaries o0 t+e leical and syntactic grammars 0ound in t+e main document- and o0 t+e
grammar etensions 0or unsa0e code. 4rammar productions appear +ere in t+e same order t+at t+ey appear in t+e
main document.
+.1 Le%ical graar
inp!t.
inp!t-sectionopt
inp!t-section.
inp!t-section-part
inp!t-section inp!t-section-part
inp!t-section-part.
inp!t-ele%entsopt new-line
pp-directive
inp!t-ele%ents.
inp!t-ele%ent
inp!t-ele%ents inp!t-ele%ent
inp!t-ele%ent.
whitespace
co%%ent
to&en
+.1.1 Line terinators
new-line.
Carriage ret!rn character 0U+000D1
2ine feed character 0U+000A1
Carriage ret!rn character 0U+000D1 followed ,+ line feed character 0U+000A1
=et line c+aracter JU+0085M
2ine separator character 0U+20281
4aragraph separator character 0U+20291
+.1.2 Coents
co%%ent.
single-line-co%%ent
deli%ited-co%%ent
single-line-co%%ent.
// inp!t-charactersopt
inp!t-characters.
inp!t-character
inp!t-characters inp!t-character
"$2 Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
+ppendix C /eferences
inp!t-character.
An+ 'nicode character e/cept a new-line-character
new-line-character.
Carriage ret!rn character 0U+000D1
2ine feed character 0U+000A1
=et line c+aracter JU+0085M
2ine separator character 0U+20281
4aragraph separator character 0U+20291
deli%ited-co%%ent.
/* deli%ited-co%%ent-te/topt asteris&s /
deli%ited-co%%ent-te/t.
deli%ited-co%%ent-section
deli%ited-co%%ent-te/t deli%ited-co%%ent-section
deli%ited-co%%ent-section.
/
asteris&sopt not-slash-or-asteris&
asteris&s.
*
asteris&s *
not-slash-or-asteris&.
An+ 'nicode character e/cept / or *
+.1.3 4-ite space
whitespace.
An+ character with 'nicode class 5s
6ori-ontal ta, character 0U+00091
ertical ta, character 0U+000B1
7or% feed character 0U+000C1
+.1.# To5ens
to&en.
identifier
&e+word
integer-literal
real-literal
character-literal
string-literal
operator-or-p!nct!ator
+.1.& 6nicode c-aracter escape se7uences
!nicode-escape-se8!ence.
\u he/-digit he/-digit he/-digit he/-digit
\U he/-digit he/-digit he/-digit he/-digit he/-digit he/-digit he/-digit he/-digit
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. "$3
C# Language Specification
+.1.' Identifiers
identifier.
availa,le-identifier
@ identifier-or-&e+word
availa,le-identifier.
An identifier-or-&e+word that is not a &e+word
identifier-or-&e+word.
identifier-start-character identifier-part-charactersopt
identifier-start-character.
letter-character
0the !nderscore character U+005F1
identifier-part-characters.
identifier-part-character
identifier-part-characters identifier-part-character
identifier-part-character.
letter-character
deci%al-digit-character
connecting-character
co%,ining-character
for%atting-character
letter-character.
A 'nicode character of classes 2!, 2l, 2t, 2%, 2o, or 3l
A !nicode-escape-se8!ence representing a character of classes 2!, 2l, 2t, 2%, 2o, or 3l
co%,ining-character.
A 'nicode character of classes Mn or Mc
A !nicode-escape-se8!ence representing a character of classes Mn or Mc
deci%al-digit-character.
A 'nicode character of the class 3d
A !nicode-escape-se8!ence representing a character of the class 3d
connecting-character.
A 'nicode character of the class 4c
A !nicode-escape-se8!ence representing a character of the class 4c
for%atting-character.
A 'nicode character of the class Cf
A !nicode-escape-se8!ence representing a character of the class Cf
"$" Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
+ppendix C /eferences
+.1.. 8e!words
&e+word. one of
!"#$%!&$ !# "!#e "''l "%e!(
")$e &!#e &!$&h &h!% &he&(ed
&l!## &'*#$ &'*$i*ue de&im!l def!ul$
dele+!$e d' d'u"le el#e e*um
e,e*$ e-.li&i$ e-$e%* f!l#e fi*!ll)
fi-ed fl'!$ f'% f'%e!&h +'$'
if im.li&i$ i* i*$ i*$e%f!&e
i*$e%*!l i# l'&( l'*+ *!me#.!&e
*ew *ull '"/e&$ '.e%!$'% 'u$
',e%%ide .!%!m# .%i,!$e .%'$e&$ed .u"li&
%e!d'*l) %ef %e$u%* #")$e #e!led
#h'%$ #i0e'f #$!&(!ll'& #$!$i& #$%i*+
#$%u&$ #wi$&h $hi# $h%'w $%ue
$%) $).e'f ui*$ ul'*+ u*&he&(ed
u*#!fe u#h'%$ u#i*+ ,i%$u!l ,'id
,'l!$ile while
+.1.0 Literals
literal.
,oolean-literal
integer-literal
real-literal
character-literal
string-literal
n!ll-literal
,oolean-literal.
$%ue
f!l#e
integer-literal.
deci%al-integer-literal
he/adeci%al-integer-literal
deci%al-integer-literal.
deci%al-digits integer-t+pe-s!ffi/opt
deci%al-digits.
deci%al-digit
deci%al-digits deci%al-digit
deci%al-digit. one of
0 1 2 2 3 5 4 5 8 9
integer-t+pe-s!ffi/. one of
U u 6 l U6 Ul u6 ul 6U 6u lU lu
he/adeci%al-integer-literal.
0- he/-digits integer-t+pe-s!ffi/opt
07 he/-digits integer-t+pe-s!ffi/opt
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. "$
C# Language Specification
he/-digits.
he/-digit
he/-digits he/-digit
he/-digit. one of
0 1 2 2 3 5 4 5 8 9 A B C D 8 F ! " & d e f
real-literal.
deci%al-digits 9 deci%al-digits e/ponent-partopt real-t+pe-s!ffi/opt
9 deci%al-digits e/ponent-partopt real-t+pe-s!ffi/opt
deci%al-digits e/ponent-part real-t+pe-s!ffi/opt
deci%al-digits real-t+pe-s!ffi/
e/ponent-part.
e signopt deci%al-digits
8 signopt deci%al-digits
sign. one of
+ :
real-t+pe-s!ffi/. one of
F f D d M m
character-literal.
; character ;
character.
single-character
si%ple-escape-se8!ence
he/adeci%al-escape-se8!ence
!nicode-escape-se8!ence
single-character.
An+ character e/cept ; 0U+00251, \ 0U+005C1, and new-line-character
si%ple-escape-se8!ence. one of
\; \< \\ \0 \! \" \f \* \% \$ \,
he/adeci%al-escape-se8!ence.
\- he/-digit he/-digitopt he/-digitopt he/-digitopt
string-literal.
reg!lar-string-literal
ver,ati%-string-literal
reg!lar-string-literal.
< reg!lar-string-literal-charactersopt <
reg!lar-string-literal-characters.
reg!lar-string-literal-character
reg!lar-string-literal-characters reg!lar-string-literal-character
reg!lar-string-literal-character.
single-reg!lar-string-literal-character
si%ple-escape-se8!ence
he/adeci%al-escape-se8!ence
!nicode-escape-se8!ence
"$' Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
+ppendix C /eferences
single-reg!lar-string-literal-character.
An+ character e/cept < 0U+00221, \ 0U+005C1, and new-line-character
ver,ati%-string-literal.
@< ver,ati% -string-literal-charactersopt <
ver,ati%-string-literal-characters.
ver,ati%-string-literal-character
ver,ati%-string-literal-characters ver,ati%-string-literal-character
ver,ati%-string-literal-character.
single-ver,ati%-string-literal-character
8!ote-escape-se8!ence
single-ver,ati%-string-literal-character.
an+ character e/cept <
8!ote-escape-se8!ence.
<<
n!ll-literal.
*ull
+.1.1 /perators and punctuators
operator-or-p!nct!ator. one of
{ } = > ( ) 9 ? @ A
+ : * / B C D E F G
H I J K KK @@ ++ :: CC DD
:J HH FH IH JH +H :H *H /H BH
CH DH EH II IIH HJ
right-shift.
J;J
right-shift-assign%ent.
J;JH
+.1.10 Pre9processing directi"es
pp-directive.
pp-declaration
pp-conditional
pp-line
pp-diagnostic
pp-region
pp-prag%a
conditional-s+%,ol.
An+ identifier-or-&e+word e/cept $%ue or f!l#e
pp-e/pression.
whitespaceopt pp-or-e/pression whitespaceopt
pp-or-e/pression.
pp-and-e/pression
pp-or-e/pression whitespaceopt DD whitespaceopt pp-and-e/pression
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. "$7
C# Language Specification
pp-and-e/pression.
pp-e8!alit+-e/pression
pp-and-e/pression whitespaceopt CC whitespaceopt pp-e8!alit+-e/pression
pp-e8!alit+-e/pression.
pp-!nar+-e/pression
pp-e8!alit+-e/pression whitespaceopt HH whitespaceopt pp-!nar+-e/pression
pp-e8!alit+-e/pression whitespaceopt FH whitespaceopt pp-!nar+-e/pression
pp-!nar+-e/pression.
pp-pri%ar+-e/pression
F whitespaceopt pp-!nar+-e/pression
pp-pri%ar+-e/pression.
$%ue
f!l#e
conditional-s+%,ol
( whitespaceopt pp-e/pression whitespaceopt )
pp-declaration.
whitespaceopt L whitespaceopt defi*e whitespace conditional-s+%,ol pp-new-line
whitespaceopt L whitespaceopt u*def whitespace conditional-s+%,ol pp-new-line
pp-new-line.
whitespaceopt single-line-co%%entopt new-line
pp-conditional.
pp-if-section pp-elif-sectionsopt pp-else-sectionopt pp-endif
pp-if-section.
whitespaceopt L whitespaceopt if whitespace pp-e/pression pp-new-line conditional-
sectionopt
pp-elif-sections.
pp-elif-section
pp-elif-sections pp-elif-section
pp-elif-section.
whitespaceopt L whitespaceopt elif whitespace pp-e/pression pp-new-line conditional-
sectionopt
pp-else-section.
whitespaceopt L whitespaceopt el#e pp-new-line conditional-sectionopt
pp-endif.
whitespaceopt L whitespaceopt e*dif pp-new-line
conditional-section.
inp!t-section
s&ipped-section
s&ipped-section.
s&ipped-section-part
s&ipped-section s&ipped-section-part
s&ipped-section-part.
s&ipped-charactersopt new-line
pp-directive
"$$ Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
+ppendix C /eferences
s&ipped-characters.
whitespaceopt not-n!%,er-sign inp!t-charactersopt
not-n!%,er-sign.
An+ inp!t-character e/cept L
pp-diagnostic.
whitespaceopt L whitespaceopt e%%'% pp-%essage
whitespaceopt L whitespaceopt w!%*i*+ pp-%essage
pp-%essage.
new-line
whitespace inp!t-charactersopt new-line
pp-region.
pp-start-region conditional-sectionopt pp-end-region
pp-start-region.
whitespaceopt L whitespaceopt %e+i'* pp-%essage
pp-end-region.
whitespaceopt L whitespaceopt e*d%e+i'* pp-%essage
pp-line.
whitespaceopt L whitespaceopt li*e whitespace line-indicator pp-new-line
line-indicator.
deci%al-digits whitespace file-na%e
deci%al-digits
def!ul$
hidde*
file-na%e.
< file-na%e-characters <
file-na%e-characters.
file-na%e-character
file-na%e-characters file-na%e-character
file-na%e-character.
An+ inp!t-character e/cept <
pp-prag%a.
whitespaceopt L whitespaceopt .%!+m! whitespace prag%a-,od+ pp-new-line
prag%a-,od+.
prag%a-warning-,od+
prag%a-warning-,od+.
w!%*i*+ whitespace warning-action
w!%*i*+ whitespace warning-action whitespace warning-list
warning-action.
di#!"le
%e#$'%e
warning-list.
deci%al-digits
warning-list whitespaceopt ? whitespaceopt deci%al-digits
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. "$!
C# Language Specification
+.2 S!ntactic graar
+.2.1 +asic concepts
na%espace-na%e.
na%espace-or-t+pe-na%e
t+pe-na%e.
na%espace-or-t+pe-na%e
na%espace-or-t+pe-na%e.
identifier t+pe-arg!%ent-listopt
na%espace-or-t+pe-na%e 9 identifier t+pe-arg!%ent-listop
8!alified-alias-%e%,er
+.2.2 T!pes
t+pe.
val!e-t+pe
reference-t+pe
t+pe-para%eter
val!e-t+pe.
str!ct-t+pe
en!%-t+pe
str!ct-t+pe.
t+pe-na%e
si%ple-t+pe
n!lla,le-t+pe
si%ple-t+pe.
n!%eric-t+pe
"''l
n!%eric-t+pe.
integral-t+pe
floating-point-t+pe
de&im!l
integral-t+pe.
#")$e
")$e
#h'%$
u#h'%$
i*$
ui*$
l'*+
ul'*+
&h!%
floating-point-t+pe.
fl'!$
d'u"le
n!lla,le-t+pe.
non-n!lla,le-val!e-t+pe K
"!* Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
+ppendix C /eferences
non-n!lla,le-val!e-t+pe.
t+pe
en!%-t+pe.
t+pe-na%e
reference-t+pe.
class-t+pe
interface-t+pe
arra+-t+pe
delegate-t+pe
class-t+pe.
t+pe-na%e
'"/e&$
#$%i*+
interface-t+pe.
t+pe-na%e
arra+-t+pe.
non-arra+-t+pe ran&-specifiers
non-arra+-t+pe.
t+pe
ran&-specifiers.
ran&-specifier
ran&-specifiers ran&-specifier
ran&-specifier.
= di%-separatorsopt >
di%-separators.
?
di%-separators ?
delegate-t+pe.
t+pe-na%e
t+pe-arg!%ent-list.
I t+pe-arg!%ents J
t+pe-arg!%ents.
t+pe-arg!%ent
t+pe-arg!%ents ? t+pe-arg!%ent
t+pe-arg!%ent.
t+pe
t+pe-para%eter.
identifier
+.2.3 Variables
varia,le-reference.
e/pression
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. "!1
C# Language Specification
+.2.# $%pressions
arg!%ent-list.
arg!%ent
arg!%ent-list ? arg!%ent
arg!%ent.
e/pression
%ef varia,le-reference
'u$ varia,le-reference
pri%ar+-e/pression.
pri%ar+-no-arra+-creation-e/pression
arra+-creation-e/pression
pri%ar+-no-arra+-creation-e/pression.
literal
si%ple-na%e
parenthesi-ed-e/pression
%e%,er-access
invocation-e/pression
ele%ent-access
this-access
,ase-access
post-incre%ent-e/pression
post-decre%ent-e/pression
o,<ect-creation-e/pression
delegate-creation-e/pression
anon+%o!s-o,<ect-creation-e/pression
t+peof-e/pression
chec&ed-e/pression
!nchec&ed-e/pression
defa!lt-val!e-e/pression
anon+%o!s-%ethod-e/pression
si%ple-na%e.
identifier t+pe-arg!%ent-listopt
parenthesi-ed-e/pression.
( e/pression )
%e%,er-access.
pri%ar+-e/pression 9 identifier t+pe-arg!%ent-listopt
predefined-t+pe 9 identifier t+pe-arg!%ent-listopt
8!alified-alias-%e%,er 9 identifier
predefined-t+pe. one of
"''l ")$e &h!% de&im!l d'u"le fl'!$ i*$ l'*+
'"/e&$ #")$e #h'%$ #$%i*+ ui*$ ul'*+ u#h'%$
invocation-e/pression.
pri%ar+-e/pression ( arg!%ent-listopt )
ele%ent-access.
pri%ar+-no-arra+-creation-e/pression = e/pression-list >
"!2 Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
+ppendix C /eferences
e/pression-list.
e/pression
e/pression-list ? e/pression
this-access.
$hi#
,ase-access.
"!#e 9 identifier
"!#e = e/pression-list >
post-incre%ent-e/pression.
pri%ar+-e/pression ++
post-decre%ent-e/pression.
pri%ar+-e/pression ::
o,<ect-creation-e/pression.
*ew t+pe ( arg!%ent-listopt ) o,<ect-or-collection-initiali-eropt
*ew t+pe o,<ect-or-collection-initiali-er
o,<ect-or-collection-initiali-er.
o,<ect-initiali-er
collection-initiali-er
o,<ect-initiali-er.
{ %e%,er-initiali-er-listopt }
{ %e%,er-initiali-er-list ? }
%e%,er-initiali-er-list.
%e%,er-initiali-er
%e%,er-initiali-er-list ? %e%,er-initiali-er
%e%,er-initiali-er.
identifier = initiali-er-val!e
initiali-er-val!e.
e/pression
o,<ect-or-collection-initiali-er
collection-initiali-er.
{ ele%ent-initiali-er-list }
{ ele%ent-initiali-er-list ? }
ele%ent-initiali-er-list.
ele%ent-initiali-er
ele%ent-initiali-er-list ? ele%ent-initiali-er
ele%ent-initiali-er.
non-assign%ent-e/pression
{ e/pression-list }
arra+-creation-e/pression.
*ew non-arra+-t+pe = e/pression-list > ran&-specifiersopt arra+-initiali-eropt
*ew arra+-t+pe arra+-initiali-er
*ew ran&-specifier arra+-initiali-er
delegate-creation-e/pression.
*ew delegate-t+pe ( e/pression )
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. "!3
C# Language Specification
anon+%o!s-o,<ect-creation-e/pression.
*ew anon+%o!s-o,<ect-initiali-er
anon+%o!s-o,<ect-initiali-er.
{ %e%,er-declarator-listopt }
{ %e%,er-declarator-list ? }
%e%,er-declarator-list.
%e%,er-declarator
%e%,er-declarator-list ? %e%,er-declarator
%e%,er-declarator.
si%ple-na%e
%e%,er-access
identifier = e/pression
t+peof-e/pression.
$).e'f ( t+pe )
$).e'f ( !n,o!nd-t+pe-na%e )
$).e'f ( ,'id )
!n,o!nd-t+pe-na%e.
identifier generic-di%ension-specifieropt
identifier @@ identifier generic-di%ension-specifieropt
!n,o!nd-t+pe-na%e . identifier generic-di%ension-specifieropt
generic-di%ension-specifier.
I co%%asopt J
co%%as.
?
co%%as ?
chec&ed-e/pression.
&he&(ed ( e/pression )
!nchec&ed-e/pression.
u*&he&(ed ( e/pression )
defa!lt-val!e-e/pression.
def!ul$ ( t+pe )
!nar+-e/pression.
pri%ar+-e/pression
+ !nar+-e/pression
: !nar+-e/pression
F !nar+-e/pression
G !nar+-e/pression
pre-incre%ent-e/pression
pre-decre%ent-e/pression
cast-e/pression
pre-incre%ent-e/pression.
++ !nar+-e/pression
pre-decre%ent-e/pression.
:: !nar+-e/pression
"!" Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
+ppendix C /eferences
cast-e/pression.
( t+pe ) !nar+-e/pression
%!ltiplicative-e/pression.
!nar+-e/pression
%!ltiplicative-e/pression * !nar+-e/pression
%!ltiplicative-e/pression / !nar+-e/pression
%!ltiplicative-e/pression B !nar+-e/pression
additive-e/pression.
%!ltiplicative-e/pression
additive-e/pression + %!ltiplicative-e/pression
additive-e/pression M %!ltiplicative-e/pression
shift-e/pression.
additive-e/pression
shift-e/pression II additive-e/pression
shift-e/pression right-shift additive-e/pression
relational-e/pression.
shift-e/pression
relational-e/pression I shift-e/pression
relational-e/pression J shift-e/pression
relational-e/pression IH shift-e/pression
relational-e/pression JH shift-e/pression
relational-e/pression i# t+pe
relational-e/pression !# t+pe
e8!alit+-e/pression.
relational-e/pression
e8!alit+-e/pression HH relational-e/pression
e8!alit+-e/pression FH relational-e/pression
and-e/pression.
e8!alit+-e/pression
and-e/pression C e8!alit+-e/pression
e/cl!sive-or-e/pression.
and-e/pression
e/cl!sive-or-e/pression E and-e/pression
incl!sive-or-e/pression.
e/cl!sive-or-e/pression
incl!sive-or-e/pression D e/cl!sive-or-e/pression
conditional-and-e/pression.
incl!sive-or-e/pression
conditional-and-e/pression CC incl!sive-or-e/pression
conditional-or-e/pression.
conditional-and-e/pression
conditional-or-e/pression DD conditional-and-e/pression
n!ll-coalescing-e/pression.
conditional-or-e/pression
conditional-or-e/pression KK n!ll-coalescing-e/pression
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. "!
C# Language Specification
conditional-e/pression.
n!ll-coalescing-e/pression
n!ll-coalescing-e/pression K e/pression @ e/pression
la%,da-e/pression.
anon+%o!s-f!nction-signat!re HJ anon+%o!s-f!nction-,od+
anon+%o!s-%ethod-e/pression.
dele+!$e e/plicit-anon+%o!s-f!nction-signat!reopt ,loc&
anon+%o!s-f!nction-signat!re.
e/plicit-anon+%o!s-f!nction-signat!re
i%plicit-anon+%o!s-f!nction-signat!re
e/plicit-anon+%o!s-f!nction-signat!re.
( e/plicit-anon+%o!s-f!nction-para%eter-listopt )
e/plicit-anon+%o!s-f!nction-para%eter-list
e/plicit-anon+%o!s-f!nction-para%eter
e/plicit-anon+%o!s-f!nction-para%eter-list ? e/plicit-anon+%o!s-f!nction-para%eter
e/plicit-anon+%o!s-f!nction-para%eter.
anon+%o!s-f!nction-para%eter-%odifieropt t+pe identifier
anon+%o!s-f!nction-para%eter-%odifier.
%ef
'u$
i%plicit-anon+%o!s-f!nction-signat!re.
( i%plicit-anon+%o!s-f!nction-para%eter-listopt )
i%plicit-anon+%o!s-f!nction-para%eter
i%plicit-anon+%o!s-f!nction-para%eter-list
i%plicit-anon+%o!s-f!nction-para%eter
i%plicit-anon+%o!s-f!nction-para%eter-list ? i%plicit-anon+%o!s-f!nction-para%eter
i%plicit-anon+%o!s-f!nction-para%eter.
identifier
anon+%o!s-f!nction-,od+.
e/pression
,loc&
8!er+-e/pression.
fro%-cla!se 8!er+-,od+
fro%-cla!se.
f%'m t+peopt identifier i* e/pression
8!er+-,od+.
8!er+-,od+-cla!sesopt select-or-gro!p-cla!se 8!er+-contin!ationopt
8!er+-,od+-cla!ses.
8!er+-,od+-cla!se
8!er+-,od+-cla!ses 8!er+-,od+-cla!se
"!' Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
+ppendix C /eferences
8!er+-,od+-cla!se.
fro%-cla!se
let-cla!se
where-cla!se
<oin-cla!se
<oin-into-cla!se
order,+-cla!se
let-cla!se.
le$ identifier H e/pression
where-cla!se.
whe%e ,oolean-e/pression
<oin-cla!se.
/'i* t+peopt identifier i* e/pression '* e/pression eNu!l# e/pression
<oin-into-cla!se.
/'i* t+peopt identifier i* e/pression '* e/pression eNu!l# e/pression i*$' identifier
order,+-cla!se.
'%de%") orderings
orderings.
ordering
orderings ? ordering
ordering.
e/pression ordering-directionopt
ordering-direction.
!#&e*di*+
de#&e*di*+
select-or-gro!p-cla!se.
select-cla!se
gro!p-cla!se
select-cla!se.
#ele&$ e/pression
gro!p-cla!se.
+%'u. e/pression ") e/pression
8!er+-contin!ation.
i*$' identifier 8!er+-,od+
assign%ent.
!nar+-e/pression assign%ent-operator e/pression
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. "!7
C# Language Specification
assign%ent-operator.
H
+H
:H
*H
/H
BH
CH
DH
EH
IIH
right-shift-assign%ent
e/pression.
non-assign%ent-e/pression
assign%ent
non-assign%ent-e/pression.
conditional-e/pression
la%,da-e/pression
8!er+-e/pression
constant-e/pression.
e/pression
,oolean-e/pression.
e/pression
+.2.& Stateents
state%ent.
la,eled-state%ent
declaration-state%ent
e%,edded-state%ent
e%,edded-state%ent.
,loc&
e%pt+-state%ent
e/pression-state%ent
selection-state%ent
iteration-state%ent
<!%p-state%ent
tr+-state%ent
chec&ed-state%ent
!nchec&ed-state%ent
loc&-state%ent
!sing-state%ent
+ield-state%ent
,loc&.
{ state%ent-listopt }
state%ent-list.
state%ent
state%ent-list state%ent
"!$ Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
+ppendix C /eferences
e%pt+-state%ent.
A
la,eled-state%ent.
identifier @ state%ent
declaration-state%ent.
local-varia,le-declaration A
local-constant-declaration A
local-varia,le-declaration.
local-varia,le-t+pe local-varia,le-declarators
local-varia,le-t+pe.
t+pe
,!%
local-varia,le-declarators.
local-varia,le-declarator
local-varia,le-declarators ? local-varia,le-declarator
local-varia,le-declarator.
identifier
identifier = local-varia,le-initiali-er
local-varia,le-initiali-er.
e/pression
arra+-initiali-er
local-constant-declaration.
&'*#$ t+pe constant-declarators
constant-declarators.
constant-declarator
constant-declarators ? constant-declarator
constant-declarator.
identifier = constant-e/pression
e/pression-state%ent.
state%ent-e/pression A
state%ent-e/pression.
invocation-e/pression
o,<ect-creation-e/pression
assign%ent
post-incre%ent-e/pression
post-decre%ent-e/pression
pre-incre%ent-e/pression
pre-decre%ent-e/pression
selection-state%ent.
if-state%ent
switch-state%ent
if-state%ent.
if ( ,oolean-e/pression ) e%,edded-state%ent
if ( ,oolean-e/pression ) e%,edded-state%ent el#e e%,edded-state%ent
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. "!!
C# Language Specification
switch-state%ent.
#wi$&h ( e/pression ) switch-,loc&
switch-,loc&.
{ switch-sectionsopt }
switch-sections.
switch-section
switch-sections switch-section
switch-section.
switch-la,els state%ent-list
switch-la,els.
switch-la,el
switch-la,els switch-la,el
switch-la,el.
&!#e constant-e/pression @
def!ul$ @
iteration-state%ent.
while-state%ent
do-state%ent
for-state%ent
foreach-state%ent
while-state%ent.
while ( ,oolean-e/pression ) e%,edded-state%ent
do-state%ent.
d' e%,edded-state%ent while ( ,oolean-e/pression ) A
for-state%ent.
f'% ( for-initiali-eropt A for-conditionopt A for-iteratoropt ) e%,edded-state%ent
for-initiali-er.
local-varia,le-declaration
state%ent-e/pression-list
for-condition.
,oolean-e/pression
for-iterator.
state%ent-e/pression-list
state%ent-e/pression-list.
state%ent-e/pression
state%ent-e/pression-list ? state%ent-e/pression
foreach-state%ent.
f'%e!&h ( local-varia,le-t+pe identifier i* e/pression ) e%,edded-state%ent
<!%p-state%ent.
,rea&-state%ent
contin!e-state%ent
goto-state%ent
ret!rn-state%ent
throw-state%ent
** Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
+ppendix C /eferences
,rea&-state%ent.
"%e!( A
contin!e-state%ent.
&'*$i*ue A
goto-state%ent.
+'$' identifier A
+'$' &!#e constant-e/pression ?
+'$' def!ul$ A
ret!rn-state%ent.
%e$u%* e/pressionopt A
throw-state%ent.
$h%'w e/pressionopt A
tr+-state%ent.
$%) ,loc& catch-cla!ses
$%) ,loc& finall+-cla!se
$%) ,loc& catch-cla!ses finall+-cla!se
catch-cla!ses.
specific-catch-cla!ses general-catch-cla!seopt
specific-catch-cla!sesopt general-catch-cla!se
specific-catch-cla!ses.
specific-catch-cla!se
specific-catch-cla!ses specific-catch-cla!se
specific-catch-cla!se.
&!$&h ( class-t+pe identifieropt ) ,loc&
general-catch-cla!se.
&!$&h ,loc&
finall+-cla!se.
fi*!ll) ,loc&
chec&ed-state%ent.
&he&(ed ,loc&
!nchec&ed-state%ent.
u*&he&(ed ,loc&
loc&-state%ent.
l'&( ( e/pression ) e%,edded-state%ent
!sing-state%ent.
u#i*+ ( reso!rce-ac8!isition ) e%,edded-state%ent
reso!rce-ac8!isition.
local-varia,le-declaration
e/pression
+ield-state%ent.
)ield %e$u%* e/pression A
)ield "%e!( A
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. *1
C# Language Specification
+.2.' ;aespaces
co%pilation-!nit.
e/tern-alias-directivesopt !sing-directivesopt glo,al-attri,!tesopt
na%espace-%e%,er-declarationsopt
na%espace-declaration.
*!me#.!&e 8!alified-identifier na%espace-,od+ Aopt
8!alified-identifier.
identifier
8!alified-identifier 9 identifier
na%espace-,od+.
{ e/tern-alias-directivesopt !sing-directivesopt na%espace-%e%,er-declarationsopt }
e/tern-alias-directives.
e/tern-alias-directive
e/tern-alias-directives e/tern-alias-directive
e/tern-alias-directive.
e-$e%* !li!# identifier A
!sing-directives.
!sing-directive
!sing-directives !sing-directive
!sing-directive.
!sing-alias-directive
!sing-na%espace-directive
!sing-alias-directive.
u#i*+ identifier H na%espace-or-t+pe-na%e A
!sing-na%espace-directive.
u#i*+ na%espace-na%e A
na%espace-%e%,er-declarations.
na%espace-%e%,er-declaration
na%espace-%e%,er-declarations na%espace-%e%,er-declaration
na%espace-%e%,er-declaration.
na%espace-declaration
t+pe-declaration
t+pe-declaration.
class-declaration
str!ct-declaration
interface-declaration
en!%-declaration
delegate-declaration
8!alified-alias-%e%,er.
identifier @@ identifier t+pe-arg!%ent-listopt
*2 Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
+ppendix C /eferences
+.2.. Classes
class-declaration.
attri,!tesopt class-%odifiersopt .!%$i!lopt &l!## identifier t+pe-para%eter-listopt
class-,aseopt t+pe-para%eter-constraints-cla!sesopt class-,od+ Aopt
class-%odifiers.
class-%odifier
class-%odifiers class-%odifier
class-%odifier.
*ew
.u"li&
.%'$e&$ed
i*$e%*!l
.%i,!$e
!"#$%!&$
#e!led
#$!$i&
t+pe-para%eter-list.
I t+pe-para%eters J
t+pe-para%eters.
attri,!tesopt t+pe-para%eter
t+pe-para%eters ? attri,!tesopt t+pe-para%eter
t+pe-para%eter.
identifier
class-,ase.
@ class-t+pe
@ interface-t+pe-list
@ class-t+pe ? interface-t+pe-list
interface-t+pe-list.
interface-t+pe
interface-t+pe-list ? interface-t+pe
t+pe-para%eter-constraints-cla!ses.
t+pe-para%eter-constraints-cla!se
t+pe-para%eter-constraints-cla!ses t+pe-para%eter-constraints-cla!se
t+pe-para%eter-constraints-cla!se.
whe%e t+pe-para%eter @ t+pe-para%eter-constraints
t+pe-para%eter-constraints.
pri%ar+-constraint
secondar+-constraints
constr!ctor-constraint
pri%ar+-constraint ? secondar+-constraints
pri%ar+-constraint ? constr!ctor-constraint
secondar+-constraints ? constr!ctor-constraint
pri%ar+-constraint ? secondar+-constraints ? constr!ctor-constraint
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. *3
C# Language Specification
pri%ar+-constraint.
class-t+pe
&l!##
#$%u&$
secondar+-constraints.
interface-t+pe
t+pe-para%eter
secondar+-constraints ? interface-t+pe
secondar+-constraints ? t+pe-para%eter
constr!ctor-constraint.
*ew ( )
class-,od+.
{ class-%e%,er-declarationsopt }
class-%e%,er-declarations.
class-%e%,er-declaration
class-%e%,er-declarations class-%e%,er-declaration
class-%e%,er-declaration.
constant-declaration
field-declaration
%ethod-declaration
propert+-declaration
event-declaration
inde/er-declaration
operator-declaration
constr!ctor-declaration
destr!ctor-declaration
static-constr!ctor-declaration
t+pe-declaration
constant-declaration.
attri,!tesopt constant-%odifiersopt &'*#$ t+pe constant-declarators A
constant-%odifiers.
constant-%odifier
constant-%odifiers constant-%odifier
constant-%odifier.
*ew
.u"li&
.%'$e&$ed
i*$e%*!l
.%i,!$e
constant-declarators.
constant-declarator
constant-declarators ? constant-declarator
constant-declarator.
identifier = constant-e/pression
field-declaration.
attri,!tesopt field-%odifiersopt t+pe varia,le-declarators A
*" Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
+ppendix C /eferences
field-%odifiers.
field-%odifier
field-%odifiers field-%odifier
field-%odifier.
*ew
.u"li&
.%'$e&$ed
i*$e%*!l
.%i,!$e
#$!$i&
%e!d'*l)
,'l!$ile
varia,le-declarators.
varia,le-declarator
varia,le-declarators ? varia,le-declarator
varia,le-declarator.
identifier
identifier = varia,le-initiali-er
varia,le-initiali-er.
e/pression
arra+-initiali-er
%ethod-declaration.
%ethod-header %ethod-,od+
%ethod-header.
attri,!tesopt %ethod-%odifiersopt .!%$i!lopt ret!rn-t+pe %e%,er-na%e t+pe-para%eter-listopt
( for%al-para%eter-listopt ) t+pe-para%eter-constraints-cla!sesopt
%ethod-%odifiers.
%ethod-%odifier
%ethod-%odifiers %ethod-%odifier
%ethod-%odifier.
*ew
.u"li&
.%'$e&$ed
i*$e%*!l
.%i,!$e
#$!$i&
,i%$u!l
#e!led
',e%%ide
!"#$%!&$
e-$e%*
ret!rn-t+pe.
t+pe
,'id
%e%,er-na%e.
identifier
interface-t+pe 9 identifier
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. *
C# Language Specification
%ethod-,od+.
,loc&
A
for%al-para%eter-list.
fi/ed-para%eters
fi/ed-para%eters ? para%eter-arra+
para%eter-arra+
fi/ed-para%eters.
fi/ed-para%eter
fi/ed-para%eters ? fi/ed-para%eter
fi/ed-para%eter.
attri,!tesopt para%eter-%odifieropt t+pe identifier
para%eter-%odifier.
%ef
'u$
$hi#
para%eter-arra+.
attri,!tesopt .!%!m# arra+-t+pe identifier
propert+-declaration.
attri,!tesopt propert+-%odifiersopt t+pe %e%,er-na%e { accessor-declarations }
propert+-%odifiers.
propert+-%odifier
propert+-%odifiers propert+-%odifier
propert+-%odifier.
*ew
.u"li&
.%'$e&$ed
i*$e%*!l
.%i,!$e
#$!$i&
,i%$u!l
#e!led
',e%%ide
!"#$%!&$
e-$e%*
%e%,er-na%e.
identifier
interface-t+pe 9 identifier
accessor-declarations.
get-accessor-declaration set-accessor-declarationopt
set-accessor-declaration get-accessor-declarationopt
get-accessor-declaration.
attri,!tesopt accessor-%odifieropt +e$ accessor-,od+
set-accessor-declaration.
attri,!tesopt accessor-%odifieropt #e$ accessor-,od+
*' Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
+ppendix C /eferences
accessor-%odifier.
.%'$e&$ed
i*$e%*!l
.%i,!$e
.%'$e&$ed i*$e%*!l
i*$e%*!l .%'$e&$ed
accessor-,od+.
,loc&
A
event-declaration.
attri,!tesopt event-%odifiersopt e,e*$ t+pe varia,le-declarators A
attri,!tesopt event-%odifiersopt e,e*$ t+pe %e%,er-na%e { event-accessor-declarations }
event-%odifiers.
event-%odifier
event-%odifiers event-%odifier
event-%odifier.
*ew
.u"li&
.%'$e&$ed
i*$e%*!l
.%i,!$e
#$!$i&
,i%$u!l
#e!led
',e%%ide
!"#$%!&$
e-$e%*
event-accessor-declarations.
add-accessor-declaration re%ove-accessor-declaration
re%ove-accessor-declaration add-accessor-declaration
add-accessor-declaration.
attri,!tesopt !dd ,loc&
re%ove-accessor-declaration.
attri,!tesopt %em',e ,loc&
inde/er-declaration.
attri,!tesopt inde/er-%odifiersopt inde/er-declarator { accessor-declarations }
inde/er-%odifiers.
inde/er-%odifier
inde/er-%odifiers inde/er-%odifier
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. *7
C# Language Specification
inde/er-%odifier.
*ew
.u"li&
.%'$e&$ed
i*$e%*!l
.%i,!$e
,i%$u!l
#e!led
',e%%ide
!"#$%!&$
e-$e%*
inde/er-declarator.
t+pe $hi# = for%al-para%eter-list >
t+pe interface-t+pe 9 $hi# = for%al-para%eter-list >
operator-declaration.
attri,!tesopt operator-%odifiers operator-declarator operator-,od+
operator-%odifiers.
operator-%odifier
operator-%odifiers operator-%odifier
operator-%odifier.
.u"li&
#$!$i&
e-$e%*
operator-declarator.
!nar+-operator-declarator
,inar+-operator-declarator
conversion-operator-declarator
!nar+-operator-declarator.
t+pe '.e%!$'% overloada,le-!nar+-operator ( t+pe identifier )
overloada,le-!nar+-operator. one of
+ : F G ++ :: $%ue f!l#e
,inar+-operator-declarator.
t+pe '.e%!$'% overloada,le-,inar+-operator ( t+pe identifier ? t+pe identifier )
*$ Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
+ppendix C /eferences
overloada,le-,inar+-operator.
+
:
*
/
B
C
D
E
II
right-shift
HH
FH
J
I
JH
IH
conversion-operator-declarator.
im.li&i$ '.e%!$'% t+pe ( t+pe identifier )
e-.li&i$ '.e%!$'% t+pe ( t+pe identifier )
operator-,od+.
,loc&
A
constr!ctor-declaration.
attri,!tesopt constr!ctor-%odifiersopt constr!ctor-declarator constr!ctor-,od+
constr!ctor-%odifiers.
constr!ctor-%odifier
constr!ctor-%odifiers constr!ctor-%odifier
constr!ctor-%odifier.
.u"li&
.%'$e&$ed
i*$e%*!l
.%i,!$e
e-$e%*
constr!ctor-declarator.
identifier ( for%al-para%eter-listopt ) constr!ctor-initiali-eropt
constr!ctor-initiali-er.
@ "!#e ( arg!%ent-listopt )
@ $hi# ( arg!%ent-listopt )
constr!ctor-,od+.
,loc&
A
static-constr!ctor-declaration.
attri,!tesopt static-constr!ctor-%odifiers identifier ( ) static-constr!ctor-,od+
static-constr!ctor-%odifiers.
e-$e%*opt #$!$i&
#$!$i& e-$e%*opt
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. *!
C# Language Specification
static-constr!ctor-,od+.
,loc&
A
destr!ctor-declaration.
attri,!tesopt e-$e%*opt G identifier ( ) destr!ctor-,od+
destr!ctor-,od+.
,loc&
A
+.2.0 Structs
str!ct-declaration.
attri,!tesopt str!ct-%odifiersopt .!%$i!lopt #$%u&$ identifier t+pe-para%eter-listopt
str!ct-interfacesopt t+pe-para%eter-constraints-cla!sesopt str!ct-,od+ Aopt
str!ct-%odifiers.
str!ct-%odifier
str!ct-%odifiers str!ct-%odifier
str!ct-%odifier.
*ew
.u"li&
.%'$e&$ed
i*$e%*!l
.%i,!$e
str!ct-interfaces.
@ interface-t+pe-list
str!ct-,od+.
{ str!ct-%e%,er-declarationsopt }
str!ct-%e%,er-declarations.
str!ct-%e%,er-declaration
str!ct-%e%,er-declarations str!ct-%e%,er-declaration
str!ct-%e%,er-declaration.
constant-declaration
field-declaration
%ethod-declaration
propert+-declaration
event-declaration
inde/er-declaration
operator-declaration
constr!ctor-declaration
static-constr!ctor-declaration
t+pe-declaration
+.2.1 *rra!s
arra+-t+pe.
non-arra+-t+pe ran&-specifiers
non-arra+-t+pe.
t+pe
1* Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
+ppendix C /eferences
ran&-specifiers.
ran&-specifier
ran&-specifiers ran&-specifier
ran&-specifier.
= di%-separatorsopt >
di%-separators.
?
di%-separators ?
arra+-initiali-er.
{ varia,le-initiali-er-listopt }
{ varia,le-initiali-er-list ? }
varia,le-initiali-er-list.
varia,le-initiali-er
varia,le-initiali-er-list ? varia,le-initiali-er
varia,le-initiali-er.
e/pression
arra+-initiali-er
+.2.10 Interfaces
interface-declaration.
attri,!tesopt interface-%odifiersopt .!%$i!lopt i*$e%f!&e identifier t+pe-para%eter-listopt
interface-,aseopt t+pe-para%eter-constraints-cla!sesopt interface-,od+ Aopt
interface-%odifiers.
interface-%odifier
interface-%odifiers interface-%odifier
interface-%odifier.
*ew
.u"li&
.%'$e&$ed
i*$e%*!l
.%i,!$e
interface-,ase.
@ interface-t+pe-list
interface-,od+.
{ interface-%e%,er-declarationsopt }
interface-%e%,er-declarations.
interface-%e%,er-declaration
interface-%e%,er-declarations interface-%e%,er-declaration
interface-%e%,er-declaration.
interface-%ethod-declaration
interface-propert+-declaration
interface-event-declaration
interface-inde/er-declaration
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 11
C# Language Specification
interface-%ethod-declaration.
attri,!tesopt *ewopt ret!rn-t+pe identifier t+pe-para%eter-list
( for%al-para%eter-listopt ) t+pe-para%eter-constraints-cla!sesopt A
interface-propert+-declaration.
attri,!tesopt *ewopt t+pe identifier { interface-accessors }
interface-accessors.
attri,!tesopt +e$ A
attri,!tesopt #e$ A
attri,!tesopt +e$ A attri,!tesopt #e$ A
attri,!tesopt #e$ A attri,!tesopt +e$ A
interface-event-declaration.
attri,!tesopt *ewopt e,e*$ t+pe identifier A
interface-inde/er-declaration.
attri,!tesopt *ewopt t+pe $hi# = for%al-para%eter-list > { interface-accessors }
+.2.11 $nus
en!%-declaration.
attri,!tesopt en!%-%odifiersopt e*um identifier en!%-,aseopt en!%-,od+ Aopt
en!%-,ase.
@ integral-t+pe
en!%-,od+.
{ en!%-%e%,er-declarationsopt }
{ en!%-%e%,er-declarations ? }
en!%-%odifiers.
en!%-%odifier
en!%-%odifiers en!%-%odifier
en!%-%odifier.
*ew
.u"li&
.%'$e&$ed
i*$e%*!l
.%i,!$e
en!%-%e%,er-declarations.
en!%-%e%,er-declaration
en!%-%e%,er-declarations ? en!%-%e%,er-declaration
en!%-%e%,er-declaration.
attri,!tesopt identifier
attri,!tesopt identifier H constant-e/pression
+.2.12 2elegates
delegate-declaration.
attri,!tesopt delegate-%odifiersopt dele+!$e ret!rn-t+pe identifier t+pe-para%eter-listopt
( for%al-para%eter-listopt ) t+pe-para%eter-constraints-cla!sesopt A
12 Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
+ppendix C /eferences
delegate-%odifiers.
delegate-%odifier
delegate-%odifiers delegate-%odifier
delegate-%odifier.
*ew
.u"li&
.%'$e&$ed
i*$e%*!l
.%i,!$e
+.2.13 *ttributes
glo,al-attri,!tes.
glo,al-attri,!te-sections
glo,al-attri,!te-sections.
glo,al-attri,!te-section
glo,al-attri,!te-sections glo,al-attri,!te-section
glo,al-attri,!te-section.
= glo,al-attri,!te-target-specifier attri,!te-list >
= glo,al-attri,!te-target-specifier attri,!te-list ? >
glo,al-attri,!te-target-specifier.
glo,al-attri,!te-target @
glo,al-attri,!te-target.
!##em"l)
m'dule
attri,!tes.
attri,!te-sections
attri,!te-sections.
attri,!te-section
attri,!te-sections attri,!te-section
attri,!te-section.
= attri,!te-target-specifieropt attri,!te-list >
= attri,!te-target-specifieropt attri,!te-list ? >
attri,!te-target-specifier.
attri,!te-target @
attri,!te-target.
field
e,e*$
me$h'd
.!%!m
.%'.e%$)
%e$u%*
$).e
attri,!te-list.
attri,!te
attri,!te-list ? attri,!te
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 13
C# Language Specification
attri,!te.
attri,!te-na%e attri,!te-arg!%entsopt
attri,!te-na%e.
t+pe-na%e
attri,!te-arg!%ents.
( positional-arg!%ent-listopt )
( positional-arg!%ent-list ? na%ed-arg!%ent-list )
( na%ed-arg!%ent-list )
positional-arg!%ent-list.
positional-arg!%ent
positional-arg!%ent-list ? positional-arg!%ent
positional-arg!%ent.
attri,!te-arg!%ent-e/pression
na%ed-arg!%ent-list.
na%ed-arg!%ent
na%ed-arg!%ent-list ? na%ed-arg!%ent
na%ed-arg!%ent.
identifier H attri,!te-arg!%ent-e/pression
attri,!te-arg!%ent-e/pression.
e/pression
+.3 3raar e%tensions for unsafe code
class-%odifier.
...
u*#!fe
str!ct-%odifier.
...
u*#!fe
interface-%odifier.
...
u*#!fe
delegate-%odifier.
...
u*#!fe
field-%odifier.
...
u*#!fe
%ethod-%odifier.
...
u*#!fe
propert+-%odifier.
...
u*#!fe
1" Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
+ppendix C /eferences
event-%odifier.
...
u*#!fe
inde/er-%odifier.
...
u*#!fe
operator-%odifier.
...
u*#!fe
constr!ctor-%odifier.
...
u*#!fe
destr!ctor-declaration.
attri,!tesopt e-$e%*opt u*#!feopt G identifier ( ) destr!ctor-,od+
attri,!tesopt u*#!feopt e-$e%*opt G identifier ( ) destr!ctor-,od+
static-constr!ctor-%odifiers.
e-$e%*opt u*#!feopt #$!$i&
u*#!feopt e-$e%*opt #$!$i&
e-$e%*opt #$!$i& u*#!feopt
u*#!feopt #$!$i& e-$e%*opt
#$!$i& e-$e%*opt u*#!feopt
#$!$i& u*#!feopt e-$e%*opt
e%,edded-state%ent.
...
!nsafe-state%ent
!nsafe-state%ent.
u*#!fe ,loc&
t+pe.
...
pointer-t+pe
pointer-t+pe.
!n%anaged-t+pe *
,'id *
!n%anaged-t+pe.
t+pe
pri%ar+-no-arra+-creation-e/pression.
...
pointer-%e%,er-access
pointer-ele%ent-access
si-eof-e/pression
!nar+-e/pression.
...
pointer-indirection-e/pression
addressof-e/pression
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 1
C# Language Specification
pointer-indirection-e/pression.
* !nar+-e/pression
pointer-%e%,er-access.
pri%ar+-e/pression :J identifier
pointer-ele%ent-access.
pri%ar+-no-arra+-creation-e/pression = e/pression >
addressof-e/pression.
C !nar+-e/pression
si-eof-e/pression.
#i0e'f ( !n%anaged-t+pe )
e%,edded-state%ent.
...
fi/ed-state%ent
fi/ed-state%ent.
fi-ed ( pointer-t+pe fi/ed-pointer-declarators ) e%,edded-state%ent
fi/ed-pointer-declarators.
fi/ed-pointer-declarator
fi/ed-pointer-declarators ? fi/ed-pointer-declarator
fi/ed-pointer-declarator.
identifier H fi/ed-pointer-initiali-er
fi/ed-pointer-initiali-er.
C varia,le-reference
e/pression
str!ct-%e%,er-declaration.
>
fi/ed-si-e-,!ffer-declaration
fi/ed-si-e-,!ffer-declaration.
attri,!tesopt fi/ed-si-e-,!ffer-%odifiersopt fi-ed ,!ffer-ele%ent-t+pe
fi/ed-si-e-,!ffer-declarators A
fi/ed-si-e-,!ffer-%odifiers.
fi/ed-si-e-,!ffer-%odifier
fi/ed-si-e-,!ffer-%odifier fi/ed-si-e-,!ffer-%odifiers
fi/ed-si-e-,!ffer-%odifier.
*ew
.u"li&
.%'$e&$ed
i*$e%*!l
.%i,!$e
u*#!fe
,!ffer-ele%ent-t+pe.
t+pe
fi/ed-si-e-,!ffer-declarators.
fi/ed-si-e-,!ffer-declarator
fi/ed-si-e-,!ffer-declarator fi/ed-si-e-,!ffer-declarators
1' Copyright Microsoft Corporation 1999-2007. All Rights Reserved.
+ppendix C /eferences
fi/ed-si-e-,!ffer-declarator.
identifier = const-e/pression >
local-varia,le-initiali-er.
>
stac&alloc-initiali-er
stac&alloc-initiali-er.
#$!&(!ll'& !n%anaged-t+pe = e/pression >
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 17
+ppendix C /eferences
C. :eferences
8nicode Consortium. 9he 'nicode (tandard, ersion :.0. (ddison<6esley- ;eading- 'assac+usetts- 2...-
1#)= .<2.1<%1%33"<".
1EEE. A@@@ (tandard for "inar+ 7loating-4oint Arith%etic. (=#1O1EEE #tandard !"4<1$3". (vailable 0rom
+ttpCOOwww.ieee.org.
1#/O1EC. C$$. (=#1O1#/O1EC 14332C1$$3.
Copyright Microsoft Corporation 1999-2007. All Rights Reserved. 1!

Вам также может понравиться