C#3.0PocketReference
byJosephAlbahari;BenAlbahari
Publisher:O'Reilly
PubDate:February15,2008
PrintISBN-13:978-0-59-651922-3
Pages:242
TableofContents|Index
Overview
Thisbookisforbusyprogrammerswhowantasuccinctandyet
readableguidetoC#3.0andLINQ.C#3.0PocketReference
tellsyouexactlywhatyouneedtoknow,withoutlong
introductionsorbloatedsamples.Despiteitsconciseness,this
bookdoesn'tskimpondepthordetail,andembracesthe
conceptualchallengesinlearningC#3.0andLINQ.Tightly
focusedandhighlypractical,thispocketreferencecoversmore
groundthanmanyofthebigbooksonC#.C#3.0Pocket
Referenceincludesplentyofillustrationsandcodeexamplesto
explain:
FeaturesnewtoC#3.0,suchaslambdaexpressions,
anonymoustypes,automaticproperties,andmore
AllaspectsofC#syntax,predefinedtypes,expressions,
andoperators
Creatingclasses,structs,delegatesandevents,enums,
genericsandconstraints,exceptionhandling,anditerators
Thesubtletiesofboxing,operatingoverloading,delegate
covariance,extensionmethodresolution,interface
reimplementation,nullabletypes,andoperatinglifting
LINQ,startingwiththeprinciplesofsequences,deferred
executionandstandardqueryoperators,andfinishingwith
acompletereferencetoquerysyntax-includingmultiple
generators,joining,grouping,andquerycontinuations
Consuming,writing,andreflectingoncustomattributes
You'llalsofindchaptersonunsafecodeandpointers,
preprocessordirectives,XMLdocumentation,andaframework
overview.Ifyou'realreadyfamiliarwithJava,C++,oran
earlierversionofC#,C#3.0PocketReferenceisanideal
choice.Nootherbookoronlineresourcecangetyouupto
speedsoquickly.
C#3.0PocketReference
byJosephAlbahari;BenAlbahari
Publisher:O'Reilly
PubDate:February15,2008
PrintISBN-13:978-0-59-651922-3
Pages:242
TableofContents|Index
C#3.0PocketReference,SecondEdition
Chapter1.C#3.0PocketReference
Section1.1.What'sNewinC#3.0
Section1.2.AFirstC#Program
Section1.3.Syntax
Section1.4.TypeBasics
Section1.5.NumericTypes
Section1.6.BooleanTypeandOperators
Section1.7.StringsandCharacters
Section1.8.Arrays
Section1.9.VariablesandParameters
Section1.10.ExpressionsandOperators
Section1.11.Statements
Section1.12.Namespaces
Section1.13.Classes
Section1.14.Inheritance
Section1.15.TheobjectType
Section1.16.Structs
Section1.17.AccessModifiers
Section1.18.Interfaces
Section1.19.Enums
Section1.20.NestedTypes
Section1.21.Generics
Section1.22.Delegates
Section1.23.Events
Section1.24.LambdaExpressions(C#3.0)
Section1.25.AnonymousMethods
Section1.26.tryStatementsandExceptions
Section1.27.EnumerationandIterators
Section1.28.NullableTypes
Section1.29.OperatorOverloading
Section1.30.ExtensionMethods(C#3.0)
Section1.31.AnonymousTypes(C#3.0)
Section1.32.LINQ(C#3.0)
Section1.33.Attributes
Section1.34.UnsafeCodeandPointers
Section1.35.PreprocessorDirectives
Section1.36.XMLDocumentation
Section1.37.FrameworkOverview
Index
C#3.0PocketReference,SecondEdition
byJosephAlbahariandBenAlbahari
Copyright©2008JosephAlbahariandBenAlbahari.Allrights
reserved.PrintedinCanada.
PublishedbyO'ReillyMedia,Inc.,1005GravensteinHighway
North,Sebastopol,CA95472.
O'Reillybooksmaybepurchasedforeducational,business,or
salespromotionaluse.Onlineeditionsarealsoavailablefor
mosttitles(safari.oreilly.com).Formoreinformation,contact
ourcorporate/institutionalsalesdepartment:(800)998-9938
or
Editor:
LaurelR.T.
Ruma
Cover
Designer:
Karen
Montgomery
Production
Editor:
Loranah
Dimant
Interior
Designer:
DavidFutato
Proofreader:
Loranah
Dimant
Illustrator:
Jessamyn
Read
Indexer:
Angela
Howard
PrintingHistory:
November2002:
FirstEdition.
February2008:
SecondEdition.
NutshellHandbook,theNutshellHandbooklogo,andthe
O'ReillylogoareregisteredtrademarksofO'ReillyMedia,Inc.
ThePocketReference/PocketGuideseriesdesignations,C#3.0
PocketReference,theimageofanAfricancrownedcrane,and
relatedtradedressaretrademarksofO'ReillyMedia,Inc.
Manyofthedesignationsusedbymanufacturersandsellersto
distinguishtheirproductsareclaimedastrademarks.Where
thosedesignationsappearinthisbook,andO'ReillyMedia,Inc.
wasawareofatrademarkclaim,thedesignationshavebeen
printedincapsorinitialcaps.
.NETisaregisteredtrademarkofMicrosoftCorporation.
Whileeveryprecautionhasbeentakeninthepreparationofthis
book,thepublisherandauthorsassumenoresponsibilityfor
errorsoromissions,orfordamagesresultingfromtheuseof
theinformationcontainedherein.
ISBN:978-0-596-51922-3
[TM]
Chapter1.C#3.0PocketReference
C#isageneral-purpose,type-safe,object-oriented
programminglanguagewhosegoalisprogrammerproductivity.
Tothisend,thelanguagebalancessimplicity,expressiveness,
andperformance.TheC#languageisplatform-neutral,butit
waswrittentoworkwellwiththeMicrosoft.NETFramework.C#
3.0targets.NETFramework3.5.
1.1.What'sNewinC#3.0
C#3.0featuresarecenteredonLanguageIntegratedQuery
capabilities,orLINQforshort.LINQenablesSQL-likequeriesto
bewrittendirectlywithinaC#program,andcheckedstatically
forcorrectness.Queriescanexecuteeitherlocallyorremotely;
the.NETFrameworkprovidesLINQ-enabledAPIsacrosslocal
collections,remotedatabases,andXML.
C#3.0featuresinclude:
Lambdaexpressions
Extensionmethods
Implicitlytypedlocalvariables
Querycomprehensions
Anonymoustypes
Implicitlytypedarrays
Objectinitializers
Automaticproperties
Partialmethods
Expressiontrees
Lambdaexpressionsarelikeminiaturefunctionscreatedonthe
fly.Theyareanaturalevolutionofanonymousmethods
introducedinC#2.0,andinfact,completelysubsumethe
functionalityofanonymousmethods.Forexample:
Func<int,int>sqr=x=>x*x;
Console.WriteLine(sqr(3));//9
TheprimaryusecaseinC#iswithLINQqueries,suchasthe
following:
string[]names={"Tom","Dick","Harry"};
//Includeonlynamesof>=4characters:
IEnumerable<string>filteredNames=
Enumerable.Where(names,n=>n.Length>=4);
Extensionmethodsextendanexistingtypewithnewmethods,
withoutalteringthetype'sdefinition.Theyactassyntactic
sugar,makingstaticmethodsfeellikeinstancemethods.
BecauseLINQ'squeryoperatorsareimplementedasextension
methods,wecansimplifyourprecedingqueryasfollows:
IEnumerable<string>filteredNames=
names.Where(n=>n.Length>=4);
Implicitlytypedlocalvariablesletyouomitthevariabletypein
adeclarationstatement,allowingthecompilertoinferit.
Becausethecompilercandeterminethetypeof
filteredNames,wecanfurthersimplifyourquery:
varfilteredNames=names.Where(n=>n.Length==4);
QuerycomprehensionsyntaxprovidesSQL-stylesyntaxfor
writingqueries.Comprehensionsyntaxcansimplifycertain
kindsofqueriessubstantially,aswellasservingassyntactic
sugarforlambda-stylequeries.Here'sthepreviousexamplein
comprehensionsyntax:
varfilteredNames=fromninnames
wheren.Length>=4
selectn;
Anonymoustypesaresimpleclassescreatedonthefly,andare
commonlyusedinthefinaloutputofqueries:
varquery=fromninnameswheren.Length>=4
selectnew{
Name=n,
Length=n.Length
};
Here'sasimplerexample:
vardude=new{Name="Bob",Age=20};
Implicitlytypedarrayseliminatetheneedtostatethearray
type,whenconstructingandinitializinganarrayinonestep:
vardudes=new[]
{
new{Name="Bob",Age=20},
new{Name="Rob",Age=30}
};
Objectinitializerssimplifyobjectconstructionbyallowing
propertiestobesetinlineaftertheconstructorcall.Object
initializersworkwithbothanonymousandnamedtypes.For
example:
Bunnyb1=newBunny{
Name="Bo",
LikesCarrots=true,
};
TheequivalentinC#2.0is:
Bunnyb2=newBunny();
b2.Name="Bo";
b2.LikesCarrots=false;
Automaticpropertiescuttheworkinwritingpropertiesthat
simplyget/setaprivatebackingfield.Inthefollowing
example,thecompilerautomaticallygeneratesaprivate
backingfieldforX:
publicclassStock
{
publicdecimalX{get;set;}
}
Partialmethodsletanauto-generatedpartialclassprovide
customizablehooksformanualauthoring.LINQtoSQLmakes
useofpartialmethodsforgeneratedclassesthatmapSQL
tables.
ExpressiontreesareminiaturecodeDOMsthatdescribelambda
expressions.TheC#3.0compilergeneratesexpressiontrees
whenalambdaexpressionisassignedtothespecialtype
Expression<TDelegate>:
Expression
s=>s.Length>10;
ExpressiontreesmakeitpossibleforLINQqueriestoexecute
remotely(e.g.,onadatabaseserver)becausetheycanbe
introspectedandtranslatedatruntime(e.g.,intoanSQL
statement).
Chapter1.C#3.0PocketReference
C#isageneral-purpose,type-safe,object-oriented
programminglanguagewhosegoalisprogrammerproductivity.
Tothisend,thelanguagebalancessimplicity,expressiveness,
andperformance.TheC#languageisplatform-neutral,butit
waswrittentoworkwellwiththeMicrosoft.NETFramework.C#
3.0targets.NETFramework3.5.
1.1.What'sNewinC#3.0
C#3.0featuresarecenteredonLanguageIntegratedQuery
capabilities,orLINQforshort.LINQenablesSQL-likequeriesto
bewrittendirectlywithinaC#program,andcheckedstatically
forcorrectness.Queriescanexecuteeitherlocallyorremotely;
the.NETFrameworkprovidesLINQ-enabledAPIsacrosslocal
collections,remotedatabases,andXML.
C#3.0featuresinclude:
Lambdaexpressions
Extensionmethods
Implicitlytypedlocalvariables
Querycomprehensions
Anonymoustypes
Implicitlytypedarrays
Objectinitializers
Automaticproperties
Partialmethods
Expressiontrees
Lambdaexpressionsarelikeminiaturefunctionscreatedonthe
fly.Theyareanaturalevolutionofanonymousmethods
introducedinC#2.0,andinfact,completelysubsumethe
functionalityofanonymousmethods.Forexample:
Func<int,int>sqr=x=>x*x;
Console.WriteLine(sqr(3));//9
TheprimaryusecaseinC#iswithLINQqueries,suchasthe
following:
string[]names={"Tom","Dick","Harry"};
//Includeonlynamesof>=4characters:
IEnumerable<string>filteredNames=
Enumerable.Where(names,n=>n.Length>=4);
Extensionmethodsextendanexistingtypewithnewmethods,
withoutalteringthetype'sdefinition.Theyactassyntactic
sugar,makingstaticmethodsfeellikeinstancemethods.
BecauseLINQ'squeryoperatorsareimplementedasextension
methods,wecansimplifyourprecedingqueryasfollows:
IEnumerable<string>filteredNames=
names.Where(n=>n.Length>=4);
Implicitlytypedlocalvariablesletyouomitthevariabletypein
adeclarationstatement,allowingthecompilertoinferit.
Becausethecompilercandeterminethetypeof
filteredNames,wecanfurthersimplifyourquery:
varfilteredNames=names.Where(n=>n.Length==4);
QuerycomprehensionsyntaxprovidesSQL-stylesyntaxfor
writingqueries.Comprehensionsyntaxcansimplifycertain
kindsofqueriessubstantially,aswellasservingassyntactic
sugarforlambda-stylequeries.Here'sthepreviousexamplein
comprehensionsyntax:
varfilteredNames=fromninnames
wheren.Length>=4
selectn;
Anonymoustypesaresimpleclassescreatedonthefly,andare
commonlyusedinthefinaloutputofqueries:
varquery=fromninnameswheren.Length>=4
selectnew{
Name=n,
Length=n.Length
};
Here'sasimplerexample:
vardude=new{Name="Bob",Age=20};
Implicitlytypedarrayseliminatetheneedtostatethearray
type,whenconstructingandinitializinganarrayinonestep:
vardudes=new[]
{
new{Name="Bob",Age=20},
new{Name="Rob",Age=30}
};
Objectinitializerssimplifyobjectconstructionbyallowing
propertiestobesetinlineaftertheconstructorcall.Object
initializersworkwithbothanonymousandnamedtypes.For
example:
Bunnyb1=newBunny{
Name="Bo",
LikesCarrots=true,
};
TheequivalentinC#2.0is:
Bunnyb2=newBunny();
b2.Name="Bo";
b2.LikesCarrots=false;
Automaticpropertiescuttheworkinwritingpropertiesthat
simplyget/setaprivatebackingfield.Inthefollowing
example,thecompilerautomaticallygeneratesaprivate
backingfieldforX:
publicclassStock
{
publicdecimalX{get;set;}
}
Partialmethodsletanauto-generatedpartialclassprovide
customizablehooksformanualauthoring.LINQtoSQLmakes
useofpartialmethodsforgeneratedclassesthatmapSQL
tables.
ExpressiontreesareminiaturecodeDOMsthatdescribelambda
expressions.TheC#3.0compilergeneratesexpressiontrees
whenalambdaexpressionisassignedtothespecialtype
Expression<TDelegate>:
Expression
s=>s.Length>10;
ExpressiontreesmakeitpossibleforLINQqueriestoexecute
remotely(e.g.,onadatabaseserver)becausetheycanbe
introspectedandtranslatedatruntime(e.g.,intoanSQL
statement).
1.2.AFirstC#Program
Hereisaprogramthatmultiplies12x30,andprintstheresult,
360,tothescreen.Thedouble-forwardslashindicatesthatthe
remainderofalineisacomment.
usingSystem;//importingnamespace
classTest//classdeclaration
{
staticvoidMain()//methoddeclaration
{
intx=12*30;//statement1
Console.WriteLine(x);//statement2
}//endofmethod
}//endofclass
Attheheartofthisprogramlietwostatements.Statementsin
C#executesequentially.Eachstatementisterminatedbya
semicolon:
intx=12*30;
Console.WriteLine(x);
Thefirststatementcomputestheexpression12*30andstores
theresultinalocalvariable,namedx,whichisanintegertype.
ThesecondstatementcallstheConsoleclass'sWriteLine
methodtoprintthevariablextoatextwindowonthescreen.
Amethodperformsanactioninaseriesofstatements,calleda
statementblock—apairofbracescontainingzeroormore
statements.WedefinedasinglemethodnamedMain:
staticvoidMain()
{
...
}
Writinghigher-levelfunctionsthatcalluponlower-level
functionssimplifiesaprogram.Wecanrefactorourprogram
withareusablemethodthatmultipliesanintegerby12as
follows:
usingSystem;
classTest
{
staticvoidMain()
{
Console.WriteLine(FeetToInches(30));//360
Console.WriteLine(FeetToInches(100));//1200
}
staticintFeetToInches(intfeet)
{
intinches=feet*12;
returninches;
}
}
Amethodcanreceiveinputdatafromthecallerbyspecifying
parameters,andoutputdatabacktothecallerbyspecifyinga
returntype.WedefinedamethodcalledFeetToInchesthathas
aparameterforinputtingfeet,andareturntypeforoutputting
inches:
staticintInchesToFeet(intfeet){...}
Theliterals30and100aretheargumentspassedtothe
FeetToInchesmethod.TheMainmethodinourexamplehas
emptyparenthesesbecauseithasnoparameters,anditisvoid
becauseitdoesn'treturnanyvaluetoitscaller:
staticvoidMain()
C#recognizesamethodcalledMainassignalingthedefault
entrypointofexecution.TheMainmethodmayoptionally
returnaninteger(ratherthanvoid)toreturnavaluetothe
executionenvironment.TheMainmethodcanalsooptionally
takeanarrayofstringarguments(thatwillbepopulatedwith
anyargumentspassedtotheexecutable).Forexample:
staticintMain(string[]args){...}
Anarray(suchasstring[])representsafixed
numberofelementsofaparticulartype(seethe
upcoming"Arrays,"section).
MethodsareoneofseveralkindsoffunctionsinC#.Another
kindoffunctionweusedwasthe*operator,usedtoperform
multiplication.Therearealsoconstructors,properties,events,
indexers,andfinalizers.
Inourexample,thetwomethodsaregroupedintoaclass.A
classgroupsfunctionmembersanddatamemberstoforman
object-orientedbuildingblock.TheConsoleclassgroups
membersthathandlecommand-lineinput/outputfunctionality,
suchastheWriteLinemethod.OurTestclassgroupstwo
methods—theMainmethodandtheFeetToInchesmethod.A
classisakindoftype,whichwewillexaminelaterinthe"Type
Basics"section.
Attheoutermostlevelofaprogram,typesareorganizedinto
namespaces.TheusingdirectivemadetheSystemnamespace
availabletoourapplication,sowecouldreference
System.ConsolewithouttheSystem.prefix.Wecoulddefineall
ourclasseswithintheTestProgramsnamespace,asfollows:
usingSystem;
namespaceTestPrograms
{
classTest{...}
classTest2{...}
}
The.NETFrameworkisorganizedintonestednamespaces.For
example,thisisthenamespacethatcontainstypesforhandling
text:
usingSystem.Text;
Theusingdirectiveisthereforconvenience;youcanalsorefer
toatypebyitsfullyqualifiedname,whichisthetypename
prefixedwithitsnamespace,suchasSystem.Text.
StringBuilder.
1.2.1.Compilation
TheC#compilercompilessourcecode,specifiedasasetoffiles
withthe.csextension,intoanassembly.Anassemblyisthe
unitofpackaginganddeploymentin.NET.,anditcanbeeither
anapplicationoralibrary.AnormalconsoleorWindows
applicationhasaMainmethodandisan.exe.Alibraryisa.dll,
andisequivalenttoan.exewithoutanentrypoint.Itspurpose
istobecalledupon(referenced)byanapplicationorbyother
libraries.The.NETFrameworkisasetoflibraries.
ThenameoftheC#compileriscsc.exe.Youcaneitherusean
IDEsuchasVisualStudio.NETtocallcscautomatically,or
compilemanuallyfromthecommandline.Tocompilemanually,
firstsaveaprogramtoafilesuchasMyFirstProgram.cs,and
theninvokecsc(locatedunder
<windows>/Microsoft.NET/Framework)fromthecommand
line,asfollows:
cscMyFirstProgram.cs
ThisproducesanapplicationnamedMyFirstProgram.exe.To
producealibrary(.dll),you'ddothefollowing:
csc/target:libraryMyFirstProgram.cs
1.3.Syntax
C#syntaxisbasedonCandC++syntax.Inthissection,we
describeC#'selementsofsyntax,usingthefollowingprogram:
usingSystem;
classTest
{
staticvoidMain()
{
intx=12*30;
Console.WriteLine(x);
}
}
1.3.1.IdentifiersandKeywords
Identifiersarenamesthatprogrammerschoosefortheir
classes,methods,variables,andsoon.Thesearetheidentifiers
inourexampleprogramintheorderinwhichtheyappear:
SystemTestMainxConsoleWriteLine
Anidentifiermustbeawholeword,essentiallymadeupof
Unicodecharactersstartingwithaletterorunderscore.C#
identifiersarecase-sensitive.Byconvention,arguments,local
variables,andprivatefieldsshouldbeincamelcase(e.g.,
myVariable),andallotheridentifiersshouldbeinPascalcase
(e.g.,MyMethod).
Keywordsarenamesreservedbythecompilerthatyoucan't
useasidentifiers.Thesearethekeywordsinourexample
program:
usingclassstaticvoidint
HereisthefulllistofC#keywords:
abstract
enum
long
stackalloc
as
event
namespace
static
base
explicit
new
string
bool
extern
null
struct
break
false
object
switch
byte
finally
operator
this
case
fixed
out
throw
catch
float
override
true
char
for
params
try
checked
foreach
private
typeof
class
goto
protected
uint
const
if
public
ulong
continue
implicit
readonly
unchecked
decimal
in
ref
unsafe
default
int
return
ushort
delegate
interface
sbyte
using
do
internal
sealed
virtual
double
is
short
void
else
lock
sizeof
while
1.3.1.1.Avoidingconflicts
Ifyoureallywanttouseanidentifierthatclasheswitha
keyword,youcanqualifyitwiththe@prefix.Forinstance:
classclass{...}//illegal
class@class{...}//legal
The@symboldoesn'tformpartoftheidentifieritself,so
@myVariableisthesameasmyVariable.
1.3.1.2.Contextualkeywords
Somekeywordsarecontextual,meaningthattheycanalsobe
usedasidentifiers—withoutan@symbol.Thefollowingare
contextualkeywords:
add
get
let
set
ascending
global
on
value
by
group
orderby
var
descending
in
partial
where
equals
into
remove
yield
from
join
select
Withcontextualkeywords,ambiguitycannotarisewithinthe
contextinwhichtheyareused.
1.3.2.Literals,Punctuators,andOperators
Literalsareprimitivepiecesofdatastaticallyembeddedintothe
program.Theliteralsinourexampleprogramare12and30.
Punctuatorshelpdemarcatethestructureoftheprogram.
Thesearethepunctuatorsinourexampleprogram:
;{}
Thesemicolonisusedtoterminateastatementandallows
statementstowrapmultiplelines:
Console.WriteLine
(1+2+3+4+5+6+7+8+9+10);
Thebracesareusedtogroupmultiplestatementsintoa
statementblock.
Operatorstransformandcombineexpressions.Mostoperators
inC#aredenotedwithasymbol,suchasthemultiplication
operator,*.Wewilldiscussoperatorsinmoredetaillaterinthis
book.Thesearetheoperatorsweusedinourexample
program:
.()*=
Theperiodreferstoamemberofsomething.Theparentheses
areusedwhendeclaringorcallingamethod;empty
parenthesesareusedwhenthemethoddoesnotaccept
arguments.Theequalssignisusedforassignment(thedouble
equalssign,==,isusedforequalitycomparison).
1.3.3.Comments
C#offerstwodifferentstylesofsourcecodedocumentation:
single-linecommentsandmultilinecomments.Asingle-line
commentbeginswithadouble-forwardslashandcontinues
untiltheendoftheline.Forexample:
intx=3;//commentaboutassigning3tox
Amultilinecommentbeginswith/*andendswith*/: