C# Programming in easy steps - 101books.ru€¦ · • C# is designed to be a simple, modern,...

Preview:

Citation preview

MikeMcGrath

C#Programming

IneasystepsisanimprintofInEasyStepsLimited16HamiltonTerrace.HollyWalk.LeamingtonSpaWarwickshire.CV324LYwww.ineasysteps.com

Copyright©2016byInEasyStepsLimited.Allrightsreserved.Nopartofthisbookmaybereproducedortransmittedinanyformorbyanymeans,electronicormechanical,includingphotocopying,recording,orbyanyinformationstorageorretrievalsystem,withoutpriorwrittenpermissionfromthepublisher.

NoticeofLiabilityEveryefforthasbeenmadetoensurethatthisbookcontainsaccurateandcurrentinformation.However,InEasyStepsLimitedandtheauthorshallnotbeliableforanylossordamagesufferedbyreadersasaresultofanyinformationcontainedherein.

TrademarksAlltrademarksareacknowledgedasbelongingtotheirrespectivecompanies.

Contents

1GettingstartedIntroducingC#InstallingVisualStudioExploringtheIDEStartingaConsoleprojectWritingyourfirstprogramFollowingtherulesSummary

2StoringvaluesCreatingvariablesReadinginputEmployingarraysCastingdatatypesFixingconstantsSummary

3PerformingoperationsDoingarithmeticAssigningvaluesComparingvaluesAssessinglogicExaminingconditionsSettingprecedenceSummary

4MakingstatementsBranchingwithifSwitchingbranchesLoopingforLoopingwhileIteratingforeachSummary

5DevisingmethodsCreatingfunctionPassingargumentsOverloadingmethodsRefactoringcodeSummary

6Handlingstrings

DiscoveringstringfeaturesManipulatingstringsJoiningandcomparingstringsCopyingandswappingstringsFindingsubstringsFormattingstringsFormattingdatestringsSummary

7AccessingfilesWritingafileAppendingtoafileReadingtextandlinesStreaminglinesManipulatinginputandoutputSummary

8SolvingproblemsDetectingreal-timeerrorsFixingcompile-timeerrorsDebuggingcodeSettingbreakpointsCatchingrun-timeerrorsGettinghelpSummary

9CreatingobjectsEncapsulatingdataCreatingmultipleobjectsInitializingclassmembersInheritingclasspropertiesCallingbaseconstructorsHidingbasemethodsDirectingmethodcallsProvidingcapabilityclassesEmployingpartialclassesSummary

10ControllingeventsStartingaFormsprojectAddingvisualcontrolsWritingfunctionalcodeGatheringtextentriesTickingoptionboxesShowingusermessagesCallingsystemdialogsCreatingapplicationmenusMakingmenusworkImportingaudioresourcesSummary

11BuildinganapplicationPlanningtheprogramAssigningfixedpropertiesDesigningthelayoutSettingdynamicpropertiesAddingruntimefunctionTestingtheprogramPublishingtheapplicationSummary

12TargetingdevicesStartingaUniversalprojectInsertingpagecomponentsImportingprogramassetsDesigningthelayoutAddingruntimefunctionTestingtheprogramAdjustingtheinterfaceDeployingtheapplicationSummary

1

Gettingstarted

WelcometotheexcitingworldofC#programming.ThischapterintroducestheVisualStudioIntegratedDevelopment

EnvironmentandshowsyouhowtocreatearealWindowsapplication.

IntroducingC#InstallingVisualStudioExploringtheIDEStartingaConsoleprojectWritingyourfirstprogramFollowingtherulesSummary

IntroducingC#TheintroductionoftheMicrosoft.NETframeworkattheProfessionalDevelopersConferenceinJuly2000alsosawMicrosoftintroduceanewprogramminglanguagecalledC#(pronounced“see-sharp”).Thenamewasinspiredbymusicalnotationwherea#sharpsymbolindicatesthatawrittennoteshouldbeasemitonehigherinpitch.ThisnotionissimilartothenamingoftheC++programminglanguagewherethe++symbolindicatesthatawrittenvalueshouldbeincrementedby1.

• C#isdesignedtobeasimple,modern,general-purpose,object-orientedprogramminglanguage,borrowingkeyconceptsfromseveralotherlanguages–mostnotablytheJavaprogramminglanguage.Consequently,everythinginC#isaclass“object”with“properties”and“methods”thatcanbeemployedbyaprogram.

• C#isanelegantand“type-safe”programminglanguagethatenablesdeveloperstobuildavarietyofsecureandrobustapplications.YoucanuseC#tocreateWindowsclientapplications,XMLwebservices,distributedcomponents,client-serverapplications,databaseapplications,andmuch,muchmore.

• C#isspecificallydesignedtoutilizetheprovenfunctionalitybuiltintothe.NETframework“classlibraries”.WindowsapplicationswritteninC#thereforerequiretheMicrosoft.NETframeworktobeinstalledonthecomputerrunningtheapplication–typicallyanintegralcomponentofthesystem.

Thesourcecodeofallexamplesinthisbookisavailableforfreedownloadatwww.ineasysteps.com/resource-center/downloads

TheMicrosoft.NETFrameworkEachversionoftheMicrosoft.NETframeworkincludesaunifiedsetofclasslibrariesandavirtualexecutionsystemcalledtheCommonLanguageRuntime(CLR).TheCLRallowstheC#languageandtheclasslibrariestoworktogetherseamlessly.

Tocreateanexecutableprogram,sourcecodewrittenintheC#languageiscompiledbytheC#CompilerintoIntermediateLanguage(IL)code.Thisisstoredondisk,togetherwithotherprogramresourcessuchasimages,inan“assembly”.Typically,theassemblywillhaveafileextensionof.exeor.dll.Eachassemblycontainsa“manifest”whichprovidesinformationaboutthatprogram’ssecurityrequirements.

WhenaC#programisexecuted,theassemblyisloadedintotheCommonLanguageRuntime(CLR),andthesecurityrequirementsspecifiedinitsassemblymanifestareexamined.Whenthesecurityrequirementsaresatisfied,theCLRperformsJust-In-Time(JIT)compilationoftheILcodeintonativemachineinstructions.TheCLRthenperforms“garbagecollection”,exceptionhandling,andresourcemanagementtasksbeforecallingupontheoperatingsystemtoexecutetheprogram:

AslanguageinteroperabilityisakeyfeatureoftheMicrosoft.NETframework,theILcodegeneratedbytheC#Compilercaninteractwithcodegeneratedbythe.NETversionsofotherlanguagessuchasVisualBasicandVisualC++.TheexamplesthroughoutthisbookdemonstrateVisualC#programcode.

Just-In-Timecompilationisalsoknownas“DynamicTranslation”.

Just-In-Timecompilationoccursduringprogramexecution,ratherthanpriortoitsexecution.

InstallingVisualStudioInordertocreateWindowsapplicationswiththeC#programminglanguage,youwillfirstneedtoinstallaVisualStudioIntegratedDevelopmentEnvironment(IDE).

MicrosoftVisualStudioistheprofessionaldevelopmenttoolthatprovidesafullyIntegratedDevelopmentEnvironmentforVisualBasic,VisualC++,VisualJ#,andVisualC#.WithinitsIDE,codecanbewritteninVisualBasic,C++,J#ortheC#programminglanguagetocreateWindowsapplications.

VisualStudioCommunityeditionisastreamlinedversionofVisualStudio,speciallycreatedforthosepeoplelearningprogramming.Ithasasimplifieduserinterfaceandomitsadvancedfeaturesoftheprofessionaleditiontoavoidconfusion.C#codecanbewrittenwithintheCodeEditorofeitherversionoftheVisualStudioIDEtocreateWindowsapplications.

BothVisualStudioandVisualStudioCommunityprovideanIDEforC#programmingbut,unlikethefully-featuredVisualStudioproduct,theVisualStudioCommunityeditioniscompletelyfreeandcanbeinstalledonanysystemmeetingthefollowingminimumrequirements:

Component: Requirement:

Operatingsystem

Windows10Windows8/8.1Windows7ServicePack1WindowsServer2012/2012R2WindowsServer2008R2SP1

CPU(processor) 1.6GHzorfaster

RAM(memory) 1024MB(1GB)minimum

HDD(harddrive) 4GBavailablespace,5400RPMspeed

VideoCard DirectX9-capable,andascreenresolutionof1024x768orhigher

TheVisualStudioCommunityeditionisusedthroughoutthisbooktodemonstrateprogrammingwiththeC#language,buttheexamplescanalsoberecreatedinVisualStudio.FollowthestepsoppositetoinstalltheVisualStudioCommunityedition.

TheNewiconpicturedaboveindicatesaneworenhancedfeatureintroducedwiththelatestversionofC#andVisualStudio.

OpenyourwebbrowserandnavigatetotheVisualStudioCommunitydownloadpage–atthetimeofwritingthiscanbefoundatvisual-studio.com/vs

Scrolldownthepagethenclickthebuttontodownloadavs_communityinstallerfile

Clickonthevs_communityfiletoruntheinstaller

Acceptthesuggestedinstallationlocation,thenclickNext

ChoosetheDefaulttypeofinstallation,thenclickInstalltobeginthedownloadandinstallationprocess

Choosingadifferentdestinationfoldermayrequireotherpathstobeadjustedlater–it’ssimplertojustacceptthesuggesteddefault.

TheVisualStudio2015installerallowsyoutoinstalljustthecomponentsyouneed.

Youcanre-runtheinstalleratalaterdatetoaddorremovefeatures.

ExploringtheIDEGototheStartmenu,thenselecttheVisualStudio2015menuitemaddedtherebytheinstaller:

SigninwithyourMicrosoftAccount,orregisteranaccountthensignin,tocontinue

ClicktheStartVisualStudiobuttontolaunchtheapplication

ThefirsttimeVisualStudiostartsittakesafewminutesasitperformsconfigurationroutines.

TheVisualStudioIntegratedDevelopmentEnvironment(IDE)appears,fromwhichyouhaveinstantaccesstoeverythingneededtoproducecompleteWindowsapplications–fromhereyoucancreateexcitingvisualinterfaces,entercode,compileandexecuteapplications,debugerrors,andmuchmore.

TheVisualStudioIDEinitiallyincludesadefaultStartPage,alongwiththestandardIDEcomponents,andlookslikethis:

Tochangethecolor,choosetheTools,OptionsmenuthenselectEnvironment,General,Colortheme.

StartPageelementsThedefaultStartPageprovidestheseusefulfeatures:

• Start–provideslinksyoucanclicktobeginanewprojectorreopenanexistingproject.

• Recent–convenientlylistsrecentlyopenedprojectssoyoucanquicklyselectonetoreopen.

• News–feedsthelatestonlinenewsdirectfromtheMicrosoftDeveloperNetwork(MSDN).

YoucanreturntotheStartPageatanytimebyselectingView,StartPageontheMenuBar.

VisualStudioIDEcomponentsTheVisualStudioIDEinitiallyprovidesthesestandardfeatures:

• MenuBar–whereyoucanselectactionstoperformonallyourprojectfilesandtoaccessHelp.Whenaprojectisopen,extramenusofProjectandBuildareshown,inadditiontothedefaultmenuselectionofFile,Edit,View,Debug,Team,Tools,Test,Analyze,Window,andHelp.

• Toolbar–whereyoucanperformthemostpopularmenuactionswithjustasingleclickonitsassociatedshortcuticon.

• Toolbox–whereyoucanselectvisualelementstoaddtoaproject.PlacethecursorovertheToolboxtoseeitscontents.Whenaprojectisopen,“controls”suchasButton,Label,CheckBox,RadioButton,andTextBoxareshownhere.

• SolutionExplorer–whereyoucanseeataglanceallthefilesandresourcecomponentscontainedwithinanopenproject.

• StatusBar–whereyoucanreadthestateofthecurrentactivitybeingundertaken.Whenbuildinganapplication,a“Buildstarted”messageisdisplayedhere,changingtoa“Buildsucceeded”or“Buildfailed”messageuponcompletion.

ThemenusareonceagaininTitleCase,ratherthantheALLCAPSstyleofthepreviousversion.

OnlineelementsoftheStartPagerequirealiveinternetconnection–ifthehyperlinksdonotappeartowork,verifyyourinternetconnection.

StartingaConsoleproject

GettingStarted

OntheMenuBar,clickFile,New,Project...,orpresstheCtrl+Shift+Nkeys,toopenthe“NewProject”dialogbox

Inthe“NewProject”dialogbox,selecttheInstalled,Template,VisualC#,ConsoleApplicationitem

EnteraprojectnameofyourchoiceintheNamefield–inthiscasetheprojectnamewillbe“GettingStarted”

ClicktheOKbuttontocreatethenewproject

LeavetheCreatedirectoryforsolutionoptioncheckedtocreateafoldernamedastheprojectname,andlocatedbydefaultinyourDocuments,VisualStudio2015,Projectsdirectory.

VisualStudionowcreatesyournewprojectandloadsitintotheIDE.Anew,tabbedCodeEditorwindowappears(inplaceoftheStartPagetabbedwindow)containingdefaultskeletonprojectcodegeneratedbyVisualStudio.

DragtheCodeEditorwindowtabtoundocktheCodeEditorwindowfromtheVisualStudioIDEframe

Thesourcecodeofallexamplesinthisbookisavailableforfreedownloadatwww.ineasysteps.com/resource-center/downloads

Theundockedwindowtitledisplaystheprojectname,andthetabdisplaysthefilenameofthecodeas“Program.cs”.

Thecodenamespaceisdeclaredusingyourchosenprojectname–inthiscaseit’s“GettingStarted”.

SelecttheView,SolutionExplorermenutoopenaSolutionExplorerwindowtodiscoveralltheitemsinyourproject

SelecttheView,PropertiesmenutoopenaPropertieswindow,thenselectanyitemintheSolutionExplorerwindowtoseeitspropertiesinthePropertieswindow

TheCodeEditorwindowiswhereyouwriteC#codetocreateanapplication.TheVisualStudioIDEhasnowgatheredalltheresourcesneededtobuildadefaultConsoleapplication.YoucanclicktheDebug,StartDebuggingmenutoseeVisualStudiobuildtheapplication,butitwilldonothinguntilyouaddsomecode.

YoucandragthetitlebarofanywindowtoundockthatwindowfromtheVisualStudioIDEframe.Whendragging,youcandropawindowonthe“guidediamond”(shownbelow)todockthewindowinyourpreferredposition.

Alternatively,youcanpresstheF5shortcutkeytostartDebugging.

WritingyourfirstprogramInordertocreateaworkingConsoleapplicationyouneedtoaddC#codetothedefaultskeletonprojectcodegeneratedbytheVisualStudioIDE:

Hello

OntheMenuBar,clickFile,New,Project,orpresstheCtrl+Shift+Nkeys,toopenthe“NewProject”dialogbox

Inthe“NewProject”dialogbox,selecttheInstalled,Template,VisualC#,ConsoleApplicationitem

EnteraprojectnameofyourchoiceintheNamefield–inthiscasetheprojectnamewillbe“Hello”

ClicktheOKbuttontocreatethenewprojectandseetheCodeEditordisplaythedefaultskeletonprojectcode

Positionthecursorbetweentheinnermost{}curlybrackets(braces),thenhitEntertoaddanewline

Onthenewline,preciselytypethisC#codeConsole.WriteLine(“HelloWorld!”);Console.WriteLine(“PressAnyKeyToContinue...”);

HitEntertoaddanothernewline,thenpreciselytypethisC#codeConsole.ReadKey();

Asyoutypethecodeasuggestionboxwillappear.Thisisthe“IntelliSense”feature.YoucanselectanitemtheninsertitintoyourcodebypressingtheTabkeyortheSpacebar.

TheMain()methodisautomaticallycalledwheneveraC#programisrun–toexecutetheinstructionscontainedwithinits{}braces.

Now,selectFile,SaveHello,orpresstheCtrl+Skeys,tosavethecompletedC#Consoleapplication

Then,selectthe StartbuttonontheToolbar,orpresstheF5key,tobuildandruntheapplication

AConsolewindowliketheoneshownaboveshouldnowappear,displayingatraditionalprogramminggreeting.

HitEnter,orclickthe Stopbutton,toclosetheapplicationandseetheConsolewindowdisappear

ToeditthedefaultConsolewindowcolorsandfont,right-clickitswindowTitlebarandchooseProperties.Forclarity,allotherConsolewindowscreenshotsinthisbookfeatureLucidaConsole14-pixelFontinblackScreenTextonawhiteScreenBackground.

CodeanalysisExaminationofthecodehelpstounderstandwhatishappening:

• usingSystem;ThisisadirectiveallowingtheSystem.ConsoleclassobjecttobewrittenwithouttheSystem.prefix.

• namespaceHello{}Thisisadeclarationthatcreatesauniquenamespacewrapperinwhichtoencloseyourprogram.

• classProgram{}Thisdeclarationcreatesa“Program”classinwhichtocreateyourownprogrampropertiesandmethods.

• staticvoidMain(string[]args){}ThisdeclarationcreatesastandardMain()methodinwhichtowriteyourC#code.

• Console.WriteLine(“HelloWorld!”);ThisisastatementthatcallsupontheWriteLine()methodoftheConsoleclasstooutputtextenclosedinquotemarkswithinitsparentheses.

• Console.ReadKey();ThisstatementcallsupontheReadKey()methodoftheConsoleclasstowaitforanykeytobepressed.

CodelistedthroughoutthisbookiscoloredtomatchthedefaultsyntaxhighlightcolorsoftheVisualStudioCodeEditor,foreasyrecognition.

CallingtheReadKey()methodisalittletricktokeeptheConsolewindowopenuntilyoupressanykey.Withoutthisstatementtheapplicationwouldoutputitsmessagethenimmediatelyexit.

FollowingtherulesAswithallprogramminglanguages,C#hasanumberofsyntaxrulesthatmustbepreciselyfollowedtoensurethecodeiscorrectlyformattedfortheC#compilertoclearlyunderstand:

• Case-sensitivity–C#isacase-sensitivelanguage,whichmeansthatuppercase“A”andlowercase“a”areregardedastotallydifferentitems.

• Termination–AllstatementsinC#languagemustbeterminatedbya;semicoloncharacter,justasallsentencesinEnglishlanguagemustbeterminatedbya.periodcharacter.Forexample:Console.WriteLine(“HelloWorld!”);

• Single-linecomments–Briefcommentsonasinglelinemustbeginwith//twoforwardslashcharacters.Forexample://Outputthetraditionalgreeting.

• Blockcomments–Extendedcommentsonmultiplelinesmustbeginwith/*forwardslashandasteriskcharacters,andmustendwiththereverse*/asteriskandforwardslash.Forexample:/*C#Programmingineasysteps.Gettingstartedwiththetraditionalgreeting.

*/

• Whitespace–Spaces,tabs,newlinecharacters,andcommentsareignoredbytheC#compiler,socanbeusedextensivelytoorganizecodewithoutperformancepenalty.

• Escapesequences–TheC#compilerrecognizes\nasanewlinecharacterand\tasatabcharacter,sothesecanbeusedtoformatoutput.Forexample:Console.WriteLine(“LineOne\nLineTwo”);

• Namingconventions–Aprogrammer-definedidentifiernameinC#codemaybeginwithan_underscorecharacteroraletterinuppercaseorlowercase.Thenamemayalsocontainanunderscore,lettersandnumerals.Forexample:classMyNo1_Class

• Keywords–TheC#languagehasanumberofkeywords(listedopposite)thathavespecialsyntacticmeaningandmaynotbeusedtonameprogrammer-defineditemsincode.

Itisrecommendedthatyoucommentyourcodetomakeitreadilyunderstoodbyothersorwhenrevisitingyourowncodelater.

TheWriteLine()methodautomaticallyaddsanewlineafteritsoutput.

C#ReservedKeywords

abstract as base bool

break byte case catch

char checked class const

continue decimal default delegate

do double else enum

event explicit extern false

finally fixed float for

foreach goto if implicit

in int interface internal

is lock long namespace

new null object operator

out override params private

protected public readonly ref

return sbyte sealed short

sizeof stackalloc static string

struct switch this throw

true try typeof uint

ulong unchecked unsafe ushort

using virtual void volatile

while

Ifyouabsolutelymustuseakeywordtonameaprogrammer-definedelement,itmay

beprefixedbyan@charactertodistinguishitfromthekeyword–butthisisbestavoided.

C#ContextualKeywords

add alias ascending async

await descending dynamic from

get global group into

join let orderby partial

remove select set value

var where yield

Contextualkeywordshavespecialsignificanceincertaincode.Forexample,getandsetinmethoddeclarations.

Summary• C#isanobject-orientedprogramminglanguagethatutilizestheprovenfunctionalityofthe

Microsoft.NETclasslibraries.

• TheC#compilergeneratesIntermediateLanguage(IL)codethatisstoredondiskalongsideresourcesinanassembly.

• TheCommonLanguageRuntime(CLR)examinesanassembly’ssecurityrequirementsbeforeJITcompilation.

• Just-In-TimecompilationtranslatesILcodeintonativemachinecodeforexecutionbytheoperatingsystem.

• MicrosoftVisualStudioprovidesafullyIntegratedDevelopmentEnvironment(IDE)forC#programming.

• AnewVisualC#ConsoleapplicationgeneratesdefaultskeletonprojectcodeintheVisualStudioCodeEditor.

• TheVisualStudioSolutionExplorershowsallfilesinaprojectandthePropertieswindowshowstheirproperties.

• C#codeneedstobeaddedtothedefaultskeletoncodeintheCodeEditortocreateaC#program.

• TheusingSystemdirectiveallowstheSystem.ConsoleclasstobewritteninthecodewithoutitsSystem.prefix.

• TheConsoleclasshasaWriteLine()methodthatcanbeusedtooutputaspecifiedtextstring,andaReadKey()methodthatcanrecognizewhentheuserpressesanykey.

• AC#programcanberunintheVisualStudioIDEbyselectingtheDebug,StartDebuggingmenu,orbyclickingtheStartbutton,orbypressingtheF5key.

• C#isacase-sensitiveprogramminglanguageinwhichallstatementsmustbeterminatedbya;semicoloncharacter.

• Single-line//commentsand/**/blockcommentscanbeincorporatedtoexplainC#programcode.

• C#haskeywordsthathavespecialsyntacticmeaning,socannotbeusedtonameprogrammer-definedcodeitems.

2

Storingvalues

ThischapterdemonstrateshowtostorevarioustypesofdatawithinaC#program.

CreatingvariablesReadinginputEmployingarraysCastingdatatypesFixingconstantsSummary

CreatingvariablesA“variable”islikeacontainerinaC#programinwhichadatavaluecanbestoredinsidethecomputer’smemory.Thestoredvaluecanbereferencedusingthevariable’sname.

Theprogrammercanchooseanynameforavariable,providingitadherestotheC#namingconventions–achosennamemayonlycontainletters,digits,andtheunderscorecharacter,butmustbeginwithaletter,underscore,or@character.AlsotheC#keywordsmustbeavoided.It’sgoodpracticetochoosemeaningfulnamestomakethecodemorecomprehensible.

Tocreateanewvariableinaprogramitmustbe“declared”,specifyingthetypeofdataitmaycontainanditschosenname.Avariabledeclarationhasthissyntax:

data-typevariable-name;

Multiplevariablesofthesamedatatypecanbecreatedinasingledeclarationasacomma-separatedlistwiththissyntax:

data-typevariable-name1,variable-name2,variable-name3;

ThemostcommonC#datatypesarelistedinthetablebelow,togetherwithabriefdescriptionandexamplecontent:

DataType: Description:

int Anintegerwholenumber,e.g.100

char Asinglecharacter,e.g.‘A’

float Afloating-pointnumberof7-digitprecision

double Afloating-pointnumberof15-digitprecision

decimal Afloating-pointnumberof28-digitprecision

bool ABooleanvalueoftrueorfalse

string Astringofcharacters,e.g.“InEasySteps”

Variabledeclarationsmustappearbeforeexecutablestatements–sotheywillbeavailableforreferencewithinstatements.

Namesarecase-sensitiveinC#–sovariablesnamednum,Num,andNUMaretreatedasthreeindividualvariables.Traditionally,C#variablenamesarecreatedinalllowercasecharacters.

Charactervaluesofthechardatatypemustbeenclosedinsinglequotes,butcharacterstringsofthestringdatatypemustbeenclosedbetweendoublequotes.

Thedecimaldatatypeispreferredforstorageofmonetaryvalues.

Whenavalueisassignedtoavariableitissaidtohavebeen“initialized”.Optionally,avariablemaybeinitializedinitsdeclaration.ThevaluestoredinanyinitializedvariablecanbedisplayedusingtheWriteLine()method,whichwasusedheretodisplaythe“HelloWorld!”greeting:

Variables

OpentheVisualStudioIDE,thenstartanewConsoleApplicationprojectandnameit“Variables”

Positionthecursorbetweenthe{}curlybracketsoftheMain()method,thentypethiscodetonametheConsoleConsole.Title=“Variables”;

Next,preciselytypethesestatementstodeclareandinitializevariablesofcommonC#datatypescharletter; letter=‘A’; //Declaredtheninitialized.intnumber; number=100; //Declaredtheninitialized.floatbody=98.6f; //Declaredandinitialized.doublepi=3.14159; //Declaredandinitialized.

decimalsum=1000.00m; //Declaredandinitialized.boolflag=false; //Declaredandinitialized.stringtext=“C#IsFun”; //Declaredandinitialized.

Now,insertstatementstodisplayeachstoredvalueConsole.WriteLine(“charletter:\t”+letter);Console.WriteLine(“intnumber:\t”+number);Console.WriteLine(“floatbody:\t”+body);Console.WriteLine(“doublepi:\t”+pi);Console.WriteLine(“decimalsum:\t”+sum);Console.WriteLine(“boolflag:\t”+flag);Console.WriteLine(“stringtext:\t”+text);Console.ReadKey();

PressStarttoruntheapplicationandseethestoredvalues

Suffixftoafloatvalueandmtoadecimalvaluetodistinguishthemfromadoublevalue.

Theinclusionof\tinthestringisan“escapesequence”thatprintsatabintheoutput.The+symbolisa“concatenation”operator,whichaddsthestoredvaluetothestringforoutput.

ReadinginputInordertointeractwiththeuser,C#programswilltypicallyrequiretheusertoinputsomevalues.TheReadLine()method,acompaniontotheReadKey()method,canbeusedtoreaduserinput.UserinputwithintheConsolecanbeassignedtoastringvariablebytheReadLine()methodwhentheuserhitsEntertocompletealine.

ItisimportanttorecognizethattheReadLine()methodalwaysreadsinputasastringvalue.

Whenrequestinguserinput,it’spreferabletoprompttheuserwithoutaddinganewlineaftertherequest.ThisiseasilyachievedusingtheConsole.Write()method:

Input

OpentheVisualStudioIDE,thenstartanewConsoleApplicationprojectandnameit“Input”

Positionthecursorbetweenthe{}curlybracketsoftheMain()method,thentypethiscodetonametheConsoleConsole.Title=“Input”;

Next,preciselytypethesestatementstorequestuserinputforassignmenttoavariableConsole.Write(“PleaseEnterYourName:“);stringname=Console.ReadLine();

Now,addstatementstodisplayamessagecontainingthestoreduserinputvalueConsole.WriteLine(“Welcome”+name+“!”);Console.ReadKey();

PressStartorF5toruntheapplicationandseethestoreduserinputvaluedisplayedinoutput

Numericalvaluesinputbytheuserareassignedtothestringvariableascharacters–soarithmeticcannotbeperformedonthese.

Noticehowtwo+concatenationoperatorsareusedheretoinsertinputintoastring.

WhenyourequiretheusertoinputnumericalvaluesitisnecessarytoconvertthestringvaluesreadbytheReadLine()methodintonumericaldatatypes.TheSystem.Convertclassprovidesanumberofusefulmethodsforthispurpose,including:

Method: Returns:

Convert.ToInt32() A32-bitsignedinteger

Convert.ToDouble() Afloating-pointprecisionnumber

Convert.ToDecimal() Adecimalprecisionnumber

ThereisalsoausefulConvert.ToString()methodtotranslatevaluestostringtype.

ThestringvaluereadbytheReadLine()methodneedssimplytobespecifiedwithintheparenthesesoftheappropriatemethod:

Conversion

StartanewConsoleApplication,thennametheprojectandConsole.Titleas“Conversion”

TypethesestatementstorequestuserinputforconversionandassignmenttotwovariablesConsole.Write(“PleaseEnterANumber:“);

doublenum=Convert.ToDouble(Console.ReadLine());Console.Write(“NowEnterAnotherNumber:“);doublesum=

num+Convert.ToDouble(Console.ReadLine());

Now,addstatementstodisplayamessagecontainingthesumtotaloftheuserinputvaluesConsole.WriteLine(“Total=”+sum);Console.ReadKey();

PressStartorF5toruntheapplication,thenentertwovaluestoseetheconvertedinputaddedinoutput

Here,thesecondinputnumbergetsconvertedtoanumericalvaluebeforeadditiontothefirstinputnumber.

EmployingarraysAnarrayisavariablethatcanstoremultipleitemsofdata–unlikearegularvariable,whichcanonlystoreonepieceofdata.Thepiecesofdataarestoredsequentiallyinarray“elements”thatarenumbered,startingatzero.Sothefirstvalueisstoredinelementzero,thesecondvalueisstoredinelementone,andsoon.

Anarrayisdeclaredbystatingthedatatype,suffixedby[]squarebracketstodenoteanarray.Thisalonedoesnotinitializethearrayvariableinmemoryuntilanarray“instance”iscreatedbyspecifyinganelementsizeusingthenewkeyword,likethis:

data-type[]array-name=newdata-type[size];

Valuescanthenbeindividuallyassignedtoeachavailableelement:

array-name[element-number]=value;

Arraynumberingstartsatzero–sothefinalelementinanarrayofsixelementsisnumberfive,notnumbersix.Thisnumberingisknownasa“zero-basedindex”.

Alternatively,anarraycanbeinitializedandvaluesassignedtoeachelementwhenitisdeclaredbystatingvaluesforeachelementinacomma-separatedlist,groupedwithinbraces:

data-type[]array-name=newdata-type[size]{value,value,value};

Anyindividualelement’svaluecanbereferencedusingthearraynamefollowedbysquarebracketscontainingtheelementnumber.Forexample,toreferencethevaluewithinthefirstelement:

array-name[0]

Collectively,theelementsofanarrayareknownasan“index”.Arrayscanhavemorethanoneindex–torepresentmultipledimensions,ratherthanthesingledimensionofaregulararray.Multi-dimensionalarraysofthreeindicesandmoreareuncommon,buttwo-dimensionalarraysareusefultostoregrid-basedinformation,suchascoordinates.

Youcanonlystoredatawithinarrayelementsofthedatatypespecifiedinthearraydeclaration.

Tocreateamulti-dimensionalarray,the[]squarebracketsfollowingthedatatypeinthedeclarationmustcontainacommaforeachadditionalindex.Similarly,thesizeofeachindexmustbespecifiedasacomma-separatedlist,likethis:

data-type[,]array-name=newdata-type[size,size];

Valuescanthenbeindividuallyassignedtoeachavailableelement:

array-name[element-number,element-number]=value;

Aspecialforeachloopconstructallowsyoutoeasilyiteratethroughallelementsofanarray–seeherefordetails.

Alternativelyamulti-dimensionalarraycanbeinitializedandvaluesassignedtoeachelementwhenitisdeclaredbystatingvaluesforeachindexinacomma-separatedlist,groupedwithinbraces–inacomma-separatedgroupenclosedwithinbraces:

data-type[,]array-name=newdata-type[size]{{value,value,value},{value,value,value}};

Thenumberofspecifiedvaluesmustexactlymatchthespecifiedarraysizetoavoidanerror.

Anyindividualelement’svaluecanbereferencedusingthearraynamefollowedbysquarebracketscontainingtheelementnumberforeachindex.Forexample,toreferencethevaluewithinthefirstelementofthesecondindex:

array-name[1,0]

Arrays

StartanewConsoleApplication,thennametheprojectandConsole.Titleas“Arrays”

Next,typethisstatementtocreateastringarraystring[]cars=newstring[3]{“BMW”,”Ford”,”Opel”};

Now,typethisstatementtocreatea2-dimensionalarrayint[,]coords=newint[2,3]{{1,2,3},{4,5,6}};

AddstatementstodisplayoutputcontainingthestoredarrayelementvaluesConsole.WriteLine(“SecondCar:”+cars[1]);Console.WriteLine(“X1,Y1:”+coords[0,0]);Console.WriteLine(“X2,Y3:”+coords[1,2]);Console.ReadKey();

PressStartorF5toruntheapplicationandseethevaluesstoredwithinarrayelements

CastingdatatypesAvaluestoredinavariablecanbeforced(coerced)intoavariableofadifferentdatatypebyconvertingthevaluetoadifferenttype.Thisprocessisknownas“casting”andmaybeimplicitorexplicit.

Castingisalsoknownas“typeconversion”.

• ImplicitcastingisautomaticallyperformedbyC#inatype-safemannerwhenconvertingnumbersfromsmallertolargerprecisiondatatypes.Forexample,whenaddinganinttoadouble.

• Explicitcasting,ontheotherhand,requiresacastoperatortobeincludedinastatementtospecifythedatatypetowhichthevalueshouldbecast.Therequirednewdatatypemustbespecifiedinparenthesesprecedingthenameofthevariablecontainingthedatatobecast,soitssyntaxlookslikethis:

variable-name=(data-type)variable-name;

ThisisthetraditionalformofcastingthatisalsofoundintheCprogramminglanguage.Castingisoftennecessarytoaccuratelystoretheresultofanarithmeticoperationtopreventdataloss.Divisionofoneintegerbyanotherintegerwillalwaysproduceanintegerresult,whichmaybetruncated.Forexample,theintegerdivision7/2producesthetruncatedintegerresultof3.

Tostoretheaccuratefloating-pointresultwouldrequiretheresultbecastintoasuitabledatatype,suchasadouble,likethis:

doublesum=(double)7/2; //Sumis3.5

Theresultofdividinganintegerbyanotherintegeristruncated,notrounded–soaresultof9.9wouldbecome9.

Itshouldbenotedthatoperatorprecedencecaststhefirstoperand7intothespecifieddatatypebeforeimplementingthearithmeticoperation/2division,soeffectivelythestatementis:

doublesum=(double)(7)/2; //Sumis3.5

Bracketingtheexpressionas(7/2)wouldperformthearithmeticfirstonintegers,sotheintegerresultwouldbetruncatedbeforebeingcastintothefloatvariable–notthedesiredeffect!

doublesum=(double)(7/2); //Sumis3.0

SinglecharactervaluescanusefullybeexplicitlycasttoanintdatatypetorevealtheirASCIIcodevalue.Similarly,theprocesscanbereversedtorevealthecharactervalueofaninteger.

Cast

StartanewConsoleApplication,thennametheprojectandConsole.Titleas“Cast”

Typethesestatementstocreateandinitializeanintegervariableandadouble-precisionfloating-pointvariabledoublenum=10.5;intinteger=2;

Next,addstatementstoimplicitlycasttheintegervalueintoadouble-precisionvalue,anddisplaytheresultnum=num+integer;Console.WriteLine(“ImplicitCast:”+num);

Now,explicitlycasttheresultofanintegerdivisionintoadouble-precisionvalue,anddisplaythatresultnum=(double)7/integer;Console.WriteLine(“ExplicitCast:”+num);

CastanintegervalueintoachardatatypeanddisplayitsASCIIequivalentcharactercharletter=(char)65;Console.WriteLine(“CastInteger:”+letter);

CastacharactervalueintoanintdatatypeanddisplayitsASCIIequivalentcodenumberintascii=(int)‘A’;Console.WriteLine(“CastLetter:”+ascii);Console.ReadKey();

PressStartorF5toruntheapplicationandseethevaluescastintootherdatatypes

Removethe(double)castfromStep4toseetheresultbecometruncated.

ASCII(pronounced“askee”)istheAmericanStandardCodeforInformationInterchange,whichistheacceptedstandardforplaintext.InASCII,charactersarerepresentednumericallywithintherange0-127.Uppercase‘A’is65sothatintegervaluegetscastintoanintvariable.

FixingconstantsVariabledeclarationsexplicitlyspecifytheirpermissibledatatypeusingkeywords,suchasstring,int,ordouble,toensuretheprogramcannotaccidentallyassigninappropriatedata.Whereyouarecertainthiswillneveroccur,youmayusethevar(variant)keywordwhendeclaringavariable,toimplicitlyspecifyitsdatatypeaccordingtothedatatypeofitsinitialvalue.Inthiscase,theC#compilerwillautomaticallydeterminetheappropriatedatatype.ThevarkeywordismostusefultostoreavaluethatisotherthanofthestandardC#numerical,Boolean,orstringdatatypes.Allvariabledeclarationsmadeusingthevarkeywordmustassignaninitialvaluetoimmediatelydeterminethatvariable’sdatatype.

Declaringvariablesusingthevarkeywordcanmaketheprogramcodelessreadable,asitdoesnotindicatedatatypes.

Thedatatypeofanyvariablecanberevealedbydot-suffixingtheGetType()methodontothevariablename.Forexample,whereanumvariableisadoubledatatype,callingnum.GetType()willreturnaSystem.Doubleresult.

Whenastoredvalueisneverintendedtobechanged,a“constant”containercanbecreatedtosafeguarditfromchange.Itsdeclarationissimilartothatofavariable,butbeginswiththeconstkeyword.Alldeclarationsmadeusingtheconstkeywordmustassignaninitialvaluetoimmediatelyfixitsconstantvalue.

Multipleconstantvaluescanbedefinedinanenumeratorlistusingtheenumkeywordandaspecifiedidentifiername.Thiscreatesadatatypethatconsistsofacomma-separatedlistofnamedconstantswithin{}braces.Theenumeratorlisthasanunderlyingdefaultintvaluethatnumbersthelistnamesfromzero,muchliketheelementsinanarray.Anynamewithinthelistcanbereferencedbydot-suffixingittothelistname,anditsunderlyingvaluerevealedbycasting.

Anenumeratorlistcannotbedeclaredwithinanymethodblock,somustbedeclaredoutsidetheMain()method.

TheC#Enumclassprovidesseveralmethodstoworkwithenumeratorlists.Manyoftheserequirethedatatypeofthelistasanargumentsothiscanusefullybeassignedtoavarvariableby

specifyingthelistnameasanargumenttothetypeof()method.TheEnumclassGetName()methodcanrevealthenameataspecifiedindexposition,andtheIsDefined()methodcanbeusedtotestwhetherthelistcontainsaspecifiedname.Anenumeratorlistdeclarationmustbewrittendirectlywithintheprogramnamespaceorwithinaclassblock.

Constant

StartanewConsoleApplication,thennametheprojectandConsole.Titleas“Constant”

Typethisstatementwithintheclassblock,beforetheMain()methodblock,tocreateanenumeratorlistenumDays{Sat,Sun,Mon,Tue,Wed,Thu,Fri};

Now,turnyourattentiontotheMain()method,thendeclareandinitializeaconstantandavariableconstdoublepi=3.14159265358979;vardaysType=typeof(Days);

Next,addstatementstorevealtheconstant’sdatatypeanduseitsvalueforoutputConsole.WriteLine(“PiType:”+pi.GetType());Console.WriteLine(“Circumference:”+(pi*3));

Then,addstatementstodisplaythenameandindexpositionofthefirstitemintheenumeratorlistConsole.WriteLine(“\nFirstName:”+Days.Sat);Console.WriteLine(“1stIndex:”+(int)Days.Sat);

Finally,addstatementstodisplaythenameatthesecondindexpositionandtoquerytheenumeratorliststringname=Enum.GetName(daysType,1);Console.WriteLine(“\n2ndIndex:”+name);boolflag=Enum.IsDefined(daysType,“Mon”);Console.WriteLine(“ContainsMon?:”+flag);Console.ReadKey();

PressStartorF5toruntheapplicationandseetheconstantvaluesinoperation

Theenumeratorlistcontainsnames,notstrings,sotheyneednotbeenclosedinquotemarks,butthenamemustbesuppliedasastringargumenttotheIsDefined()method.

Youmaywanttoavoidthevarkeywordwherepossibletobesureofvariabledatatypes.Forexample,withthelinevarid=getID();theassignedvalue(andthereforethevariabledatatype)couldbenumericorastring.

Summary• Avariablestoresadatavaluewithinthecomputer’smemory,andthevaluecanbereferenced

usingthatvariable’sname.

• Avariabledeclarationmustspecifythetypeofdataitmaycontain,andavalidprogrammer-specifiedname.

• CommonC#datatypesincludeint,char,float,double,decimal,bool,andstring.

• Variablesmustbedeclaredbeforetheycanbereferenced.

• Avariablebecomesinitializedwhenitisassignedavalue.

• TheConsole.ReadLine()methodcanbeusedtoassignuserinputtoavariable.

• TheConsole.WriteLine()methodaddsanewlineafteritsoutput,buttheConsole.Write()methoddoesnot.

• TheSystem.Convertclassprovidesanumberofusefulmethodstoconvertstringvaluestonumericaldatatypes.

• Anarrayvariablecanstoremultipleitemsofdatawithinsequentialelementsofazero-basedindex.

• Anarraydeclarationmustspecifythetypeofdataitmaycontain,followedby[]andaprogrammer-specifiedname.

• Anarrayisnotinitializeduntilanarrayinstanceiscreatedusingthenewkeywordtospecifydatatypeandelementsize.

• Valuescanbeassignedtoindividualarrayelementsusingthearraynameandtheelementindexnumber.

• Anarraydeclarationcanassignvaluestoallofitsarrayelementsasacomma-separatedlistofvalueswithin{}braces.

• Arrayscanhavemorethanoneindex,torepresentmultipledimensions,whereeachindexisseparatedbyacomma.

• Castingistheconversionofonedatatypetoanother.

• ImplicitcastingisperformedautomaticallybyC#.

• Explicitcastingisperformedbyincludingacastoperatorwithinastatement,tospecifytherequirednewdatatype.

3

Performingoperations

ThischapterintroducesC#operatorsanddemonstratestheoperationstheycanperform.

DoingarithmeticAssigningvaluesComparingvaluesAssessinglogicExaminingconditionsSettingprecedenceSummary

DoingarithmeticThearithmeticoperatorscommonlyusedinC#programsarelistedinthetablebelow,togetherwiththeoperationtheyperform:

Operator: Operation:

+ Addition

- Subtraction

* Multiplication

/ Division

% Modulus

++ Increment

-- Decrement

The%modulusoperatorisalsoknownasthe“remainder”operator.

The+operatorisdual-purpose–itisalsousedtoconcatenatestrings.

Theoperatorsforassignment,addition,subtraction,multiplication,anddivisionactasyouwouldexpect,butcaremustbetakentogroupexpressionswheremorethanoneoperatorisused–operationswithininnermost()parenthesesareperformedfirst:

a=b*c-d%e/f; //Thisisunclear.

a=(b*c)-((d%e)/f); //Thisisclearer.

Valuesusedwithoperatorstoformexpressionsarecalled“operands”–intheexpression2+3thenumericalvalues2and3aretheoperands.

The%modulusoperatorwilldividethefirstgivennumberbythesecondgivennumberandreturntheremainderoftheoperation.Thisisusefultodetermineifanumberhasanoddorevenvalue.

The++incrementoperatorand--decrementoperatoralterthegivennumberbyoneandreturntheresultingvalue.Thesearemostcommonlyusedtocountiterationsinaloop–countinguponeachiterationwiththe++incrementoperator,orcountingdownoneachiterationwiththe--decrementoperator.

The++incrementand--decrementoperatorscanbeplacedbeforeorafteravaluetodifferenteffect–placedbeforetheoperand(prefix)itsvalueisimmediatelychanged;placedaftertheoperand(postfix)itsvalueisnotedfirst,thenthevalueischanged.

Arithmetic

StartanewConsoleApplication,thennametheprojectandConsole.Titleas“Arithmetic”

Typethesestatementstocreateandinitializetwointegervariablesinta=8;intb=4;

Next,addstatementstooutputtheresultofeachbasicarithmeticaloperationConsole.WriteLine(“Addition:\t:”+(a+b));Console.WriteLine(“Subtraction:\t:”+(a-b));Console.WriteLine(“Multiplication:\t:”+(a*b));Console.WriteLine(“Division:\t:”+(a/b));Console.WriteLine(“Modulus:\t:”+(a%b));

Now,addstatementstooutputtheresultofapostfixincrementoperationConsole.WriteLine(“\nPostfix:\t:”+(a++));Console.WriteLine(“PostfixResult.....:\t:”+a);

Finally,addstatementstooutputtheresultofaprefixincrementoperation–forcomparisonwithpostfixConsole.WriteLine(“\nPrefix:\t:”+(++b));Console.WriteLine(“PrefixResult.....:\t:”+b);Console.ReadKey();

PressStartorF5toruntheapplicationandseetheresultsproducedbyeacharithmeticoperator

Here,the\tescapesequenceisusedtooutputatabspace,andthe\nescapesequenceisusedtooutputadditionalnewlines.

Rememberthataprefixoperatorchangesthevariablevalueimmediatelybutapostfixoperatorchangesthevaluesubsequently.

AssigningvaluesTheoperatorsthatareusedinC++programmingtoassignvaluesarelistedinthetablebelow.Allexceptthesimple=assignmentoperatorareashorthandformofalongerexpressionsoeachequivalentisgivenforclarity:

Operator: Example: Equivalent:

= a=b a=b

+= a+=b a=(a+b)

-= a-=b a=(a-b)

*= a*=b a=(a*b)

/= a/=b a=(a/b)

%= a%=b a=(a%b)

The+=combinedoperatorisdual-purpose–itcanalsobeusedtoconcatenatestrings.

Intheassignmentexampleabove,wherea=b,thevariablenamed“a”isassignedthevaluethatiscontainedinthevariablenamed“b”–sothatisthenthevaluestoredintheavariable.Technicallyspeaking,theassignmentoperatorstoresthevalueoftheright-handoperandinthememorylocationdenotedbytheleft-handoperand,thenreturnsthevalueasaresult.

Itisimportanttoregardthe=operatortomean“assign”ratherthan“equals”toavoidconfusionwiththe==equalityoperatorthatisdescribedhere.

The+=combinedoperatorisusefultoaddavalueontoanexistingvaluethatisstoredintheavariable.Intheexampleabove,wherea+=b,thevalueinvariablebisaddedtothatinvariablea–sothetotalisthenthevaluestoredintheavariable.Thearithmeticoperationisperformedfirstwiththegroupedoperands.Theresultisthenstoredinthememorylocationdenotedbythefirstvariableandreturned.

Alltheothercombinedoperatorsworkinthesamewaybymakingthearithmeticaloperation

betweenthetwovaluesfirst,thenassigningtheresultofthatoperationtothefirstvariable–tobecomeitsnewstoredvalue.

Withthe%=combinedoperator,thegroupedleft-handoperandaisdividedbythegroupedright-handoperandb,thentheremainderofthatoperationisassignedtotheafirstvariable.

Assign

StartanewConsoleApplication,thennametheprojectandConsole.Titleas“Assign”

Typethesestatementstodeclaretwointegervariablesinta;intb;

Next,addstatementstooutputsimpleassignedvaluesConsole.Write(“AssignValues:”);Console.Write(“\ta=”+(a=8));Console.WriteLine(“\tb=”+(b=4));

Now,addstatementstooutputcombinedassignedvaluesConsole.Write(“\n\nAddandAssign:”);Console.Write(“\ta+=b(8+=4)\ta=”+(a+=b));

Console.Write(“\n\nSubtractandAssign:”);Console.Write(“\ta-=b(12-=4)\ta=”+(a-=b));

Console.Write(“\n\nMultiplyandAssign:”);Console.Write(“\ta*=b(8*=4)\ta=”+(a*=b));

Console.Write(“\n\nDivideandAssign:”);Console.Write(“\ta/=b(32/=4)\ta=”+(a/=b));

Console.Write(“\n\nModulusandAssign:”);Console.Write(“\ta%=b(8%=4)\ta=”+(a%=b));Console.ReadKey();

PressStartorF5toruntheapplicationandseetheresultsproducedbyeachassignmentoperator

Noticehow\n\nescapesequencesareusedheretoaddtwonewlinesforspacingoutput.

Theoperandsmustbeofthesamedatatype,ortheright-handoperandmustbeimplicitlyconvertibletothetypeoftheleft-handoperand.

ComparingvaluesTheoperatorsthatarecommonlyusedinC#programmingtocomparetwonumericalvaluesarelistedinthetablebelow:

Operator: Comparativetest:

== Equality

!= Inequality

> Greaterthan

< Lessthan

>= Greaterthanorequalto

<= Lessthanorequalto

Thecomparisonoperatorsarealsoknownas“relationaloperators”.

The==equalityoperatorcomparestwooperandsandwillreturntrueifbothareequalinvalue,otherwisethe==operatorwillreturnfalse.Ifbotharethesamenumber,theyareequal,orifbotharecharacters,theirASCIIcodevaluesarecomparednumerically.

Conversely,the!=inequalityoperatorreturnstrueiftwooperandsarenotequal,usingthesamerulesasthe==equalityoperator,otherwiseitreturnsfalse.Equalityandinequalityoperatorsareusefulintestingthestateoftwovariablestoperformconditionalbranchinginaprogram.

YoucanspecifyaBooleanvaluetotheConvert.ToDouble()methodtodiscoverthattrueisrepresentednumericallyas1,andfalseisrepresentedas0.

The>“greaterthan”operatorcomparestwooperandsandwillreturntrueifthefirstisgreaterinvaluethanthesecond,oritwillreturnfalseifitisequalorlessinvalue.The<“lessthan”operatormakesthesamecomparisonbutreturnstrueifthefirstoperandislessinvaluethanthesecond,otherwiseitreturnsfalse.Typically,a>“greaterthan”or<“lessthan”operatorisusedtotestthevalueofaniterationcounterinaloopstructure.

Addingthe=assignmentoperatoraftera>“greaterthan”operatorora<“lessthan”operatormakesitalsoreturntrueifthetwooperandsareexactlyequalinvalue.

Comparison

StartanewConsoleApplication,thennametheprojectandConsole.Titleas“Comparison”

Typethesestatementstodeclarethreeintegervariablesandtwocharactervariablestobecomparedintnil=0,num=0,max=1;charcap=‘A’,low=‘a’;

Next,addstatementstooutputtheresultofequalitycomparisonsofintegersandcharactersConsole.Write(“Equality:”);Console.Write(“\t(0==0):”+(nil==num));Console.Write(“\n\t\t(A==a):”+(cap==low));

Now,addstatementstooutputtheresultofotherintegercomparisonsConsole.Write(“\n\nInequality:”);Console.Write(“\t(0!=1):”+(nil!=max));

Console.Write(“\n\nGreater:”);Console.Write(“\t(0>1):”+(nil>max));

Console.Write(“\nLess:”);Console.Write(“\t\t(0<1):”+(nil<max));

Console.Write(“\n\nGreater/Equal:”);Console.Write(“\t(0>=0):”+(nil>=num));

Console.Write(“\nLessorEqual:”);Console.Write(“\t(1<=0):”+(max<=nil));Console.ReadKey();

PressStartorF5toruntheapplicationandseetheresultsproducedbyeachcomparison

TheASCIIcodevalueforuppercase‘A’is65butforlowercase‘a’it’s97–sotheircomparisonherereturnsfalse.

Whencomparingnumbers,remembertotestforequalityaswellastestingforhigherandlowervalues.

AssessinglogicThelogicaloperatorsmostcommonlyusedinC#programmingarelistedinthetablebelow:

Operator: Operation:

&& Logical-AND

|| Logical-OR

! Logical-NOT

ThelogicaloperatorsareusedwithoperandsthathaveBooleanvaluesoftrueorfalse,orarevaluesthatconverttotrueorfalse.

The&&logical-ANDoperatorwillevaluatetwooperandsandreturntrueonlyifbothoperandsthemselvesaretrue.Otherwise,the&&logical-ANDoperatorwillreturnfalse.Thisisusedinconditionalbranchingwherethedirectionofaprogramisdeterminedbytestingtwoconditions–ifbothconditionsaresatisfied,theprogramwillgoinacertaindirection,otherwiseitwilltakeadifferentdirection.

Theterm“Boolean”referstoasystemoflogicalthoughtdevelopedbytheEnglishmathematicianGeorgeBoole(1815-1864).

Unlikethe&&logical-ANDoperator,whichneedsbothoperandstobetrue,the||logical-ORoperatorwillevaluateitstwooperandsandreturntrueifeitheroneoftheoperandsitselfreturnstrue.If,however,neitheroperandreturnstrue,thenthe||logical-ORoperatorwillreturnfalse.ThisisusefulinC#programmingtoperformacertainactionifeitheroneoftwotestconditionshasbeenmet.

The!logical-NOToperatorisaunaryoperatorthatisusedbeforeasingleoperand.Itreturnsthe

inversevalueofthegivenoperand,soifthevariableahadavalueoftruethen!awouldhaveavalueoffalse.The!logical-NOToperatorisusefulinC#programstotogglethevalueofavariableinsuccessiveloopiterationswithastatementlikea=!a.Thisensuresthatoneachpassthevalueischanged,likeflickingalightswitchonandoff.

Logic

StartanewConsoleApplication,thennametheprojectandConsole.Titleas“Logic”

TypethisstatementtodeclaretwoBooleanvariablesboolyes=true,no=false;

AddthesestatementstooutputtheresultofANDlogicConsole.Write(“ANDLogic:”);Console.Write(“\t(yes&&yes):”+(yes&&yes));Console.Write(“\n\t\t(yes&&no):”+(yes&&no));Console.Write(“\n\t\t(no&&no):”+(no&&no));

Now,addstatementstooutputtheresultofORlogicConsole.Write(“\n\nORLogic:”);Console.Write(“\t(yes||yes):”+(yes||yes));Console.Write(“\n\t\t(yes||no):”+(yes||no));Console.Write(“\n\t\t(no||no):”+(no||no));

Then,addstatementstooutputtheresultofNOTlogicConsole.Write(“\n\nNOTLogic:”);Console.Write(“\tyes=”+yes);Console.Write(“\t!yes=”+!yes);Console.Write(“\n\t\tno=”+no);Console.Write(“\t!no=”+!no);Console.ReadKey();

PressStartorF5toruntheapplicationandseetheresultsproducedbyeachlogicaloperation

Thevaluereturnedbythe!logical-NOToperatoristheinverseofthestoredvalue–thestoredvalueitselfremainsunchanged.

Noticethatfalse&&falsereturnsfalse,nottrue–demonstratingthemaxim“twowrongsdon’tmakearight”.

ExaminingconditionsPossiblytheC#programmer’smostfavoritetestoperatoristhe?:“ternary”operator.Thisoperatorfirstevaluatesanexpressionforatrueorfalsecondition,thenreturnsoneoftwospecifiedvaluesdependingontheresultoftheevaluation.Forthisreasonitisalsoknownasthe“conditional”operator.

The?:ternaryoperatorhasthissyntax:

(test-expression)?if-true-return-this:if-false-return-this;

Althoughtheternaryoperatorcaninitiallyappearalittleconfusing,itiswellworthbecomingfamiliarwiththisoperatorasitcanexecutepowerfulprogrambranchingwithminimalcode.Forexample,tobranchwhenavariableisnotavalueofone:

(variable!=1)?if-true-do-this:if-false-do-this;

Theternaryoperatorhasthreeoperands–theonebeforethe?andthosebeforeandafterthe:.

TheternaryoperatoriscommonlyusedinC#programmingtoassignthemaximumorminimumvalueoftwovariablestoathirdvariable.Forexample,toassignaminimumlikethis:

c=(a<b)?a:b;

Theexpressioninparenthesesreturnstruewhenthevalueofvariableaislessthanthatofvariableb–sointhiscase,thelesservalueofvariableagetsassignedtovariablec.

Similarly,replacingthe<lessthanoperatorinthetestexpressionwiththe>greaterthanoperatorwouldassignthegreatervalueofvariablebtovariablec.

Anothercommonuseoftheternaryoperatorincorporatesthe%modulusoperatorinthetestexpressiontodeterminewhethertheparityvalueofavariableisanoddnumberoranevennumber:

(variable%2!=0)?if-true(odd)-do-this:if-false(even)-do-this;

Wheretheresultofdividingthevariablevaluebytwodoesleavearemainder,thenumberisodd–wherethereisnoremainder,thenumberiseven.Thetestexpression(variable%2==1)wouldhavethesameeffect,butitispreferabletotestforinequality–it’seasiertospotwhensomethingisdifferentthanwhenit’sidentical.

Valueequality,wheretwovariablescontainanequalvalue,isalsoknownas“equivalence”.

Condition

StartanewConsoleApplication,thennametheprojectandConsole.Titleas“Condition”

Typethisstatementtodeclareandinitializetwointegervariablesinta=8;intb=3;

Next,addthesestatementstooutputanappropriatestringwithcorrectgrammarforquantitystringverb=(a!=1)?“are“:“is“;Console.Write(“There”+verb+a+”\n”);

Now,addstatementstooutputanappropriatestringcorrectlydescribingtheparityofeachvariablevaluestringparity=(a%2!=0)?“Odd“:“Even“;Console.Write(a+“is“+parity);

parity=(b%2!=0)?“Odd“:“Even“;Console.Write(b+“is“+parity);

Then,addstatementstooutputastringreportingthegreaterofthesetwovariablevaluesintmax=(a>b)?a:b;Console.Write(“\nMaximumis“+max);Console.ReadKey();

PressStartorF5toruntheapplicationandseetheresultsproducedbyexaminingeachvariablevalue

The?:ternaryoperatorcanreturnvaluesofanydatatype–numbers,strings,Booleans,etc.

SettingprecedenceOperatorprecedencedeterminestheorderinwhichC#evaluatesexpressions.Forexample,theexpression1+5*3evaluatesto16,not18,becausethe*multiplicationoperatorhasahigherprecedencethanthe+additionoperator.Parenthesescanbeusedtospecifyprecedence,sothat(1+5)*3evaluatesto18.

The*multiplyoperatorisonahigherrowthanthe+additionoperator–sointheexpressiona=1+5*3,multiplicationiscompletedfirst,beforetheaddition.

Whenoperatorshaveequalprecedence,their“associativity”determineshowexpressionsaregrouped.Forexample,the-subtractionoperatorisleft-associative,groupingleft-to-right(LTR),so8-4-2isgroupedas(8-4)-2andthusevaluatesto2.Otheroperatorsareright-associative,groupingright-to-left(RTL).

Thetablebelowlistscommonoperatorsinorderofprecedence,withthehighest-precedenceonesatthetop.Operatorsonthesamelinehaveequalprecedence,sooperatorassociativitydetermineshowexpressionsaregroupedandevaluated.

Category: Operator: Associativity:

Postfix ()[].++-- LTR

UnarySignPrefix

!+-++--

RTL

Multiplicative */% LTR

Additive +- LTR

Comparative <<=>>= LTR

Equivalence ==!= LTR

Conditional && LTR

Conditional || LTR

Conditional ?: RTL

Assignment =+=-=*=/=%= RTL

Comma , LTR

Therearealsoanumberof“bitwise”operators,whichareusedtoperformbinaryarithmetic.ThisisoutsidethescopeofthisbookbutthereisasectiondevotedtobinaryarithmeticinourbookCProgrammingineasysteps.ThoseoperatorsperforminjustthesamewayinC#.

Precedence

StartanewConsoleApplication,thennametheprojectandConsole.Titleas“Precedence”

Typethisstatementtodeclareanintegervariableintsum;

Addthesestatementstoinitializethevariablewiththeresultofanungroupedexpressionanddisplaythatresultsum=1+4*3;Console.Write(“DefaultOrder:\t\t”+sum);

Next,addstatementstoassigntheresultofagroupedexpressionanddisplaythatresultsum=(1+4)*3;Console.Write(“ForcedOrder:\t\t”+sum);

Addstatementstoassigntheresultofanewungroupedexpressionanddisplaythatresultsum=7-4+2;Console.Write(“\nDefaultDirection:\t”+sum);

Now,addstatementstoassigntheresultofthenewgroupedexpressionanddisplaythatresultsum=7-(4+2);Console.Write(“\nForcedDirection:\t”+sum);Console.ReadKey();

PressStartorF5toruntheapplicationandseetheresultsproducedbyexaminingeachvariablevalue

The*multiplicationoperatortakesprecedenceoverthe+additionoperator–somultiplicationisperformedfirst.

The-subtractionoperatorandthe+additionoperatorhaveequalprecedencebutalsohaveleft-to-rightassociativity–sosubtractionisperformedfirstbeforeaddition.

Itisbesttoclarifyallexpressionsbyaddingparenthesestogroupoperations.

Summary• Arithmeticoperatorscanformexpressionswithtwooperandsfor+addition,-subtraction,*

multiplication,and/division.

• The%modulusarithmeticoperatordividesthefirstoperandbyitssecondoperand,thenreturnstheremainder.

• Caremustbetakentogroupexpressionswithin()parentheseswheremorethanoneoperatorisused.

• The++incrementand--decrementoperatorsmaybepostfixedorprefixedtomodifyasingleoperandbyone.

• The=assignmentoperatorcanbecombinedwithanarithmeticoperatortoassigntheresultofanoperation.

• Comparisonoperatorscanformexpressionswithtwooperandsfor==equalityorfor!=inequality.

• Comparisonoperatorscanformexpressionswithtwooperandsfor>greaterorfor<lesservaluecomparison.

• Equalitycanalsoberecognizedincomparisonswiththe>=greater-or-equaland<=less-or-equaloperators.

• The&&logical-ANDoperatorevaluatestwooperandsandwillreturntrueonlyifbothoperandsarethemselvestrue.

• The||logical-ORoperatorevaluatestwooperandsandwillreturntrueifeitherofthetwooperandsarethemselvestrue.

• The!logical-NOToperatorreturnstheinverseBooleanvalueofasinglegivenoperand.

• The?:ternaryoperatorevaluatesagivenBooleanexpression,thenreturnsoneoftwooperandsdependingontheresult.

• Operatorprecedencedeterminestheorderinwhichexpressionsareevaluated.

• Whenoperatorshaveequalprecedence,theirassociativitydetermineshowexpressionsaregroupedforevaluation.

4

Makingstatements

ThischapterdemonstrateshowstatementscanevaluateexpressionstodeterminethedirectioninwhichaC#programwill

proceed.

BranchingwithifSwitchingbranchesLoopingforLoopingwhileIteratingforeachSummary

BranchingwithifTheC#ifkeywordperformsthebasicconditionaltestthatevaluatesagivenexpressionforaBooleanvalueoftrueorfalse–anditssyntaxlookslikethis:

if(test-expression){statements-to-execute-when-true}

Thebracesfollowingthetestmaycontainoneormorestatements,eachterminatedbya;semicolon,butthesewillonlybeexecutedwhentheexpressionisfoundtobetrue.Whenthetestisfoundtobefalse,theprogramproceedstoitsnexttask.

Toallow“conditionalbranching”,anifstatementcanofferalternativestatementstoexecutewhenthetestfailsbyappendinganelsestatementblockaftertheifstatementblock,likethis:

if(test-expression){statements-to-execute-when-true}else{statements-to-execute-when-false}

Totesttwoconditions,thetestexpressionmayusethe&&operator.Forexample,if((num>5)&&(letter==‘A’)).

ShorthandcanbeusedwhentestingaBooleanvalue–sotheexpressionif(flag==true)canbewrittenasif(flag).

Alternatively,anifstatementcanbe“nested”withinanotherifstatement,sothosestatementsintheinnerstatementblockwillonlybeexecutedwhenbothtestssucceed–butstatementsintheouterstatementblockwillbeexecutediftheoutertestsucceeds:

IfElse

StartanewConsoleApplication,thennametheprojectandConsole.Titleas“IfElse”

TypethesestatementstocreateandinitializetwovariablesfromuserinputConsole.Write(“PleaseEnterANumber:”);doublenum=Convert.ToDouble(Console.ReadLine());Console.Write(“Thanks.NowEnterALetter:”);charletter=Convert.ToChar(Console.ReadLine());

Next,addastatementtooutputamessageiftheuser’snumberinputexceedsaspecifiedvalueif(num>=6){Console.WriteLine(“\nNumberExceeds5”);//Nestedstatementtobeinsertedhere(Step5).

}

Avoidnestingmorethanthreelevelsofifstatements–topreventconfusionanderrors.

Now,addastatementtooutputanalternativemessageiftheuser’snumberinputislessthanthespecifiedvalueelse{Console.WriteLine(“\nNumberIs5OrLess”);

}Console.ReadKey();

Insertastatementwithintheifblocktooutputamessagewhentheuser’sletterinputmatchesaspecifiedvalueif(letter==‘C’){Console.WriteLine(“LetterIs‘C’”);

}

PressStartorF5toruntheapplicationandentervaluestoseetheprogrambranchaccordingtoyourinput

Wherethereisonlyonestatementtoexecute,whenthetestsucceedsthe{}bracesmaybeomitted–butretainingthemaidscodeclarity.

SwitchingbranchesTheifandelsekeywords,introducedabove,allowprogramstobranchinaparticulardirectionaccordingtotheresultofatestcondition,andcanbeusedtorepeatedlytestavariabletomatchavalue.Forexample,testingforaninteger:

if(num==1){Console.Write(“Monday”);}elseif(num==2){Console.Write(“Tuesday”);}elseif(num==3){Console.Write(“Wednesday”);}elseif(num==4){Console.Write(“Thursday”);}elseif(num==5){Console.Write(“Friday”);}

Theprogramwillbranchinthedirectionofthematch.

Avoidwritinglengthyif-elsestatementsliketheoneshownhere–wherepossible,useaswitchstatementinstead.

Conditionalbranchingwithlongif-elsestatementscanoftenbemoreefficientlyperformedusingaswitchstatementinstead,especiallywhenthetestexpressionevaluatesjustonevariable.

Theswitchstatementworksinanunusualway.Ittakesagivenvariablevalue,orexpression,thenseeksamatchingvalueamonganumberofcasestatements.Statementsassociatedwiththematchingcasestatementbya:colonwillthenbeexecuted.

Whennomatchisfound,nocasestatementswillbeexecuted,butyoumayaddadefaultstatementafterthefinalcasestatementtospecifystatementstobeexecutedwhennomatchisfound.Thesyntaxofatypicalswitchstatementlookslikethis:

switch(variable-name){casevalue1:statement;break;casevalue2:statement;break;casevalue3:statement;break;default:statement;

}

Itisimportanttofolloweachcasestatementwiththebreakkeyword.Unlikeotherprogramminglanguages,C#doesnotallowfall-throughfromonecasestatementtoanother–eachcasestatementmustallowcontroltobehandedbackinordertoexittheswitchblock.

MissingbreakkeywordsinC#casestatementsaresyntaxerrors.

Switch

StartanewConsoleApplication,thennametheprojectandConsole.Titleas“Switch”

Typethisstatementtocreateandinitializeanintegervariableintnum=3;

Next,addastatementtodeclareastringvariablestringday;

Now,addastatementtoinitializethestringvariableaccordingtothevalueoftheintegervariableswitch(num){case1:day=“Monday”;break;case2:day=“Tuesday”;break;case3:day=“Wednesday”;break;case4:day=“Thursday”;break;case5:day=“Friday”;break;//Defaultstatementtobeinsertedhere(Step5).

}

Then,insertafinalstatementintotheswitchblocktoinitializethestringvariablewhennomatchisfounddefault:day=“WeekendDay”;

Finally,addstatementstooutputtheassignedvalueConsole.WriteLine(“Day”+num+“:“+day);Console.ReadKey();

PressStartorF5toruntheapplicationandseethestringresultoftheswitchblockassignment

Acasestatementcanalsotrytomatchagainstastringvalue.Forexample:case:“ABC”.

Thedefaultstatementdoesnotneedtobefollowedbyabreakkeyword–becauseadefaultstatementalwaysappearsattheendofaswitchblock.

LoopingforAloopisapieceofcodeinaprogramthatautomaticallyrepeats.Onecompleteexecutionofallstatementscontainedwithintheloopblockisknownasan“iteration”or“pass”.

Thenumberofiterationsmadebyaloopiscontrolledbyaconditionaltestmadewithintheloop.Whilethetestedexpressionremainstrue,theloopwillcontinue–untilthetestedexpressionbecomesfalse,atwhichtimetheloopends.

ThethreetypesofloopstructuresinC#programmingareforloops,whileloops,anddo-whileloops.Perhapsthemostcommonlyusedloopistheforloop,whichhasthissyntax:

for(initializer;test-expression;updater){statements}

Theinitializersetsthestartingvalueforacounterofthenumberofiterationstobemadebytheloop.Anintegervariableisusedforthispurposeandistraditionallynamed“i”.

Uponeachiterationoftheloop,thetestexpressionisevaluatedandthatiterationwillonlycontinuewhilethisexpressionistrue.Whenthetestedexpressionbecomesfalse,theloopendsimmediatelywithoutexecutingthestatementsagain.Oneachiterationthecounterisupdatedthenthestatementsexecuted.

Loopsmaybenestedwithinotherloops–sothattheinnerloopwillfullyexecuteitsiterationsoneachiterationoftheouterloop.

Theupdatermayincrementthecounterusingthe++operatortocountup,ordecrementthecounterusingthe--decrementoperatortocountdown.

ForLoop

StartanewConsoleApplication,thennametheprojectandConsole.Titleas“ForLoop”

Typethesestatementstocreatealoopthatwillmakethreeiterationsfor(inti=1;i<4;i++){Console.WriteLine(“LoopIteration:“+i);//Nestedlooptobeinsertedhere(Step4).

}Console.ReadKey();

PressStartorF5toruntheapplicationandseetheloopcounterdisplayedoneachiteration

Insidetheforloopblock,insertanotherforloopthatwillalsomakethreeiterationsfor(intj=1;j<4;j++){Console.WriteLine(“\tInnerLoopIteration:“+j);

}

PressStartorF5toruntheapplicationoncemoreandnowseebothloopcountersdisplayedoneachiteration

Onthethirditerationoftheseloops,theupdaterincrementsthecountervalueto4–sowhenitisnextevaluatedthetestexpressionreturnsfalseandtheloopends.

LoopingwhileAnalternativetotheforloop,introducedhere,usesthewhilekeyword,followedbyanexpressiontobeevaluated.Whentheexpressionistrue,statementscontainedwithinbracesfollowingthetestexpressionwillbeexecuted.Theexpressionwillthenbeevaluatedagainandthewhileloopwillcontinueuntiltheexpressionisfoundtobefalse.

while(test-expression){statements}

Theloop’sstatementblockmustcontaincodethatwillaffectthetestedexpressioninordertochangetheevaluationresulttofalse,otherwiseaninfiniteloopiscreatedthatwilllockthesystem!Whenthetestedexpressionisfoundtobefalseuponitsfirstevaluation,thewhileloop’sstatementblockwillneverbeexecuted.

Asubtlevariationofthewhileloopplacesthedokeywordbeforetheloop’sstatementblockandawhiletestafterit,withthissyntax:

do{statements}while(test-expression);

Inado-whileloopthestatementblockwillalwaysbeexecutedatleastonce–becausetheexpressionisnotevaluateduntilafterthefirstiterationoftheloop.

Ifyouaccidentallystartrunninganinfiniteloop,forexample:while(true){Console.Write(i);i++;

}pressCtrl+Ckeystoterminatetheprocess.

BreakingoutofloopsAbreakstatementcanbeincludedinanykindoflooptoimmediatelyterminatetheloopwhenatestconditionismet.Thebreakensuresnofurtheriterationsofthatloopwillbeexecuted.

Similarly,acontinuestatementcanbeincludedinanykindoflooptoimmediatelyterminatethatparticulariterationoftheloopwhenatestconditionismet.Thecontinuestatementallowsthelooptoproceedtothenextiteration:

WhileLoop

StartanewConsoleApplication,thennametheprojectandConsole.Titleas“WhileLoop”

Typethesestatementstocreateandinitializeanintegerarrayvariableandaregularintegercountervariableint[]nums=newint[10];inti=0;

Next,addawhilelooptoassignitsincrementingcountervaluetoanarrayelementanddisplayitoneachiterationwhile(i<nums.Length){nums[i]=i;Console.Write(“|“+nums[i]);i++;

}Console.Write(“\n\n“);

Noticehowthearray’sLengthpropertyisusedtodeterminethenumberofelementsitcontains.

Now,addado-whilelooptodisplayitsdecrementingcountervalueoneachiterationdo{i--;//Statementstobeinsertedhere(Step6).Console.Write(“|“+nums[i]);

}while(i>0);Console.ReadKey();

Rememberthatthewhilestatementattheendofado-whileloopmustbeterminatedwitha;semicolon.

PressStartorF5toruntheapplicationandseebothloopcountersdisplayedoneachiteration

Inthedo-whileloop,insertastatementtoskipasingleiteration,andastatementtoprematurelyexittheloopif(i==8){Console.Write(“|Skipped”);continue;}if(i==3){Console.Write(“|Done”);break;}

PressStartorF5toruntheapplicationoncemore,andnowseethedo-whileloopiterationsskipped

Thepositionofbreakandcontinuestatementsisimportant–theymustappearaftertheupdater,toavoidcreatinganinfiniteloop,butbeforeanyotherstatements,topreventtheirexecution.

IteratingforeachC#providesaspecialforeach-instatementthatallowsyoutoeasilytraverseallelementsinanarraytoaccessallstoredvalues.Thisisan“iterator”,ratherthanaloopstructure,soitcannotbeusedtoassignormodifyelementvalues–itcanonlybeusedtoreadtheirvalues.Syntaxofaforeach-instatementlookslikethis:

foreach(data-typevariable-nameinarray-name){statements}

Useaforloopifyouneedtoassignormodifyelementvalues.

Theforeachkeywordmustspecifyavariableofanappropriatedatatypetowhicheachelementvaluecanbeassigned,onebyone,andtheinkeywordmustspecifythenameofthearray:

ForEach

StartanewConsoleApplication,thennametheprojectandConsole.Titleas“ForEach”

Typethisstatementtocreateandinitializeastringarraystring[]websites=newstring[5]{“Google”,“YouTube”,“Facebook”,“Baidu”,“Yahoo!”};

Next,addastatementtodisplayalistheadingConsole.WriteLine(“PopularWebsites...“);

Now,addaforeachstatementtodisplayacountervalueandelementvalueoneachiterationintrank=1;foreach(stringsiteinwebsites){Console.WriteLine(“Position:“+rank+”\t”+site);rank++;

}Console.ReadKey();

PressStartorF5toruntheapplicationandseetheiteratordisplaythecounterandelementvalues

Thebreakandcontinuekeywordscanbeusedinaforeachstatementtoexittheiterationcycle.

Aforeach-instatementcanalsobeusedtotraverseallelementsofaC#“dictionary”thatcontainsassociatedkey-valuepairs.Thedatatypesofthekeyandvaluemustbespecifiedasacomma-separatedpairwithin<>angledbracketsinthedeclaration:

Dictionary<data-type,data-type>dictionary-name=newDictionary<data-type,data-type>();

TheforeachkeywordmustspecifyaKeyValuePairtowhicheachkey-valuepairvaluecanbeassigned,onebyone,andtheinkeywordmustspecifythenameofthedictionary:

KeyValue

StartanewConsoleApplication,thennametheprojectandConsole.Titleas“KeyValue”

Typethesestatementstocreateandinitializeadictionarynamed“BookList”Dictionary<string,string>BookList=

newDictionary<string,string>();BookList.Add(“StuartYarnold”,“Arduino”);BookList.Add(“NickVandome”,“Windows10”);BookList.Add(“MikeMcGrath”,“Java”);

Now,addastatementtodisplayalistheadingConsole.WriteLine(“PopularTitles...“);

Addaforeachstatementtodisplayeachkey-valuepairforeach(KeyValuePair<string,string>bookinBookList){Console.WriteLine(“Key:“+book.Key+

“\tValue:”+book.Value+“ineasysteps”);}Console.ReadKey();

PressStartorF5toruntheapplicationandseetheiteratordisplaythedictionary’skey-

valuepairs

NotethataDictionaryobjecthasAdd()andRemove()methods,andhasKeyandValueproperties.

TheDictionaryclassispartoftheSystem.Collections.Genericlibrary–sothismustbeincludedintheprogramusingstatements.

Summary• AnifstatementevaluatesagiventestexpressionforaBooleanvalueoftrueorfalse.

• Statementscontainedinbracesafteranifstatementwillonlybeexecutedwhentheevaluationisfoundtobetrue.

• Multipleifstatementscanbenested,sostatementsintheinnerloopareonlyexecutedwhenbothlooptestsreturntrue.

• Theifandelsekeywordsareusedtoperformconditionalbranchingaccordingtotheresultofatestedexpression.

• Aswitchstatementisanalternativeformofconditionalbranchingthatmatchesacasestatementtoagivenvalue.

• Eachcasestatementmustbeterminatedbythebreakkeyword,asC#doesnotallowfall-through.

• Theforloopstructurehasparametersdeclaringaninitializer,atestexpression,andanupdater.

• Aloopupdatermay++incrementacountertocountup,ormay--decrementacountertocountdown.

• Awhileloopmayneverexecuteitsstatements,butado-whileloopwillalwaysexecuteitsstatementsatleastonce.

• Awhileloopanddo-whileloopmustalwayshaveanupdaterwithintheirloopbodytoavoidcreatinganinfiniteloop.

• Anytypeofloopcanbeimmediatelyterminatedbyincludingabreakstatementwithintheloopbody.

• Asingleiterationofanytypeofloopcanbeskippedbyincludingacontinuestatementwithintheloopbody.

• Aforeach-instatementisaniteratorthatcantraverseallelementsofanarraytoreadtheirvalues.

• Aforeach-instatementcantraverseallkey-valuepairsofadictionarytoreadtheirvalues.

5

Devisingmethods

ThischapterdemonstrateshowtocreatemethodsthatcanbecalledtoexecutestatementswhenevertheC#program

requiresthem.

CreatingfunctionPassingargumentsOverloadingmethodsRefactoringcodeSummary

CreatingfunctionC#programmer-specifiedmethodsencloseasectionofcodethatprovidesparticularfunctionalitytotheprogram.WhenamethodiscalledfromwithinthedefaultMain()programmethod,itsstatementsareexecutedand,optionally,avaluecanbereturnedtothemainprogramuponcompletion.Wrappingfunctionalityinmodularmethodsprovidesthesethreemainbenefits:

• Modularprogramcodeiseasiertounderstandandmaintain

• Triedandtestedmethodscanbere-usedbyotherprograms

• Theworkloadonlargeprogramscanbemoreeasilyshared

AmethodisdeclaredinaC#programbyspecifyingthevariouselementsofitsstructurewiththissyntax:

access-specifierreturn-data-typemethod-name(parameters){statements

}

Thefirstpartofamethoddeclaration,definingitsaccess,returntype,name,andparameters,isknownasthemethod“signature”.

Theaccessspecifierdeterminesthevisibilityofthemethodtootherclasses,usingkeywordssuchaspublicandprivate.Alternatively,ifthemethodisnotintendedforusebyotherclasses,itcanbeinitializedinmemoryusingthestatickeyword.

Ifthemethodwillreturnavaluetothecaller,thedatatypeofthatvaluemustbespecified.If,ontheotherhand,themethodwillneverreturnavalue,thevoidkeywordmustbespecified.

TheuseofmethodsbyotherclassesisdescribedanddemonstratedinthechapteronObjectOrientedProgramming–seehere.

Anamemustbespecifiedforeachprogrammer-definedmethod,adheringtothesamenamingconventionsasvariablenames.

Optionally,parametersmaybespecifiedwithinparenthesesafterthemethodnametorepresentargumentvaluespassedintothemethodbythecaller.Oncedefined,amethodwithoutparametersmaybecalledsimplybystatingitsnamefollowedbyparentheses.

Variablesdeclaredwithinamethodarenot,bydefault,visibletootherpartsoftheprogram–theyareonlyavailabletocodewithinthatmethodbody.Thevisibilityofvariablesisknownas“variablescope”andvariableswithinmethodshaveonly“local”scope.Thismeansthatvariablesdeclaredindifferentmethodsmaybegiventhesamenamewithoutconflict.

Parametersandargumentsaredemonstratedintheexamplehere.

Method

StartanewConsoleApplication,thennametheprojectandConsole.Titleas“Method”

AftertheMain()method,addthismethoddefinitionwithinthe{}bracesoftheclassProgramstaticvoidbodyTempC(){Console.WriteLine(“BodyTemperature...”);Console.WriteLine(“Centigrade:\t37ºC”);

}

YoucanusetheWindowsAccessories,CharacterMapfacilitytoproducethedegree

symbol.

Next,addamethoddefinitionthatreturnsafloating-pointvaluetothecallerstaticdoublebodyTempF(){doubletemperature=98.6;returntemperature;

}

Eachvariablecansharethesamenameastheyhaveonlylocalscope.

Now,addamethoddefinitionthatreturnsanintegervaluetothecallerstaticintbodyTempK(){inttemperature=310;returntemperature;

}

Finally,addstatementswithintheMain()methodtocalleachoftheprogrammer-specifiedmethodsabovebodyTempC();Console.WriteLine(“Fahrenheit:\t”+bodyTempF()+“ºF”);Console.WriteLine(“Kelvin:\t”+bodyTempK()+“K”);Console.ReadKey();

PressStartorF5toruntheapplicationandseetheoutputfeaturingthemethodcalls

PassingargumentsMethodsmayoptionallyspecifyoneormoreparametersasacomma-separatedlistwithintheparenthesesoftheirdefinition.Eachspecifiedparametermuststatethedatatypeitmaycontain,andanamebywhichitmaybereferencedwithinthemethod.Forexample,parametersfortextandanumber,likethis:

staticvoidsetUser(stringname,intage){statements}

Whenamethodwithparametersiscalled,thecallermustnormallypassthecorrectnumberofargumentvaluesoftherequireddatatype.Thesearelistedwithintheparenthesesofthecallingstatement.Forexample,callingthemethoddefinedabove:

setUser(“Alison”,18);

Callingamethodwithoutpassingrequiredarguments,orargumentsofthewrongdatatype,willcauseanerror.

Optionally,theparameterdeclarationmaybeassignedadefaultvaluetouseifnoargumentvalueispassedbythecaller.Inthiscase,thecallermaypassoromitanargumentvalue:

staticvoidsetUser(stringname,intage=21){statements}

setUser(“Brenda”,19);setUser(“Christine”); //Agewillbe21.

Therearethreewaystopassargumentsintomethods:

• ByValue–argumentspassedtomethods“byvalue”assignacopyoftheoriginalvaluetotheparameter.Changesmadetotheparameterinsidethemethoddonotaffecttheoriginalvalue.

• ByReference–argumentspassedtomethods“byreference”assigntheaddressofthememorylocationoftheoriginalvaluetotheparameter.Changesmadetotheparameterinsidethemethoddoaffecttheoriginalvalue.ReferenceargumentsmustincludetheC#refkeywordinboththemethodcallparenthesesandthemethoddefinitionparameterlist.

• ForOutput–argumentspassedtomethods“foroutput”assigntheaddressofthememorylocationoftheargumenttotheparameter,towhichthemethodcanassignavalue.Thisissimilartopassinganargumentbyreferenceexceptthatdataispassedfromthemethod,ratherthantothemethod.OutputargumentsmustincludetheC#outkeywordinboththemethodcallparenthesesandthemethoddefinitionparameterlist.Thisisusefultoreturnmorethanonevaluefromamethod.

Mostmethodcallspassargumentsbyvalueratherthanbyreferenceorforoutput.

Parameter

StartanewConsoleApplication,thennametheprojectandConsole.Titleas“Parameter”

Typethesestatementstodeclaretwovariablesdoubleweight;stringnum;

AftertheMain()method,addthismethoddefinitiontooutputadoublevalueandtoreturnastringvaluestaticstringgetWeight(outdoubletheWeight){theWeight=10;return“Ten”;

}

Next,addamethoddefinitionthatreturnsamultipliedvalueofitsparameterargumentstaticdoublelbToKg(doublepounds=5){return(pounds*0.45359237);}

Thedefaultparametervalueisnotusedhereasthecallerpassesinanargumentvalue.

Now,addamethoddefinitionthatassignsadividedvaluetoitsparameterreferenceargumentstaticvoidkgToLb(refdoubleweight){weight=(weight/0.45359237);}

Finally,addstatementswithintheMain()methodtopassargumentstoeachofthemethodsdeclaredabovenum=getWeight(outweight);Console.WriteLine(num+“lb=”+lbToKg(weight)+“kg”);kgToLb(refweight);Console.WriteLine(num+“kg=”+weight+“lb”);Console.ReadKey();

PressStartorF5toruntheapplicationandseetheoutputfeaturingargumentspassedtomethodparameters

BoththenumandweightvariablesareinitializedbythegetWeight()method.Areferencetotheweightvariableispassedlatertoassignitanewvalue.

OverloadingmethodsMethod“overloading”allowsmethodsofthesamenametohappilyco-existinthesameprogram,providingtheirparametersdifferinnumber,datatype,orbothnumberanddatatype.Thecompilermatchesamethodcalltothecorrectversionofthemethodbyrecognizingitsparameternumberanddatatypes–aprocessknownas“methodresolution”.Therearesomepointstoconsiderwhencreatingoverloadedmethods:

• Whereaparameterrepresentsthesamevalueasthatinanothermethod,theparametersshouldhavethesamename.

• Parameterswiththesamenameshouldappearinthesamepositionineachmethod’sparameterlist.

• Youshouldnotusereforoutmodifierstooverloadmethods.

Itisusefultocreateoverloadedmethodswhenthetaskstheyaretoperformaresimilar,yetsubtlydifferent.

Overload

StartanewConsoleApplication,thennametheprojectandConsole.Titleas“Overload”

AftertheMain()method,addthismethoddefinitiontoreturnthecalculatedareaofacirclestaticdoublecomputeArea(doublewidth){doubleradius=width/2;return((radius*radius)*3.141593);

}

Next,addamethoddefinitiontoreturnthecalculatedareaofasquarestaticdoublecomputeArea(doublewidth,doubleheight){return(width*height);

}

Then,addamethoddefinitiontoreturnthecalculatedareaofatrianglestaticdoublecomputeArea(doublewidth,doubleheight,charletter){return((width/2)*height);

}

Methoddefinitionsthatonlydifferbytheirreturndatatypecannotbeoverloaded–it’stheparametersthatmustdiffer.Methodresolutiondoesnottakereturndatatypesintoconsideration.

Now,turnyourattentiontotheMain()methodandbeginbydeclaringtwofloating-pointvariablesdoublenum;doublearea;

Next,addstatementstoinitializethefirstvariablefromuserinputConsole.Write(“PleaseEnterDimensionInFeet:“);num=Convert.ToDouble(Console.ReadLine());

RememberthattheReadLine()methodreturnsastringvalue–sothismustbeconvertedinordertoperformarithmetic.

Now,initializethesecondvariablebycallingthemethodthatacceptsonlyoneargumentanddisplayitsvaluearea=computeArea(num);Console.WriteLine(“\nCircle:\t\tArea=“+area+“sq.ft.”);

Assignanewvaluetothesecondvariablebycallingthemethodthatacceptstwoargumentsanddisplayitsvaluearea=computeArea(num,num);Console.WriteLine(“Square:\t\tArea=“+area+“sq.ft.”);

Assignanothervaluetothesecondvariablebycallingthemethodthatacceptsthreeargumentsanddisplayitsvaluearea=computeArea(num,num,‘T’);Console.WriteLine(“Triangle:\tArea=“+area+“sq.ft.”);Console.ReadKey();

PressStartorF5toruntheapplication,thenenteranumberandseetheoutputfromtheoverloadedmethods

Thevaluepassedtothecharletterparameterisneverusedhere–itisincludedmerelytodeterminewhichmethodshouldbecalled.

RefactoringcodeMethodscancallthemselvesrecursively,torepeatedlyexecutethestatementscontainedintheirmethodbody–muchlikealoop.Aswithloops,arecursivemethodmustcontainanupdater,andaconditionaltesttocallitselfagainorstoprepeatingwhenaconditionismet.Thesyntaxofarecursivemethodlookslikethis:

return-data-typemethod-name(parameter-list){

statements-to-be-executed;updater;conditional-test-to-recall-or-exit;

}

Theupdaterwillchangethevalueofapassedargument–sosubsequentcallswillpasstheadjustedvaluebacktothemethod:

Refactor

StartanewConsoleApplication,thennametheprojectandConsole.Titleas“Refactor”

AftertheMain()method,addthisrecursivemethodtoreturnthefactorialvalueofanintegerargumentstaticintfactorial(intnum){intresult;if(num==1){result=1;

}else{result=(factorial(num-1)*num);

}returnresult;

}

Next,addamethodtodisplayarangeofintegersandtheircomputedfactorialvaluesstaticvoidcomputeFactorials(intnum,intmax){while(num<=max){Console.Write(“FactorialOf“+num+“:“);Console.WriteLine(factorial(num));num++;

}}

ThetwocallstowriteoutputinStep3couldberefactoredintoasingleWriteLine()callforgreaterefficiency.

Now,addstatementswithintheMain()methodtopassarangeofargumentvaluestobecomputedfordisplaycomputeFactorials(1,8);Console.ReadKey();

PressStartorF5toruntheapplicationtoseetheoutput

IfyouaccidentallyrunaninfiniterecursivefunctionpresstheCtrl+Ckeystoterminatetheprocess.

Theoutputlistsfactorialvalues(factorial3is3x2x1=6,etc.)buttheprogramcanbeoptimizedbyrefactoringtherecursivefactorial()method.Thismethoddoesnotneedavariableifwrittenwiththeternaryoperator:

Editthefactorial()method,listedinStep2,tomakeitmoreefficientstaticintfactorial(intnum){return(num==1)?1:(factorial(num-1)*num);

}

PressStartorF5toruntheapplicationoncemoreandseethesameoutput,producedmoreefficiently

Arecursivemethodgenerallyusesmoresystemresourcesthanaloop–butitcanmakethecodemorereadable.

Summary• Aprogrammer-specifiedmethodisamodularsectionofcodethatcanbecalledtoexecuteits

statementswheneverrequired.

• Itiseasiertounderstand,maintain,re-use,andsharemodularprogramcodethatcontainsmethods.

• Amethoddeclarationmustatleastspecifyareturndatatypeandthemethodname.

• Methodsnotintendedforusebyotherclassesmustbeinitializedinmemorybythestatickeyword.

• Optionally,amethoddeclarationmayincludeaparameterlist.

• Variablesdeclaredwithinamethodhavelocalscopebydefault,soarenotaccessiblefromoutsidethatmethod.

• Argumentspassedbyvalueassignacopyoftheoriginalvaluetothemethodparameter,sotheoriginalwillnotbeaffected.

• Argumentspassedbyreferenceassignamemorylocationtothemethodparameter,sotheoriginalvaluewillbeaffected.

• Argumentspassedforoutputretrieveavaluefromthemethodandareusefultoreturnmorethanonevalue.

• Methodoverloadingallowsmethodsofthesamenametoco-existinthesameprogramiftheirparametersdiffer.

• Thecompilermatchescallstooverloadedmethodsbyrecognizingtheirparameternumberanddatatypes.

• Parametersrepresentingthesamevaluesinoverloadedmethodsshouldhavethesamenameandthesameposition.

• Thereferencerefandoutputoutmodifiersshouldnotbeusedwithoverloadedmethods.

• Codecanberefactoredforoptimumefficiencybyreducingthenumberofvariablesandmethodcalls.

• Recursivemethodsrepeatedlyexecutetheirstatements,somustcontainanupdatertostoprepeatingatsomepoint.

6

Handlingstrings

ThischapterdemonstrateshowtomanipulateandformattextstringswithinC#programs.

DiscoveringstringfeaturesManipulatingstringsJoiningandcomparingstringsCopyingandswappingstringsFindingsubstringsFormattingstringsFormattingdatestringsSummary

DiscoveringstringfeaturesTheC#Stringclasslibraryprovidespropertiesandmethodsthatenableaprogramtoeasilydiscoverfeaturesofatextstring.Usefully,theString.IsNullOrWhiteSpace()andString.IsNullOrEmpty()methodscanbeusedtovalidateuserinput.Thesearestaticmethods,soarewrittendot-suffixedtotheStringclassname.

StringclassmethodscanbewrittenusingtheString.classprefixoritsstring.aliasprefix–ourexamplesuseStringtodifferentiatefromthestringdatatype.

Otherpropertiesandmethodsoperateonan“instance”oftheclass,soarewrittendot-suffixedtoastringvariablename.Instancemethodscanreportstringsizeandqueryitscontents.TheLengthpropertyreturnsanintegerthatisthenumberofcharacterswithinthestring,includingspaces.Additionally,theStartsWith(),EndsWith(),andContains()methodscaneachacceptastringargumenttomatchwithinthestringvariablevalue.Whenamatchisfound,theyreturntrue,otherwisetheyreturnfalse:

Features

StartanewConsoleApplication,thennametheprojectandConsole.Titleas“Features”

TypethesestatementsrequestinguserinputtoinitializeastringvariableConsole.Write(“PleaseEnterText:”);stringtext=Console.ReadLine();

Next,addaconditionaltesttoensuretheuserenteredinputbeforehittingtheEnterkeyif(String.IsNullOrWhiteSpace(text)){Console.WriteLine(“\nERROR:NoTextFound!”);

}else{//Statementstobeinsertedhere(Steps4-7).

}Console.ReadKey();

Now,insertstatementstoreportthelengthofthestringConsole.WriteLine(“\nThanks.YouEntered:\n’”+text+”’”);Console.WriteLine(“\nTextLength:”+text.Length);

Insertanotherstatementtotesthowthestringbeginsstringquery=text.StartsWith(“C#”)?“Does”:“DoesNot”;Console.WriteLine(“Text”+query+“StartWith‘C#’”);

MethodswithaString.(orstring.)prefixareusingtheStringclassitself,whereasdot-suffixedmethodsusean“instance”objectoftheclass–seeChapterNine.

Notethatsomeofthesestringsinclude‘singlequoteswithintheouter“doublequotemarks.

Next,insertastatementtotesthowthestringendsquery=text.EndsWith(“steps”)?“Does”:“DoesNot”;Console.WriteLine(“Text”+query+“EndWith‘steps’”);

Now,insertastatementtotestwhatthestringcontainsquery=text.Contains(“easy”)?“Does”:“DoesNot”;Console.WriteLine(“Text”+query+“Contain‘easy’”);

PressStartorF5toruntheapplication,andhitEnterwithoutinputtoseetheerrormessage

PressStartorF5toruntheapplicationagain,typeinputthenhitEntertodiscoverinputstringfeatures

Noticethatthe?:ternaryoperatorisusedheretoassignanappropriatestringvalue.

Stringvaluesareoftenreferredtoas“literals”,astheycomprisecharacterstobereadliterally,astext.

ManipulatingstringsTheC#Stringclasslibraryprovidesmethodsthatenableaprogramtomanipulatetextstrings.TheToLower()andToUpper()methodscanbedot-suffixedtoastringvariabletochangeallcharacterswithinthestringtolowercase,ortouppercase.

Similarly,theTrimStart(),TrimEnd(),andTrim()methodscanbeusedtoremovewhitespace,orothercharacters,fromastringatitsstart,end,orbothstartandend.Bydefault,thesemethodswillremovewhitespacefromthestring,butyoucanalternativelyspecifyacharactertoberemovedasanargumenttothemethod.

Youcanalsospecifymultiplecharacterstobetrimmedasacomma-separatedlistofargumentstotheTrimStart(),TrimEnd(),orTrim()methods.

Conversely,thePadLeft()andPadRight()methodscanbeusedtoaddwhitespace,orothercharacters,ontoastringatitsstartorend.Theirargumentsmustspecifythetotalcharacterlengthofthepaddedstring,andapaddingcharacterunlessdefaultwhitespacepaddingisrequired.Ifyouwanttoaddpaddingontobothstartandend,themethodscanbe“chained”asPadLeft().PadRight()statingeachpaddinglengthargument,andcharacterifrequired:

Manipulate

StartanewConsoleApplication,thennametheprojectandConsole.Titleas“Manipulate”

TypethesestatementsrequestinguserinputtoinitializeastringvariableConsole.Write(“PleaseEnterText:”);stringtext=Console.ReadLine();

AddstatementstodisplaytheuserinputstringandreportitslengthConsole.Write(“\nThanks.YouEntered:\n’”+text+”’”);Console.WriteLine(“\t\tTextLength:”+text.Length);

Removeleadingandtrailingwhitespace,thendisplaythemanipulatedversionandreportitslengthtext=text.Trim();Console.Write(“\nTrimmed:\t’”+text+”’”);Console.WriteLine(“\tTextLength:”+text.Length);

Next,addstatementstocreateanddisplayanuppercaseversionofthetrimmedstringstringupper=text.ToUpper();Console.WriteLine(“\nUpperCase:\t’”+upper+”’”);

ItisagoodideatoalwaysuseTrim()toremovespacesaccidentallyaddedbytheuserwhentypinginput.

Now,createanddisplayalowercaseversionofthetrimmedstringstringlower=text.ToLower();Console.WriteLine(“LowerCase:\t’”+lower+”’”);

Then,furthermanipulateallthreestringstoaddwhitespaceandcharacterpaddingupper=upper.PadLeft(40);lower=lower.PadRight(40,‘#’);text=text.PadLeft(30,‘*’).PadRight(40,‘*’);

AddstatementstodisplayallthreestringstoseethepaddedwhitespaceandpaddedcharactersConsole.WriteLine(“\nPaddedLeft:\t’”+upper+“’”);Console.WriteLine(“PaddedRight:\t’”+lower+“’”);Console.WriteLine(“PaddedBoth:\t’”+text+“’”);

Finally,addstatementstodisplaytrimmedversionsoftwopaddedstringsConsole.WriteLine(“\nTrimmedStart:\t’”+upper.TrimStart()+“’”);Console.WriteLine(“TrimmedEnd:\t’”+text.TrimEnd(‘*’)+“’”);Console.ReadKey();

PressStartorF5toruntheapplicationandenterastringwithleadingandtrailingspacetoseeitmanipulated

Here,allthreestringsareexpandedtoatotalwidthof40characters.

Whenpaddingbothleftandrightyoumustindividuallyspecifybyhowmuchtoexpandthestringineachdirection–inthiscaseexpandingfrom20to30charactersleft,thenfrom30to40charactersright.

JoiningandcomparingstringsWhenthe+operatorisusedtoconcatenate(join)stringsinanassignment,thecombinedstringsgetstoredinthestringvariable.ButwhenusedintheWrite()orWriteLine()methods,thestringsareonlycombinedinoutput–thevariablevaluesareunchanged.

TheC#StringclasslibraryprovidesaString.Concat()methodthatcanbeusedtojoinstringsasanalternativetousingthe+operator.Thismethodacceptsacomma-separatedlistofstringargumentstobejoinedintoasinglestring.

Theexamplesinthisbookusethe+operatorforconcatenationratherthanString.Concat()asitprovidesbetterreadabilitywithoutanylossofperformance.

Similarly,theString.Join()methodcanalsobeusedtojoinstringsasanalternativetousingthe+operator.Thistooacceptsacomma-separatedlistofstringargumentstobejoined,butitsfirstargumentusefullyspecifiesaseparatorstring.Itplacesthisseparatorbetweeneachotherstringargumentinthejoinedstring.Theseparatormightbeasinglespacetoseparatewords,orperhapsanHTMLtagtoseparatetext,oranyotherstringvalue.

StringcomparisonscanbemadeforalphabeticorderbyspecifyingtwostringargumentstotheString.Compare()method.Thisreturnsanintegerdenotingwhetherthealphabeticrelationshipofthefirststringtothesecondisbefore(-1),after(1),orequal(0).ThereisalsoaCompareTo()methodthatprovidesthesameresults,butthiscanbedot-suffixedontothefirststring,andthesecondstringspecifiedasitsargument.

Aswithnumericcomparisons,the==operatorcanbeusedtotestforstringequality.Alternatively,theEquals()methodcanbedot-suffixedontothefirststring,andthesecondstringspecifiedasitsargument.EitherwillreturnatrueorfalseBooleanresult.

Joined

StartanewConsoleApplication,thennametheprojectandConsole.Titleas“Joined”

Typethisstatementtocreateandinitializeastringarrayvariablesimplynamed“a”string[]a=newstring[3]{“Alpha”,”Bravo”,”Charlie”};

Next,assignaconcatenatedversionofthefirsttwoarrayelementvaluestoastring

variableanddisplayitsvaluestrings=String.Concat(a[0],a[1]);Console.WriteLine(“Concatenated:\t”+s);

Assignajoinedversionofthefirsttwoarrayelementsandspaceseparatortothestringvariable,thendisplayitsvalues=String.Join(““,a[0],a[1]);Console.WriteLine(“Joined:\t\t”+s);

Assignajoinedversionofallthreearrayelementsandtagseparatortothestringvariable,thendisplayitsvalues=String.Join(“<br>“,a);Console.WriteLine(“\nHTML:\t”+s+”\n”);

Next,addstatementstocompare,inturn,allthreearrayelementsforalphabeticorderintnum=String.Compare(a[0],a[1]);Console.WriteLine(a[0]+”v“+a[1]+”:\t”+num);

num=String.Compare(a[2],a[1]);Console.WriteLine(a[2]+”v“+a[1]+”:\t”+num);

num=a[1].CompareTo(a[1]);Console.WriteLine(a[1]+”v“+a[1]+”:\t”+num+“\n”);

Finally,testthearrayelementvaluesforequalityboolflag=(a[0]==a[1]);Console.WriteLine(a[0]+”==“+a[1]+”:\t\t”+flag);flag=a[2].Equals(a[2]);Console.WriteLine(a[2]+”==“+a[2]+”:\t\t”+flag);Console.ReadKey();

PressStartorF5toruntheapplicationtoseethejoinedstringsandcomparisonresults

Noticehowonlythearraynameneedstobespecifiedastheargumenttojoinallthreearrayelements.

Youcanaddorremovethe\tescapesequencestoformattheoutputtoyourliking.

Twoalternativemethodsareusedheretocomparestringsandtotestforequality.

CopyingandswappingstringsTheC#StringclasslibraryprovidesaString.Copy()methodthatcanbeusedtocopyonestringtoanotherstringasanalternativetousingthe=assignmentoperator.Thismethodacceptsthestringtobecopiedasitsargument.Perhapsmoreusefully,theCopyTo()methodcanbedot-suffixedontoastringvariabletocopyitscontentsintoacharcharacterarray.Thisrequiresfourargumentstospecifytheindexnumberfromwhichtostartcopyinginthesourcestring,thenameofthechararray,theindexnumberatwhichtostartcopyinginthedestinationchararray,andthenumberofcharacterstocopy.

Copyingwithan=assignmentproducestwostringvariablesthatcontainthesamevalueandreferencethesamememorylocation,whereascopyingwiththeString.Copy()methodproducestwostringvariablesthatcontainthesamevaluebutreferencedifferentmemorylocations.

Othermethodscanbedot-suffixedtoastringvariabletoswapitscontents.TheRemove()methodrequiresanintegerargumenttospecifytheindexnumberatwhichtobeginremovingcharactersfromthestring.Thiswillremoveallcharactersfromthespecifiedindexpositionuptotheendofthestring,unlessyouaddasecondargumenttospecifythenumberofcharacterstoberemoved.

Conversely,theInsert()methodrequiresanintegerargumenttospecifytheindexnumberatwhichtobegininsertingcharactersintothestring,andanargumentspecifyingthestringtoinsert.TheReplace()methodsimplyrequirestwostringargumentstospecifyasubstringtoseekwithinthestring,andastringtoreplacethatsubstringwhenamatchisfound:

Copied

StartanewConsoleApplication,thennametheprojectandConsole.Titleas“Copied”

TypethesestatementstocreateandinitializetwostringvariableswiththenamesoftwoMaseraticarmodelsstringcar1=“Ghibli”;stringcar2=“GranTurismo”;

Next,displaytheoriginalvaluescontainedineachvariableConsole.WriteLine(“Original:”);Console.WriteLine(“\tCar1:”+car1+“\t\tCar2:“+car2);

Now,copythevalueofthesecondstringvariableintothefirststringvariableanddisplaytheirmodifiedvaluescar1=String.Copy(car2);Console.WriteLine(“\nCopied:”);Console.WriteLine(“\tCar1:”+car1+“\tCar2:“+car2);

Initializeanintegervariablewiththelengthofthefirststringvariable,thencreateacharacterarrayofthatlengthintnum=car1.Length;char[]model=newchar[num];

Next,copythefirststringvariableintothecharacterarray,thendisplayaspace-separatedlistoftheelementcontentscar1.CopyTo(0,model,0,num);Console.WriteLine(“\nCharacterArray:”);foreach(charcinmodel){Console.Write(c+““);}

Now,removetheendofthefirststringvariable,startingfromitsfifthelement,anddisplaythemodifiedvaluecar1=car1.Remove(4);Console.WriteLine(“\n\nRemoved...\tCar1:”+car1);

Inserttwostringsintothefirststringvariable,atitsbeginningandend,thendisplaythemodifiedvaluecar1=car1.Insert(0,“Maserati”);car1=car1.Insert(13,“Cabrio”);Console.WriteLine(“\nInserted...\tCar1:”+car1);

Finally,replaceasubstringwithinthefirststringvariable,andoncemoredisplaythemodifiedvaluecar1=car1.Replace(“GranCabrio”,“Quattroporte”);Console.WriteLine(“\nReplaced...\tCar1:”+car1);Console.ReadKey();

PressStartorF5toruntheapplicationtoseethecopiedandswappedstrings

Thechararraymustbeofthesamesizeasthestringtobecopied–usethestring’sLengthpropertytospecifythesizeofthechararray.

Thefifthelementofanarrayisatindexposition4inazero-basedindex.

FindingsubstringsTheC#Stringclasslibraryprovidesanumberofmethodsthatcanbedot-suffixedtoastringvariabletoseekastringwithinastring(i.e.a“substring”).TheIndexOf()methodrequiresthesubstringasitsargumentand,iffound,returnstheindexpositionofthesubstringwithinthesearchedstring.Otherwiseitwillreturn-1.TheIndexOf()methodsearchesforwards,fromleft-to-right,andreturnstheindexpositionofthefirstoccurenceofthesubstring.IthasacompanionLastIndexOf()methodthatworksinjustthesameway,butsearchesbackwards,fromright-to-left.

Thepositionreportedwhenasubstringisfoundistheindexpositionofthefirstcharacterofthatsubstringwithinthesearchedstring–whethersearchingforwardsorbackwards.

Similarly,thereisanIndexOfAny()methodanditscompanionLastIndexOfAny()methodthatrequireacharacterarrayargument.Theseseekanycharacterofthespecifiedarraywithinastring,andreturntheindexpositionofthefirstoccurrence,or-1otherwise.

Youcanalsodot-suffixaSubstring()methodtoastringvariableifyouwanttoextractacopyofasubstringfromwithinthatstring.Thismethodrequirestwoargumentstospecifytheindexpositionatwhichtobegincopying,andthenumberofcharacterstocopy:

Substring

StartanewConsoleApplication,thennametheprojectandConsole.Titleas“Substring”

AftertheMain()method,addthismethoddeclarationtoreporttheresultofasubstringsearchstaticvoidreport(intpos,stringsub){if(pos!=-1){Console.WriteLine(“‘“+sub+”’FoundAt“+pos);}else{Console.WriteLine(“‘“+sub+”’NotFound!“);}

}

Now,turnyourattentiontotheMain()methodandinitializeastringvariable,thendisplayitsvalueandlengthstringtext=“Mydogisacutedog”;

Console.WriteLine(text+”\tLength:“+text.Length);

Next,requestuserinputtoinitializeanotherstringvariablewithasubstringtoseekConsole.WriteLine(“\nPleaseEnterASubstringToSeek:”);stringsub=Console.ReadLine();

Createacharacterarrayandcopytheentiresubstringvalueintothecharacterarraychar[]arr=newchar[sub.Length];sub.CopyTo(0,arr,0,sub.Length);

Then,seekthefirstoccurrenceofthesubstringandcallthemethodyoudefinedtoreportthesearchresultintpos=text.IndexOf(sub);report(pos,sub);

Now,seekthelastoccurrenceofthesubstringandreporttheresultpos=text.LastIndexOf(sub);report(pos,sub);

Next,seekthefirstoccurrenceofanycharacterofthesubstringandreporttheresultpos=text.IndexOfAny(arr);report(pos,text.Substring(pos,1));

Finally,seekthelastoccurrenceofanycharacterofthesubstringandreporttheresultpos=text.LastIndexOfAny(arr);report(pos,text.Substring(pos,1));Console.ReadKey();

PressStartorF5toruntheapplication,thenenterasubstringtoseekandseethereportedresults

TheCopyTo()methodisdescribedanddemonstratedinthepreviousexamplehere.

NoticethatacopyofthelocatedcharacterisextractedfromtheoriginalstringusingtheSubstring()methodforoutputinthereport.

FormattingstringsInC#everyobjecthasaToString()methodthatreturnsastringrepresentationofthatobject.ThismeansthattheToString()methodcanbedot-suffixedtoanynumericvariabletogetitsvaluerepresentedinstringformat.TheToString()methodcan,optionally,acceptastringargumenttospecifyhowthestringversionshouldbeformatted.Commonspecifiersarelistedbelow:

Specifier: Returns:

G General

F FixedPoint

N Number(withcomma-separatedthousands)

C Currency(prevailingonyoursystem)

P Percentage(multipliedby100)

00.0000 ZeroPadding

TheC#specificationsprovidefurtherstringformattingspecifieroptionsinadditiontothecommonlyusedonesshownhere.

TheC#StringclasslibraryprovidesaString.Format()methodthatusesthesamespecifierstoalsoproducevaluesrepresentedinstringformat.Thisrequiresanargumenttospecifythestringtobeformatted,whichmayinclude“placeholders”,andanargumentlisttobesubstitutedforeachplaceholderintheoutputstring.

Multipleplaceholdersinonestringcanbenumberedalike–ifyouwanteachonetobesubstitutedbythesamelistargumentvalue.

Eachplaceholdercanbenumberedsequentially(startingatzero)within{}braces,tomatchthelistpositionofthesubstitutionargument.Forexample,{0}matchesthefirstargumentinthesubstitutionargumentlist,{1}matchesthesecond,andsoon.Additionally,thenumbermaybefollowedbya:colonandoneoftheformatspecifiersinthetableabove–tospecifyhowthe

substitutedvalueshouldappearinitsstring.Forexample,{0:G}.

Datastringsthatcontainseparators,suchasacomma-separatedlistofdataretrievedfromadatabasequery,canbeeasilybrokenintoindividualitemsofdatabydot-suffixingtheSplit()methodtoastringvariable.Theindividualstringscanbeassignedtoastringarrayvariable,andcouldthenbeformattedinoutputbytheString.Format()methodifrequired.

Format

StartanewConsoleApplication,thennametheprojectandConsole.Titleas“Format”

Initializeanumericvariable,thenusetheToString()methodtooutputitsvalueasacurrencystringformatintsum=2500;Console.WriteLine(“CurrencyString:“+sum.ToString(“C”));

Next,usetheString.Format()methodtooutputthesamenumericvalueinvariouscommonstringformatsConsole.Write(String.Format(“\nGeneral:\t{0:G}”,sum));Console.Write(String.Format(“\nFixedPoint:\t{0:F}”,sum));Console.Write(String.Format(“\nNumber:\t\t{0:N}”,sum));Console.Write(String.Format(“\nCurrency:\t{0:C}”,sum));

Now,reducethenumericvalue,thenoutputitinapercentagestringformatandwithpaddedzeroessum/=1000;Console.Write(String.Format(“\nPercentage:\t{0:P}”,sum));Console.Write(String.Format(“\nZeroPadded:\t{0:00.0000}\n”,sum));

Then,createacomma-separatedstringlistandsplititintoindividualelementsofastringarrayvariableforoutputstringdata=“Mike,McGrath,Author”;string[]items=data.Split(‘,’);foreach(stringiteminitems){Console.Write(String.Format(“\n*{0}”,item));}Console.ReadKey();

PressStartorF5toseetheformattedstringoutput

Thespecifierlettersmaybewrittenaseitheruppercaseorlowercase.

TheargumenttotheSplit()methodmustbeasinglecharcharacter–enclosedinsinglequotes.

Youcanusethe+concatenationoperatorforformatting,butmanypreferString.Format()foreasilyreadablecode.

FormattingdatestringsTheC#DateTimeclasslibraryprovidesmethodsandpropertiestoeasilyworkwithdatesandtimes.ItsNowpropertyreturnsaDateTimeobjectofthecurrentlocaldateandtimeofyoursystem.Alternatively,youcancreateaDateTimeobjectusingthenewkeyword,andspecifyingadateandtimeasacomma-separatedlistofarguments.Manymethodsandpropertiescanbedot-suffixedtoanyDateTimeobjecttospecifyitsformat,ortoextractspecificcomponentsofthedateortime,ortomodifyitsvalue.Forexample,theDayOfWeekpropertysuppliesthedayname,theToShortString()methodsuppliesthedateinnumberform,andtheAddYears()methodcanmodifytheyearcomponent.

YoucanuseIntelliSensetochoosemethodsandproperties–forexample,typeDateTime.Now.andselectfromthepop-uplistthatappears.

TheString.Format()method,introducedinthepreviousexample,alsohasthesespecifiersthatcanbeusedtodeterminetheformatofdatesandtimesinoutput:

Specifier: Returns: Example:

d Shortdate 7/4/2017

D Longdate Tuesday,July4,2017

t Shorttime 8:15AM

T Longtime 8:15:30AM

f Fulldatetime Tuesday,July4,20178:15AM

F Full+seconds Tuesday,July4,20178:15:30AM

M Month+day July4

Y Month+year July2017

dd Daynumber 04

dddd Dayname Tuesday

HH Hour0-23 08

mm Minute 15

ss Second 30

YYYY Year 2017

TheC#specificationsprovidefurtherdateandtimeformattingspecifieroptionsinadditiontothecommonlyusedonesshownhere.

DateFormat

StartanewConsoleApplication,thennametheprojectandConsole.Titleas“DateFormat”

InitializeaDateTimeobjectanddisplayitsvalueDateTimenow=DateTime.Now;Console.Write(“CurrentDateAndTime:“+now);

Next,displayspecificcomponentsoftheDateTimeobjectConsole.Write(“\nDayName:“+now.DayOfWeek);Console.Write(“\nDateOnly:“+now.ToShortDateString());Console.Write(“\nTimeOnly:“+now.ToShortTimeString());

ModifytheDateTimeobjectanddisplayitsnewvaluenow=now.AddYears(4);Console.Write(“\n\nFutureDate:“+now);

Now,createanewDateTimeobjectanddisplayitsvalueDateTimedt=newDateTime(2017,7,4,8,15,30);Console.Write(“\n\nSetDateAndTime:{0:f}“,dt);

DisplayspecificcomponentsofthenewDateTimeobjectConsole.Write(“\nDayName:{0:dddd}“,dt);Console.Write(“\nLongDate:{0:D}“,dt);Console.Write(“\nLongTime:{0:T}“,dt);Console.ReadKey();

PressStartorF5toruntheapplicationandseetheformatteddateandtimeoutput

YouneedonlyspecifythedatecomponentswhencreatinganewDateTimeobject–thetimewillautomaticallybesetto12:00AM(midnight).

Summary• Classlibrarystaticmethods,suchasString.IsNullOrEmpty(),aredot-suffixedontotheStringclass

libraryname.

• StringvaluescanbejoinedusingtheString.Concat()andString.Join()methods,orusingthe+concatenationoperator.

• StringcomparisonscanbemadeforalphabeticorderusingtheString.Compare()method.

• AvaluecanbecopiedfromonestringvariabletoanotherusingtheString.Copy()method,or=assignmentoperator.

• TheString.Format()methodcanbeusedtoformatbothnumericanddatestringsinoutput.

• TheDateTimeclasslibraryprovidesmethodsandproperties,suchasNow,toworkwithdateandtimestrings.

• Instancemethodsandproperties,suchasContains()andLength,aredot-suffixedontostringvariablenames.

• ThecharactercaseofastringvaluecanbechangedusingtheToLower()andToUpper()methods.

• Whitespace,orothercharacters,canberemovedfromastringvalueusingtheTrimStart(),TrimEnd(),andTrim()methods.

• Whitespace,orothercharacters,canbeaddedtoastringvalueusingthePadLeft()andPadRight()methods.

• StringcomparisonscanbemadeusingtheCompareTo()andEquals()methods,orthe==equalityoperator.

• AstringvaluecanbecopiedfromastringvariableintoachararrayusingtheCopyTo()method.

• ThecontentsofastringvariablecanbeswappedusingtheRemove(),Insert(),andReplace()methods.

• AsubstringcanbesoughtusingIndexOf(),LastIndexOf(),IndexOfAny(),LastIndexOfAny(),andSubstring()methods.

• EveryobjecthasaToString()methodthatreturnsastringrepresentation,whichcanbeformattedinoutput.

7

Accessingfiles

ThischapterdemonstrateshowC#programscanstoredataintextfiles,andretrievedatafromtextfiles.

WritingafileAppendingtoafileReadingtextandlinesStreaminglinesManipulatinginputandoutputSummary

WritingafileTheC#System.IO.Fileclasslibraryprovidesmethodsthatenableaprogramtoeasilywritetextintoafileonyourcomputer.TheSystem.IOclassisnotautomaticallylistedinthedefaultusingdirectivegeneratedbyVisualStudio.ThismeansyoumustincludetheSystem.IOprefixwhenusingFilemethodsor,moreconveniently,addafurtherusingdirectivesotheprefixmaythenbeomittedinyourprogramcode:

usingSystem.IO;

TheFile.WriteAllText()methodsimplyrequirestwoargumentstospecifythetextfilepathandthestringtowrite.Backslashcharactersinthepathstringmustbeescapedtoavoidanerror.

Ifyouwouldliketoensurethespecifiedtextfiledoesnotalreadyexist,youcanfirsttestforitsexistencebyspecifyingitspathastheargumenttotheFile.Exists()method.Thiswillreturntruewhenthefileisfound,otherwiseitwillreturnfalse.

Ifyoudon’taddtheusingSystem.IO;statementyoumustwriteSystem.IO.File.WriteAllText()andSystem.IO.File.Exists()tocallthesemethods.

Inordertoensurethetextfilewaswrittensuccessfully,itisworthwhilewrappingtheFile.WriteAllText()callinatry-catchblock.Astatementconfirmingsuccesscanbeincludedinthetrypartoftheblock,andastatementtoadviseoffailurecanbeincludedinthecatchpartoftheblock:

WriteText

StartanewConsoleApplication,thennametheprojectandConsole.Titleas“WriteText”

TypethisdirectiveabovethenamespacedeclarationtomakeafurtherclasslibraryavailabletotheprogramusingSystem.IO;

BackintheMain()method,addthesestatementstoinitializetwovariables–insertyourownusernamewhereindicatedinthepath//Editthelinebelowtoincludeyourusername.stringpath=“C:\\Users\\username\\Desktop\\poem.txt”;stringpoem=“\r\n\tIneversawamanwholooked”;poem+=“\r\n\tWithsuchawistfuleye”;

poem+=“\r\n\tUponthatlittletentofblue”;poem+=“\r\n\tWhichprisonerscallthesky”;

The\r\n\tescapesequenceisacarriagereturn,newline,andtab.

Next,addastatementtotestifafilealreadyexistsofthespecifiedpathandfilenameif(File.Exists(path)){Console.WriteLine(“FileAlreadyExists:“+path);

}else{//Statementstobeinsertedhere(Step5).

}Console.ReadKey();

Now,insertstatementsthatattempttowriteatextfileandconfirmsuccess,oradviseoffailuretry{File.WriteAllText(path,poem);Console.WriteLine(“FileWritten:“+path);

}catch(Exceptionerror){Console.WriteLine(error.Message);

}

PressStartorF5toruntheapplicationandseeatextfilewrittenonyourDesktop,orseeanerrormessage

Catchingexceptionswiththetry-catchblockisfullydescribedinthenextchapterdealingwithproblemsolving–seehere.

Runthisapplicationagaintoseethemessageadvisingthatthefilealreadyexists.

AppendingtoafileTheC#System.IO.FileclasslibraryprovidesaWriteAllLines()methodthatcanbeusedtowritethecontentsofastringarraytoatextfile,witheachelementappearingonaseparateline,andatry-catchblockcanensurethetextfilewaswrittensuccessfully.

Additionally,theSystem.IO.FileclasshasanAppendAllText()method,whichcanbeusedtoaddtexttoanexistingfile,andtheFile.Exists()methodcanensurethatthefilefirstexists:

AppendText

StartanewConsoleApplication,thennametheprojectandConsole.Titleas“AppendText”

TypethisdirectiveabovethenamespacedeclarationtomakeafurtherclasslibraryavailabletotheprogramusingSystem.IO;

BackintheMain()method,addthesestatementstoinitializethreevariables–insertyourownusernamewhereindicatedinthepathstringpath=“C:\\Users\\username\\Desktop\\oscar.txt”;string[]poem=newstring[]{“\tInDebtors’Yardthestonesarehard”,“\tAndthedrippingwallishigh”

};stringattrib=“\r\n\tTheBalladOfReadingGaol”;attrib+=“(OscarWilde1898)”;

Next,addastatementtotestifafilealreadyexistsofthespecifiedpathandfilenameif(File.Exists(path)){//Statementstobeinsertedhere(Step5).

}else{//Statementstobeinsertedhere(Step6).

}Console.ReadKey();

Now,insertstatementsthatattempttoappendtextifthefilealreadyexists,andadviseofsuccessFile.AppendAllText(path,attrib);Console.WriteLine(“AppendedToFile:“+path);

The\r\ncharacterreturn,newlineescapesequencescanbeomittedfromthestringarray,astheWriteAllLines()methodautomaticallywriteseachelementonnewlines.

Then,insertstatementsthatattempttowriteatextfileandconfirmsuccess,oradviseoffailuretry{File.WriteAllLines(path,poem);Console.WriteLine(“FileWritten:“+path);

}catch(Exceptionerror){Console.WriteLine(error.Message);

}

AswithWriteAllText(),theWriteAllLines()methodrequiresthetextfilepathandstringtowriteasitsarguments.

PressStartorF5toruntheapplicationandseeatextfilewrittenonyourDesktop,orseeanerrormessage

ThereisalsoanAppendAllLines()methodthatcanbeusedtoaddthecontentsofa

stringarraytoafile.

Runtheapplicationoncemoreandseeaconfirmationappearandseetextappendedtothefile

Afteritsfirstrun,thisapplicationwillappendtexteachtimeitisrun.

ReadingtextandlinesTheC#System.IO.FileclasslibraryprovidesaReadAllText()methodthatcanbeusedtoreadtextfromanexistingfileandassignitsentirecontentstoastringvariable.TheFile.Exists()methodcanensurethatthetextfilefirstexistsandatry-catchblockcanensurethefilewasreadsuccessfully.

Additionally,theSystem.IO.FileclasshasaReadAllLines()method,whichcanbeusedtoassigneachlineofatextfiletoanindividualelementofastringarray:

ReadText

StartanewConsoleApplication,thennametheprojectandConsole.Titleas“ReadText”

TypethisdirectiveabovethenamespacedeclarationtomakeafurtherclasslibraryavailabletotheprogramusingSystem.IO;

BackintheMain()method,addthisstatementtoinitializeavariable–insertyourownusernamewhereindicatedinthepathstringpath=“C:\\Users\\username\\Desktop\\word.txt”;

Next,addastatementtotestifafilealreadyexistsofthespecifiedpathandfilenameif(File.Exists(path)){//Statementstobeinsertedhere(Step5).

}else{Console.WriteLine(“FileNotFound:“+path);

}Console.ReadKey();

Now,insertastatementtodisplayamessageifthefilecannotbereadsuccessfullytry{//Statementstobeinsertedhere(Steps6and7).

}catch(Exceptionerror){Console.WriteLine(error.Message);

}

Whenatextfileisreadintoastringarray,thearray’sLengthproperty,whichreturnsthenumberofitselements,willrepresentthenumberoflinesread–includingemptylines!

Then,insertstatementstoassignthetextfilecontentstoavariableanddisplayitsvaluestringtext=File.ReadAllText(path);Console.WriteLine(“FileRead:“+path+“\n”);Console.WriteLine(text+“\n”);

Finally,insertstatementstoassignthetextfilecontentstoanarrayvariableanddisplayeachelementwithacounterstring[]lines=File.ReadAllLines(path);intnum=1;foreach(stringlineinlines){Console.WriteLine(num+“:”+line);num++;

}

Openatexteditor,suchasNotepad,andcreateamulti-linetextfilenamed“word.txt”onyourDesktop

PressStartorF5toruntheapplicationandseeatextfilereadfromyourDesktop,orseeanerrormessage

Thetextfile’sinvisiblenewlineandtabcharactersarepreservedwhenreadbytheReadAllText()method,butonlytheinvisibletabcharactersarepreservedwhenitisreadbytheReadAllLines()method.

Removethetextfiles’ReadandReadWritepermissionsonyoursystemandruntheapplicationagaintoseean“Accesstopathdenied”message.

StreaminglinesTheFile.WriteAllText()andFile.AppendAllText()methodsaresimpletousebutprovidefewoptions.TheSystem.IO.StreamWriterclassalsoprovidesobjectmethodsthatcanbeusedtowritetexttoafile,andtheseprovidemoreoptions.AninstanceofaStreamWriterobjectmustfirstbecreatedusingthenewkeywordandthetextfilepathspecifiedasanargumenttoits“constructor”methodlikethis:

StreamWritername=newStreamWriter(path);

Methods,suchasWrite()andWriteLine()canthenbedot-suffixedtotheobjectname.AStreamWriterobjectisdisposable,soitsstatementsarebestenclosedwithinausingconstructtoensureitisremovedfrommemoryuponcompletion,likethis:

using(StreamWritername=newStreamWriter(path)){//Statements.

}

Theusingkeywordhasdifferentmeaningsaccordingtoitscontext.

Theusingconstructcanalsobewrappedinatry-catchblock,toensurethetextfilewaswrittensuccessfully.Optionally,theStreamWriterconstructorcanacceptasecondargumentoftruetoappendtoexistingtext:

WriteStream

StartanewConsoleApplication,thennametheprojectandConsole.Titleas“WriteStream”

TypethisdirectiveabovethenamespacedeclarationtomakeafurtherclasslibraryavailabletotheprogramusingSystem.IO;

BackintheMain()method,addthesestatementstoinitializethreevariables–insertyourownusernamewhereindicatedinthepathstringpath=“C:\\Users\\username\\Desktop\\robert.txt”;stringpoem=newstring[]{“\tThistruthfindshonestTamo’Shanter”,

“\tAshefromAyronenightdidcanter”,“\tOldAyr,whichneveratownsurpasses”,“\tForhonestmenandbonnielasses.”

};stringattrib=“\r\n\tTamO’Shanter(RobertBurns1790)”;

Next,addastatementtodisplayamessageifthefilecannotbewrittensuccessfullytry{//Statementstobeinsertedhere(Steps5and6).

}catch(Exceptionerror){Console.WriteLine(error.Message);}Console.ReadKey();

Now,insertstatementsthatattempttowritethecontentsofthevariablearrayintoatextfileusing(StreamWriterwriter=newStreamWriter(path)){foreach(stringlineinpoem){writer.WriteLine(line);}

}

Finally,insertstatementsthatattempttoappendthecontentsoftheregularvariableintoatextfileusing(StreamWriterwriter=

newStreamWriter(path,true)){writer.WriteLine(attrib);Console.WriteLine(“FileWritten:“+path);}

}

PressStartorF5toruntheapplicationandseeatextfilewrittenonyourDesktop,orseeanerrormessage

TheusingconstructensurestheStreamWriterisdisposedofwhenitsoperationscomplete,sothesamenamecanbeusedforthenewobject.

Trywritingthisfileintoaread-onlydirectorytoseean“Accesstopathdenied”message.

ManipulatinginputandoutputTheSystem.IO.StreamReaderclassprovidesobjectmethodsthatcanbeusedtoreadtextfromafile.AninstanceofaStreamReaderobjectmustfirstbecreatedusingthenewkeywordandthetextfilepathspecifiedasanargumenttoits“constructor”:

StreamReadername=newStreamReader(path);

MethodssuchasRead()andReadLine()canthenbedot-suffixedtotheobjectname.AStreamReaderobjectisdisposable,soitsoperationstatementsarebestenclosedwithinausingconstructtoensureitisremovedfrommemorywhentheoperationhascompleted.Theusingconstructcanalsobewrappedinatry-catchblock,toensurethetextfilewasreadsuccessfully.

TextreadbyaStreamReaderobjectcanbemanipulatedtochangeitsformatbeforeoutput.Forexample,tomanipulatecellsexportedfromanExcelspreadsheetascomma-separatedvalues:

ReadStream

StartanewConsoleApplication,thennametheprojectandConsole.Titleas“ReadStream”

TypethisdirectiveabovethenamespacedeclarationtomakeafurtherclasslibraryavailabletotheprogramusingSystem.IO;

BackintheMain()method,addastatementtoinitializeavariable–insertyourownusernameinthepathstringpath=“C:\\Users\\username\\Desktop\\TopFive.csv”;

Next,addastatementtodisplayamessageifthefilecannotbereadsuccessfully

try{//Statementstobeinsertedhere(Step5).

}catch(Exceptionerror){Console.WriteLine(error.Message);}Console.ReadKey();

Now,insertstatementsthatattempttoreadthecontentsofthetextfileintoavariable,linebylineusing(StreamReaderreader=newStreamReader(path)){stringline;while((line=reader.ReadLine())!=null){//Statementstobeinsertedhere(Steps6-7).

}}

Insertstatementstomodifythecaseofthecolumnheadersandamendanartistnameif(line.IndexOf(“Rank”)!=-1)line=line.ToUpper();if(line.IndexOf(“Sia”)!=-1)line+=“ft.SeanPaul”;

Finallyinsertstatementsthatdisplaythecontentofjusttwocolumns,formattedforalignment

string[]sub=line.Split(‘,’);line=String.Format(“{0,-30}{1,-20}”,sub[1],sub[2]);Console.WriteLine(line);

PressStartorF5toruntheapplicationandseethemanipulatedoutputfromthefilecontent

WhentheReadLine()methodreachestheendofthefilebeingread,itreturnsanullvalue.

TheString.Format()placeholdersspecifycharacterwidthsasnegativenumberstoalignstringstotheleft.

Summary• TheSystem.IOclassisnotautomaticallylistedintheusingdirectivesgeneratedbyVisual

Studio,soitmustbeaddedmanuallywithausingSystem.IO;statement.

• TheSystem.IO.Fileclassprovidesmethodstoeasilyreadorwritetextfilesonyourcomputer.

• TheSystem.IO.File.WriteAllText()methodrequirestwoarguments,tospecifyafilepathandcontenttowritethere.

• TheSystem.IO.File.Exists()methodwilldetermineifthefilespecifiedasitsargumentalreadyexists.

• Itisrecommendedallreadorwriteoperationsbewrappedinatry-catchblocktoreportwhenanattemptedoperationfails.

• TheSystem.IO.File.WriteAllLines()methodcanwritetheelementcontentofastringarrayasseparatelinesofafile.

• TheSystem.IO.File.AppendAllText()methodrequirestwoargumentstospecifyafilepathandcontenttoappendthere.

• TheSystem.IO.File.ReadAllText()methodcanbeusedtoassigntheentirecontentofatextfiletoastringvariable.

• TheSystem.IO.File.ReadAllLines()methodcanassignindividuallinesofatextfiletoelementsofastringarray.

• TheSystem.IO.StreamWriterclassprovidesobjectmethodstowritetextfilesonyourcomputer.

• TheSystem.IO.StreamReaderclassprovidesobjectmethodstoreadfromtextfilesonyourcomputer.

• AninstanceofaStreamReaderobjectorStreamWriterobjectiscreatedusingthenewkeywordandbyspecifyingafilepathwithintheparenthesesofitsconstructor.

• AStreamReaderobjecthasRead()andReadLine()methodsthatcanbedot-suffixedtoaninstancename.

• AStreamWriterobjecthasWrite()andWriteLine()methodsthatcanbedot-suffixedtoaninstancename.

• AllStreamReaderandStreamWriterobjectsaredisposable,soshouldeachbeenclosedinausingconstruct.

8

Solvingproblems

ThischapterdemonstrateshowtodetectandmanageerrorsinC#programs.

Detectingreal-timeerrorsFixingcompile-timeerrorsDebuggingcodeSettingbreakpointsCatchingrun-timeerrorsGettinghelpSummary

Detectingreal-timeerrorsAsyoutypecodeintheCodeEditorwindow,theVisualStudioIDEisconstantlymonitoringyourcodeforpossibleerrors.Itexaminesthecodeyoutypeandprovidesreal-timefeedbackofpossibleerrorsbyaddingawavyunderlinetoquestionablecode.

Warningsofpotentialproblemsareindicatedbyagreenwavyunderline.Thesearenotcriticalandwillnotpreventexecutionoftheapplication.ArolloverTooltipexplainsthewarning:

First,typethisvariabledeclarationintheCodeEditorintnum

Awavygreenlineappearsbelowthenumvariablename.Placethecursoroverthegreenwavyunderlinetodiscoverthatthewarningismerelyindicatingapotentialproblemasthevariablehasnotyetbeenassignedavalue

Errorsareindicatedbyaredwavyunderline.Unlikewarnings,thesearecriticalandwillpreventexecutionoftheapplication:

Next,typethisvariabledeclarationintheCodeEditorintnum=

Placethecursorovertheredwavyunderlinetodiscoverthattheerrorisduetoamissingvalueintheexpression

Warningscanbeignoredbuterrorsmustbecorrected.

Real-timeerrordetectionintheVisualStudioIDEisafantastictooltohelppreventerrorswhen

youarewritingcode.Itnotonlyindicateserrors,butcanevenprovidealistofcorrectionoptions:

Now,typethisvariabledeclarationintheCodeEditorintrnum=1;

Awavyredlineappearsbelowtheintrvariabletype.Placethecursorovertheredwavyunderlinetodiscoverthattheerrorisduetoanunknowntypespecification

Clickthelightbulbicon,orclicktheShowpotentialfixeslink,toseealistoferrorcorrectionoptions

Ifthiserrorissimplyaspellingerrorfortheintdatatype,selecttheoptiontoChange‘intr’to‘int’–seeyourcodegetinstantlycorrectedaccordingly

VisualStudio2015provideslivecodeanalysis,whichdisplaysalightbulbwhenthecompilerdetectsanissuewithyourcode,andhasasuggestionofhowtofixthatissue.

Othercorrectionoptionsallowyoutocreateanewdatatypeifthatiswhatyourequire.

Fixingcompile-timeerrorsWhilesyntaxerrorslikethoseherecanbedetectedbytheCodeEditorinreal-time,othererrorsthatemploycorrectsyntaxcannotbedetecteduntilthecodeiscompiled.Compileerrorsaretypicallyerrorsoflogic,andtheycausetheexecutiontohaltwhenan“exception”occurs.Forexample,whenincompatibledatatypesappearinanexpression,anInvalidCastExceptionoccursandexecutionstopsimmediately:

TypethefollowinglinesintotheCodeEditorboolflag=true;IConvertibleconvertible=flag;charletter=convertible.ToChar(null);

PressStartorF5toruntheapplicationandseeexecutionissoonhalted.ThelinecausingtheexceptionbecomeshighlightedintheCodeEditorandanExceptionAssistantpop-upwindowappearswithalistofpossiblesolutions

TheIConvertibleinterfaceprovidesmethodsthatconvertavaluetoaCLRtype,butitcannotmeaningfullyconvertabooltochar.

YoucanclickontheViewDetail...linkintheExceptionAssistant’sActions:listformoreerrorinformation.

TofixthisInvalidCastException,thecodewouldneedamendmentsobothvaluesareofcompatibledatatypes.

Thecauseofothercompileerrorsmaybelessobviouswithoutsomefurtherinvestigation.Forexample,whenaloopthatisreadingarrayelementsattemptstoaddressanelementindexthatdoesnotexist,causinganIndexOutOfRangeException.

Executionhaltsimmediately,soitisusefultoexaminethecountervaluetoidentifythepreciseiterationcausingthecompileerror.

IntheCodeEditor,typethefollowingvariablearraydeclarationoftenelements(0-9),andaloopint[]nums=newint[10];for(i=1;i<20;i++){nums[i]=i;}

PressStartorF5toruntheapplicationandseeexecutionissoonhalted.ThecodecausingtheexceptionbecomeshighlightedintheCodeEditorandanExceptionAssistantpop-upwindowappearswithalistofpossiblesolutions

Placethecursorovertheassignmenttothearrayvariabletoseeapop-upappeardisplayingitscurrentvalue

It’snowclearthatexecutionhaltedwhentheloopattemptedtoaddressnums[10]–beyondtheboundsoflastelementnums[9].TofixthisIndexOutOfRangeException,thecodewouldneedamendmenttoendtheloopafter10iterations.

AnothercommoncompileerroristheFileNotFoundExceptionthatoccurswhenafileismissingoritspathnameisincorrect.

DebuggingcodeItissometimesusefultocloselyexaminetheprogressionofaprogrambywatchingitsexecutionlinebylinetolocateanybugs.Progressiscontrolledbyclickingthe StepIntobuttonontheDebugMenuBartomovethroughtheprogramonelineatatime.WhenyoubegindebuggingyoucanopenaWatchwindowtomonitorthevalueofparticularvariablesasexecutionproceeds:

Debug

AddthefollowingcodewithintheMain()methodintpass=0;intunit=2;

for(inti=1;i<3;i++){pass=(pass+1);unit=square(unit);

}

Now,addthisarithmeticmethodaftertheMain()methodstaticintsquare(intnum){return(num*num);

}

IntheCodeEditor,clickinthegraymarginagainsttheMain()method–tosetadebugstarting“breakpoint”

ClicktheStepIntobuttononcetobegindebugging

ClickDebug,Windows,Watch,Watch1ontheMenuBartolaunchaWatchwindow

Typethevariablename“pass”intotheNamecolumnandhitEnter,thenrepeattoaddthe“unit”variablename

Ifyoucan’tseetheStepIntobutton,right-clickontheMenuBarandselectDebugtoaddthedebuggingbuttons.

YoucanclicktheStopDebuggingbuttonatanytimetoreturntoCodeEditormode.

ClickStepIntoseventimestoreachthesquare()methodcallinthefirstloopiteration,andnotethevalues

ClickStepInto10moretimestoprogressthrougheachlineofthesquare()methodandtheloop,returningtothesquare()methodcallontheseconditeration

Clickthe StepOverbuttononcetoexecutethefunctionwithoutsteppingthrougheachline

ClicktheStepOverbuttonfourmoretimestomovethroughtotheendoftheprogram

ThedebuggerwillautomaticallycloseandreturntotheregularCodeEditormode

Clickthereddotyouaddedinthemargintoremovethebreakpoint

TheStepOutbuttonisusedtoreturntothefunctioncallerwhenyouaresteppingthroughlinesofacalledfunction.

SettingbreakpointsInallbutthesmallestofprograms,steppingthrougheachlineisverytediouswhendebugging.Instead,youcanquicklyreachthepartyouwishtoexaminebysettingmultiplebreakpointstohaltexecutiononparticularlines.SettingoneormorebreakpointsisusefultohelpyouunderstandhowcertainC#codeconstructswork–suchasthenestedloopconstructshownhere:

Breakpoints

Typethiscodetocreatethreenestedloopsthateachincrementacountervariablewithineachloop,andatotalpassiterationcounterintheinnermostloopinti,j,k;intpass=0;

for(i=1;i<4;i++){for(j=1;j<4;j++){for(k=1;k<4;k++){pass++;

}}

}

Clickinthegraymarginagainsteachlinecontainingtheclosingbraceofeachlooptosetthreebreakpoints–areddotwillappearinthemarginandeachclosingbraceishighlightedtoindicatethebreakpointsareset

ClicktheStartbuttonandseetheapplicationruntothefirstbreakpointitmeets

ClickDebug,Windows,LocalstolaunchtheLocalswindowandnoticethecurrentvalueofeachvariable

Yellowarrowsindicatethecurrentposition.Clickonthereddottocancelabreakpoint.

WatchthevariablevalueschangeasyourepeatedlyclicktheStart(Continue)buttontomovetoeachsuccessivebreakpointuntilyoureachthethirdouterloopbreakpoint

RepeatedlyclickStepIntountilyoureachtheclosingbraceoftheMain()methodtoseethefinalvalues

Attheendoftheprogram,eachcountervariablehasbeenincrementedbeyondtheupperlimitsetintheforstatements,toexiteachloop,andtherehasbeenatotalof27iterations(3x3x3).

ClicktheStartbuttononcemoretoruntothefirstbreakpoint,thenclickDebug,Windows,ImmediatetolaunchtheImmediatewindow

IntheImmediatewindow,typei=3andhitEnter,thenusetheStepIntobuttontostepthrougheachlineofjustthefinalcompleteouterloop’snineiterations

TheLocalswindowshowsallvariablesincurrentscopeastheprogramproceeds.

AnycodeyoutypeintotheImmediatewindowisdynamicallyappliedtotheapplicationbeingdebugged,butdoesnotchangeitscode.

Catchingrun-timeerrorsWhenyouareabletopredictpotentialruntimeerrors,byconsideringalleventualities,youcanprovidecodetohandleeachExceptionclasserrorthatmayarise–byaddingatry-catchconstruct.Yourprogramcansupplyinformationtotheuserabouttheerror,shouldyouwishtodoso,thenproceednormally:

ErrorHandling

Addthisprogramcodetorequestuserinputoftwonumericvaluesforaddition,thendisplaytheirsumtotalConsole.Write(“PleaseEnterANumber:“);doublenum1=Convert.ToInt16(Console.ReadLine());

Console.Write(“NowEnterAnotherNumber:“);doublenum2=Convert.ToInt16(Console.ReadLine());

Console.WriteLine(“Total:“+(num1+num2));

PressStartorF5toruntheapplication,thenenteranysix-figureintegerandhitEnter

ThecompilerreportsanOverflowExceptionerror

ClicktheStopDebuggingbuttonsoyoucaneditthecode

AnInt16isa16-bitintegerwithintherange-32,768to+32,767–whereasanInt32isa32-bitintegerwithin-2,147,483,648to+2,147,483,647.

DragthemousetohighlightallstatementsinStep1,thenright-clickonthehighlightedareaandchooseInsertSnippet:,VisualC#,tryfromthecontextmenu

TheInsertSnippetfeatureprovideslotsofusefulpiecesofcodetopasteintotheCodeEditor–takesometimetoexploreitscontents.

Atry-catchconstructisaddedtothecode,enclosingthehighlightedstatementswithinthetryblock

Editthedefaultcatchblocktodisplayanerrormessagecatch(Exceptionerror){Console.WriteLine(error.Message);}

EachExceptionhasseveralmethodsandproperties.Forexample,useerror.GetType()toseethetypeofException.

Runtheapplication,thenenteranysix-figureintegerandhitEntertonowseeadefaultexplanatoryerrormessage

YoucanprovideyourownerrormessagestohandleaspecificExceptionbystatingitstypeinthecatch()parentheses:

Editthedefaultcatchblocktodisplayacustommessagecatch(OverflowException){Console.WriteLine(”\nMaximum:“+Int16.MaxValue);}

Runtheapplication,thenenteranysix-figureintegerandhitEntertonowseeacustomexplanatoryerrormessage

Youcanaddmultiplecatchblocksafterthetryblock,tohandledifferenttypesofException.

GettinghelpTheVisualStudioHelpsystemprovidesanextensivesourceofreferenceformanyprogramminglanguages.YoucanchoosetoinstallaHelpLibraryonyourcomputerfortheC#programminglanguagesoyoucaneasilyrefertoitatanytime:

OntheVisualStudioMenuBar,clickHelp,AddandRemoveHelpContenttoopentheHelpViewer

OntheManageContenttab,expandRecommendedDocumentationthenchoosetheAddlinkintheActioncolumnfortheVisualBasicandVisualC#library

WhenyourselectionisaddedtothePendingchangeslist,clicktheUpdatebuttontodownloadthatlibrary

TheHelpViewerallowsyoutodownloadHelplibrariesforofflineuse,checkforavailableupdates,andseekhelpfrominstalledHelplibraries.

HelplibrarydocumentationcanbesearchedforanswerstoyourC#codingquestions.Forexample,youmightwanttodiscoverbuilt-indatatypesavailableinC#programming:

OntheMenuBar,clickHelp,SetHelpPreference,LaunchinHelpViewertouseinstalledlibraries

Next,clickHelp,ViewHelptolaunchHelpViewer

Now,selecttheIndextabintheleft-handpane

Finally,enter“C#language,datatypes”intheHelpViewersearchbox,thenhitEntertoseetheresults

YoucanSetHelpPreferencetoLaunchinBrowserifyouwanttosearchonlinehelpwithoutinstallinglibraries,butlocalhelpisoftenmoreconvenient.

Summary• TheCodeEditorconstantlymonitorsyourcodetoprovidereal-timeerrordetection.

• Warningsarenotcriticalandareindicatedbyagreenwavyunderline–whereaserrorsarecriticalandareindicatedbyaredwavyunderline.

• Alightbulbiconbesidearedwavyunderlineindicatesthatalistofpotentialfixesisavailable.

• Typically,real-timeerrorsareerrorsofsyntax,andcompileerrorsareerrorsoflogic.

• WhenacompileerroroccursinDebugMode,executionstopsandtheExceptionAssistantoffersalistofpossiblefixes.

• InDebugModeyoucandiscoverthecurrentvalueofanyvariablesimplybyplacingthecursoroverthevariablename.

• Whendebuggingcode,theStepIntobuttonletsyouwalkthroughaprogramonelineatatime.

• TheStepOverbuttonletsyoubypassthelinesofacalledmethod,andtheStepOutbuttonletsyoureturntothelinewherethatmethodiscalled.

• Variablevaluescanbemonitoredasaprogramproceeds,usingtheWatchwindowortheLocalswindow.

• Breakpointshalttheexecutionofaprogramtoallowexaminationofthepartoftheprogramwheretheyareset.

• InDebugMode,codecanbedynamicallyappliedusingtheImmediatewindow.

• Runtimeerrorsoccurwhentheuseractionhasnotbeenanticipatedbytheprogrammer.

• Atry-catchblockcanbeusedtohandleanticipatedexceptions.

• TheHelplibrarysystemprovidesextensivereferencesourcesforbothoff-lineandonlineassistance.

9

Creatingobjects

Thischapterdemonstratesencapsulation,inheritance,andpolymorphism–thethreeprinciplesofC#ObjectOriented

Programming.

EncapsulatingdataCreatingmultipleobjectsInitializingclassmembersInheritingclasspropertiesCallingbaseconstructorsHidingbasemethodsDirectingmethodcallsProvidingcapabilityclassesEmployingpartialclassesSummary

EncapsulatingdataAclassisadatastructurethatcancontainbothvariablesandmethodsinasingleentity.Thesearecollectivelyknownasits“members”,andthevariablesarealsoknownasits“properties”.

Ifaclassisnotdeclaredasstaticitcanbeusedtocreate“instances”thatareassignedtoavariableforusebyotherclasses.

Accesstoclassmembersfromoutsidetheclassiscontrolledby“accessspecifiers”intheclassdeclaration.Typically,thesewilldenyaccesstothevariablemembers,butallowaccesstomethodsthatcanstoreandretrievedatafromthosevariablemembers.Thistechniqueof“datahiding”ensuresthatstoreddataissafelyencapsulatedwithintheclassvariablemembers,andisthefirstprincipleofObjectOrientedProgramming(OOP).

Aclassdeclarationcomprisesaclassaccessspecifier,theclasskeyword,andaprogrammer-specifiedname–adheringtotheusualC#namingconventions,butbeginninginuppercase.

Ifnotspecified,thedefaultaccessspecifierforaclassdeclarationisinternal,andthedefaultaccessspecifierforclassmembersisprivate.

Theclassdeclarationisfollowedbyapairofbracescontainingthevariableandmethoddeclarations,whichtypicallybeginwiththeirownaccessspecifier.So,classsyntaxlookslikethis:

access-specifierclassClassName{//Membervariableproperty.access-specifierdata-typevariable-name;

//Membermethod.access-specifierreturn-typemethod-name(parameter-list){statements

}}

Anaccessspecifiermaybeanyoneofthesekeywords:

• public–accessiblefromanyplacewheretheclassisvisible

• private–accessibleonlytoothermembersofthesameclass

• protected–accessibleonlytoothermembersofthesameclassandmembersofclassesderivedfromthatclass

• internal–accessibleonlytomembersofthesameassembly

Derivedclasses,whichusetheprotectedmemberaccessspecifier,areintroducedlater–seehere.

Anyreal-worldobjectcanbedefinedbyitsattributesandbyitsactions.Forexample,adoghasattributessuchasname,age,andcolor,plusactionsitcanperformsuchasbark.TheclassmechanisminC#providesawaytocreateavirtualdogobjectwithinaprogram,wherethevariablemembersofaclasscanrepresentitsattributesandthemethodsrepresentitsactions:

publicclassDog{//MEMBERVARIABLES...privatestringname;privateintage;privatestringcolor;

//MEMBERMETHODS...

//Setter&GetterMethods:publicvoidsetName(stringtag){

name=tag; //Storetheargumentvalue.}

publicstringgetName(){

returnname; //Retrievethestoredvalue.}

publicvoidsetAge(intyrs){age=yrs;}publicintgetAge(){returnage;}

publicvoidsetColor(stringcoat){color=coat;}publicstringgetColor(){returncolor;}

//OtherMethods:publicstringbark(){return“\nWoof,woof!\n”;}

}

Itisimportanttorecognizethataclassdeclarationonlydefinesadatastructure–inordertocreateanobjectyoumustdeclarean“instance”ofthatdatastructure,assignedtoavariable.Thisrequiresthenewkeywordandclassnamefollowedbyparentheses:

//Createaninstancenamed“fido”ofthe//programmer-definedDogdatastructure.Dogfido=newDog();

TheprincipleofencapsulationinC#programmingdescribesthegroupingtogetherofdataandfunctionalityinclassmembers–name,age,colorattributesandbarkactionintheDogclass.

Aprogramclasscannotperfectlyemulateareal-worldobject,butaimstoencapsulateallrelevantattributesandactions.

Thepublic“setter”and“getter”methodsassignvaluesto,andretrievevaluesfrom,theprivatevariablemembers.

Itisconventionaltobeginclassnameswithanuppercasecharacter,andobjectnameswithlowercase.

CreatingmultipleobjectsAprogramcaneasilycreatemultipleobjectssimplybydeclaringmultiplenewinstancesofaclass,andeachobjectcanhaveuniqueattributesbyassigningindividualvalueswithitssettermethods.

Itisoftenconvenienttocombinethesettermethodsintoasinglemethodthatacceptsargumentsforeachprivatevariable.Thismeansthatallvaluescanbeassignedwithasinglestatementintheprogram,butthemethodwillcontainmultiplestatements.

InC#classdeclarations,thepublic“setter”methods,whichassigndatatoprivatevariablemembers,andpublic“getter”methods,whichretrievedatafromprivatevariablemembers,areoftennamedasthevariabletheyaddress–butwiththefirstlettermadeuppercaseandprefixedby“set”or“get”respectively.Forexample,methodstoaccessanagevariablemaybesetAge()andgetAge().

Parametersmayalsobenamedasthevariabletheyaddress.Thecodecandifferentiatebetweentheparameterandlike-namedvariablememberbydot-prefixingthistothevariablename:

Objects

AfterthedefaultProgramclass,declareaclassnamed“Dog”withthreevariablememberspublicclassDog{privatestringname,color;privateintage;

//Methodstobeinsertedhere(Steps2-4).}

Next,insertasettermethodforallvariablememberspublicvoidsetValues(stringname,intage,stringcolor){this.name=name;this.age=age;this.color=color;

}

Now,insertgettermethodsforeachvariablememberpublicstringgetName(){returnname;}publicintgetAge(){returnage;}publicstringgetColor(){returncolor;}

Then,insertanothermiscellaneousmethodpublicstringbark(){return“\nWoof,woof!\n”;}

Inthesettermethod,thethisprefixednamesreferencetheclassvariablemembers,andthosewithoutprefixreferencetheparameters.Noprefixisneededtoreferencetheclassvariablemembers.

TurnyourattentiontotheMain()methodinthedefaultProgramclassandcreateaninstanceoftheDogclassDogfido=newDog();

Next,callthenewinstanceobject’ssettermethodtoinitializeallitsvariablemembersfido.setValues(“Fido”,3,“Brown”);

Now,retrieveallpropertiesofthenewobjectstringtagF=String.Format(“{0}isa{1}yearold{2}dog”,

fido.getName(),fido.getAge(),fido.getColor()

};

DisplayallpropertiesandcallthemiscellaneousmethodConsole.WriteLine(tagF+fido.bark());

Now,createanotherinstanceoftheDogclassDoglucy=newDog();lucy.setValues(“Lucy”,2,“Gray”);

Next,retrieveallpropertiesofthisnewobjectstringtagL=String.Format(“{0}isa{1}yearold{2}dog”,

lucy.getName(),lucy.getAge(),lucy.getColor()

};

DisplayallpropertiesandcallthemiscellaneousmethodConsole.WriteLine(tagL+lucy.bark());Console.ReadKey();

PressStartorF5toseeeachobject’sproperties

NoticeherehowtheString.Format()methodiscodedusingnewlinestoclearlybuildastringvalueforoutput.

InitializingclassmembersClassvariablememberscanbeinitializedbyaspecial“constructor”methodthatiscalledwheneveraninstanceoftheclassiscreated–allowingyoutospecifydefaultvaluesforclassvariablemembers.

Theconstructormethodisalwaysnamedexactlyastheclassnameandcancontainstatementstoinitializeclassvariablemembers.Forexample,publicclassCathasapublicCat()constructor.

Whenallclassvariableshavebeeninitializedbytheclassconstructormethod,anyinstanceobjectofthatclasswillimmediatelyhavethoseinitialpropertyvalues.Individualsettermethodscanusefullyadjusttheclassvariablevaluesasneeded:

Constructor

AfterthedefaultProgramclass,declareaclassnamed“Cat”withthreevariablememberspublicclassCat{privatestringname,color;privateintage;

//Methodstobeinsertedhere(Steps2-5).}

Next,insertaclassconstructormethodtosetdefaultvaluesforallitsvariablememberspublicCat(){name=“Tigger”;age=3;color=“Brown”;

}

Now,insertsettermethodsforeachvariablememberpublicvoidsetName(stringname){this.name=name;}publicvoidsetAge(intage){this.age=age;}publicvoidsetColor(stringcolor){this.color=color;}

Then,insertgettermethodsforeachvariablememberpublicstringgetName(){returnname;}publicintgetAge(){returnage;}publicstringgetColor(){returncolor;}

Lastly,insertanothermiscellaneousclassmethodpublicstringcry(){return“\nMeow,meow!\n”;}

Youcannotspecifyaconstructortobeprivateasitmustbeaccessibleinordertocreateinstanceobjectsinotherclasses.

TurnyourattentiontotheMain()methodinthedefaultProgramclassandcreateaninstanceoftheCatclassCattigger=newCat();

Now,retrieveall(default)propertiesofthenewobjectstringtagT=String.Format(“{0}isa{1}yearold{2}cat”,

tigger.getName(),tigger.getAge(),tigger.getColor()

};

DisplayallpropertiesandcallthemiscellaneousmethodConsole.WriteLine(tagT+tigger.cry());

Now,createanotherinstanceoftheCatclassandseteachpropertywithnewvaluesCatsmokey=newCat();

smokey.setName(“Smokey”);smokey.setAge(2);smokey.setColor(“Gray”);

Next,retrieveall(adjusted)propertiesofthisnewobjectstringtagS=String.Format(“{0}isa{1}yearold{2}cat”,

smokey.getName(),smokey.getAge(),smokey.getColor()

};

DisplayallpropertiesandcallthemiscellaneousmethodConsole.WriteLine(tagS+smokey.cry());Console.ReadKey();

PressStartorF5toruntheapplicationandseethepropertiesofeachobjectinstanceandmethodcalled

Objectinstancescannotbecreatedfromstaticclasses,butyoucansupplyaconstructormethodinstaticclasses.

Youcanalsospecifyparameterstoaconstructormethodinordertoallowargumentvaluestobepassedinwhenanewinstanceobjectiscreated.

InheritingclasspropertiesAC#classcanbecreatedasabrandnewclass,likethoseinpreviousexamples,orcanbe“derived”fromanexistingclass.Importantly,aderivedclassinheritsmembersoftheparent(base)classfromwhichitisderived–inadditiontoitsownmembers.

Theabilitytoinheritmembersfromabaseclassallowsderivedclassestobecreatedthatsharecertaincommonproperties,whichhavebeendefinedinthebaseclass.Forexample,a“Polygon”baseclassmaydefinewidthandheightpropertiesthatarecommontoallpolygons.Classesof“Rectangle”andTriangle”couldbederivedfromthePolygonclass–inheritingwidthandheightproperties,inadditiontotheirownmembersdefiningtheiruniquefeatures.

ThevirtueofinheritanceisextremelypowerfulandisthesecondprincipleofObjectOrientedProgramming(OOP).

Aderivedclassdeclarationaddsacolon:afteritsclassname,followedbythenameoftheclassfromwhichitderives:

Inheritance

AfterthedefaultProgramclass,declareabaseclassnamed“Polygon”,containingtwovariablemembersandonesettermethodmemberpublicclassPolygon{protectedintwidth,height;

publicvoidsetValues(intwidth,intheight){this.width=width;this.height=height;

}

}

Next,defineaclassthatderivesfromthebaseclass,inheritingmembersandaddingamethodpublicclassRectangle:Polygon{publicintarea(){return(width*height);}

}

Now,defineanotherclassthatderivesfromthebaseclass,inheritingmembersandaddingasimilarmethodtothatintheprevioussteppublicclassTriangle:Polygon{publicintarea(){return((width*height)/2);}

}

TurnyourattentiontotheMain()methodinthedefaultProgramclassandcreateaninstanceobjectfromeachderivedclassRectanglerect=newRectangle();Trianglecone=newTriangle();

Calltheinheritedsettermethodofeachderivedclasstoinitializealltheinheritedvariablemembersrect.setValues(4,5);cone.setValues(4,5);

Finally,calltheaddedmethodineachderivedclasstodisplaytheircomputedvaluesConsole.WriteLine(“RectangleArea:“+rect.area());Console.WriteLine(“\nTriangleArea:“+cone.area());Console.ReadKey();

PressStartorF5toruntheapplicationandseetheoutputfrominheritedvariables

Themethodsaddedtoeachderivedclasscanbenamedalike,astheyonlyexistwithinthescopeoftheirrespectiveclass.

The:operatorisusedheretocreatederivedclasses,andisequivalenttotheextendskeywordinotherprogramminglanguages–suchasJava.

Noticethatthesettermethodandvariablesarenotdefinedinthederivedclasses,astheyareinheritedfromthebaseclass.

CallingbaseconstructorsAlthoughderivedclassesinheritthemembersoftheirparentbaseclass,theydonotinherititsconstructormethod.Nonetheless,aconstructormethodofthebaseclassisalwayscalledwhenanewobjectofaderivedclassiscreated.Thecalltothebaseclassconstructormethodismadeinadditiontothecalltotheconstructormethodofthederivedclass.

Thedefaultconstructormethodofabaseclasshasnoparameters–butthebaseclassmayalsohaveoneormore“overloaded”constructormethodswhichdohaveparameters.

Ifyouprefertocallanoverloadedconstructorofthebaseclasswhenanewobjectofaderivedclassiscreated,youcancreateamatchingoverloadedconstructorinthederivedclass–havingthesamenumberandtypeofarguments.Thematchingderivedclassconstructormustthenexplicitlycalltheoverloadedbaseclassconstructorusingthebasekeyword.Thisisappendedtothederivedclassconstructordeclarationaftera:coloncharacter.

Anoverloadedmethodisonethathasthesamenameasanothermethodbutdifferentparameters.

Whenanewobjectofaderivedclassiscreated,argumentvaluescanbepassedtoanoverloadedderivedclassconstructor,andalsoonwardstoitsmatchingoverloadedbaseclassconstructorinparenthesesfollowingthebasekeyword:

Base

AfterthedefaultProgramclass,declareabaseclassnamed“Parent”,containingadefaultconstructormethodpublicclassParent{publicParent(){Console.WriteLine(“ParentCalled”);

}

//Overloadedconstructortobeinsertedhere(Step2).}

Next,insertanoverloadedconstructormethodintothebaseclassthatrequiresasingle

integerargumentpublicParent(intnum){

Console.WriteLine(“Parent+Called:”+num);}

Afterthebaseclass,addaderivedclasscontainingadefaultconstructormethodpublicclassDaughter:Parent{publicDaughter(){Console.WriteLine(“\tDaughterCalled\n”);}

}

Son–Parent–Daughter

Next,addanotherderivedclass,containingadefaultconstructormethodpublicclassSon:Parent{publicSon(){Console.WriteLine(“\tSonCalled\n”);}

//Overloadedconstructortobeinsertedhere(Step5).}

Now,insertanoverloadedconstructormethodintothederivedclass,whichrequiresasingleintegerargumentpublicSon(intnum):base(num){Console.WriteLine(“\tSon+Called:”+num);

}

TurnyourattentiontotheMain()methodinthedefaultProgramclassandcreateinstancesofthederivedclassesDaughteranna=newDaughter();Sonbrad=newSon();Soncarl=newSon(100);Console.ReadKey();

PressStartorF5toruntheapplicationandseetheoutputfrombaseandderivedclassconstructors

Thedefaultbaseconstructormethodwillbecalledimplicitlyunlessthebasekeywordisusedtocallexplicitly.

Here,theargumentvalueispassedtothederivedclassandbaseclass.

HidingbasemethodsAmethodcanbedeclaredinaderivedclassto“hide”asimilarmethodinthebaseclass–ifbothmethoddeclarationshavematchingname,arguments,andreturntype.

Creationofamatchingmethodinaderivedclasseffectivelyhidesthebaseclassmethod,asitgenerallybecomesinaccessible.Toindicatethathidingisintentional,ratherthanaccidental,thehidingmethoddeclarationshouldincludethenewkeyword.

Baseclassmethodscanbecalledexplicitlyfromwithinnon-staticclassesbyprefixingtheirmethodnamewiththebasekeyword.Alternatively,asaderivedclassisaspecializationofitsbaseclass,baseclassmethodscanbecalledexplicitlyusinganexplicitcast:

Hide

AfterthedefaultProgramclass,declareabaseclassnamed“Man”,containingasimplemethodwithoutparametersplusanoverloadedmethodwithasingleparameterpublicclassMan{publicvoidspeak(){Console.Write(“Hello:”);

}

publicvoidspeak(stringmessage){Console.WriteLine(message+“!\n”);

}}

Afterthebaseclass,addaderivedclasscontainingamethodtointentionallyhidetheoverloadedmethodofthesamenameandparametersinthebaseclasspublicclassHombre:Man{publicnewvoidspeak(stringmessage){//Statementtobeinsertedhere(Step3).Console.WriteLine(message);}

}

Next,insertastatementinthederivedclasstoexplicitlycallthesimplemethodinthebaseclassbase.speak();

Aderivedclassmethodnameandparameterlistmustmatchthatinitsbaseclasstooverrideit.

TurnyourattentiontotheMain()methodinthedefaultProgramclass,andcreateaninstanceofthebaseclassManhenry=newMan();

Next,createaninstanceofthederivedclassHombreenrique=newHombre();

HenryandEnrique

Addacalltothesimplemethodinheritedbytheinstancefromthebaseclasshenry.speak();

Now,addacalltotheoverloadedmethodinheritedfromthebaseclasshenry.speak(“It’sabeautifulevening”);

Then,addacalltothehidingmethodinthederivedclass–thatwillalsoexplicitlycallthesimplemethodinthebaseclassenrique.speak(“Hola...”);

Finally,addastatementusinganexplicitcast–toexplicitlycalltheoverloadedmethodinthebaseclass((Man)enrique).speak(“Esunatardehermosa”);Console.ReadKey();

PressStartorF5toruntheapplicationandseetheoutputfrombaseclassmethodsandhidingmethod

ThebasekeywordcannotbeusedintheMain()method,asthatisastaticmethod.

DirectingmethodcallsThethreecornerstonesofObjectOrientedProgramming(OOP)areencapsulation,inheritance,andpolymorphism.Previousexampleshavedemonstratedencapsulationofdatawithinaclass,andinheritanceofbaseclassmembersbyderivedclasses.Thetermpolymorphism(fromGreek,meaning“manyforms”)describestheabilitytoassignadifferentmeaning,orpurpose,toanentityaccordingtoitscontext.C#overloadedoperatorscanbedescribedaspolymorphic.Forexample,the+symbolrepresentstheadditionorconcatenationoperator–accordingtoitscontext.C#classmethodscanalsobepolymorphic.Methoddeclarationsinabaseclasscanincludethevirtualkeywordtoallowthatmethodtobeoverriddeninderivedclasses.Similarly,methoddefinitionsinaderivedclasscanincludetheoverridekeywordtodenoteitwillbeoverridingavirtualbaseclassmethod.Inthisway,derivedclassmethodscanprovidetheirownversionofabaseclassmethod.Thegreatadvantageofpolymorphismwithmultiplederivedclassobjectsisthatcallstomethodsofthesamenamearedirectedtotheappropriateoverridingmethod.Thiscanallowinconsistencies,however–thisexampleseemstoimplythatchickenscanfly!

Override

AfterthedefaultProgramclass,declareabaseclassnamed“Bird”,containingtwomethodsthatallowoverridingpublicclassBird{publicvirtualvoidtalk(){Console.WriteLine(“ABirdTalks...”);}

publicvirtualvoidfly(){Console.WriteLine(“ABirdFlies...\n”);}

}

Afterthebaseclass,addaderivedclasscontainingtwomethodsthatwilloverridethebaseclassmethodspublicclassPigeon:Bird{publicoverridevoidtalk()

{Console.WriteLine(“PigeonSays:Coo!Coo!”);}

publicoverridevoidfly(){Console.WriteLine(“APigeonFliesAway...”);base.fly();

}}

Here,thefly()methodineachderivedclassalsocallsthebaseclassfly()methoddirectly.

Next,addanotherderivedclasscontainingtwomethodsthatwillalsooverridethebaseclassmethodspublicclassChicken:Bird{publicoverridevoidtalk(){Console.WriteLine(“ChickenSays:Cluck!Cluck!”);}

publicoverridevoidfly(){Console.WriteLine(“I’mAChicken-ICan’tFly”);base.fly();

}}

TurnyourattentiontothedefaultProgramclassandaddamethodtocallbothoverridingmethodsstaticvoiddescribe(Birdobj){

obj.talk();obj.fly();

}

TurnyourattentiontotheMain()methodinthedefaultProgramclassandcreateinstancesofeachnon-baseclassPigeonjoey=newPigeon();Chickenlola=newChicken();

Finally,addstatementstocallappropriatemethodsdescribe(joey);describe(lola);Console.ReadKey();

PressStartorF5toruntheapplicationandseetheoutputfromtheoverridingmethodsofderivedclasses

Youmustusethebasekeywordprefixtodirectlycallabaseclassmethodfromaderivedclass.

EachinstanceobjectispassedasanargumentforC#todeterminetheappropriateoverridingmethodtoexecute.

Polymorphisminprogrammingisoftencalled“oneinterface,multiplefunctions”.

ProvidingcapabilityclassesClasseswhosesolepurposeistoallowotherclassestobederivedfromthemareknownas“capabilityclasses”–theyprovidecapabilitiestothederivedclasses.Capabilityclassesgenerallycontainnodata,butmerelydeclareanumberofmethodsthatcanbeoverriddenintheirderivedclasses.

Acapabilityclassanditsmethodscanallbedeclaredusingtheabstractkeywordtodenotethattheycanonlybeimplementedinderivedclasses.Inthiscase,themethodsignatureisfollowedbyasemicolon,ratherthanamethodblockcontainingstatements.Methoddefinitionsinderivedclassescanthenincludetheoverridekeywordtoimplementthecapabilityclassmethods.

Youcannotcreateaninstanceofanabstractbaseclass.

Addingthesealedkeywordtoaclassdeclarationisasafeguardwhichpreventsthatclassbeingusedasabaseclass.Understandably,anabstractcapabilityclasscannotbesealed.

Thefollowingexamplebuildsuponthepreviousexampletodemonstratehowthe“Bird”classcanbebetterwrittenasacapabilityclass.Thisnowpreventsthebaseclassmethodsbeingcalleddirectly,toavoidinconsistencies:

Capability

AfterthedefaultProgramclass,defineabasecapabilityclassnamed“Bird”,containingtwomethodspublicabstractclassBird{publicabstractvoidtalk();

publicabstractvoidfly();}

AddaderivedclasscontainingtwomethodsthatwilloverridethebaseclassmethodspublicsealedclassPigeon:Bird{publicoverridevoidtalk(){Console.WriteLine(“PigeonSays:Coo!Coo!”);}

publicoverridevoidfly(){Console.WriteLine(“APigeonFliesAway...”);}

}

Next,addanotherclasswhichalsocontainstwomethodsthatwilloverridethebaseclassmethodspublicsealedclassChicken:Bird{publicoverridevoidtalk(){Console.WriteLine(“ChickenSays:Cluck!Cluck!”);}

publicoverridevoidfly(){Console.WriteLine(“I’mAChicken-ICan’tFly”);}

}

Chicken(Bird)

Pigeon(Bird)

Next,addanotherclasscontainingasinglemethodthatacceptsanobjectargumentpublicsealedclassCaller{publicvoiddescribe(Birdobj){obj.talk();obj.fly();

}}

TurnyourattentiontotheMain()methodinthedefaultProgramclassandcreateinstancesofeachnon-baseclassPigeonjoey=newPigeon();Chickenlola=newChicken();Callercall=newCaller();

Finally,addstatementstocallappropriatemethodsbypassinganobjectasanargumentcall.describe(joey);call.describe(lola);Console.ReadKey();

PressStartorF5toruntheapplicationandseetheputfromtheoverridingmethodsofderivedclasses

EachinstanceobjectispassedasanargumentforC#todeterminetheappropriateoverridingmethodtoexecute.

EmployingpartialclassesThesourcecodeforeachexamplelistedinthisbookisgenerallycontainedinasingle.csfile,aseachoneisjustasimpleprogram.Whenworkingonlargerprojectsitisoftendesirabletospreadthesourcecodeoverseparatefilestoallowmultipleprogrammerstoworkontheprojectatthesametime.VisualStudioallowsyoutoeasilyaddoneormorecodefilesinwhichtowriteclasses.

Ifanypartisdeclaredabstract,thewholeclasswillbeabstract,andifanypartisdeclaredsealed,thewholeclasswillbesealed.

Classdefinitionscanalsobespreadacrossseveralfilesbyincludingthepartialkeywordineachseparatepartofthedefinition.Providingallpartshavethesamelevelofaccessibility,theC#compilerwillcombineallpartsintoasingledefinition:

Parts

StartanewConsoleApplication,thennametheprojectandConsole.Titleas“Parts”

FromtheVisualStudiomenu,selectProject,AddClasstolaunchthe“AddNewItem”dialogbox

Editthenamefieldtothenameoftheclasstobeaddedthere–inthiscaseit’stobeaclassnamed“Sailboat”

ClicktheAddbuttontoaddthenewfiletoyourproject

Next,selectView,SolutionExplorerandclickonSailboat.cstoopenthatfileinCodeEditor

Alternatively,youcanright-clickontheprojectnameinSolutionExplorerandchooseAdd,NewItemtolaunchthisdialogbox.

EdittheaddedfiletoprovideaclassconstructorpartpublicpartialclassSailboat{privatestringmake;privatestringmodel;

publicSailboat(stringmake,stringmodel){this.make=make;this.model=model;

}}

LaserSailboat(Boat)

Now,inSolutionExplorer,clickonProgram.cstoopenthatfileinCodeEditor

AfterthedefaultProgramclassaddaclassmethodpartpublicpartialclassSailboat{publicvoiddescribe(){Console.WriteLine(“Sailboat:{0}{1}”,make,model);

}}

TurnyourattentiontotheMain()methodinthedefaultProgramclassandcreateaninstanceobjectSailboatboat=newSailboat(“Laser”,“Classic”);

Finally,addastatementtocalltheaddedclassmethodboat.describe();Console.ReadKey();

PressStartorF5toruntheapplicationandseetheoutputfromtheclasspartsspreadovertwofiles

Noticehowthestringsaresubstitutedforoutputinthisexample.

Partialclassesarepartofthesamenamespace–hereitis“Parts”.

Summary• Encapsulation,inheritance,andpolymorphismarethethreecornerstonesofObjectOriented

Programming.

• AC#classisadatastructurethatcancontainbothvariablemembersandmethodmembers.

• Accesstoclassmembersiscontrolledbyaccessspecifiers.

• Aninstanceobjectofaclassiscreatedusingthenewkeywordfollowedbytheclassnameandparentheses.

• Typically,publicsetterandgettermethodsprovideaccesstoprivatevariablestoensurestoreddataissafelyencapsulated.

• Parameterscanbenamedasthevariabletheyaddress,andthethiskeywordprefixcanbeusedtodifferentiatebetweenthem.

• Theconstructormethodofaclassisnamedastheclassnameandiscalledeachtimeaninstanceofthatclassiscreated.

• Derivedclassesinheritmembersofthebaseparentclassfromwhichtheyarederived.

• Aderivedclassdeclarationaddsacolonaftertheclassname,followedbythenameoftheclassfromwhichitderives.

• Anoverloadedconstructorofabaseclasscanbecalledusingthebasekeywordinaderivedclassdeclaration.

• Aderivedclasscanincludeanewmethodtohideamethodinitsparentclassifname,arguments,andreturntypematch.

• Baseclassmethodscanbecalledexplicitlyfromaderivedclassbyprefixingthemethodnamewiththebasekeyword.

• Thevirtualandoverridekeywordscanbeusedtoallowbaseclassmethodstobeoverriddenbyderivedclassmethods.

• Capabilityclassescanincludetheabstractkeywordtodenotetheirmethodscanonlybeimplementedinderivedclasses.

• Addingthesealedkeywordtoaclassdeclarationisasafeguardwhichpreventsthatclassbeingusedasabaseclass.

• Classdefinitionscanbespreadacrossseveralfilesbyincludingthepartialkeywordineachpartofthedefinition.

10

Controllingevents

ThischapterdemonstrateshowaC#programcanrecognizeandrespondtoeventsthatoccurinagraphicalapplication.

StartingaFormsprojectAddingvisualcontrolsWritingfunctionalcodeGatheringtextentriesTickingoptionboxesShowingusermessagesCallingsystemdialogsCreatingapplicationmenusMakingmenusworkImportingaudioresourcesSummary

StartingaFormsprojectVisualStudioprovidesaWindowsFormsApplicationtemplatethatallowsyoutoeasilycreateaC#programwhichprovidesaGraphicalUserInterface(GUI)tointeractwiththeuser:

FirstGUI

OntheMenuBar,clickFile,New,Project,orpresstheCtrl+Shift+Nkeys,toopentheNewProjectdialogbox

IntheNewProjectdialog,expandInstalled,Templates,VisualC#,thenselecttheWindowsFormsApplication

EnteraprojectnameofyourchoiceintheNamefield,thenclickontheOKbuttontocreatethenewproject–inthiscasetheprojectnamewillbe“FirstGUI”

WaitwhileVisualStudiocreatesyournewprojectandloadsitintotheIDE,thenseeaFormDesignerwindowappeardisplayingadefaultemptyForm

SelecttheView,SolutionExplorermenutoopenaSolutionExplorerwindowandseeallfilesinyourproject

WindowsGUIapplicationsprovideinteractivecontrolsthatproduce“events”inresponsetouseractions,andyourprogramcanrespondtothoseactions.Thisisknownasevent-drivenprogramming.

Now,selecttheView,PropertiesmenutoopenaPropertieswindowtorevealallpropertiesofyourForm

TheFormDesigneriswhereyoucreatevisualinterfacesforyourapplications,andthePropertieswindowcontainsdetailsoftheitemthatiscurrentlyselectedintheFormDesignerwindow.

TheVisualStudioIDEhasnowgatheredalltheresourcesneededtobuildadefaultWindowsapplication–clicktheStartbuttononthetoolbartolaunchthisapplication

Theapplicationsimplycreatesabasicwindow–youcanmoveit,minimizeit,maximizeit,resizeit,andquittheapplicationbyclosingit.Itmaynotdomuch,butyouhavealreadycreatedarealWindowsGUIapp!

Alternatively,youcanrunapplicationsusingtheDebug,StartDebuggingmenuoptionsorpressF5.

AddingvisualcontrolsTheToolboxintheVisualStudioIDEcontainsawiderangeofvisualcontrols,whicharethebuildingblocksofyourapplications.Usingtheprojectcreatedhere,followthesestepstostartusingtheToolboxnow:

FirstGUI

PlacethecursorovertheverticalToolboxtabattheleftedgeoftheIDEwindow,orclickView,ToolboxontheMenuBar,todisplaytheToolboxcontents.Thevisualcontrolsarecontainedundervariouscategoryheadingsbesidean expansionarrow

ClickontheexpansionarrowbesidetheCommonControlscategoryheadingtoexpandthelistofmostcommonlyusedvisualcontrols.Usefully,eachcontrolnameappearsbesideanicondepictingthatcontrolasareminder.Youcanclickonthecategoryheadingagaintocollapsethelist,thenexpandtheothercategoriestoexploretherangeofcontrolsavailabletobuildyourapplicationinterfaces

AnypinnedWindowintheIDEcanbedraggedfromitsusuallocationtoanypositionyouprefer.Dragbacktotheinitiallocationtore-dockit.

TheToolboxwillautomaticallyhidewhenyouclickonanotherpartoftheIDE,butitcanbefixedinplacesoitwillneverhide,usingthe PinbuttonontheToolboxbar.

ClickanddragtheButtonitemfromtheCommonControlscategoryintheToolboxontotheFormintheDesignerwindow,ordouble-clicktheButtonitem,toaddaButtoncontroltotheForm

AButtonisoneofthemostusefulinterfacecontrols–yourprogramdetermineswhathappenswhentheuserclicksit.

TheButtoncontrolappearsontheFormsurroundedby“handles”whichcanbedraggedtoresizethebutton’swidthandheight.

Clickthe StartbuttontoruntheapplicationandseetheButtoncontrolappearinitsinitialdefaultstate

Next,movethepointerovertheButtoncontroltoseeitsappearancechangetoits“MouseHover”state

Now,clickandholddowntheButtoncontroltoseeitsappearancechangetoits“MouseDown”state

Finally,releasetheButtoncontroltoseeitsappearancechangetoits“MouseUp”state

ThisButtoncontrolperformsnofunctionwhenit’sclicked–untilyouaddsomecode.

EachchangeofappearanceisWindows’defaultresponsetoaneventthatoccursontheButton

control,butyourC#programcanprovideitsownresponsetothese,andmanymore,controlevents:

SelecttheButtoncontrolthenopenitsPropertieswindow

ClicktheEventsbuttonandscrolldowntoseeallpossibleButtonevents

EachcontrolcanbegivenamoremeaningfulnameinthePropertieswindow,butforsimplicity,thedefaultnamesareusedbytheexamplesinthisbook.

WritingfunctionalcodeTheVisualStudioIDEautomaticallygeneratescodeinthebackground,toincorporatethevisualcontrolsyouaddtoyourprograminterface.Additionalcodecanbeaddedmanuallytothe“code-behind”pageusingtheIDE’sintegralCodeEditor,todeterminehowyourprogramshouldrespondtointerfaceevents:

UsethetabstoswitchbetweentheCodeEditorandFormDesigner.

Usingtheprojectcreatedhere,followthesestepstoaddyourownresponsestouseractionswhichproduceevents:

FirstGUI

SelecttheButtoncontrolnamedbutton1,thenopenitsPropertieswindowandclicktheEventsbutton

Double-clickontheMouseHoveritemtoopenaForm1.cscode-behindpageinCodeEditoratageneratedevent-handlermethod

Next,insertthisstatementwithinthegeneratedmethod–tochangetheButton’sbackgroundcolorinresponsetoaMouseHovereventbutton1.BackColor=Color.Fuchsia;

Similarly,double-clickontheMouseDownitemandinsertthisstatementwithinanother

generatedmethod–tochangetheButton’sbackgroundcolorinresponsetoaMouseDowneventbutton1.BackColor=Color.Lime;

Likewise,double-clickontheMouseUpitemandinsertthisstatementwithinafurthergeneratedmethod–tochangetheButton’sbackgroundcolorinresponsetoaMouseUpeventbutton1.BackColor=Color.Aqua;

TheColorclassprovideslotsofstandardcolorproperties–typeColorthenaperiodanduseIntelliSensetoseethem.

ThelinesofcodeinthisexamplearetobeinsertedintoeachindividualeventhandlermethodthatisautomaticallygeneratedbyVisualStudio.

Now,clicktheForm1.cs[Design]tabtoreturntotheFormDesignerwindow

Double-clickontheButtoncontrolontheFormtoopentheForm1.cscode-behindpageinCodeEditoratyetanothergeneratedevent-handlermethod

Finally,insertthisstatementwithinthegeneratedmethod–toopenamessageboxinresponsetoaClickeventMessageBox.Show(“C#Programmingineasysteps”);

Runtheapplication,thenclickthebuttontoseetheMouseHover,MouseDown,andClickeventresponses

PushtheOKbuttontoclosethemessageboxandseetheMouseUpeventresponse

YoucanusetheViewmenuontheMenuBartoopentheCodeEditor,FormDesigner,oranyotherwindowyourequireatanytime.

YoucanseemanymoreusesfortheMessageBoxclasshere.

MostWindowssoftwareworksbyrespondingtoevents.Forexample,whenyoupressakey,aKeyPresseventcancallitsevent-handlertorespondtothatevent.

GatheringtextentriesATextBoxcontrolcanbeaddedtoaForminaWindowsFormsApplicationtoallowtheusertoenterinput.ThecurrentvaluewithinaTextBoxcanbeassignedtoavariable,typicallyinresponsetoaButtonClickevent,foruseinsidetheprogramcode.

ALabelcontrolisgenerallyusedtodisplaynon-dynamictext.

AnewvaluecanbeassignedtoaTextBoxasoutputtotheuser,buttheusercanmodifythisvalue.Alternatively,outputcanbeassignedtoaLabelcontrol,whichtheusercannotmodify:

Entry

StartanewWindowsFormsApplication,thenaddaTextBox,aButton,andtwoLabelcontrols

SelecttheFormitself,theninthePropertieswindowmodifyitsTextvalueandheight

Next,modifytheTextpropertyvaluesoftheButtoncontrolandLabelcontrolssotheylooklikethis:

Now,double-clicktheButtoncontroltoopentheCodeEditoratageneratedClickevent-handler

AttheverybeginningoftheForm1classblock,addavariablewithsetterandgettermethodsprivateintnum;publicvoidsetNum(intnum){this.num=num;}publicintgetNum(){returnnum;}

IntheLayoutpropertycategory,youmustsetAutoSizetoFalsebeforeyoucanadjusttheWidthandHeightvaluesintheSizepropertycategory.

IntheForm1()constructormethodblock,insertstatementstoinitializethevariablewitharandomvalueRandomrnd=newRandom();setNum(rnd.Next(1,21));

Then,addamethodtocomparetwoargumentsandsetaLabelcontrol’sTextpropertywithanappropriatemessagepublicvoidrate(intguess,intnum){if(guess<num)label2.text=“TooLow!”;elseif(guess>num)label2.text=“TooHigh!”;elselabel2.text=“***Correct***”;

}

Finally,insertstatementswithintheButtonClickevent-handlertocompareuserinputagainsttherandomvalueintguess=Convert.ToInt16(textBox1.text);rate(guess,getNum());

PressStartorF5toruntheapplicationandenterinputtoseetheappropriateoutputmessages

IfyouspecifyminimumandmaximumargumentstotheNext()method,itwillreturnarandomintegerbetweenthespecifiedminimumandmaximum-1–sospecifying21willallowamaximumof20.

ThecontentofaTextBoxcontrolisastringvalue–soitmustbeconvertedtoanumericdatatypefornumericcomparison.

TickingoptionboxesACheckBoxcontrolisasmallboxwithacaption.Itletstheuserselectthecaptionchoicebyclickingonthebox,andacheckmarkappearsintheboxtoindicateithasbeenchosen.Clickingtheboxoncemoredeselectsthechoiceandunchecksthebox.CheckBoxcontrolsareidealtopresentasetofchoicesfromwhichtheusercanselectnone,one,ormorethanonechoice.

ARadioButtoncontrolislikeaCheckBox,butwithonecrucialdifference–theusercancheckonlyonechoiceinthegroup.CheckingaRadioButtonautomaticallyunchecksanyothers.RadioButtoncontrolsareidealtopresentasetofchoicesfromwhichtheusercanselectonlyonechoice.

SetoneRadioButtoncontroltoCheckedtospecifyadefaultoption.

SelectedCheckBoxandRadioButtonitemscanusefullybeaddedtothecollectiondisplayedinaListBoxcontrol:

Option

StartanewWindowsFormsApplication,thenaddRadioButton,CheckBox,ListBox,Button,andLabelcontrolstotheForm

ModifytheTextpropertyvaluesofthecontrolstolooklikethis:

Now,double-clickthe“ShowSelection”ButtoncontroltoopentheCodeEditoratitsgeneratedClickevent-handler

ThenameoftheListBoxcontrolthatappearsintheFormDesignerwillnotbedisplayedwhentheapplicationruns.

IntheForm1()constructormethodblock,insertastatementtospecifyadefaultoptionradioButton1.Checked=true;

Next,insertastatementwithinthe“ShowSelection”ButtonClickevent-handlertoemptyanylisteditemslistBox1.Items.Clear();

Insertstatementswithinthe“ShowSelection”ButtonClickevent-handlertoaddselectedoptionstothelistif(radioButton1.Checked)listBox1.Items.Add(radioButton1.Text);

if(radioButton2.Checked)listBox1.Items.Add(radioButton2.Text);

if(checkBox1.Checked)listBox1.Items.Add(checkBox1.Text);

if(checkBox2.Checked)listBox1.Items.Add(checkBox2.Text);

Now,double-clickthe“Clear”ButtoncontroltoopentheCodeEditoratitsgeneratedClickevent-handler

Insertstatementswithinthe“Clear”ButtonClickevent-handlertoresetalltheoptionslistBox1.Items.Clear();radioButton1.Checked=true;checkBox1.Checked=false;checkBox2.Checked=false;

PressStartorF5toruntheapplicationandselectoptionstoseethemappearinthelist–thenhitClear

TheListBoxcontrolhasanItemspropertythatprovidesmethodstoaddorremovelistitemsfromacollection.

ShowingusermessagesThefeaturesofaMessageBoxdialogcanbedeterminedbyaddingthreefurtherargumentsafterthemessagestringwithinitsShow()method.Thesecanspecifyacaption,whichbuttonsthedialogwilldisplay,andwhichgraphiciconwillappearonthedialog.

MessageBoxButtonsconstants

AbortRetryIgnore

OK

OKCancel

RetryCancel

YesNo

YesNoCancel

ThedialogbuttoncombinationscanbespecifiedusingtheMessageBoxButtonsconstantvalueslistedinthistable.Forexample,tohavethedialogdisplayYes,No,andCancelbuttons,specifytheMessageBoxButtons.YesNoCancelconstant.

AMessageBoxis“modal”–theusermustdealwithitsdialogmessagebeforetheprogramcanproceed.

MessageBoxIcon constants

ErrorHandStop

Question

ExclamationWarning

AsteriskInformation

None

ThedialogiconcanbespecifiedusingtheMessageBoxIconconstantvalueslistedinthistable.Forexample,tohavethedialogdisplaythequestionmarkicon,specifytheMessageBoxIcon.Questionconstant.

WhentheuserpressesaMessageBoxdialogbuttonitreturnsanappropriateDialogResultconstantvaluetotheprogram.Thesearenamedexactlyastheindividualbuttonlabeltheyrepresent.Forexample,anyMessageBoxdialogOKbuttonreturnstheDialogResult.OKconstant.Theprogramcanthereforeexaminethereturnedvaluetodeterminehowtoproceed.

AlwaysspecifyagraphiciconwhencallingaMessageBoxdialogtohelptheusereasilyunderstandthenatureofthemessage.

Message

StartanewWindowsFormsApplication,thenaddaButton,aTextBox,andaLabelcontroltotheForm

Double-clickthe“ShowMessage”ButtoncontroltoopentheCodeEditoratitsgeneratedClickevent-handler

Insertablockwithinthe“ShowMessage”ButtonClickevent-handlertodeliberatelythrowanexceptiontry{thrownewNotImplementedException();

}catch(NotImplementedExceptionnotImp){//Statementstobeinsertedhere(Steps4-5).

}

Addastatementtoassigntheuser’sdecisiontoavariableDialogResultresult=MessageBox.Show(“Proceed?”,notImp.Message,MessageBoxButtons.YesNo,MessageBoxIcon.Error);

Now,addstatementstorespondtotheuser’sdecisiontextBox1.Text=result.ToString();if(result==DialogResult.Yes)label1.Text=“Proceeding...”;if(result==DialogResult.No)label1.Text=“Stopping...”;

PressStartorF5toruntheapplicationandusetheMessageBoxbuttonstodeterminehowtoproceed

ThistechniqueofthrowingaNotImplementedExceptionisfavoredbysomeprogrammersasaremindertocompleteanunfinishedpartoftheprogramcode.

Alternatively,thisprogramcouldstopbycallingtheform’sClose()methodinresponsetoDialogResult.No.

CallingsystemdialogsVisualStudiomakesitsimpletoaddtheabilitytocalluponthestandardWindowsselectiondialogssotheusercanchooseoptionswithinyourapplications.Forexample,selectionofcolors,fonts,andimages:

Dialog

StartanewWindowsFormsApplicationprojectandaddaPictureBox,TextBox,andthreeButtoncontrolstotheForm

FromtheDialogssectionoftheToolbox,addaColorDialog,FontDialog,andOpenFileDialogcomponenttotheForm–seethemappearintheComponentTrayatthebottomoftheFormDesigner

Double-clickthefirstButtontoopentheCodeEditoratitsgeneratedClickevent-handler,theninsertthiscodetochangethebackgroundcoloroftheFormif(colorDialog1.ShowDialog()==DialogResult.OK)this.BackColor=colorDialog1.Color;

Double-clickthesecondButtontoopentheCodeEditoratitsgeneratedClickevent-handler,theninsertthiscodetochangethefontoftheTextBoxcontrolif(fontDialog1.ShowDialog()==DialogResult.OK)textBox1.Font=fontDialog1.Font;

Double-clickthethirdButtontoopentheCodeEditoratitsgeneratedClickevent-handler,theninsertthiscodetochooseanimageforthePictureBoxcontrolif(openFileDialog1.ShowDialog()==DialogResult.OK){//Statementstobeinsertedhere(Step6).

}

TheDialogResult.OKvalueindicatestheuserpressedtheOKbutton–justasitdoesintheMessageBoxexamplehere.

TheSaveFileDialogisdemonstratedintheexamplehere.

Insertablocktoassignaselectedimageordisplayanerrormessagetry{pictureBox1.SizeMode=

PictureBoxSizeMode.StretchImage;pictureBox1.Image=

newBitmap(openFileDialog1.FileName);}catch(Exceptionerror){MessageBox.Show(“Error:SelectAnImageFile!”);

}

PressStartorF5toruntheapplicationandcallthesystemdialogstochooseprogramoptions

ThePictureBoxSizeMode.StretchImagepropertywillstretch,orshrink,aselectedimagetofitthePictureBoxdimensionsasanewBitmapimage.

CreatingapplicationmenusDropdownmenus,toolbars,andstatusbars,likethosefoundinmostWindowsapplications,caneasilybeaddedtoyourownC#GUIapplicationsfromtheToolbox:

Jotter

StartanewWindowsFormsApplicationprojectandfindtheMenus&ToolbarssectionoftheToolbox,thendouble-clicktheMenuStripitemtoaddittotheForm

ClicktheMenuStripcontrol’sarrowbuttontoopenitsSmartTag,thenselectInsertStandardItems

WhenthefamiliarheadingsanditemshavebeenaddedtotheMenuStrip,right-clickonanyitemandusethecontextmenutoeditthatitem.Also,typenewcustomitemsintotheTypeHereboxasrequired

IntheToolbox,double-clickontheToolStripitemtoaddittotheForm,thenopenitsSmartTagandoncemoreselectInsertStandardItems

Alternatively,youcancreateyourowncustommenususingtheTypeHereboxinsteadofInsertStandardItems.

WhenthefamiliariconbuttonshavebeenaddedtotheToolStrip,right-clickonanyitemandusethecontextmenutoeditthatitem.Alsoaddfurthercustomitemsfromthedrop-downlistasrequired

IntheToolbox,double-clickontheStatusStripitemtoaddittotheForm

SelecttheStatusLabelitemontheStatusStripdrop-downlist,andsetitstextpropertyto“Ready”

AddaRichTextBoxcontroltothecenteroftheForm,openitsSmartTagandselecttheoptiontoDockinparentcontainer,thenensurethatitsScrollBarspropertyissettoBoth

UseStatusBarmessagestoprovidefeedbacktotheuser.

Themenusarenottrulyfunctionaluntilyouaddsomeprogramcode–asdescribedhere.

MakingmenusworkThemenuitemsandtoolbarbuttonscreatedherewillnottrulyfunctionuntilyouaddcodetomakethemwork.Foractionsthatappearbothinamenuandonabutton,youcancreateamethodthatcanbecalledfromtheClickevent-handlerofthemenuitemandthatofthebutton–toavoidduplication:

Jotter

InFormDesigner,clickFile,NewtoselecttheNewmenuitem

Double-clickontheNewmenuitemtoopentheCodeEditorinitsClickevent-handler,andaddthismethodcallnewFile();

AftertheClickevent-handlerblock,addthismethodtoclearanyexistingtextanddisplayastatusmessageprivatevoidnewFile(){richTextBox1.Text=null;toolStripStatusLabel1.Text=“Ready”;

}

ReturntotheFormDesigner,thendouble-clickontheNewtoolbarbuttontoopentheCodeEditorinthatevent-handler,andaddacalltothemethodabovenewFile();

AddanOpenFileDialogandSaveFileDialogcomponentfromtheDialogssectionoftheToolbox

IntheClickevent-handlersofboththeOpenmenuitemandtheOpentoolbarbutton,addthismethodcallopenFile();

WhenyouenableNew,Open,andSavedialogs,keyboardshortcutsarealreadyconfigured–tryCtrl+N,Ctrl+S,andCtrl+Ototestthem.

AftertheClickevent-handlerblocks,addthismethodtoloadaplaintextfileprivatevoidopenFile(){openFileDialog1.Filter=“TextFiles|*.txt”;if(openFileDialog1.ShowDialog()==DialogResult.OK){richTextBox1.LoadFile(openFileDialog1.FileName,

RichTextBoxStreamType.PlainText);}

}

IntheClickevent-handlersofboththeSavemenuitemandtheSavetoolbarbutton,addthismethodcallsaveFile();

AftertheClickevent-handlerblocks,addthismethodtosaveaplaintextfileprivatevoidsaveFile(){saveFileDialog1.Filter=“TextFiles|*.txt”;if(saveFileDialog1.ShowDialog()==DialogResult.OK){richTextBox1.SaveFile(saveFileDialog1.FileName,

RichTextBoxStreamType.PlainText);}

}

PressStartorF5toruntheapplicationandtestthefunctionalityoftheNew,Open,andSavefilemenuitemsandtoolbarbuttons

YoucanchangetheFilterto“RichText|*.rtf”andRichTextBoxStreamTypepropertyto.RichTextforfileswithembeddedobjects,suchasimages.

TomaketheFile,Exitmenuitemfunctional,simplyaddthecallApplication.Exit();toitsClickevent-handler.

ImportingaudioresourcesSoundfilescanbeincludedwithinanapplicationasaresource,inmuchthesamewaythatimagefilescanbeimportedasaresource,toenhancetheapplication.Thesecanthenbeplayed,asrequired:

Sound

StartanewWindowsFormsApplicationprojectandaddasingleButtoncontroltotheForm

SelectProject,ProjectNamePropertiesontheMenuBar,toopentheProjectDesignerwindow

InProjectDesigner,selecttheResourcesitemintheleftpane,thenchooseAudioitemfromthedrop-downlist

SelecttheAddExistingFile...itemfromtheAddResourcedrop-downlisttolaunchtheAddexistingfiletoresourcesdialog

ItisadvisabletousetheProjectDesignertoremovearesource,ratherthandeletingitfromSolutionExplorer.

YoucantypicallyfindtheWindowssoundfilesinthefolderonyourcomputeratC:\Windows\Media.

Browsetothelocationofthesoundfileyouwishtoadd,thenselectthefileandclicktheOpenbutton

ThesoundfilenowgetsaddedtotheResourcesfolderinSolutionExplorerandappearsintheResourceswindowofProjectDesigner–hereit’safilenamednotify.wav

Now,opentheCodeEditorandaddadirectiveatthebeginningofthepagetomakeanotherC#classavailableusingSystem.Media;

Double-clicktheButtoncontrol,thenaddthisstatementaboveitsClickevent-handlerblocktocreateanobjectSoundPlayernotifier=newSoundPlayer(Properties.Resources.notify);

Now,addthesestatementsinsidetheButtoncontrol’sClickevent-handlertoshowa

messageandplaythesoundlabel1.Text=“Notifying...”;notifier.Play();

PressStartorF5toruntheapplicationandpushtheButtontohearthesoundplay

AsoundcanbeplayedrepeatedlyusingthePlayLooping()method–andtheloopcanbeendedwiththeStop()method.

Thesoundfilenameonlyisdot-suffixedtoProperties.Resources–withoutitsfileextension.

Summary• TheWindowsFormsApplicationtemplateintheNewProjectdialogisusedtobegina

WindowsGUIproject.

• TheFormDesignerwindowoftheVisualStudioIDEiswhereyoucreatetheapplication’svisualinterface.

• ThePropertieswindowcontainsdetailsoftheitemthatiscurrentlyselectedintheFormDesignerwindow.

• TheCommonControlssectionoftheToolboxcontainsawiderangeofvisualcontrolstobuildGUIapplications.

• TheCodeEditorisusedtocreatethecode-behindpagethatdetermineshowtheapplicationrespondstointerfaceevents.

• WhentheuserpushesaButtoncontrol,itcreatesaClickeventtowhichitsevent-handlercanrespond.

• UserinputintoaTextBoxcontrolcanbeassignedtoavariableforusewithintheapplication.

• TheusercannotmodifytextthatappearsonaLabelcontrol.

• OnlyoneoptioncanbecheckedinaRadioButtongroup,butanynumberofoptionscanbecheckedinaCheckBoxgroup.

• AListBoxcontrolhasanItemspropertythatprovidesmethodstoaddorremoveitemsfromthelistitcontains.

• TheShow()methodoftheMessageBoxclassacceptsargumentstospecifyamessage,caption,buttons,andicon.

• TheDialogssectionoftheToolboxcontainscomponentsthatallowanapplicationtousetheWindowssystemdialogs.

• TheMenus&ToolbarssectionoftheToolboxcontainscomponentsthatallowanapplicationtoincludethefamiliarWindowssystemmenuitems.

• TheMenus&ToolbarscomponentswillnottrulyfunctionuntilcodeisaddedtotheirClickevent-handlers.

• TheProjectDesignerwindowcanbeusedtoimportresourcesintoanapplicationproject.

• ASoundPlayerobjectcanbecreatedusingtheSystem.Mediaclass,andprovidesmethodstohandleaudioresources.

11

Buildinganapplication

Thischapterdemonstrateshowtocreate,test,andpublishasimpleC#programapplication.

PlanningtheprogramAssigningfixedpropertiesDesigningthelayoutSettingdynamicpropertiesAddingruntimefunctionTestingtheprogramPublishingtheapplicationSummary

PlanningtheprogramWhencreatinganewapplicationitisusefultospendsometimeplanningitsdesign.Clearlydefinetheprogram’sprecisepurpose,decidewhatapplicationfunctionalitywillberequired,thendecidewhatinterfacecomponentswillbeneeded.

Aplanforasimpleapplicationtopicknumbersforalotterygameentrymightlooklikethis:

Programpurpose

• Theprogramwillgenerateaseriesofsixdifferentrandomnumbersintherange1–59,andhavetheabilitytobereset.

Omissionoftheplanningstagecanrequiretime-consumingchangestobemadelater.It’sbetterto“planyourwork,thenworkyourplan”.

Functionalityrequired

• Arandomnumbergenerator.

• Amethodtodisplaysixdifferentrandomnumbers.

• Amethodtoclearthelastseriesfromdisplay.

Componentsneeded

• SixLabelcontrolstodisplaytheseriesofnumbers–onenumberperLabel.

• OneButtoncontroltogenerateanddisplaythenumbersintheLabelcontrolswhenthisButtonisclicked.ThisButtonwillnotbeenabledwhennumbersareondisplay.

• OneButtoncontroltoclearthenumbersondisplayintheLabelcontrolswhenthisButtonisclicked.ThisButtonwillnotbeenabledwhennonumbersareondisplay.

• OnePictureBoxcontroltodisplayastaticimage–justtoenhancetheappearanceoftheinterface.

TogglethevalueofaButton’sEnabledpropertytosteertheuser.Inthiscase,theapplicationmustberesetbeforeafurtherseriesofnumberscanbegenerated.

HavingestablishedaprogramplanmeansyoucannowcreatetheapplicationbasicsbyaddingthecomponentsneededtoaForm:

Lotto

OpentheVisualStudioIDEandcreateanewWindowsFormsApplicationprojectcalled“Lotto”

IntheFormDesigner,addsixLabelcontrolstotheFormfromtheToolbox

Now,addtwoButtoncontrolsandaPictureBoxcontroltotheForm

VisualStudio2015supportsclassicdesktopappdevelopmentfortheWindowsStore.

YoucandraganddropitemsfromtheToolbox,ordouble-clickthemtoaddthemtotheForm.

AssigningfixedpropertiesHavingcreatedtheapplicationbasicshere,youcannowassignstaticvaluesusingthePropertieswindow:

Lotto

ClickontheFormtoselectit,theninthePropertieswindow,settheForm’sAppearance,Textpropertyto“LottoNumberPicker”

SelectthefirstButtoncontrol,theninthePropertieswindow,changeitsDesign,(Name)propertytoBtnPick,anditsAppearance,Textto“GetMyLuckyNumbers”

SelectthesecondButtoncontrol,theninthePropertieswindow,changeitsDesign,(Name)propertytoBtnReset,anditsAppearance,Textpropertyto“Reset”

YoucanopenthePropertieswindowusingtheF4key,orbyclickingView,PropertiesWindowontheMenuBar.

TheLabelcontrolsinthisprogramwillhavetheirTextpropertyvaluesassigneddynamicallyatruntime–noinitialpropertiesarerequired.

SelectthePictureBoxcontrol,theninthePropertieswindow,clicktheAppearance,ImagepropertyellipsisbuttontolaunchtheSelectResourcesdialog

ClicktheImportbutton,browsetotheimagelocation,thenclickOKtoimporttheimageresource–thisactionautomaticallyassignsittothePictureBox’sImageproperty

ClickFile,SaveForm1.csorpresstheCtrl+Skeystosavethechangesmadetotheprojectformproperties

Youcanusethedrop-downlistatthetopofthePropertieswindowtoselectanycontrolontheform.

SaveyourprojectperiodicallyasyoubuilditusingFile,SaveAllontheMenuBarorCtrl+Shift+Skeys.

DesigningthelayoutHavingassignedfixedpropertyvalueshere,youcannowdesigntheinterfacelayout.

ThesizeofboththePictureBoxcontrolandtheBtnPickcontrolfirstneedstobeadjustedtoaccommodatetheircontent.ThiscaneasilybeachievedbyspecifyinganAutoSizevaluesothatVisualStudiowillautomaticallyfitthecontrolneatlyarounditscontent:

Lotto

SelectthePictureBoxcontrol,theninthePropertieswindow,changeitsBehavior,SizeModetoAutoSize

SelecttheBtnPickcontrol,theninthePropertieswindow,setitsLayout,AutoSizepropertytoTrue

SeethatthePictureBoxcontrolnowsnuglyfitsaroundtheimage,andtheBtnPickcontrolhasexpandedtofititstext

HolddowntheleftmousebuttonanddragaroundtheLabelstoselectallLabelcontrols

Now,clickView,Toolbars,LayouttoaddtheLayouttoolbartotheVisualStudiomenus

ClicktheAlignTopsbuttontostacktheLabelsinapile

Alternatively,youcanusetheSmartTagarrowbuttononaPictureBoxcontroltosetitsSizeModeproperty.

EnsurethatallPictureBoxMarginpropertiesaresettozeroifyoudonotrequiremarginsaroundtheimage.

ClicktheMakeHorizontalSpacingEqualtoolbarbuttontoarrangethepileofLabelsintoarow

UsetheForm’srightgrabhandletoextenditswidthtoaccommodatetherowofLabelsandPictureBox,thendragtherowandbothButtonstotoprightoftheForm

DragthePictureBoxcontroltotopleftoftheForm,thenusetheForm’sbottomgrabhandletoadjustitsheighttomatchthatoftheimage

UsetheSnapLinesthatappearwhenyoudragcontrolsaroundtheFormtopositiontherowofLabelsandtheButtonstomaketheinterfacelooklikethelayoutbelow

SettheForm’sWindowStyle,MaximizeBoxandMinimizeBoxpropertiestoFalse,asmaximizeandminimizebuttonsarenotrequiredonthisinterface

Inthiscase,itdoesnotmatterinwhatordertheLabelsappearintherow.

Avoidthetemptationtochangethedefaultstylesofformcontrolssotheyremainfamiliartousers.

SettingdynamicpropertiesHavingdesignedtheinterfacehere,youcannowaddsomefunctionalitytodynamicallysettheinitialTextpropertiesoftheLabelcontrolsandtheinitialButtonstates:

Lotto

ClickView,CodeontheMenuBar,orpressF7,toopentheCodeEditorwindow

AftertheForm1()constructormethodblock,addanewmethodblockprivatevoidClear(){//Statementstobeinsertedhere(Steps4-8).

}

Withthecursorinsidethenewmethodblock,pressCtrl+J,toopentheIntelliSensepop-upwindow

ScrolldownthelistofitemsintheIntelliSensewindowanddouble-clickonthelabel1itemtoadditintotheClear()methodblock

Typeaperiod,thendouble-clicktheTextitemwhentheIntelliSensewindowreappears,toaddthatcode

ThetechniquedescribedheredemonstrateshowtouseIntelliSense–butyoucan,ofcourse,justtypethecodedirectly.

Now,type=“...”;tocompletethelinesoitreadslikethis:label1.Text=“...”;

RepeatthisprocedurefortheotherLabelcontrols–sothattheClear()methodassignseachanellipsisstring

WiththecursorinsidetheClear()methodblock,useIntelliSenseinthesameway,toaddthesetwolines:BtnPick.Enabled=true;BtnReset.Enabled=false;

Type“Intellisense”intotheQuickLaunchboxatthetopoftheVisualStudiowindowtodiscovertheIntelliSenseMenusandOptions.

ThiscompletestheClear()methodfunctionalitybysettingtheButtonstates.AllthatremainsistoaddacalltotheClear()methodtoexecuteallofitsinstructionswhentheprogramstarts.

IntheFormDesignerdouble-clickontheFormtoopentheCodeEditorinitsLoadevent-handler,thenpressCtrl+JtoopentheIntelliSensewindow

ScrolldownthelistintheIntelliSensewindowanddouble-clickontheClearitemyouhavejustcreated,toaddacallstatementintheLoadevent-handler

Youcouldaddsomecommentstomakethecodemorefriendly.

AddingruntimefunctionHavingcreatedcodetoinitializedynamicpropertieshere,youcannowaddruntimefunctionalitytorespondtoclicksontheButtoncontrols:

Lotto

IntheFormDesigner,double-clickontheBtnResetButtoncontroltoopentheCodeEditorinitsClickevent-handler,thenaddthismethodcallClear();

ThisisallthatisneededtoprovidedynamicfunctionalityfortheBtnResetcontrol.ThemaindynamicfunctionalityofthisapplicationisprovidedbytheBtnPickcontrol,whichrequiresaninstanceofaRandomclass,randomnumbergeneratorobject:

IntheFormDesigner,double-clickontheBtnPickButtoncontroltoopentheCodeEditorinitsClickevent-handler

IntheClickevent-handlerblock,addthisstatementtocreatearandomnumbergeneratorobjectRandomrnd=newRandom();

Next,addastatementtocreateanarrayof59elementstostoreasequenceofnumbersint[]seq=newint[59];

Now,addalooptofillthearrayelements(index0to58)withintegervalues1to59for(inti=1;i<60;i++){seq[i-1]=i;

}

Addasecondlooptoshufflethevalueswithinallthearrayelements–analgorithmtorandomizetheirorderfor(inti=0;i<59;i++){intj=(rnd.Next()%59);intk=seq[i];seq[i]=seq[j];seq[j]=k;

}

Therandomnumbergeneratorisusedheretogeneraterandomvaluesbetweenzeroand58toshufflearrayelements.

Youdon’tneedtounderstandindetailthealgorithmthatisusedtoshufflethevalues.

Next,addthefollowinglinestodisplaythenumberscontainedinarrayelements1-6intheLabelcontrolslabel1.Text=seq[1].ToString();label2.Text=seq[2].ToString();label3.Text=seq[3].ToString();label4.Text=seq[4].ToString();label5.Text=seq[5].ToString();label6.Text=seq[6].ToString();

Now,addthesetwolinestosettheButtonstatesreadytoresettheapplicationBtnPick.Enabled=false;BtnReset.Enabled=true;

Addcommentsforothersexaminingthecode,andforyourselfwhenrevisitingthecodelater

ClickFile,SaveAllorpresstheCtrl+Shift+Skeystosavethechangesmadetotheprojectcode-behindpage

TheLabelcontrolscanonlycontainstringvalues,sotheintnumericvaluesmustbeconverted.

YoucanhaveVisualStudionicelyformatyourcodebyselectingEdit,Advanced,FormatDocument,orusingthekeyboardshortcutshownthere–typically,thisisCtrl+K,Ctrl+D.

TestingtheprogramHavingworkedthroughtheprogramplanonthepreviouspages,thecomponentsneededandfunctionalityrequiredhavenowbeenaddedtotheapplication–soit’sreadytobetested:

Lotto

ClicktheStartbutton,orpressF5,toruntheapplicationthenexamineitsinitialstart-upappearance

TheForm’sLoadevent-handlerhassettheinitialdynamicvaluesofeachLabelcontrolanddisabledtheresetbuttonasrequired.

ClicktheBtnPickButtoncontroltoexecutetheinstructionswithinitsClickevent-handler

Noticethatnonumberisrepeatedinanyseries.

Aseriesofnumberswithinthedesiredrangeisdisplayed,andtheButtonstateshavechangedasrequired–afurtherseriesofnumberscannotbegenerateduntiltheapplicationhasbeenreset.

Makeanoteofthenumbersgeneratedinthisfirstseriesforcomparisonlater

ClicktheBtnResetcontroltoexecutetheinstructionswithinthatClickevent-handlerandseetheapplicationreturntoitsinitialstart-upappearanceasrequired

ClicktheBtnPickButtoncontrolagaintoexecuteitsClickevent-handlercodeasecondtime

Rememberthatthisapplicationinterfacehasnominimizeormaximizebuttonsbecausetheirpropertiesweresettofalse–here,Step11.

Anotherseriesofnumberswithinthedesiredrangeisdisplayedandaredifferenttothoseinthefirstserieswhencompared–good,thenumbersarebeingrandomizedasrequired.

ClicktheStopDebuggingbutton,thenclicktheStartbuttontorestarttheapplicationandclicktheBtnPickButtoncontroloncemore

Thegeneratednumbersinthisfirstseriesofnumbersaredifferenttothosenotedinthefirstseriesthelasttimetheapplicationran–great,therandomnumbergeneratorisnotrepeatingthesamesequenceofnumberserieseachtimetheapplicationruns.

Alternatively,youcanclicktheapp’sXbuttontoclosetheapplicationandstopdebugging.

PublishingtheapplicationHavingsatisfactorilytestedtheapplicationhere,youcannowcreateastand-aloneversionthatcanbeexecutedoutsidetheVisualStudioIDE,andthatcanbedistributedtoothersfordeploymentelsewhere.

Lotto

ClickProjectontheMenuBar,chooseLottoProperties,SigningthenselectasignaturecertificateorensuretheSigntheClickOncemanifestsboxisunchecked

ClickBuild,BuildLotto,thenclickBuild,PublishLottotolaunchthePublishWizarddialog

Usethewizard’sBrowsebuttontoselectalocationwhereyouwishtopublishtheapplication–thechosenlocationshownhereistherootdirectoryofremovabledriveF:

ClicktheNextbutton,thenselectwhethertheuserwillinstalltheapplicationfromawebsite,network,orportablemediasuchasCD,DVD,orremovabledrive–inthiscaseacceptthedefaultportablemediaoption

Applicationssigningisoptional,butdoesverifyauthentication.FindmoredetailsonClickOnceatmsdn.microsoft.com/en-us/library/t71a733d.aspx

Whenchoosingapublishlocation,usetheCreateNewFolderbuttonintheFileSystemdialogtomakeafoldertocontainalltheapplicationfiles.

ClicktheNextbutton,thenselectwhethertheinstallershouldcheckforapplicationupdates–acceptthedefaultoptionnottocheckforupdatesinthiscase

ClicktheNextbuttontomovetothefinaldialogpage,confirmthelistedchoices,thenclicktheFinishbuttontopublishtheapplicationatthespecifiedlocation

Eachtimeyoupublishanapplication,itsversionnumberisautomaticallyincremented–1.0.0.0,1.0.0.1,1.0.0.2,etc.

ThePublishWizardgeneratesanumberoffiles,includingafamiliar“setup.exe”executableinstaller.

Movetheportablemediatothesystemwhereitistobedeployed,thenrunsetup.exetoinstalltheapplication

Whentheapplicationisinstalledontheclientsystem,ashortcutisautomaticallyaddedtotheStartmenu,whichcanbeusedtolaunchtheapplication.Theusercanthenruntherelease

versionoftheapplicationjustasitperformedduringtestingofitsdebugversionintheVisualStudioIDE.

Theinstalleralsoaddsanitemtotheclientsystem’sAdd/RemoveProgramslist,whichcanbeusedtouninstalltheapplication–justlikeanyotherWindowsprogram.

Anapplicationcannotbepublishedunlessithasbeenbuiltfirst.

Summary• Alwaysmakeaninitialprogramplan,toavoidtheneedfortime-consumingchangeslater.

• Aprogramplanshouldclearlydefinetheprogrampurpose,functionalityrequired,andcomponentsneeded.

• FixedpropertiesthatwillnotchangewhentheapplicationisrunningcanbesetatDesigntimeinthePropertiesWindow.

• TheImportbuttonintheSelectResourcesdialogcanautomaticallyassignanimagetoaPictureBoxcontrol.

• AnAutoSizepropertyvaluemakesVisualStudioautomaticallyfitacontrolneatlyarounditscontent.

• TheFormDesigner’sLayouttoolbarcontainsusefulfeaturestoquicklyalignandspacemultipleinterfacecontrols.

• SnapLineshelpyoutoeasilyalignaselectedcontroltoothersintheinterfaceatDesigntime.

• SettingaForm’sWindowStyle,MaximizeBoxandMinimizeBoxpropertiestoFalseremovesthosebuttons.

• DynamicpropertiesthatwillchangewhentheapplicationisrunningcanbeinitializedwiththeForm’sLoadevent-handler.

• Thepop-upIntelliSensewindowletsyoueasilyaddprogramcodewhenusingtheCodeEditor.

• Runtimefunctionalityrespondstouseractionsbychangingdynamicproperties.

• ADebugversionofanapplicationallowsitsfunctionalitytobetestedastheapplicationisbeingcreatedintextformat.

• TheBuildprocesscompilesaReleaseversionofanapplicationinbinaryformat.

• ThePublishprocesscreatesafinalReleaseversionwithaninstallersotheapplicationcanbedeployedelsewhere.

• ApplicationscreatedwiththeVisualStudioIDEcanbeinstalledanduninstalledjustlikeotherWindowsapplications.

12

Targetingdevices

ThischapterdemonstrateshowtocreateaUniversalWindowsPlatformapplicationusingC#programming.

StartingaUniversalprojectInsertingpagecomponentsImportingprogramassetsDesigningthelayoutAddingruntimefunctionTestingtheprogramAdjustingtheinterfaceDeployingtheapplicationSummary

StartingaUniversalprojectWindows10introducedtheUniversalWindowsPlatform(UWP)whichenablesyoutocreateasingleapplicationthatwillrunonanymodernWindows-baseddevice–phone,tablet,orPC.

TheinterfacelayoutofaUWPapplicationusestheeXtensibleApplicationMarkupLanguage(XAML)tospecifycomponents.

TheexampleinthischapterisforVisualStudio2015onWindows10–itwon’tworkwithearlierversions.

InordertodevelopappsfortheUWP,youshouldberunningthelatestversionofWindows10,andyourVisualStudioIDEmustincludetheUniversalWindowsAppDevelopmentTools:

Universal

OpenControlPanel,ProgramsandFeatures,thenright-clickontheVisualStudioitemandselectChange–tolaunchtheVisualStudioinstaller

SelectalloptionsintheUniversalWindowsAppDevelopmentToolscategory,thenclicktheNextbutton–todownloadandinstallthetools

Afterinstallationofthetools,opentheVisualStudioIDE

AUWPapplicationisalsoknownasa“UWA”–UniversalWindowsApplication.

DependinguponyourchoiceswhenyouinstalledVisualStudio,youmayseetheoptionscheckedwhentheinstallerlaunches,toindicateyoualreadyhavetheUniversalWindowsAppDevelopmentTools.

Next,selectFile,New,ProjectandcreateanewBlankApp(UniversalWindows)projectcalled“Universal”

Whenaskedtoselectthetargetandminimalplatformversions,simplyclickOKtoaccept

thedefaultoptions

AfterVisualStudiocreatesthenewproject,selectView,SolutionExplorertoexaminethegeneratedfiles:

• AsetoflogoimagesinanAssetsfolder

• InternalXAMLandC#filesfortheApp

• XAMLandC#filesfortheMainPage–hereiswhereyouwillcreateinterfacecomponentsandfunctionalcode

• OthermiscellaneousPackagefiles

OnWindows10youshouldensurethattheDeveloperModeoptionisenabledinSettings,Update&Security,Fordevelopers.

VisualStudio2015supportscross-platformmobiledevicedevelopment.

ThesefilesareessentialtoallUWPappsusingC#,andexistineveryprojectVisualStudiocreatestotargettheUniversalWindowsPlatformwithC#.

InsertingpagecomponentsVisualStudioprovidesatwo-partwindowtoinsertinterfacecomponentsintoaUWPapp.ThiscomprisesaDesignviewofthecomponentsandaXAMLviewfortheXAMLcode:

Universal

OpenSolutionExplorerthendouble-clickonMainPage.xaml–tolaunchthetwo-partwindow

Seethat,bydefault,theDesignviewdisplaysablankcanvasinPortraitmode

Explorethesebuttonstochangethemagnificationandgridcharacteristics.

ClicktheadjacentbuttoninDesignviewtochangetheblankcanvastoLandscapemode

XAMLispronounced“zammel”.

ThereisaToolboxthatletsyouaddcomponentsontothecanvas,butyouwillneedtoeditthemintheXAMLcodelater.Inthisexample,thecomponentsarecreatedinXAMLcodefromtheverystart.

Now,seethatbydefault,theXAMLviewrevealsthereare<Grid></Grid>tags–thisistherootelementofthecanvasinwhichyoucanaddcomponentelements

Componentelementsarebestnestedwithina<StackPanel>element,asthiscanbegivenanx:Nameforreferenceinfunctionalcode,andanOrientationattributetospecifythedirectioninwhichthenestedelementsshouldappear.Commoncomponentelementsinclude<Image>,<TextBox>,<TextBlock>(label),and<Button>.Several<StackPanel>elementscanbenestedwithineachothertodeterminetheHorizontalandVerticallayoutofcomponents:

Insertelementsbetweentheroot<Grid></Grid>tags,sotheXAMLviewcodelookspreciselylikethis:

AsyouaddthecomponentelementsinXAMLview,theyappearintheDesignviewuntilitlookslikethis:

Thex:prefixbeforetheNameattributereferstotheXAMLschemausedbyUWPapps.

Theouter<StackPanel>isahorizontallayoutcontainingan<Image>andanested<StackPanel>.Thenested<StackPanel>isaverticallayoutcontainingtwofurther<StackPanel>elementsthateachdisplaytheircomponentshorizontally.

Noticethateach<TextBlock>elementhasaTextattributethatcanbereferencedinfunctionalcode.Forexample,textBlock1.Text.

ImportingprogramassetsInordertohaveaXAML<Image>componentdisplayagraphic,animagefilefirstneedstobeaddedtotheprojectsAssetsfolder.ItcanthenbeassignedtoaSourceattributeofthe<Image>tag:

Universal

OpenSolutionExplorer,thenright-clickontheAssetsfolderandchooseAddfromthecontextmenu

Now,chooseExistingItemfromthenextcontextmenu–toopenanAddExistingItemdialogbox

IntheAddExistingItemdialog,browsetothelocationofanimage,thenselectthefileandclicktheAddbutton

Animagefordisplaymaybeinanypopularfileformat–suchas.bmp,.gif,.jpg,.png,or.tif.

InSolutionExplorer,theselectedimagefilenowappearsintheproject’sAssetfolder

SelecttheImagecomponentinDesignerview,thenclickView,Propertiestorevealitsproperties

InthePropertieswindow,expandtheCommoncategory,thenclicktheSourceitem’sarrowbuttonandselecttheaddedimagefromthedrop-downlist

TheimagenowappearsintheDesignview,anditspathgetsaddedtotheXAMLviewcodeandSourceproperty

ExploretheAppearanceandTransformoptionsinanimage’sPropertieswindow,todiscoverhowyoucanmodifyhowitwillbedisplayed.

DesigningthelayoutTocompletetheapp’slayout,designattributescanbeaddedtotheXAMLelementtagstospecifywhattheywilldisplayandpreciselywhereintheinterfacetheywillappear:

Universal

OpenMainPage.xaml,thenaddtwoattributestotheouter<StackPanel>elementtofixitspositionHorizontalAlignment=”Left”VerticalAlignment=”Top”

Next,editthe<Image>elementbymodifyingtheinitialassignedvalueof200–toincreaseitswidthWidth=”300”

Now,addanattributetothenested<StackPanel>elementtofixitspositionVerticalAlignment=”Center”

Then,editallsix<TextBlock>elementsalike,tospecifytheirinitialcontent,width,andmarginonallfoursidesText=”...”Width=”20”Margin=”15”Text=”...”Width=”20”Margin=”15”Text=”...”Width=”20”Margin=”15”Text=”...”Width=”20”Margin=”15”Text=”...”Width=”20”Margin=”15”Text=”...”Width=”20”Margin=”15”

Editthefirst<Button>elementtorenameit,specifyitsbuttonlabelcontent,andmarginonallfoursidesx:Name=“BtnPick”Content=“GetMyLuckyNumbers”Margin=“15”

Editthesecond<Button>elementtorenameitandspecifyitsbuttonlabelcontentx:Name=“BtnReset”Content=“Reset”

Finally,addanattributetoeachrespective<Button>elementtospecifytheirinitialstateIsEnabled=“True”IsEnabled=“False”

AsingleMarginvaluesetsallfourmarginsaroundthatcomponent.Youcanspecifytwo

valuestosetleft&right,top&bottommargins,e.g.Margin=“10,30”.Alternatively,youcanspecifyfourvaluestosetleft,top,right,bottommarginsindividually,e.g.Margin=“10,30,10,50”.

Theorderinwhichtheattributesappearineachelementisunimportant,buttheelementswithintheMainPage.xamlfileshouldnowlooksimilartothescreenshotbelow:

YoucanoptionallyaddMargin=“0”attributestoexplicitlyrequireelementstohavenomarginwidth.

AsyoumakechangestotheXAMLviewcode,thecomponentlayoutgetschangedaccordinglyintheDesignviewandshouldnowlooklikethis:

TheDesignviewshowsthecomponents’initialstate–theResetbuttonappearsgrayedout,asitisnotenabled.

AddingruntimefunctionHavingcompletedtheapplicationcomponentlayoutwithXAMLelementshere,youarenowreadytoaddfunctionalitywithC#programmingcode:

Universal

InDesignview,double-clickontheBtnPickbutton

TheMainPage.xaml.cscode-behindpageopensintheCodeEditoratageneratedBtnPick_Clickevent-handler

IntheBtnPick_Clickevent-handlerblock,insertthesestatementstocreatearandomizedarrayofintegersbetween1and59Randomrnd=newRandom();int[]seq=newint[59];for(inti=1;i<60;i++)seq[i-1]=i;for(inti=0;i<59;i++){intj=(rnd.Next()%59);intk=seq[i];seq[i]=seq[j];seq[j]=k;

}//Statementstobeinsertedhere(Steps4-5).

Next,insertstatementstoassignsixarrayelementvaluestothe<TextBlock>componentstextBlock1.Text=seq[1].ToString();textBlock2.Text=seq[2].ToString();textBlock3.Text=seq[3].ToString();textBlock4.Text=seq[4].ToString();textBlock5.Text=seq[5].ToString();textBlock6.Text=seq[6].ToString();

Next,insertstatementstosetthe<Button>statesBtnPick.IsEnabled=false;BtnReset.IsEnabled=true;

ReturntoMainPage.xaml,theninDesignview,double-clickontheBtnResetbutton

TheMainPage.xaml.cscode-behindpageopensintheCodeEditoratageneratedBtnReset_Clickevent-handler

TherandomizerroutineusesexactlythesamelogicasthatoftheWindowsFormsApplicationexample–seehere.

ThereisnoLabelcomponentinUWPapps;itiscalledaTextBlockinstead.

ThereisnoEnabledpropertyinUWPapps;itiscalledIsEnabledinstead.

IntheBtnReset_Clickevent-handlerblock,insertstatementstoassignstringstothe<TextBlock>componentstextBlock1.Text=“...”;textBlock2.Text=“...”;textBlock3.Text=“...”;textBlock4.Text=“...”;textBlock5.Text=“...”;textBlock6.Text=“...”;//Statementstobeinsertedhere(Step9).

Finally,insertstatementstosetthe<Button>statesBtnPick.IsEnabled=true;BtnReset.IsEnabled=false;

TheBtnResetbuttonsimplyreturnsthe<TextBox>and<Button>componentstotheiroriginalstates.

TheMainPage.xaml.cscode-behindpageshouldnowlooklikethescreenshotbelow:

ReturntotheMainPage.xamlfile,theninXAMLview,seethatattributeshavebeenautomaticallyaddedtothe<Button>elementstocalltheevent-handlercode

Noticethatthefirstforloopcontainsonlyonestatementtobeexecutedoneachiteration,sobracesarenotrequired.

TestingtheprogramHavingaddedfunctionalitywithC#codehere,youarenowreadytotesttheprogramfortwodevices:

Universal

OntheVisualStudiostandardtoolbar,selectDebugforx64architectureandLocalMachineoptions,thenclicktheStartbuttontoruntheappforaPCdevice

Waitwhiletheapplicationgetsbuiltandloaded,thenclickthebuttonstotryouttheirfunctionality

TheapplooksgoodonPCdevices–numbersarebeingrandomizedandthebuttonstatesarechangingasrequired.

Now,ontheVisualStudiostandardtoolbar,selectDebug,StopDebuggingtoexittherunningprogram

YoumusthaveyourPCsettoDeveloperModeinSettings,Update&Security,Fordevelopers.

YoucansafelyignoretheDEBUGnumbersthatappearintheblackboxes,butifyouprefernottoseethem,selectProject,ProjectNameProperties,Build,thenunchecktheDefineDEBUGconstantoption.

OntheVisualStudiostandardtoolbar,selectDebugforx86architectureandsmallMobileEmulatoroptions,thenclicktheStartbuttontoruntheappforamobiledevice

Waitwhiletheemulatorstartsup–thistakesawhile

Whentheapplicationgetsbuiltandloaded,youseethecontrolsarenotvisible–soyoucan’ttryouttheirfunctionality!

What’sgoingonhere?ClickoneoftheemulatorsRotatebuttonstoflipitovertoLandscapeorientationandlookforclues

Ah-ha!Someofthecontrolsarenowvisible,butthisisunsatisfactory–adjustmentswillbeneededtotheinterfacelayoutsotheapplooksgoodonmobiledevices

Again,ontheVisualStudiostandardtoolbar,selectDebug,StopDebuggingtoexittherunningprogram

Testontheemulatorwithlowestmemoryandsmallestscreen,anditshouldbefinerunningonthoseemulatorswithbetterfeatures.

DonotclicktheXbuttonontheemulatorwindowtostoptherunningprogram,asthatwillalsoclosetheemulator.

AdjustingtheinterfaceTheapptestformobiledevicesherefailedtosatisfactorilypresentthecontrols,astheinterfaceistoowideforsmallscreendevices.Happily,theinterfacecanbemadetoadapttodifferentscreensizessoitcanalsolookgoodonmobiledevices.Theadaptationreliesuponrecognizingthescreensizeandchangingtheorientationofa<StackPanel>elementinXAMLfornarrowscreendevices:

Universal

OpenMainPage.xaml,theninXAMLview.addtheseelementsimmediatelybelowtheopening<Grid>elementandbeforethecomponentelements<VisualStateManager.VisualStateGroups><VisualStateGroup>

<!--Elementstobeinsertedhere(Steps2-3)-->

</VisualStateGroup></VisualStateManager.VisualStateGroups>

Next,insertelementstorecognizewidescreens<VisualStatex:Name=“wideState”>

<VisualState.StateTriggers><AdaptiveTriggerMinWindowWidth=“641”/>

</VisualState.StateTriggers>

</VisualState>

Now,insertelementstorecognizenarrowscreens,andtochangetheOrientationoftheouter<StackPanel><VisualStatex:Name=“narrowState”>

<VisualState.StateTriggers><AdaptiveTriggerMinWindowWidth=“0”/>

</VisualState.StateTriggers>

<VisualState.Setters><SetterTarget=“MainStack.Orientation”Value=“Vertical”/>

</VisualState.Setters>

</VisualState>

XAMLcoderecognizesthesame<!---->commenttagsthatareusedinHTMLcode.

Rememberthattheouter<StackPanel>inthisappcontainsan<Image>andanested<StackPanel>displayedhorizontally,sidebyside.Ifdisplayedvertically,theyshouldappearoneabovetheother.

ThebeginningoftheMainPage.xamlfileshouldnowlooksimilartothescreenshotbelow:

Selectx64andLocalMachinetoruntheappforaPCdeviceoncemore–itstilllooksandfunctionswell

Now,selectx86andMobileEmulatortoruntheappforamobiledevice–itnowalsolooksandfunctionswell

YoucanhaveVisualStudionicelyformattheXAMLcodebypressingCtrl+K,Ctrl+D.

Althoughanappmayworkwellonanemulator,itisrecommendedyoualwaystestonactualdevicesbeforedeployment.

DeployingtheapplicationHavingtestedtheappinaMobileEmulatorhere,itcannowbetestedonarealdevicebeforedeployment:

Universal

OnaWindows10device,selectDevelopermodefromtheSettings,Update&Security,Fordevelopersmenu

Next,connectthedevicetoyourPCviaaUSBsocket

OntheVisualStudiotoolbar,selectDebugforARMarchitectureandDeviceoptions,thenclicktheStartbuttontoruntheappontheconnecteddevice

Waitwhiletheapplicationgetsbuiltandloaded,thentapthebuttonstotryouttheirfunctionality

YoucanchoosetheRemoteMachineoptiontotestviaanetworkconnection.

Theapplooksgood,numbersarebeingrandomized,andthebuttonstatesarechangingasrequired–theappcanbedeployed.

RemovetheDebugversionoftheappfromthedevice

InSolutionExplorer,addlogoimagestotheAssetsfolder,thendouble-clickonPackage.appmanifestandaddthemtoVisualAssets

AddthreelogoimagestotheAssetsfolderoftherequiredsizes,thenclickthesebuttonstoselectthemtobetheapptiles.Youcanalsoaddtileimages,aSplashScreenimage,orselecttheApplicationtabandchangetheapp’sDisplayname–to“LuckyNumbers”,forexample.

OntheVisualStudiotoolbar,selectReleaseforARMarchitectureandDeviceoptions,thenclickBuild,DeploySolutiontobuildandinstalltheReleaseversion

YoucanuseyourC#programmingskillstobuildappsforAndroidandiOSwithVisualStudioandXamarin.Discovermoreonlineatxamarin.com

Summary• TheUniversalWindowsPlatform(UWP)enablesasingleapptorunonanymodern

Windows-baseddevice.

• TheeXtensibleApplicationMarkupLanguage(XAML)isusedtospecifycomponentsandlayoutonUWPapps.

• TheUniversalWindowsAppDevelopmentToolsareneededinordertodevelopUWPapps.

• TheBlankApp(UniversalWindows)templatecanbeusedtocreateanewUWPproject.

• VisualStudioprovidesagraphicalDesignviewandatextcodeXAMLviewfortheMainPage.xamlfile.

• ComponentelementscanbeplacedwithinXAML<StackPanel>elementstoarrangetheirorientation.

• ImagefilescanbeaddedtotheAssetsfolderandassignedtoXAML<Image>elementsfordisplayontheinterface.

• SpacecanbeaddedaroundacomponentbyaddingaMarginattributeandassignedvaluewithinitselementtag.

• FunctionalC#programmingcodecanbeaddedtotheMainPage.xaml.cscode-behindpage.

• TheDeveloperModesettingmustbeenabledintheWindows10optionsinordertodevelopandtestUWPapps.

• AUWPappcanbetestedinDebugmodeontheLocalMachine,aMobileEmulator,andaconnectedDevice.

• TheinterfaceofaUWPappcanadapttodifferentscreensizesbychangingtheorientationof<StackPanel>elements.

• ImagefilescanbeaddedtotheAssetsfolderforassignmentaslogosinthePackage.appmanifestwindow.

• TheReleaseversioncanbedeployedbyselectingthetargetconfiguration,thenusingtheBuild,DeploySolutionmenu.