navigate site menu

Start learning with our library of video tutorials taught by experts. Get started

C# Essential Training
Mark Todd

C# Essential Training

with Joe Marini

 


Take a tour of the foundational programming language at the heart of several Microsoft platforms, including Windows, ASP.NET, Silverlight, SharePoint, and Windows Phone, with author Joe Marini. Joe walks through the basic syntax and structure of the language, introduces object-oriented concepts, and shows how to define custom classes. The course also demonstrates using C# language features, compiling and running code, handling exceptions, reading and writing files, and addressing common compilation issues through debugging.
Topics include:
  • Installing the Visual Studio C# Express IDE
  • Creating a C# application
  • Reading and writing from and to the console
  • Writing conditional statements
  • Using loops
  • Exploring operators, expressions, constants, and enumerations
  • Understanding data types and type conversion
  • Working with variables such as numbers, characters, and strings
  • Defining classes and properties
  • Working with data structures such as arrays, stacks, and queues
  • Building abstract classes and methods
  • Handling, creating, and re-throwing exceptions
  • Setting breakpoints and examining code

show more

author
Joe Marini
subject
Developer, Desktop Apps, Programming Languages
software
Visual Studio 2010, C#
level
Beginner
duration
6h 44m
released
Sep 16, 2011

Share this course

Ready to join? get started


Keep up with news, tips, and latest courses.

submit Course details submit clicked more info

Please wait...

Search the closed captioning text for this course by entering the keyword you’d like to search, or browse the closed captioning text by selecting the chapter name below and choosing the video title you’d like to review.



Introduction
Welcome
00:04Hi! I am Joe Marini, and I'd like to welcome you to C# Essential Training.
00:08I've been working with C# since its initial release back in 2001.
00:12C# is a great choice for applications that run on a wide variety of
00:17Microsoft platforms.
00:18We will start off with the basics:
00:20installing the free C# development tools from Microsoft, understanding the basic
00:25structure of a C# program, and getting your first program up and running.
00:30Then we'll move on to more advanced concepts, like defining your own C# classes.
00:35I will also cover subjects like automatic memory management and reading and
00:39writing data files, and we'll see how to do all of this while using the free
00:44Visual C# Express development tools to build and debug your C# applications.
00:50So if you're ready to take a look at the foundation language for targeting
00:53Microsoft platforms then let's get started with C# Essential Training.
Collapse this transcript
What you should know
00:00In this course, I am going to make a couple of assumptions.
00:03First, I am going to assume you have some experience working with
00:06Windows-based computers.
00:08Second, I'm going to assume that you have some amount of prior programming
00:12experience--not necessarily a lot of experience, and I don't expect that you've
00:16ever even seen C# before.
00:19But you do need to at least know what things like variables, functions,
00:23loops, et cetera, are.
00:24These are the basic fundamentals of any programming language, not just C#.
00:29Just to be clear, this course is not an introduction to the fundamentals of programming.
00:33What we are going to be focusing on are the fundamentals of the C# language itself.
00:39Along the way, we will do some work with the .NET framework, which is
00:42Microsoft's runtime and class library that C# uses to build and run programs,
00:47but we will mainly focus on learning the C# language.
00:51If you already know a programming language, like C or Java or Objective-C or
00:57JavaScript, then many of the C# constructs will look very familiar to you,
01:02but don't be fooled;
01:02C# is its own language with its own way of doing some things some of which are
01:07different from all the other languages out there.
01:10Of course, if you're coming from a very different language, like Ruby or Python
01:15or Perl, that's fine too;
01:17you won't have any problem following along with this course.
Collapse this transcript
Using the exercise files
00:00If you are a Premium member of the lynda.com Online Training Library, or if
00:04you're watching this tutorial on a DVD-ROM, you have access to the exercise
00:09files used throughout this title.
00:11If you look inside the exercise files, you'll find folders that contain all the
00:16various exercises that I'm going to use in this title.
00:19The way that they're organized is, each one of the chapters has its own set of example files.
00:24So for example, if I look inside the folder for Chapter 5, you will notice that
00:28there are bunch of subfolders that are named according to the particular section
00:32that's being described in that particular chapter.
00:35If you look inside these folders, you will notice that there is a C# Express
00:40project file, along with a folder that contains the code for that exercise.
00:45When you have installed the Visual C# Express developer tools from Microsoft,
00:50you'll be able to just simply double- click on the name of the project file,
00:54which will then bring up the coding environment and the code that's in that file,
00:59and you can start working right away on it.
01:01Let me take a look back in the Exercise Files folder. You'll also notice that
01:06there is a FinishedExamples folder.
01:09In this folder, you will see the same folder structure, but what I've done here
01:13is finished off each one of these examples in the finished state.
01:17So here in the upper part of the folder, these are all the examples in the start state.
01:22These are so that you can follow along with me as you take the course.
01:25If you would rather just jump ahead and see how a finished example works, you
01:28can go inside the FinishedExamples files folder and then just choose which
01:32chapter you want to the finished example for and then go ahead and examine that code.
01:36The last thing I want to point out is that I have included a file here
01:39called ExampleSnippets.
01:41If we open this text file up, you will notice that this is just a collection of
01:45code snippets that I'm going to use in each one of these examples throughout the
01:49title, and I have organized them in various chapters.
01:52Here are the snippets for Chapter 3,
01:54here are the snippets for Chapter 4, and so on.
01:57This is so you don't have to sit and watch me type each example out.
02:01I'm going to just simply copy and paste the code that's in these snippets files.
02:05Now if you're a Monthly member or Annual number of lynda.com, you don't have
02:10access to the exercise files, but you will have access to this ExampleSnippets
02:13file because it will be made available as a free download.
02:16So you can either follow along from scratch with your own assets, or you can use the snippets.
02:21Let's go ahead and get started.
Collapse this transcript
1. Getting Started with C#
Installing the Visual C# Express IDE
00:00Okay, so we are ready to start writing our C# code, but before we can do that,
00:03we have to go get our development environment.
00:05So to do that, we are going to go to the Microsoft web site and download the C#
00:10Express development environment. So let's do that and go to the browser.
00:13In the browser, I am going to type in microsoft.com/express.
00:19This will take me to the download page for the various versions of Express
00:25products that Microsoft makes available for free.
00:27And this page might look a little bit different for you when you get here, but
00:31there should be a link to download the Express products for Visual Studio, and
00:36that's this link right here that says, "Get free Visual Studio Express products."
00:39So I am going to click on that.
00:40This will take me to a download page for all of the Visual Studio Express products.
00:46And as I scroll down the list, you can see that there's one for Windows Phone.
00:49There's Visual Web Developer. And I am just going to scroll down until I get to
00:52this link right here, and that is Visual C# 2010 Express.
00:57And again, when you get here, this may be newer. The point, though, is that
01:00you want to get the most recent version of the Visual C# Express IDE.
01:04So I am going to click on that link.
01:06This will take me to the download page for that particular version of Visual C# Express.
01:11So I can click on the Install Now link.
01:14Now depending on what browser you're using, you're going to be prompted to
01:17download and run the installer, and you can see here in IE I have got this
01:21little download bar, but this is going to look different for you if you're using
01:24a different browser.
01:25Now I have already done this.
01:27So once you have run the installer and Visual C# Express is installed, you will
01:32find it in your Programs menu.
01:34So if I go to the Start menu, you will see I have got Microsoft Visual C# 2010
01:39Express, or something like it for you. And I am going to go ahead and click on the
01:42link to make sure it's installed correctly. And you can see that Visual C#
01:46Express fires up, and it looks like we are ready to go.
01:48Now there is one other thing I wan to show you before we actually get started
01:51writing some code, and that is the Microsoft Developer Network Library.
01:54So let's jump back to the browser and head over there.
01:57So back here in the browser, I am going to make a new tab, and I am going to
02:00type msdn.microsoft.com.
02:04This is the online library for the Microsoft Developer Network, and it contains
02:09all the documentation that you'll need to build your C# and .NET programs.
02:15And you can see when I come here it's placed me on one of these four categories.
02:18In this case it's Tasks.
02:20Let me click on the Platforms link.
02:21And under Platforms, you can see that there are categories for desktop and web
02:26and cloud and phone. And if we scroll down a little bit, there is a whole bunch
02:30of content on here that's focused on building applications for the various
02:34Microsoft platforms.
02:35Let's scroll back up.
02:36I am going to click on Tasks again.
02:39You can see it takes me to a different pivot on the information here in the MSDN Library.
02:44There is a section for creating code.
02:46There is a section for testing.
02:47There is a section for understanding code.
02:49Let's go ahead and click on one of these links for understanding code.
02:51You can see here, as I scroll down, there is a whole bunch of overview material
02:55for understanding how to build .NET applications using a variety of languages.
03:00We are going to be referring back to the MSDN Library throughout the course to
03:04see documentation for the various kinds of code and objects we will be using.
03:08In fact, if I click on the Library link up here, the Library link takes me
03:12directly to the documentation for the various parts of C# and .NET. And you
03:18can see over here under the MSDN Library section, there is links for all kinds of categories:
03:23Development tools and Languages, .NET Development, and so on.
03:26This is the web site that we will be referring to for Microsoft's canonical
03:30documentation for various parts of C#.
03:33Okay, so now that we have got the IDE installed and we know MSDN is, we are
03:37ready to start building our first C# application.
Collapse this transcript
Creating your first C# application
00:00Now that we have got the IDE installed and we've seen MSDN,
00:04let's go ahead and fire up C# Express and build our first application.
00:09So I am going to go ahead and launch C# Express. And when C# Express comes up,
00:17you will see a start page and the application window frame.
00:22So this right here is the start page. Over here is something called the Solution
00:25Explorer, and we will look at that a little bit later.
00:27What I am going to do, just really quickly, is get our feet wet by writing a C# application.
00:33I don't expect that you're going to understand everything that I'm going to show you right
00:35away, but I know you're probably anxious to get started.
00:38So let's just go ahead and build a simple application. And once we've done that,
00:41we'll take a quick look at how we did it, and then we will have an introduction
00:45to C# Express that explains the various parts of the program that we will be
00:48using throughout the course to build our applications.
00:52I am going to go ahead and click on the New Project link right here. And when I
00:56click on the New Project link, you'll notice that a dialog comes up asking me,
00:59well, what kind of application do you want to build?
01:01You can see there is a whole bunch of built-in ones that we can choose from:
01:05there is Windows Forms Applications, there is WPF, there is something called a
01:09Console Application, there's Class Library, and there is a whole bunch of other
01:12things that we can choose from.
01:14To keep things simple, we are going to build what's called a console application
01:17and you may have heard this referred to in the past as something like a command-
01:22line app, or something like that.
01:24The point here is that we are not going to be focusing too much on fancy user
01:28interface or anything like that.
01:29We are going to build console applications to keep us focused on the C# language.
01:34I could name it down here something else, but this is just an example.
01:37So let's go and click on Console Application, and you can see that C# Express has
01:43created a sample application for me.
01:46It's opened up a file here called Program.cs--that's this tab right over here.
01:51If we take a look now at the Solution Explorer, we can see the Solution Explorer
01:54has now been filled out with a bunch of things:
01:57There is the name of the application that we are building right here.
01:59There is a couple of folders called Properties and References, and we will see
02:02those in depth a little bit later.
02:04And then this file right here called Program.cs.
02:07Program.cs is the C# file that contains the code for our program, and it happens
02:12to be opened in the window right here.
02:14I am going to go ahead and just type a couple of things, and again, I don't
02:18expect you to know this right away, but just follow along with me.
02:22Inside the function for Main, I am going to type Console.WriteLine.
02:31It's a bit of a tradition in programming courses that the first application you
02:36write basically does nothing more than print "Hello World" out to whatever output
02:40device you're using,
02:41so I am going to type in here "Hello World," and I am going to save it.
02:49Now what I am going to do is run it, and I can run it a couple of different ways.
02:53What I am going to do is go up to the Debug menu.
02:56You can see that I have got an option here for Start Debugging and I have got
03:00something called Build Solution.
03:01I will just quickly choose Build Solution to make sure that everything is right,
03:06and you can see down here in the status bar there is a little piece of text
03:08that says, "Build succeeded."
03:10So everything looks okay.
03:12Now I am going to run it.
03:13And instead of going back to the Debug menu, I am going to click on this little
03:16green arrow right here that says Start Debugging.
03:18So I am going to click on that and you can see that some window came up very
03:22quickly and went away, and that's because the Console Application came up, the
03:28text was written out, and then the program ended.
03:30The .NET Library said, "Oh, I guess we don't need the console window anymore.
03:33Might as well send it away."
03:34So to keep that from happening, I am going to add one more piece of code down
03:38here, Console.ReadLine, and now I am going to save that.
03:45Now this is going to have the console window wait for us to give it a line of text.
03:49This is just a way for me to keep the console window from going away as I show
03:54how this program works.
03:55So let's try it one more time.
03:56Let's go ahead and click on Run. All right!
03:59You can see that the console window comes up, the words "Hello World" got printed
04:03out, and now it's waiting for me to give it a line of input, and it's going to sit
04:07there until I do that.
04:08You can see in the background the UI for C# Express has changed somewhat.
04:14The Program.cs window has been expanded, and we've got these two other windows
04:18down here called Locals and Call Stack-- and we'll get into this later on when
04:22we look at debugging.
04:23This is C#'s way of showing me what the program is doing while it's running.
04:27So let's bring this back up here, and you can see now that when I give it a line
04:31of text and the ReadLine function completes, the Console window goes away and C#
04:36Express goes back to the state where it first launched.
04:40That's how we build our first C# program and to get further into the course, we
04:44will explain how all of these things work.
Collapse this transcript
Introduction to Visual C# Express
00:00Since we're going to be spending a lot of time using C# Express to build our
00:03applications, we should probably take a few moments and get familiar with the
00:06IDE and see how it works.
00:08So I'm going to go ahead and launch the C# 2010 Express,
00:14and you'll see that when the application comes up, it's a very simple UI.
00:17There's the start page right here on the left-hand side,
00:20and then over here there's something called the Solution Explorer.
00:24A couple things you need to know about C# right upfront.
00:26C# Express organizes everything into projects.
00:31Projects are what applications are made from.
00:33And you might sometimes hear the word project interspersed or interchanged
00:37with the word solution.
00:39That's not completely true.
00:40Solutions are basically top-level projects that can contain other projects.
00:45When we build a project, it will appear in the Solution Explorer here on the
00:49right-hand side of the screen.
00:51So let's go ahead and create a new project,
00:54and we can do that one of two ways:
00:55we can click on the New Project link here in start page, or we can go up to the
01:01File menu and choose New Project.
01:03So I'm going to choose New Project,
01:06and the New Project dialog launches and we can choose what kind of project we want to build.
01:11Throughout this course we'll be working with console applications, because
01:15it gets the user interface out of the way and just let's us concentrate on the language.
01:19So I'm going to go ahead and click on the Console Application to select it.
01:23If it's not already done so, you should do the same thing.
01:25Down here in the bottom of the dialog, there is a place where we can enter the
01:29name of the project.
01:31And I'll just type in something;
01:32I'll just call it MyProject.
01:34And I'm going to click the OK button.
01:37This is going to create the project for us. All right!
01:41Now that we have the project built, let's take a look at C# Express and see
01:46what's going on here in the UI.
01:48So over here in the Solution Explorer you'll notice that the window has been
01:52filled out with some information, and we will get back to that in just a moment.
01:56The project code is over here opened in the editor.
02:00And the new project isn't actually saved yet.
02:02It is fully functional. You can go ahead and run it. You can edit it.
02:05You can do all kinds of things.
02:06But it's sitting out in temporary space right now.
02:09If we wanted to actually put all this work onto disk, we would go the File menu
02:13and we would choose Save MyProject or Save All.
02:17And when I choose Save All, you'll see that I get a dialog that says hey, here's the name.
02:21Here's where it's going to be saved.
02:22Here's what the solution name is.
02:24I have the option to create a directory for the solution.
02:26And at this point I can choose to name it something else if I don't like the
02:30name that I originally came up with.
02:32And I'm just going to go ahead and choose Save.
02:35That will put the project on disk for me in the Documents folder, or whatever
02:39path I selected in the Save dialog.
02:42Let's go ahead and take a look at the project files over here in the Solution Explorer.
02:46You'll see that underneath the top-level MyProject heading there are a couple of folders.
02:51There's the Properties folder and References.
02:53Let's go ahead and expand those.
02:56Underneath Properties there's a file called AssemblyInfo.cs.
03:00Now I'm just going to quickly open this up so you can see what's inside it.
03:02We won't be going through this in this course, because this is a little bit of
03:05advanced information.
03:06But this is the information that C# Express will save, along with your
03:10application, that describes to the .NET Framework what the application is, how
03:14it works, various pieces of information that .NET needs to know about the
03:18program in order to run it.
03:20So let me go ahead and close that.
03:22Under the References folder you'll see a whole bunch of things, like Microsoft
03:25and System and so on.
03:27These are the actual .NET Framework libraries that get associated with your
03:31project when you make a new one.
03:33These will change based upon what kind of project you're creating.
03:37In this case, we've built a console application, so these are the .NET libraries
03:41that the console application needs to run.
03:44Some of them are optional; some of them are not.
03:46The .NET Framework just goes ahead and includes them in case you need to use them later.
03:51So let's go ahead and close those folders up.
03:53The Program.cs file,
03:55this is the default file that gets created, along with your application, that
03:59contains your main code for the application.
04:02And you can choose to add new C# files as you go along, depending on how complex
04:06your application is.
04:07We're not going to do that right now.
04:09Let's just take a trip through the user interface of C# Express, so we can see how it works.
04:14I've already shown you the File menu.
04:16That's up over here.
04:17This is where we create projects and save things.
04:19Pretty standard file-menu stuff.
04:21Let's move over to the View menu.
04:23In the View menu, you'll see it's pretty simple.
04:25I can choose to view the start page again.
04:27There's other windows that we'll be looking at.
04:29I'll just go ahead and choose one right now.
04:31This one is the Error List.
04:32This window down here shows you if there are any errors or warnings or
04:36anything else in your code.
04:37And we'll get back to that later, so let's go ahead and close that.
04:40Also under the menu, there are toolbars, and you can see that I've got
04:43some toolbars showing.
04:45The Project menu is where we control what's in our project.
04:48So we can add items to the project, we can add references, and so on.
04:52We're not going to do that right now, but we'll probably do it later.
04:54Under the Debug menu, this is how we run the application in order to test it out.
04:59We can also build our solution right here.
05:02This will build the program without actually running it.
05:04I'm going to skip over the Data menu and go to Tools.
05:08Under the Tools menu, I'm going to show you a couple of things.
05:10First, under Settings, there's a couple of ways that you can use C# Express.
05:14There's Basic Settings and there's Expert Settings.
05:17I've left it on Basic Settings right now because we are not going to be using
05:20any of the Expert Settings for now in our application.
05:23What I'm going to do, though, is show you under Options.
05:25Now under the Options dialog, there are a couple things I've changed that
05:29you might want to change along with me to make some of the examples a little
05:32bit easy to follow.
05:33You can see that under Fonts and Colors I've changed the Size and the Font to
05:37make things readable.
05:38Now there's a check box down here that says Show all settings.
05:42So I'm going to check that for a moment.
05:44You can see that when I do that, a whole bunch of other settings show up.
05:46What I'm going to do is, under Text Editor, I'm going to choose C#.
05:51And you can see that there's an option under Display for Line numbers.
05:54Now that's not there if I turn off the Show all settings function.
05:58So turn on Show all settings and then go down to the C# option here and check
06:04the Line numbers option to show line numbers in your code. Click OK.
06:09And that pretty much completes our tour through the UI for using C# Express.
06:14We'll see more of this as we go throughout the course,
06:17but for now that should be a nice overview introduction to the application
06:20and how it works.
Collapse this transcript
2. C# Language Fundamentals
Overview of the C# language
00:00C# is a language that was built by Microsoft for working with Microsoft's .NET
00:06application platforms.
00:08It is a language that's very similar to other languages you may have seen, such
00:12as JavaScript or Java or C, C++, Objective-C.
00:17If you've used any of these languages in the past, you're going to feel right at
00:21home pretty much in C#.
00:23Syntactically, the language is very similar.
00:26C# is what's called a managed-code environment.
00:29Memory management is automatic.
00:32So if you've worked with other languages, like C or Objective-C, then you've
00:37probably come across situations where you have to create and destroy objects on your own.
00:43C# does all of that for you.
00:45When you create an object, the C# interpreter, or compiler, actually takes care of
00:50making sure that that memory is returned to the system at some point, and you
00:54don't have to worry about it.
00:55C# is a compiled language.
00:58Unlike some other languages you may be familiar with, like JavaScript or Perl,
01:01you must first build a C# program before you can run it,
01:05and this step is called compiling the application.
01:09JavaScript and Perl are interpretive languages.
01:12In other words, the execution engine-- in the case of JavaScript, for example,
01:16that would be the browser--actually interprets the language line by line, as it
01:20goes through the program and runs it as it discovers new statements and other
01:25things in the language.
01:26C# isn't like that.
01:27In C#, you write your code, then you have to go through the compilation step,
01:31and then you can run the application.
01:34Now at its heart, C# is an object-oriented programming language.
01:38In C# pretty much almost everything can be treated as an object.
01:42I've underlined the word "almost" there, because there are a couple of esoteric
01:46cases where not everything is an object.
01:48But for our purposes in this course, you can pretty much think that everything
01:52in C# is an object and can be treated that way.
01:56In fact, in C# there are no global functions or variables;
01:59everything is in classes.
02:01And that might be different from other languages you might be familiar with, like
02:04JavaScript or like C. But in C# everything has to be inside of a class, and
02:09we'll come across that as we go further into the language.
02:12Now as I mentioned earlier, C# is a foundation for working with many different
02:17Microsoft platform technologies.
02:20At the bottom of the stack is something called the Common Language Runtime.
02:24This is the execution engine, or virtual machine, or whatever you want to call it,
02:28that actually interprets all the various bytes that the program gets compiled
02:33down to and is what runs your code.
02:36On top of that are the Microsoft .NET Framework Libraries.
02:40This is the code that is provided to you by .NET that performs a whole bunch of
02:45common things that applications have to do, such as reading and writing from
02:48files, working with the web, and all that kind of stuff.
02:51That's all contained in the .NET Framework Libraries.
02:55On top of that is the C# language, which we will be working with today.
02:59But the thing about .NET is that it was designed to work with lots of languages.
03:03There are other languages like VB.NET, such as Visual Basic, or Python, and so on.
03:08But we're not going to concentrate on those;
03:09we're going to be using C# throughout this course.
03:12What this allows you to do is use one language to target many
03:16different platforms.
03:17So using C# and .NET, you can build applications that will run on Windows,
03:22Windows Phone, Silverlight, SharePoint, ASP.NET, Xbox, and a whole bunch of others.
03:29So just by learning this one language, you can build applications that run in
03:32many, many different places.
03:34C# got its start way back in 2001.
03:38This was when Microsoft released the first version of .NET--that was .NET 1.0.
03:43That was where C# burst on to the scene, and it continued along for a couple
03:48of happy years, until 2003 came along, which was when Microsoft released .NET version 1.1,
03:54and that was when C# 1.2 was released.
03:57Not a whole lot of different changes between the initial C# release and 1.2--
04:01a couple of cleaning up things they did in the language.
04:03But 2005 was when things began to get interesting.
04:06That was when .NET 2.0 came out.
04:08And .NET 2.0 introduced some neat little things into C#,
04:13things like generics and anonymous methods and iterators and nullable types.
04:17Some of these things are advanced and we won't be covering them in this course,
04:21but we will be looking at things like nullable types a little bit later on.
04:24In 2007, that was when .NET 3.0 was released.
04:28And in .NET 3.0 along came C# 3.0, which introduced concepts such as object
04:34initializers, anonymous types, and so on.
04:37Again, some of these are advanced, like lambda expressions--
04:40we won't be looking at those--but we will be using things like object
04:43initializers later on.
04:44And then that brings us to 2010, which was when the .NET 4.0 Framework was released,
04:50and along came C# 4.0, with things like dynamic binding and named and
04:55optional arguments.
04:56And we'll be again--as you may have detected by now, a bit of a pattern--
05:00we will be looking at some of those later on in the course.
05:03Now as I mentioned earlier, C# is a compiled language, and that means a couple of things.
05:08In C#, you have to declare your variables before you use them.
05:12There's no way around this.
05:14You have to actually say here's the variable I'm going to use and I have to
05:17say what type it is.
05:18Now if you're used to a language like JavaScript, you simply use the keyword var
05:22to declare a variable in JavaScript.
05:24And you can also do that in the newer versions of C#.
05:28But we're not going to be doing that now;
05:29we're going to see how typing actually works.
05:31So when you declare a variable, you have to supply a type and supply a name.
05:36So, for example, I would say int myCounter or string message.
05:40In this case, myCounter is an integer variable for integer numbers and the
05:45message variable is a string.
05:47The reason you have to do this is because it helps the C# compiler optimize the
05:51program for knowing what kinds of data it's going to work with.
05:54It doesn't have to figure it out on the fly.
05:56You can also initialize variables when you first declare them.
06:00I could've written, for example, "int myCounter = 200," or "string message = "Hello World!""
06:07And this assigns an initial value to the variable when it is declared.
06:12The other thing you need to know about C# is the concept of namespaces.
06:16Again, other languages have something like this.
06:19In Java you may have seen something like packages.
06:22JavaScript doesn't really have something like this.
06:25There are some efforts to kind of fake it up using things called modules.
06:29But a namespace is basically just a way to organize a bunch of information into classes,
06:36and .NET uses namespace to organize all the classes that it provides for you.
06:41Essentially, it's a way of naming related classes and other namespaces within the
06:46namespace such that you can group them together into logical formations that
06:50make sense for various pieces of functionality.
06:53And to take an example, .NET provides a namespace called System, which we will
06:58be using a lot in this course.
07:00And inside System, there will be classes, so just Console and Environment
07:04and Math, and so on.
07:05So each of those little boxes there represents classes and the keyword System
07:09represents the namespace.
07:11And in fact, you and your applications can create their own namespaces, and
07:15we'll see that a little bit later in the course when we start creating our own applications.
07:18But this is an important concept to understand.
07:20C# and .NET in general uses namespaces to organize classes.
07:25And this is how applications get organized and it makes things a lot easier when
07:29you're writing your code in C#.
Collapse this transcript
Understanding the structure of a C# program
00:00Let's take a look at the basic structure of a C# program.
00:04Now, I've gone and fired up the C# Express development tool.
00:07I'm going to create a new project by clicking the New Project link here on
00:11the left-hand side.
00:13The New Project dialog comes up.
00:14Throughout this course, we're going to be using console applications to build
00:19our examples, because they are one of the simplest applications to create and
00:23they allow us to focus on just the C# language without having to worry about all
00:28the user-interface-related code that other projects require.
00:32I'm going to select the Console Application option, and I'm going to give it a name.
00:36I'll just call this one StructureCSharp, and I'm going to click OK.
00:45At this point, C# Express will create a new project and open it for me, and it
00:50will drop me in the editor, into a file called Program.cs.
00:53C# code is stored in files that have the .CS file extension. And right now, we
00:59only have one of these, but your application can use as many of these files as you like.
01:04And in fact, as you build your programs, you'll probably create many different
01:09.CS files to group related classes and pieces of your code, together rather than
01:14just type thousands of lines into one file.
01:16For now we've only got one, so let's go through this file line by line.
01:21Right at the top here we have a bunch of using statements.
01:26These statements tell the C# compiler which pieces of the .NET Framework that my
01:31project will be using, and they allow me to write my code using a bit of a
01:36shorthand notation that we'll see more of in a few minutes.
01:41Now, if you're familiar with other languages, like, say, Java or C or C++, these
01:48using statements are sort of analogous to things like import statements or
01:54include statements, and so on.
01:56But in C#, we use the using statement to indicate which pieces of the .NET
02:01namespaces I'm using in my program.
02:04The next line down is the namespace declaration for this project.
02:09That's here on line 6.
02:10Now, I mentioned earlier that C# uses something called namespaces to organize
02:15code into related groups, or modules, and your program is no different.
02:20Namespaces are basically just an organizational tool.
02:24They keep related code together, and they prevent certain kinds of problems.
02:29For example, if your program were to define a class that has the same name as a
02:34class in some other .NET library, either from Microsoft or some other third
02:39party, your program's namespace would keep those two classes from colliding with
02:44each other and causing a whole bunch of compile problems.
02:47Now, the C# editor creates the namespace for you when you create your project,
02:52and it defaults to the name of the project, and we're just going to leave this as it is now.
02:57Next, we have something called a class definition.
03:00You can see that here on line 8.
03:02It's the keyword "class" followed here by the word "Program."
03:07Again, I mentioned earlier that in C#, almost everything is an object, and
03:10again, your program is no exception.
03:12In C#, the way that you define and create objects is by using the "class" keyword,
03:18which we'll see more of later in the course.
03:20And again, we're just going to leave this as it is for now.
03:24Inside the class definition is the most important part of our C# program, the Main function.
03:30You can see that here on line 10.
03:32Now if you're already familiar with languages like C, Java, Objective-C, and so
03:37on, then this will look familiar to you.
03:40If not, let me explain.
03:41When .NET goes to run your C# program, it needs to know where to start.
03:46The Main function is that starting point.
03:49It doesn't matter how many functions or lines of code your application contains;
03:53somewhere in your program .NET expects to find one special function called Main,
03:58and that's where it begins running your program.
04:01It has to be written as you see it here.
04:03It needs to be called Main, and the first letter must be uppercase because C# is
04:08a case-sensitive language.
04:10Case does matter here, because if you try to ignore case in C#, whether it's
04:14for function names or variable names or anything else, you are in for a bunch of problems.
04:19Now, it's important to note that not all C# project types have a Main function,
04:25for example ASP.NET pages, but many of them do.
04:29This isn't something that you'll ever have to worry about though, because when
04:32you're using the visual C# programming tools to create projects, it will create
04:37the Main function for you if it's needed.
04:40Don't worry for now what the words "static" or "void" mean, or the stuff that's
04:45inside the parentheses;
04:47we're going to cover those later.
04:49Let's take a look at some of the syntax rules of C#.
04:51Now first, notice these curly braces on line 7, and 9, 11, 12, 13, and 14.
04:59These braces are used to group related lines of code together in what are called
05:05statement blocks of code.
05:06You can see that they come in pairs.
05:08There's an opening brace and there's a closing brace, and they must match up.
05:12Now, they define starting and ending points for things like functions and
05:17classes and loops, all of which we will see later in the course.
05:22If you have experience in languages like JavaScript or C or Java, then
05:26you've seen these before.
05:27And if not, then all you need to know is that they group lines of code together.
05:32Now, you'll notice that the Main function is empty, and that's okay, because
05:35technically, this is a complete C# program.
05:38But let's look at some basic examples of C# statement syntax.
05:43To declare a variable, I need to specify a type and a name.
05:48So for example, I can type "int" and then "myVariable."
05:54This is different from languages like JavaScript where you don't need to specify
05:59a type for your variable.
06:01Now note, also, that every statement in C# must end with a semicolon, as I've done here.
06:08Some other languages, like JavaScript for example, don't require this, but C# does.
06:13Every time you type a statement, whether it's a variable declaration or you
06:16call a function or any kind of statement that you write in the code, it has to end with a semicolon.
06:23That's a really great practice because it really makes it clear where statements end.
06:28Now, in C#, I can use some of the built-in .NET objects, since I've included
06:33them in those namespaces using the using statements--for example, the Console object.
06:39So let me just show you a quick example.
06:41I'm going to start typing the word "Console," and you can see that as I'm typing,
06:45the Visual C# Express development tool is helping me out here by trying to guess
06:50what it is I'm going to type, and you can see it's centered on the word "Console"
06:53there in the little pop-up.
06:54So if I hit Return, it'll put the word "Console" for me.
06:58Console is one of the built-in objects in .NET when you're using
07:02console applications.
07:03For example, to write something out to the console, I can use the WriteLine
07:07function. So I'm going to type dot, and once again that little code hinter comes
07:12up, and I'm going to start using word Write.
07:14You can see that it zeros in on some of the functions available to me.
07:19I'll just choose the WriteLine function.
07:23I will just simply write out something like this.
07:26Once again, notice that I've got a semicolon at the end of my statement.
07:30The other thing that you should notice is that in C#, strings are contained
07:35within two double quotes.
07:37We'll cover a lot of this a little bit later in the course.
07:39But if you're coming from languages where strings can be specified using either
07:43single or double quotes, that's not the case in C#;
07:46you have to use double quotes.
07:46Now, notice how the word Console is in light blue.
07:50That's because the Compiler notices that I'm using a built-in object in C#.
07:55The Console object is contained within the System namespace.
07:59Watch what happens when I go up here and I comment out the using System
08:04statement up here on line 1.
08:05Notice now I've got a little red squiggle down here on my Console object.
08:11It says, "The name 'Console' does not exist in the current context," when I mouse over it.
08:16So now I've gone from being able to use this object to not being able to use this object.
08:21The reason for this is, when I commented out the System namespace, if I want to
08:25be able to use that object now, I have to write what's called a fully
08:28qualified path name.
08:30So I would have to write out "System.Console.WriteLine" if I wanted to use this
08:36now. And you can see that when I put the word "System" in front of the word
08:39"Console," now it goes back to being light blue because the compiler recognizes it again.
08:43So by using these using statements, I can write my code using shorthand, rather
08:49than having to write out these big, long, fully qualified paths to all the objects in .NET.
08:55So it makes writing your code a lot easier.
08:57So I'll go back up to the top here and uncomment that line.
09:03You notice even when I have it uncommented, I can leave it fully qualified if I want to.
09:07But now, I have the ability to take out that System statement and now Console
09:11goes back to being recognized.
09:14White space doesn't really matter in C#.
09:16Now, some languages consider the indentation level of lines of code to be
09:20important, but C# does not.
09:22You can put as much or as little white space in your program statements as you like.
09:27For example, I could put this statement all the way over here, and I can just
09:31put this statement all the way back over here.
09:33It doesn't really matter; this is all good.
09:35Obviously, there are places where white space is going to matter.
09:38So for example, inside of a string, if I do this, well, that's
09:41pretty significant.
09:42That's going to affect the way that that string is written out.
09:44But within lines of code, white space does not matter.
09:49So if you're coming from a language where white space matters, you don't have to
09:52worry about that here.
09:53Indentation in C# is just used for maintaining readability.
09:58So we've seen enough C# where we can now start writing our programs, and we can
10:02go on to the next part of the course.
Collapse this transcript
Compiling and running your code
00:00One last thing that we need to look at before we jump in and start writing our
00:04C# code and learning how to do all kinds of great things, like writing programs
00:08and using variables and objects and so on, and that is compiling and running the code.
00:14I realized I've done this a couple of times so far, but I want to get a little
00:17bit deeper into this.
00:18That way, as you're working through the course, you can see how the building
00:22process works and the various tools that you'll need for when errors happen in
00:27your code. And I say when and not if because errors are going to happen and you
00:31need to be prepared for that and to see how to recover from these situations and
00:35how to build your code correctly.
00:38So as I said earlier, C# is a compiled language.
00:41You have to compile it before you can run it, so we're going to cover some
00:45tips on how to do this.
00:47Now, the term for compiling and creating your finished application is "build."
00:52So let's just make a new project, and we're going to call it BuildAndRun and make
00:59sure it's a console application.
01:01I'm going to click OK.
01:03Now, what I'm going to do first is I'm going to click the Save All icon here.
01:09I can also just choose Save All from the menu here.
01:12I'm going to save this application in my Documents folder.
01:16Now, this folder will be different for you based upon the computer that you're
01:20using and where your Documents folder is, but I'm going to save it in the
01:23default location, which is the visual studio 2010/Projects folder, and we'll go
01:28out to the file system and see this in just a minute.
01:30But I'm going to save.
01:33Now that I've saved it, I've actually put the project onto a physical
01:38location on my disk.
01:39It's no longer sitting out there in temporary space.
01:42So recall that the way that we build that application is by using either F6, or
01:46up here in the Debug menu, we can choose Build Solution.
01:50So I'm going to choose Build Solution and you can see down here in the toolbar,
01:54there's a little message that says "Build succeeded."
01:57So let's go out to the file system and see where the application is actually built to.
02:03I'm here in my Documents folder, and you can see that there's a folder here
02:07called Visual Studio 2010.
02:09This might be slightly different based upon which version you're using.
02:12But I'm going to go into Visual Studio 2010.
02:15There's a folder called Projects.
02:17Here's the project that I just built called BuildAndRun.
02:20So let's take a look in there.
02:21You'll see that inside BuildAndRun, this is the solution, the top-level project
02:25for our code, and then there's a folder that goes along with it.
02:29And inside the folder, there's the Program.cs file.
02:32This is where our code is kept.
02:34This is the project file.
02:35There's also a folder in here called bin.
02:38bin is short for binary.
02:40This is where the application is kept.
02:42Inside there, there are two folders:
02:43there's Debug, and there's Release.
02:46If we look in the Debug folder, you'll see that there's some information here
02:50about the application's debug information.
02:53If we go into the Release folder, you'll see that there's a couple of things in here.
02:57First, there is BuildAndRun, and you can see that that's an application.
03:00This is the actual finished application that gets built when you create the
03:05application using Build inside the C# Express environment.
03:08So this is the finished application.
03:10That little PDB file is called the program database.
03:14It contains some information that .NET needs to use in order to debug and run
03:18the application that we've built.
03:20But for now, all you need to know is that when you build an application, this is
03:24where it actually gets placed.
03:25When you create a project and you save it in whatever folder you save it in, the
03:29C# IDE will build this subfolder structure for you.
03:34Let's go back to the IDE.
03:36Now, we're going to take a look at how we can build errors and warnings and fix
03:42things and so on like that.
03:43Here in my Main function, what I'm going to do is write some code.
03:48I'm going to say int myInt = 50.
03:55Don't worry too much about following along with this code.
03:58We're going to cover variables and stuff later.
04:00I'm going to make one more line.
04:08This is code that we've been working with in a couple of examples now. Let me save this.
04:14Now, I'm going to hit F6, and you can see that everything built just fine.
04:18However, you can see that there's a little squiggle here under myInt.
04:21What I'm going to do is go up to the View menu, and in Other Windows, I'm going
04:29to choose Error List.
04:31When I choose the Error List, you can see here that there is a warning, and the
04:35warning is that the variable myInt is assigned, but its value is never used.
04:40Warnings are not necessarily as bad as errors; your application will still run
04:44just fine without it.
04:46And just to show it to you, let me you put one more line of code in here.
04:54Now, when I press F5 to run the application, or if I choose this little
04:58triangle up here, or if I go to the Debug menu > Start Debugging--that's
05:03where I run the program; I'll just use F5--
05:06you can see that the program ran just fine, even though I had a warning there.
05:09But that's no excuse for having warnings.
05:12If you've got a warning somewhere in your code, you should really pay attention
05:15to it because the compiler is trying to tell you something.
05:18And in this case, the warning is a little bit benign.
05:19I just created a variable that I never used.
05:22But warnings can actually be pretty serious, and they usually indicate something
05:25is wrong with your code.
05:26So if you get warnings in your code, go look them up in the error list here and go fix them.
05:30The next thing I want to do is make an error.
05:34So what I'm going to is I'm going to remove the double quotes from the end
05:38of that line there.
05:40You can see that when I do that, I get a red squiggle which says that there's
05:44some kind of error going on.
05:45And if I try to hit F6, there's a whole bunch of build errors.
05:50You can see down in the error list,
05:53there are now three errors and the warning for the variable that I had before.
05:57You can see that the errors are hey!
05:59There's a new line in the constant. There is no semicolon.
06:01There is no closing parenthesis.
06:04All of these errors are occurring because I left off that closing quote.
06:08When you get an error like this and the error list pops up, you can just
06:11double-click on any one of these guys, and it will take you right to the line
06:15where the error occurs.
06:17Now, in this case to fix this, I just need to put the double quotes back.
06:21But if I don't do that and I leave it and I ignore these warnings and I try to
06:25run, by pressing F5, you'll see that there are build errors.
06:29And C# is telling me, hey!
06:30There were build errors, but if you like, you can continue and run the last time
06:35that this was successful.
06:36But I'm not going to do that.
06:37What I'm going to do is click No and I'm going to say, okay, let's go ahead and
06:40fix that problem, so I'll put the quotes back in.
06:42Now everything is fine.
06:45Once I press F5, you can see that the code is now working again.
06:49The next thing I want to do is see away that I can get more information about my build.
06:55Under the Tools menu, I'm going to switch over to Expert Settings.
07:00Don't be intimidated; this really isn't a very big deal.
07:03What I'm going to do is choose the View menu.
07:07I have the Error List still, but now I have a new window here under Expert
07:11mode called Output.
07:12You can see that when I choose it, there it is right there.
07:15So the Output window shows me a lot more detailed information about the
07:18build-and-run process.
07:20So, for example, if I now hit F6, you'll see that the output window is giving me
07:24a whole bunch of information about the files that got compiled, any warnings or
07:28errors that popped up.
07:29You can see that whether the build succeeded or not.
07:32You can see that where the output of the application was built.
07:36You can see that BuildAndRun.exe was placed in this path down here at the bottom.
07:40By using the Output window, you can get more information about where the build
07:44process is and what it's doing and what the results are.
07:48The last thing I want to do is show you how you can find out more
07:51properties about your project.
07:54Under the Project menu, I'm going to choose BuildAndRun Properties.
07:58This menu item will change based upon whatever your project is called.
08:02It'll be project name and then the word Properties here.
08:05When I choose this, I get a whole bunch of properties about what my program is
08:09and how it's being built.
08:11So here under the Application tab, I can see that this is what my Assembly name is.
08:16An assembly is basically just a generic term that says this is some physical
08:20piece of code on the disk somewhere and it's the name of my project.
08:23Same thing for the namespace.
08:25I can also see what target framework I'm going after.
08:28In this case, I'm using the .NET Framework 4.
08:31But if I click on this, you can see I can build my application to target other
08:34versions of the .NET Framework, all the way from 2.0 up through 3 and through 4,
08:39and there are other frameworks I can install as well.
08:42Under the Output type dropdown, this controls what kind of application I'm building.
08:46Now, it's currently set to be a console application, but I can change it to be a
08:49Windows app or a class library, and so on.
08:52The last thing I want to show you is under Build, there are ways that I can
08:57control how the application is built.
09:00We'll see a little bit of these later on, but I can change how the errors and
09:04warnings are reported.
09:05I can say what the warning level is and there are four warning levels, all the
09:09way up from very verbose down to not very detailed at all. So I can choose what
09:13warning level I want.
09:14I'm going to leave it on 4.
09:15I can also suppress individual warnings that I don't want to know about.
09:19Now, I don't suggest that you do this, because it's really good idea to know
09:23about all the warnings in your code, but it is possible to do this.
09:27You can also set a little preference over here that says Treat warnings as errors.
09:31I can say None or All or Specific warnings.
09:34If I changed this to All, for example, and then went back to my application,
09:40you can see that when I hit up 6, now the warning that was hey!
09:44The variable 'myInt' is assigned, but its value is never used, it's an error now.
09:48It's no longer a warning.
09:50So I'm going to go back and change that back to the way it was.
09:55Now, I'm going to hit F6, and you can see that we're back to being a warning.
10:00This is how you can control how your application is built, and it's how you get
10:04more information about the process by which Visual C# Express builds your
10:08application and runs it and fixes errors.
10:11Now that you know how applications are actually built, we can dive right in and
10:15start doing some more interesting stuff.
Collapse this transcript
3. Program Flow
Reading and writing from and to the Console
00:00So now that we've got the foundational stuff out of the way, we can dive in and
00:03start writing some real C# code. And what we're going to do in this particular
00:07example is see how to read information from, and write information to, the console window.
00:14And this is important to know how to do because for the rest of the course
00:17we're basically going to be building examples that use the console as the place
00:21where we write information to and read information from.
00:24So we need to get a fundamental understanding of how the console works in order to do that.
00:28So I've opened up, under Chapter 3, the HelloWorldProject in the example files
00:33folder. And if you don't have that, you can just simply create a new project and follow along.
00:38The other thing I've opened up is the ExampleSnippets.txt file, and this contains
00:44the code that I'm going to be copying and pasting from so that you don't have to
00:47sit there watch me type.
00:49So let's go back to the program. You can see that we have our HelloWorldProject,
00:54and down here in our Main function, this is where we're going to be filling the code in.
00:58So let's go ahead and do something really simple, which we've already done a
01:02couple of times, but just for refresher, let's write some information out to the console.
01:05So I'm going to copy this line right here that says Console.WriteLine. I'm going to paste that in.
01:12So the console object has a series of functions that read and write data, and the
01:17most common ones are WriteLine and ReadLine. And you can guess what they do.
01:21WriteLine writes out a string of text followed by a carriage return, which takes
01:26the cursor back to the new line.
01:28Now we could use Write which writes out the string and does not put a carriage
01:31return on there, but for readability, we'll just WriteLine. And then there is the
01:35ReadLine function which reads a string of text.
01:39In this case, I'm using it just to keep the console window up, so you can see
01:42the example working, but it will return a string if we want it to.
01:46So let's just go ahead and save this, build it--
01:49you see the Build succeeded--and run it, and no surprise, the string "Hello World!"
01:55gets written out to the console.
01:56So let's go ahead and make a couple of changes here.
01:59What I'm going to do now is go back to the Snippets, and this time we're going to
02:03read information from the console window and then write it out.
02:08So I'm going to copy these three lines, paste them in.
02:13So now what we're going to do is write out a string that says, "What is your name?"
02:18And then we're going to use the ReadLine function to read a string of data from
02:22the console and then write out a message that says, "Hello there" plus whatever
02:27name the person gave us.
02:28So you can see here that we've got a string variable that is being assigned to
02:32the result of the ReadLine function.
02:35Down here, we're just not using the result, which is why the window is
02:38staying up. But here we're actually going to read the result and use it in the next string.
02:43So I'm going to save, I'll build, and we'll run.
02:47You can see it says, "Hello World! What is your name?"
02:49And I'm going to type in "joe," hit Return and it says, "Why, hello there joe."
02:54Let's go take and look at the code and see why that works.
02:56You can see that the string variable here that gets returned from ReadLine
02:59contains my name, and then in the WriteLine statement we're writing out the
03:04string "Why, hello there" and then plus the string here.
03:09Writing strings out to the console window takes many forms.
03:12It's something that you'll probably do a bunch.
03:14And although you can use the plus operator, there is actually other ways
03:17to write strings out.
03:18So let's take a look at how those work.
03:21To build strings in C# for the purposes of displaying to the user or formatting
03:26them for output, there is a couple of ways you can do this.
03:28Now you've already seen the example where we use the plus operator.
03:31This is something that you're probably familiar with if you done this in JavaScript.
03:35It works in JavaScript and as you've seen,
03:36it works in C# too.
03:38However, it's not the most efficient way to build strings in C#, for
03:42reasons we'll see later on.
03:43There are other ways to format strings for display to the user, and the way that
03:48we do that is by using the String.Format method.
03:52And that method takes an argument, which is the string you want to write out
03:55along with data that you want to put into that string.
03:59So for example, if we wrote String.Format,
04:02"There are," and then some code that we'll get back to in a second, "seconds in a
04:07year" and then an argument, which is probably a number.
04:11The way that you format a string is by using those curly braces with an integer
04:15number in there that serves as a placeholder for data that's going to be
04:19inserted into the string for you.
04:21And as you might have guessed, if you had more than one piece of data you wanted
04:24to do this with, you would use more than one curly brace.
04:28So in this example, it says String.Format.
04:30There are something seconds in a year, and that little i is going to be
04:34substituted where the 0 is in those curly braces--and in fact, it
04:38substitutes entire thing.
04:39The curly braces and the 0 don't appear in the finished string;
04:42it gets substituted with the value of the data.
04:45If you had more than one, you'd simply use more than one curly brace, and you'd
04:48increment the number for each one of the variables.
04:51So in this case, if I had two arguments that I wanted to format into the string,
04:55I would simply supply those as arguments and use two sets of curly braces in the
04:59String.Format argument.
05:01So let's go back to the code and see how this works.
05:03So I want to go back to my Snippets, and I'm going to copy this line right here.
05:07Now I'll paste it in.
05:12So now we have a variable called mySeconds, which we are calculating.
05:15So there is 60 seconds in a minute, times 60 minutes in an hour, times 24
05:20hours in a day, times 365 days in a year, and that gives us the number of
05:25seconds in one year.
05:26So you can see here that we have our Console.WriteLine, and we have our string
05:31with the curly brace.
05:32Now notice we're not using the String.Format method, and that's because the
05:35WriteLine method of the console object knows how to use the String.Format method internally.
05:41So we pass it what is called a format string, which has this little escape
05:45sequence, or code sequence in it. And we're passing in the mySeconds variable and
05:50when we run this, if everything goes well, then we should have the number that's
05:53calculated inserted into the string.
05:55So let me go up here and just comment out the code that we're not using, and we'll save.
06:03This time I am also not going to use F6;
06:05I'm just going to hit F5, which builds the program for me and runs it.
06:11So I'm going to collapse two steps down to one and press F5 and you can see
06:16that the number of seconds in one year has been substituted where those curly
06:20braces were in the string.
06:22We were going to be using Console.WriteLine and Console.ReadLine to write and
06:27read information to the console throughout this course.
06:30And after following the example here, you can see how to do it for yourself.
Collapse this transcript
Writing conditional statements
00:00One of the things that any application has to be able to do is make decisions.
00:05Decisions are inescapable.
00:07They are an important part of pretty much any nontrivial program that
00:11you're ever going to make.
00:12Decisions are made when your program flow is chugging along nicely and suddenly
00:16you come into a situation where you have to make a decision, and there is also
00:19the decision of either true or false.
00:22And this is, of course, built in classical programming using the if statement.
00:26The if statement takes a Boolean condition and if that condition is true then
00:31the code that is inside the if statement is executed.
00:35Now, of course, there is a case for when the condition is not met, and that is the else case.
00:40If the condition is not met and you have an else case on your if statement,
00:43because they are after all optional, then the code for the condition where the
00:48condition is not met is run instead.
00:50In C# you can also have the else if statement, so we could replace that else
00:55with an else if on another condition.
00:57And in fact we can chain a bunch of these together to make a whole bunch of if,
01:01else if, else if, else if, and so on. And if you want, you can have a trailing
01:06else condition to handle everything else.
01:08So let's jump over the code and see this in action.
01:11Here in the code, I've opened up my ConditionalCode example file, and I've got my
01:16Program.cs code open.
01:18I've also got the ExampleSnippets file open right here. And I'm going to scroll
01:22down to the Conditional Statements section, because these are the statements
01:25that we're going to be using.
01:27So back over here in the code, let's put together an if statement and see how it works.
01:32So I'm going to copy these lines right here in my variable declaration, along
01:38with the if statement. I'll copy and we'll just paste that in.
01:44And you can see here that we have a variable, named theVal, which is initialized
01:48to be 50, and then we have an if statement, which tests the condition to see if
01:53(theVal == 50) then run some code.
01:57Notice that there is two equal signs in here.
02:00If I just tried to put one equal sign in here, I would get an error.
02:04You can see the little red squiggle shows up, and it says, hey, you can't do a
02:07conversion. And it's not important what that error means;
02:10the point is that you can't do that.
02:12So to test for equality it's two equal signs.
02:15One equal sign does assignment; two equal signs tests for equality.
02:20So if (theVal == 50) then we'll write out this data, so it's firstVar is 50.
02:27And actually, let me change that because it's misspelled. There we go; theVal is 50.
02:32So we'll save this, and we'll run it.
02:34I'll use F5 to do that. And you can see that "theVal is 50" is being written out.
02:40So let's go back to the code and change the value.
02:43Let's make it 51, and we'll save and run it again.
02:47And you can see this time nothing is being written out because the
02:50condition is not being met.
02:51Let's go back to the code.
02:53Let's change this back to 50.
02:54The other thing I want to point out on the if statement is you'll notice that
02:58I'm using these curly braces to contain the code that's being executed in the
03:02case of the if condition.
03:04If all you have is one line of code for your if condition, you actually can
03:09technically leave these braces out and that will work just fine.
03:13However, for the sake of readability, and because if statements are very rarely
03:19limited to one line, I always use the braces.
03:21I always put them in there. it's a good idea to do so.
03:24It helps readability of code.
03:25It helps keeping your statements together.
03:27So my suggestion is to always use the curly braces, even if you only have one line.
03:32Let's go back to the Snippets, and let's bring a couple of other lines in here now.
03:38We're going to try the else if condition this time.
03:42So I'll copy this, and we'll paste it in below the if.
03:46So now we have a condition that says if (theVal == 50) then write out this
03:50statement; otherwise else if it's 51, write out something else. And once again,
03:54I'll just change that.
03:56Okay, so let's run this.
03:57Okay, so you can see that the first condition is being met.
04:02Now let's change it to 51, save and run, using F5.
04:09And you can see that this time the else if condition ran, because the value was
04:1451 instead of the 50. So this time, this condition was executed instead.
04:18One more test to try.
04:20Let's go back and copy this code over.
04:23I'll now copy this and paste at the bottom of my else. And in this case, this
04:32code is going to run when none of the conditions are met.
04:36So we have if (theVal == 50), else if (theVal == 51), and the last else condition
04:41catches everything else.
04:43So let's just change this to, I don't know, something like 75.
04:46We'll save and hit F5.
04:49And you can see that in this case "theVal is something else" is being written
04:52out, because the last else condition is triggering because the value was not
04:56equal to 50 or not equal to 51.
04:58So none of these if conditions right here fired.
05:02You can have more than one condition in the if statement.
05:06So for example, if I wanted to have this if condition execute if theVal was
05:11equal to 50, or something else, I would simply put this one in parentheses,
05:17and then I would use the OR operator, which is the two vertical bars--and we'll learn
05:24about this a little bit later, but just bear with me for now.
05:27So if ((theVal == 50) or (theVal == 49)) then you can write out "theVal is 50 or 49."
05:39We'll save and now this if condition will execute if theVal is equal to one
05:45of those two numbers.
05:46So we'll change it to 49, hit F5, and you can see that the first if condition is
05:51now being set, so that code is executing.
05:55Let's go back. If we wanted to change it to AND instead of OR, I am going to
05:58just use two ampersands.
06:00Again, we'll learn about that in a little bit. But just for sake of example, I
06:03want to show you how this works.
06:05Now in this case, theVal is something else. Why?
06:08Because here theVal is 49, but for this entire condition right here to be
06:12true, both of those statements have to be true: theVal has to be 49 and theVal has to be 50.
06:19And since that's clearly impossible, that for statement is not going to execute.
06:23So you can see here that we're using if statements to create tests for
06:27conditions in our code, and we can chain a whole bunch of these things together
06:31using if, else if, and else. But if you find yourself running into situations
06:36where you have a lot of different conditions to test for, using the whole bunch
06:39of ifs and else ifs gets really hard to read and really hard to manage, and
06:44there's a structure for doing that which we'll take a look at in a little bit.
Collapse this transcript
Using the switch statement
00:00For cases where your code has to check a lot of different conditions in order to
00:05execute different parts of your code, it's usually not very efficient to have a
00:08whole lot of if and else if statements.
00:11It makes the code harder to read, and in that particular case
00:14it's usually better to use something called the switch statement.
00:17And the switch statement can be thought of as a whole bunch of if and else if
00:21statements, but with a slightly different way of writing it.
00:25The way you use a switch statement is you write the word "switch" and there is a
00:29value that you pass to the switch statement, and then inside the switch
00:34statement, you use a whole bunch of cases.
00:36So you have a case for some value, which will then run some code, and you have a
00:41break statement which says okay that's the end of this case. And then you can do
00:45this as many times as you need it.
00:46So you can have a case for a whole bunch of different values that all
00:49run different code.
00:50Now in the case where none of the values map to a particular case, you can
00:55have a default case, which will run some code, or do nothing--
00:59it's up to you. But the default case will be executed when none of the
01:03other values match.
01:04Now if you're coming from some other languages like C or Objective-C, for
01:08example, they let you do things like this.
01:10You can take that break statement out, in which case, when value1 or valueN are
01:16met, the code will run.
01:18And in the case of value1, the code for value1 will run as well as the code for
01:23valueN, because there is no break statement in there to stop it.
01:26Now, this is not legal in C#.
01:29In C#, every case has to have a break command at the end.
01:33Your code can't fall through to next case like in some other languages.
01:38And the reason for this is because the designers of C# did a whole bunch of
01:42studying of where bugs come from in programming logic.
01:45And it turns out that a lot of bugs can be traced back to developers mistakenly
01:49leaving out break statements in their switch cases when they probably shouldn't have.
01:54So the C# language enforces this.
01:56You have to have a break at the end of each one of your cases.
02:00There is ways to get around this, but they're kind of esoteric, and I'm not
02:02going to show you how to do them in this course, because they're not good
02:04programming practices.
02:05Just suffice it to say that you have to have a break at each one of your cases.
02:10So let's go ahead over to the code and see how a switch statement works.
02:12Here I have my SwitchStatement project open, and in my ExampleSnippets, I've
02:18scrolled down to my Switch area.
02:20So what I'm going to do is copy some code. I'll just copy the first part of the
02:25switch case here, and I'll paste it in, and I'll close off the switch right
02:32there, and I'll save.
02:33So in this case, what we're going to do is write some code that does pretty much
02:37the same thing that a whole bunch of if else statements would do, but using
02:41switch case instead.
02:43So here you can see I've got an integer variable called theVal, and it's being
02:47set to a value of 50. And then the switch statement says hey what's the value of
02:52theVal? And for case of 50, the Console will write line, The value is 50.
02:59So let's save this and run it, and you can see, sure enough, "The value is 50"
03:03is being written out.
03:04So if we go back and change it to, say, something like 51 and we save that and run it,
03:08well, now nothing is happening.
03:10Okay, let's go back to the code and make some changes.
03:13Go back to my Snippets, and I'm going to copy the rest of the cases in.
03:17I'll save that, and now you can see that we have a whole bunch of cases:
03:24there is 50, 51, 52, and a default case.
03:28So in the case where I change theVal to be 52, then I save it, and then I run it,
03:34in that case, the case for 52 is being run.
03:37If I change it to something else, say 99 in this case, none of these cases is
03:43going to match, so the default case should be run instead. And sure enough, that's
03:47exactly what's happening.
03:49So let's see what happens when you try to take out this break right here.
03:52And you can see that when I take out the break, the little red error squiggle
03:57appears under this case. And specifically, it says, "Control cannot fall through
04:01from one case label to another."
04:03So you can see here that C# is explicitly enforcing the rule that you have to
04:08have breaks in your cases.
04:09So let me just undo that, and we'll save, and we'll run it again, and you can see
04:14that everything is working just fine.
04:16So the switch statement provides a pretty handy replacement for a whole bunch
04:21of nested if else, and I think you can agree with me that reading code that
04:25looks like this with a whole bunch of cases is a lot nicer than reading a whole
04:29bunch of ifs and elses.
Collapse this transcript
Using operators and expressions
00:00Any nontrivial program that you write is going to be full of calculations.
00:04You are going to be calculating things like scores and prices and all kinds of things.
00:08And in order to do that, you need expressions, and you need operators to
00:12build those expressions.
00:14An expression is essentially just a collection of operators and operands, which
00:19are the things that operators work on, that produce a result.
00:23So for example, if we had an expression like this, we had 5 + 2 * the absolute
00:29value of x, that is an expression.
00:32And the plus and the star, those are operators.
00:37Operators are simply symbols and functions that determine how expressions are evaluated.
00:43So for example, we of course have the arithmetic operators.
00:47These are pretty common in almost every programming language.
00:49There's addition, subtraction, division, multiplication, and the percent sign--
00:54maybe something you have not seen before,
00:55but it exists in a lot of other languages, like C and JavaScript and
00:59Objective-C and C++.
01:01It's the remainder, or modulus, operator.
01:04Basically it gives you the leftover results of a division operation.
01:10So for example, 5 modulus 2 would be 5 divided by 2 but what's left over, so it would be 1.
01:16There's also the assignment operator.
01:19The assignment operator is the equals sign.
01:21So take an example: if we had two variables, x and y, and we wanted to add them
01:26together using the plus operator, or the addition operator,
01:29we can then take the result of that expression and assign it to a third variable
01:33called result, using the equal sign.
01:36If we had a variable named distance and we wanted to add a number to it, we
01:40could do distance = distance + 10.
01:43This takes the existing variable, adds 10 to it, puts the result back in the same variable.
01:49In fact, this is so common that there is a shorthand notation for doing this.
01:53You can write distance = distance + 10 the same way by just doing distance += 10.
01:59And in C# that means, take the variable and add to itself the number on
02:04the right-hand side.
02:05It also works of course for the minus, the multiplication, the divide, and the
02:10modulus operators as well.
02:11In addition to the math operators, there are also comparison operators.
02:16So for example, we can check to see if things are equal to or not equal to each
02:21other by using the equality check operators.
02:23The two equal signs together say, hey, is a equal to b?
02:27Do they have the same value?
02:29We can check for things that are not equal by replacing the first equal sign
02:33with an exclamation point.
02:34In this case, this says a not equal to b. And as you might expect, there are also
02:39operators for comparison testing to see if there are a larger or smaller numbers.
02:44We can do things like a > b, a < b, a >= b, and a <= b.
02:54The logical operators, such as AND and OR, allow you to combine more than
02:55one condition.
03:01So, for example, the AND operator, we can use to see if a=b and c=d. We use
03:09two ampersands together.
03:10There is no space in there.
03:11We just put them next to each other and that is a logical AND operator.
03:15We can do the same thing for OR.
03:17The OR operator is just two vertical bars.
03:20So in this case, if a=b or c=d, then the code inside those curly
03:26braces would execute.
03:27We can also do a NOT operator.
03:30The NOT operator you can place in front of any Boolean expression to produce
03:35the opposite of what that value evaluates to.
03:38So for example, in this case, we are saying if not some Boolean value.
03:43So if we set a to true for a certain Boolean value, then if we use bool b = !a,
03:50that gives us the inverse value of a. So b is now false.
03:54That's what the NOT operator does.
03:56There are also operators for incrementing and decrementing, because again, this
03:59happens a lot in programming.
04:01The increment operators are, as you night expect, the addition operator, where you
04:05simply take a and add 1 to itself.
04:07We've already seen how to reduce that down using shorthand notation, to take the
04:11value of a variable and add a value to itself.
04:14But there's even a shorter hand way of doing this, because this is so common.
04:18So there's the ++, and the ++ operator, postfix and prefix.
04:24So when the ++ comes after the variable, that's postfix; and when ++ comes
04:29before the variable, that's prefix.
04:31They both do the same thing:
04:33they both add 1 to whatever the variable is. But they do it in a certain way
04:38that's slightly different from each other, and we'll see why in just a moment.
04:41As you might expect, there's also decrement operators.
04:44So for a + 1, we also have a = a - 1.
04:48And we've already talked about how we can do the -= operator.
04:51But there's also post and prefix versions of decrement as well, where you
04:55simply put two minus signs next to the variable rather than two plus signs.
04:59So what's the difference there?
05:01The difference is this:
05:02Suppose we had a variable whose value is 10.
05:04If we use this statement, Console.WriteLine ("The value of a is:
05:08and using our string formatting, we put the value of a into that replacement
05:13curly braces expression there, the ++ prefix notation would execute first before
05:20putting the value into the string.
05:22So in this case, the output would be 11, because a gets incremented before it
05:27gets put into the value of those curly braces.
05:30If we use the postfix notation, that increment would get done after the
05:35substitution took place.
05:37So in that case, the output would be 10, even though a would then be incremented
05:42and would be equal to 11.
05:44So that's the main difference between prefix and postfix increment.
05:47There's also type testing operators.
05:49There's the is operator and the as operator.
05:53And we'll learn more about these as we go through the object-oriented part of the course.
05:57But essentially, what happens here is the is operator returns true if a given
06:02object is a certain type.
06:04The as operator takes a given object and converts it to another type if
06:09it's possible to do so.
06:10So let's just take a quick example--and I understand if you don't follow along
06:14right away with this, but as we get to the chapter on object orientation, this
06:17will become more clear.
06:19So suppose we had a function that takes an object,
06:21a generic object type.
06:23We can say something like if obj is the type of Employee object.
06:29So the is operator will return true if the object is of type Employee.
06:34And if that's the case, we can then use the as operator, which will convert the
06:39object to the type that we give it.
06:41And if it can't be done, it will return null.
06:44So in this case, we are taking the Employee emp and we are saying obj as Employee.
06:50So it's converting the obj to an employee object which we can then operate on.
06:55There's also an operator called the ternary operator.
06:57Now most operators we have seen so far are binary operators.
07:00So for addition, for example, you have two operands.
07:03You have the two operands that are being added together.
07:05The ternary operator works a little bit differently.
07:08It actually has three operands, and it's written using the question mark and the colon.
07:13It operates as if it were a very compact if else statement.
07:18So it works like this:
07:19You have a condition which evaluates to true or false just like any other statement.
07:24You then put the question mark next to it and then the value that you want to
07:29be assigned in the case that the condition is true, and then a colon, and the
07:33value that you want to be assigned in case the condition is false.
07:36So let's take a real example.
07:37Suppose we had a couple of prices and we wanted to find out which of price1 and
07:42price2 was the low price.
07:44Now we could write it like this:
07:45we could say if price 1 < price2 then the lowPrice = price1; otherwise
07:51lowPrice is price2.
07:52Or we could write it like this:
07:54we could say lowPrice = and then the condition.
07:57The condition here is price1 < price2.
08:01Now if that evaluates to true--we put the question mark there--price1 would be the low price.
08:06That's the true case. And then a colon
08:09and then the value for the false case.
08:10In this case, it will be price2.
08:11So you can see we've taken the if statement and compacted it down to just one line of code.
08:17Finally, there is operator precedence.
08:20Most programming languages have the notion of operator precedence.
08:23Operators are operated on in a particular order, based upon what the operator is.
08:28So let's take a look at an example.
08:30Suppose I had this expression.
08:32I have an integer variable named result, and there's a whole bunch of numbers
08:36being operated on, 2 + 3 * 6 / 2.
08:40The temptation of course is to execute this expression going from the left and
08:43traveling to the right, just like you probably learned in school.
08:46And if you did that, you probably say, okay, well 2 + 3 is 5 and then 5 * 6 is
08:5130 and then 30 / 2 is 15, so hey, the answer must be 15, right? Well, wrong.
08:56And the reason it's wrong is because those operators are executed in order based
09:01upon what the operator is.
09:03This is what operator precedence means.
09:05So that's actually wrong.
09:07What happens is the multiplication operator gets executed first, because that
09:11comes first in the precedence order.
09:14So 3 * 6 would be 18.
09:16Then the division operator would execute, and 18 * 2 would be 9.
09:22Then we would go back and we would do the addition, because 9 + 2 is now 11.
09:27So the real result would be 11.
09:29Now you can change the order of precedence by using parentheses.
09:33So if we put parentheses around the 2 and the 3 then things would execute in
09:37the order that you thought they would.
09:38In this case, the (2 + 3) would be executed first because it's in parentheses.
09:42Then *6 is 30, divided by 2 is 15,
09:44so the answer in that case would be 15.
09:47So how do you know which operators come first?
09:49Well, let's take a look.
09:50The operator precedence operates in a very predictable order.
09:53First, there is the Multiplicative operators, which are things like
09:57multiplication, division, and the modulus operator.
10:00Next comes the Additive operators, which in this case are + and -.
10:04Then there is the Comparison and Type Testing, so things like >, <, >=, <=, the
10:11is, the as operators.
10:13Then the Equality tests come, so == and !=.
10:17That's followed by a Conditional AND, which is followed by Conditional OR.
10:21Then the Ternary operator comes.
10:23And then finally, the last operator to execute is the Assignment operator.
10:27Keep these rules in mind, because this is the source of a lot of bugs in programs
10:32of beginning developers.
10:34And once you realize that the operators execute in an order of precedence, this
10:38will save you a lot of headaches down the road.
Collapse this transcript
Using constants and enumerations
00:00In this example, we are going to look at using constants and enumerations.
00:04Constants and enumerations are basically C# programming constructs that make
00:09your code easier to understand and easier to maintain.
00:13So let's take a look at what we mean by that.
00:16Suppose we had some code that looked like this.
00:19So we have some if statement and we've got some variable, and we are comparing it
00:23to the constant number 32.
00:26And if that condition evaluates to true then some code is going to run.
00:30The problem is this is a bad practice. First of all, what does 32 even mean?
00:33I mean if I am a programmer, I am writing the code,
00:35I might know what it means, but two years from now, I might not know what it means.
00:39Somebody goes to look at my code, but has no idea what that means.
00:42Worse yet, what if it changes in the future?
00:44If I am using this 32 value all over my program, I am going to have to change it
00:48if for some reason in the future that 32 is no longer applicable and the test
00:53needs to test for some other number.
00:55Well, the way that we fix this problem is by using constants and enumerations.
01:00So we can write the same thing by writing if (someVar == FREEZING), then the code runs.
01:07That's much better.
01:08It's clear what the code is trying to do.
01:10It's testing for some freezing value of some liquid.
01:14And if we ever decide to switch it, we just change the constant definition in one place.
01:19And the way you define that constant freezing is by using the const structure.
01:24So here I am saying const and then the int, and then the name of the constant
01:29that I want to use is equal to some number.
01:33So constants are used for numbers whose value is not going to change over the
01:38life of the program.
01:40So here you can see I have got a definition for const int FREEZING = 32.
01:45That's the freezing point of water.
01:47The freezing point of water is very unlikely to change in the future,
01:50so therefore, I define a constant for it.
01:53So if I want to change this constant to something else in the future, or change
01:57it to some other definition, I just do it in one place and the rest of my code
02:01just picks up the change,
02:03and people reading my code in the future know what that means.
02:06Enumerations are a close cousin to constants.
02:09And what you'll probably find in many situations is that you'll use a whole
02:14bunch of constants that are related to each other.
02:16For example, if we had a constant for the freezing point of water, we might have
02:20a whole bunch of other constants that go along with it.
02:22There might be one for LUKEWARM and for HOT and for BOILING.
02:25Well, it seems kind of silly to have all these separate constants defined for
02:30different values that are really all related.
02:32So the way you solve that problem is using what's called an enumeration.
02:37In this case, we can build what's called an enumeration for temperatures, and
02:41we just simply group them altogether.
02:43So, for example, we would group the value of FREEZING and LUKEWARM and HOT and
02:48BOILING all into one enumeration.
02:51This way if we wanted to add a new one in the future--like say we want to add
02:54one for ROOMTEMP--all we would do is make room for it in the enumeration, add
02:59the value for it, and then we are done.
03:01So now we have a whole bunch of temperatures that are grouped together logically,
03:05instead of having a whole bunch of different const int definitions.
03:08Enumerations start off at 0 by default if there is no value assignment.
03:13So for example, if we have our temperatures enumeration and we put something at
03:17the front of it, like, say, REALLYCOLD, that's going to default to the value of
03:210, unless you explicitly assign a value to it.
03:24So to build an enumeration, you simply have the values that you want to assign
03:28to words which are easy to read.
03:30And if you don't assign it, then it defaults to 0.
03:34If you also don't make a definition after one that's already been defined, then
03:38that defaults to one more than whatever the previous definition was.
03:42So for example, if we were to put another definition in here right after
03:46FREEZING which would be, say, JUSTBARELYABOVEFREEZING and we didn't put an
03:50equal sign, then it would default to the value of 33 in this case.
03:54Now enumerations by default are integer types, but you can specify other
04:00types if you want to.
04:01Now we'll learn a little bit more about types in the next section, but just bear
04:05with me here for a second.
04:06So if we have temperatures and we have all of these values assigned to our
04:11temperature enumeration, those default to integers.
04:14But if I wanted to, say, assign them to the value of a byte in order to save space
04:18in my program for some reason, then I could put a colon there and the name of
04:22the type that I want the temperature enumeration to be.
04:25So for example, in this case, if I know the value is never going to go above
04:27255, which is the maximum value that one byte can hold, I can just define this to be a byte.
04:34To define enumerations, you can use types that are numeric in nature, such as
04:38byte and shorts and ints and longs.
04:41And again, we'll learn what these are a little bit later in the course.
04:44But I just wanted to point this out here, that you can define enumerations
04:48that are not integers by using a colon and then the type that you want the enumeration to be.
04:53So let's go ahead and jump over to the code and see some constants and
04:56enumerations in action.
04:57Here I have got my ConstAndEnums project open in my editor, and I've got
05:03my Snippets.txt file.
05:05And I've scrolled down to the Constants and Enumerations section.
05:08So let's go ahead and copy some code over and see how things work.
05:11So I am going to start with these lines right here, copy those, and put them in
05:17my program, right here in Main.
05:20So I have now defined constants for the freezing point of water and the
05:24boiling point of water.
05:25You can see I am getting a little warning that says, hey, you've defined this
05:28constant, but you've never used it, so let's go ahead and fix that.
05:31I am going to save, go back over to my Snippets, and I am going to copy
05:36this code right here.
05:37So now I have copied in some code that's going to use those constants.
05:47So here, let's go down a little bit.
05:49I've got an integer variable named myTemp, and I am setting it to be 65.
05:53And then I have an if else condition for if myTemp is greater than freezing
05:58point and it's less than the boiling point, then we write out, hey, at this
06:02temperature, water was liquid;
06:04otherwise we write out, hey, water is not liquid at this temperature.
06:07So let's save and let's run it,
06:11and we can see that at 65 degrees, water is a liquid.
06:14And if we change this to, say, 30 and run it, then we say, aah!
06:20At this temperature, water is not a liquid.
06:24So let's do the same thing now, only using an enumeration, because you can see
06:27here, I've got two different constants for freezing and boiling.
06:30Let's go back to my Snippets.
06:31What I am going to do is up here I have an enumeration for my temperature,
06:36so I am going to copy that back over to my program.
06:42Now I am going to put this definition outside the Main function.
06:45I am going to put it in my class definition up here.
06:48Paste that in, so now I have an enumeration for my temperatures. So you can see
06:51here that the syntax highlighting is showing me that everything looks right.
06:55So I have enumeration for FREEZING, LUKEWARM, ROOMTEMP, HOT, and BOILING.
06:59Go back to my snippets. And now I am going to use these two lines down here instead.
07:07Copy. And we'll go back to Main. And what we'll do is we'll get rid of these
07:14guys, and we'll paste these in.
07:17So now you can see I am using temperatures enumeration instead of the constants
07:21that I've got defined here.
07:22And in fact, since I am not using them anymore, let's just get rid of them.
07:25The nice thing about enumerations is that, because they are part of your program
07:29and the C# interpreter can look at them and see what they are,
07:32when you type, it will actually help you type the value out.
07:36So for example, suppose this piece of code wasn't there.
07:41I can start writing the word Temperatures,
07:43and you can see that the Temperatures IntelliSense is showing up right there.
07:46So I am going to double-click that and it's going to get inserted.
07:48Then when I hit the period, you can see that it's introspecting the
07:52enumeration for me.
07:53So I can scroll down to the one that I want, and that's FREEZING.
07:58So I am going to have to just do this. Bear with me for a second while I do this,
08:03because we'll learn about conversion in the future, but I have to tell the
08:07interpreter that the Temperatures enumeration is an integer.
08:11And now I can say okay, if the temperature is greater than FREEZING and is less
08:16than BOILING, then we are doing the same thing.
08:18At this temperature, water is a liquid or it's not.
08:21So let's change this to 65 and run it,
08:24and you can see that water is a liquid at 65.
08:28The nice thing about this is that the code here is much easier to read than
08:31having some numerical value that you don't know what it is.
08:35And in the future, if I ever wanted to, I could change these numbers up here,
08:39and I would not have to change them all over my program wherever they are being used.
08:43Just make the change in one place.
08:45So that's the argument for using constants and enumerations to make your code a
08:49lot easier to read and a lot easier to maintain.
Collapse this transcript
Using loops
00:00Along with some pretty basic stuff, like constants and enumerations and
00:05conditional statements and operators and expressions, loops are one of the most
00:09basic building blocks of any kind of programming language.
00:13Loops are essentially blocks of code that execute over and over again.
00:18And there are two different basic kinds of loops:
00:22there are loops that execute while a condition is met and there are loops that
00:26execute a set number of times.
00:29So for example, you might have a loop that's running some piece of code for as
00:33long as a certain condition is true, like the user has not logged out, or the end
00:38of a file has not yet been reached, or something like that.
00:41You might also have a loop that runs a set number of times: the number of people
00:45attending a concert or something like that.
00:48The way that you write loops is by using a couple of different constructs.
00:52For loops that execute while a condition is met, you have a while loop,
00:57and the while loop is written as you see it there.
00:59It can have the keyword while.
01:01And then inside some parentheses, you have a condition that is true.
01:05And then inside the curly braces, you've got some code that's going to execute
01:09as long as that condition is true.
01:10There's also a close cousin of the while loop, which is the do-while loop.
01:15And in this case, the while goes at the bottom of the loop instead of the top.
01:20And the main difference here is that the while loop is only going to execute
01:25when that condition is met.
01:27If that condition test is not met, nothing inside the while loop is going to
01:31run and that condition is evaluated before the while loop ever even gets a chance to run.
01:36The do-while loop is a little bit different.
01:38The code that is inside that loop is going to execute at least one time.
01:43And that's because it executes once-- then the while is executed at the end of
01:48the loop to see if things should keep going.
01:51So in the case where you want to have a loop that runs only while a condition is
01:55met and no other times, use the while loop.
01:57If you have a condition where you want to execute some code just one time and
02:02then check to see if you should keep going, that's the do-while loop.
02:05For the set number of times case, there is the for loop.
02:10And the for loop executes a given number of times and it runs the code that's
02:15inside the curly braces.
02:16A close relative of the for loop is the for-each loop,
02:21but we're not going to cover that one in this particular movie because it has to
02:25do with something called enumeration.
02:27And we'll look at it a little bit later in the course.
02:30For now we're going to concentrate on the while, do-while, and for loops.
02:35Let's take a look at the code to see how this works.
02:38I've got my example here opened.
02:41This is my Loops project.
02:43And over in my Snippets, I've got my code, and I'm scrolled down to the Loops section.
02:49So let's take a look at how the basic while loop works.
02:52So I am going to copy these lines of code here.
02:54I am going to copy that, and I'm going to paste into my Main.
03:01So I've got here an integer variable named myVal, and we have a basic while loop.
03:07We're first going to write out a string of text that says Basic while() loop.
03:11And then you see here, here's the while definition:
03:14so while (myVal < 20). We're going to write myVal is currently and we're going
03:21to use the console's WriteLine method with some string formatting here to write
03:25out what the current value of myVal is.
03:28As always with loops, you want to make sure that the loop has some way to exit;
03:32otherwise, you'll end up with what's known as an infinite loop.
03:36An infinite loop is a loop of code that just keeps going and going and going and
03:39going and never has any way to get out of it.
03:42So you want to make sure that you've got some code inside your loop, such that at some point
03:47this condition up here is going to become false, and therefore your loop can
03:50terminate, and your program can continue on its merry way.
03:54So what we're doing here is, at the bottom of this loop, we're taking myVal and
03:59we're adding 3 to it each time.
04:01And recall that the += notation there means myVal = myVal + 3.
04:07So when myVal becomes greater than 20, that condition will no longer be true if
04:11they're in the while loop, and the loop should stop.
04:13So let's save this, and we're going to go ahead and run it.
04:17And you can see that the string gets written out, Basic while() loop, and myVal is
04:2315, and then we add 3, so myVal is currently 18.
04:27And then we add 3 and myVal becomes 21.
04:30So when the code executes and goes back to the top of the loop, that test is no
04:35longer true, and the loop stops.
04:38So right here. So the code executes in this line, from top to bottom. The last
04:43statement is the myVal += 3 right here.
04:46When that executes, it gets to this curly brace,
04:49it will go back up to the top of the loop, and then this condition gets tested, and it fails the test.
04:54And that's what terminates the loop. Okay.
04:56Let's take a look at another example.
04:59In this case, we're going to look at the do-while loop. And I am going to copy
05:05these lines of code right here.
05:07Okay, let's get rid of this one. And paste.
05:19In this case, we have a do-while loop, and remember that in the case of
05:22the do-while loop, the code inside the braces gets executed once before
05:26this condition gets met.
05:28So in this case we have pretty much the same code.
05:30We're writing out the Console.WriteLine value there.
05:33We're adding 3 each time.
05:34But let's see what happens.
05:36So this time we're going to save, and we're going to run it.
05:40You can see here that the do-while() loop, myVal is currently 15, myVal is
05:44currently 18, and then we add 3 and then myVal is 21, and the condition no longer
05:50is true and therefore the loop executes right here.
05:53So right here when we add the myVal += 3. This is no longer running.
05:57But let's watch what happens when I set this up at 20 to begin with.
06:02I am going to save it.
06:03I am going to run it.
06:05And you see even though myVal is not less than 20,
06:08it still goes through the loop at least one time.
06:12So that code is going to get executed once before the while condition has a
06:15chance to be evaluated.
06:17So even though the condition is false, the code got executed one time.
06:22So that's the do-while loop.
06:23Let's take a look at our friend, the for loop.
06:25Here's the code for the for loop right here.
06:31I am going to copy that, and we're going to paste it.
06:37A for loop is set up using three compact statements within the for statement itself.
06:43So here's the for right here.
06:46And then the first statement is the initialization of the counter variable.
06:51In fact, I could expand that out and do something like this, where I say int i,
06:57and then I wouldn't need to do this here.
06:59I would simply say for (i = 0).
07:01What I was doing there was just concatenating one with the other.
07:05So this is the initialization, or setup, of the counter variable.
07:08Then we have the test to see if i is less than myVal.
07:12This is the condition that gets evaluated each time.
07:15And then this is the statement that gets evaluated when the loop is complete. So this is setup,
07:20this is the condition, and then this is what happens each time through the loop.
07:24So i is going to start out at 0.
07:26We're going to test to see if it's less than myVal, which is 20 right here, and
07:30we're going to add 5 each time.
07:32And each time through the loop we're going to write out i is currently
07:35whatever its value is.
07:36So I am going to save and we run it.
07:38And you can see that i starts out at 0, then it's 5, then it's 10, then it's 15,
07:44and then it gets to be 20, and that condition no longer needs to be true.
07:49So 20 is not less than 20.
07:52If we change this to be less than or equal to, then 20 will actually match the condition.
07:57So if we run it again, you'll see that in this case i is less than or equal to
08:02myVal, because 20 matches the less than or equal to part of the condition.
08:08So that's the for loop, and that's how you get a loop to execute a certain number of times.
08:13Let's take a look at some other keywords we can use with loops.
08:15There are two special keywords that can be used with loops.
08:18There's the break keyword, which breaks out of the loop at the current point,
08:23regardless of whether the test condition has been met or not.
08:27And there's the continue keyword, which basically says, hey, skip the rest of the
08:32code in the loop and then just jump back to the top of the loop code as if you
08:37had it completed one of the loops.
08:39So let's take a look at how these work.
08:41So I am going to erase the code from my previous example, and we're going to
08:45go back to the Snippets, and I am going to copy over the last part of the
08:49example right here.
08:50I am going to copy, and I am going to paste.
08:56So in this case, we're going to use the continue and break keywords.
09:00So here I have a for loop that's starting off at 0, and it's going to run until i
09:06is less than 10, and we're going to increment i by 1 each time.
09:10We're using the postfix increment operator here.
09:13Now, there are two special conditions in here.
09:16When i is equal to 5, I am going to use the continue keyword.
09:21continue basically says, hey, skip everything from here on down, go down to the
09:25last brace, and then go back to the top again and execute whatever the third
09:29statement over here is--
09:31this part of the increment loop right here.
09:33And then in the case where i is equal to 9, I am going to use the break keyword,
09:38which basically means, hey, you know what?
09:40Just stop the loop.
09:41It doesn't really matter where we are.
09:43It doesn't matter what the condition test up here. Just stop.
09:46So let's save and we will run it.
09:49Let's take a look at the output.
09:50So you can see that i starts off at 0, Then it goes to 1, then 2, then 3, then 4.
09:56But remember, for the 5 case, we use the continue keyword.
10:01So we skipped over the line of code that said Console.WriteLine, so that line of
10:05code never got executed.
10:07The loop just continued as if it had run, but it skipped passed all the logic
10:11that put where the continue keyword was.
10:14And then we continue incrementing, so i is now 6, then 7, and then 8.
10:19And then remember, when we got to the 9 case, we used the break keyword, which
10:24stops the loop in its tracks, as if the condition had failed.
10:28So let's go back to the code, and let's take this statement out.
10:32I am going to comment this out and run it again.
10:37And you can see, in this case, the loop does make it to 9, and then the value of i
10:41becomes 10, which is where it triggers the condition, and the condition is no
10:45longer met and the loop stops.
10:47So if we go back to the code and we uncomment this, put the code back in, if I
10:52change this to say 7 and save and then run, you'll see that in this case, the
10:57loop only makes it as far as 6 because as soon as i gets to be 7, we're calling
11:02the break command, which stops the loop.
11:05Loops are a very powerful part of programming, and you can see that C# loops are
11:10pretty versatile and pretty powerful in their own right.
Collapse this transcript
Using functions and methods
00:00The last major piece of program flow that we're going to take a look at in this
00:03section are functions.
00:05Functions are a nice mechanism for breaking up large sections of code into
00:12smaller pieces that are reusable, and make your programs easier to understand and
00:17maintain. And one of the things you'll find when you're doing your C#
00:21development, or development in any language, really, you'll find that any
00:24nontrivial program that consists of many lines of code starts to get really
00:29unwieldy and is really hard to change and maintain, and functions really make
00:33that process a lot easier.
00:35Now the reason why I included the word "methods" is because C# is an
00:40object-oriented language and in object-oriented parlance, functions are
00:44typically called methods, because in C# a function has to be part of an object.
00:50There are no global functions, which I covered a little bit earlier.
00:53So the word function and method are pretty much interchangeable in this context.
00:59So anywhere you see me use the word functions, you can just mentally hear me
01:03using the word methods, and/or vice versa.
01:06To define a function, it's a pretty straightforward process.
01:11We start off by giving it a name.
01:14So to create a function, the function has to have a name, and you can use
01:17whatever uppercase, lowercase rules you want to use. In this case, I am starting
01:20off with a lowercase letter and I am using what's called CamelCase, and I am
01:24capitalizing the interior words of the function.
01:28But that's up to you.
01:29You can use letters.
01:30You can't use special symbols, like dollar signs or parentheses or anything like that;
01:34it's got to be alphanumeric.
01:35So here I have a function and I have given it a name.
01:38Then I have to give it what's called a parameter list.
01:41There are two parentheses and inside those parentheses, these are the arguments
01:47that the function takes.
01:49This is the data that the function is going to operate on. And inside the
01:53function, I have the code of the function.
01:56This is the stuff that the function does.
01:59In this case, the function is simply calling Console.WriteLine.
02:03In the parameter list, where the arguments go, I can supply one or more arguments,
02:09or parameters, to the function.
02:11So for example, if I want to pass in an integer, I would pass in int x. In
02:16some other languages, like JavaScript, you don't have to declare the type in
02:20front of the argument.
02:21You simply give the argument a name, and you pass it into the function, and C# doesn't work like that.
02:27In C# you have to tell the function, here's the kind of argument that's going to be coming in.
02:32In this case, it's an integer.
02:34If I wanted to pass in more than one, I would use a comma to separate them.
02:38And in this case I am passing in an integer named X and a date argument named D.
02:44Now in addition to the name of the function and the arguments, I have to say
02:49what the return type of the function is. What kind of value does the function pass back?
02:55I can say, for example, that the function passes back an integer.
02:58Now, notice I don't name what the function is passing back.
03:01I am just simply saying here that the function returns an integer. And it
03:04can return an integer; it can return a string;
03:07it can return any other kind of data type. And we'll learn a little bit more
03:10about data types later on in the course.
03:11But for now, just follow along with me here. I am saying that this function
03:15returns an integer, and it takes an integer and a date as an argument.
03:20If I didn't want to pass in any argument, I can simply leave the area inside the
03:24parentheses blank and not pass in any arguments at all. But in this case, I've
03:29got a couple of arguments.
03:30And then finally, there is the code inside the curly braces for the function, and
03:34that's what the function actually does.
03:36In cases where functions return a value--in this case, this function is
03:40returning an integer--
03:41I have to make sure that the function actually does that, and I do that by using
03:44the return statement.
03:46In this case, I am returning a variable named someValue, which is probably
03:52defined somewhere in this function as an integer.
03:55The value that I am returning has to match the type of the return value for the function.
04:01So if I declare this someValue variable in my function somewhere, it would have
04:05to be an integer just like the return type of the function.
04:08Functions don't have to return values.
04:10I could just simply say void, in which case I've defined a function that takes a
04:14couple of arguments but doesn't return anything. And in that case I don't need a
04:19return statement at all.
04:20I can just simply get rid of that, because there is no return value for the function.
04:25I can also just simply use the word return with a semicolon by itself, but in
04:29this case I've just got rid of it because it doesn't return anything.
04:32So let's actually jump over to the code and see how to write a function that
04:36does what we have described here.
04:38So in my FuncsAndMethods project I've also got my Snippets file open, and I have
04:44scrolled down to the Functions and Methods part.
04:46So let's go ahead and copy some of this code and paste it in.
04:49I am going to copy these three lines.
04:52I will paste that, and let's take a look at what I've pasted in.
04:58I have got an integer variable named result1, and then I am assigning
05:02result1 the result of a formula function. And you can see here there are some
05:08red squiggles there.
05:09It says, "The name 'formula' does not exist in the current context."
05:12That's a function that apparently takes an integer argument which I have not defined yet.
05:18So let me go get the code for the formula function, and that's it right here.
05:24I am going to copy that, and I am going to paste it.
05:30So now, I have defined a function named formula which takes an integer argument
05:35and returns an integer.
05:36For the moment, you've probably noticed this word static right here. Just bear
05:40with me about why we need that.
05:42I am not going to cover it right now.
05:43We'll get to that when we get to the section on object-oriented programming
05:46a little bit later. It's just something we need right now for the function to work.
05:50So don't worry about that right now. Let's pretend it's not there.
05:53What's important is the return type right here of int, and the argument it takes
05:57is an int, and this is the name of the function right here.
06:01In some languages, for example C or Objective-C, the order in which you define
06:06your functions is somewhat important.
06:08So for example, if this were C and I put the definition of this function down
06:13below where I am calling it up here,
06:15I would have to have some type of code statement up here that says, "Hey!
06:20program, there is going to be this function called formula that you're going to come across.
06:23Don't worry about it."
06:24I am just telling you about it now.
06:26In C# you don't need to do that.
06:28In C# you can just declare this function wherever you like and you can call it
06:31from over here, and the C# interpreter is smart enough to realize oh, okay,
06:35well, there must be a function named formula coming down, so I will just wait till I see it.
06:39So here's what we're going to do.
06:40We're going to call the formula function with an argument--in this case, it's
06:4414. The function is going to do its work.
06:46It's going to return an integer value and that value is going to be set into
06:50result1, and then this statement right here Console.WriteLine is going to write
06:55out whatever the result is.
06:56So let's go ahead and save that, and let's run it. And you can see that the
07:02result being written out is 24.
07:05So the result of the formula inside the function evaluated to be 24.
07:10So I'll say, okay. Let's go back up here.
07:12Let's change this to something else.
07:13I am going to type a new variable, and I am going to call it arg1. And I am going
07:22to give it a value of 25. And now instead of passing in the hard-coded value of
07:3214, I am going to copy arg1 and I am going to paste it in the calling place
07:38where I am calling formula.
07:39I am going to save it, I am going to run it, and you can see that now we've
07:43produced a different result.
07:45So that pretty much brings us to the close of this section.
07:48In this section we've seen how program flow works.
07:50We've covered things like functions, and we've seen constants and enumerations.
07:53We learned how to write conditional statements, and we have learned about
07:56operators and expressions.
07:58We've got to the point now where we continue on and learn more about C# and
08:01learn how to do things like declare variables and use objects and so on.
08:05But this chapter should have given you a good foundation for a lot of the
08:08basic parts of C# that you're going to come across in any program that you
08:12decide to write, or work on.
Collapse this transcript
4. Variables
Understanding data types
00:00Earlier in one of the course, I mentioned that C# was a strongly typed
00:04language, meaning that you can't just simply declare variables and not tell the
00:10system what the types are.
00:11You'll find that as you build your C# programs, this actually becomes quite an
00:15advantage, rather than the encumbrance that it sounds like.
00:19Program store and keep track of all kinds of data.
00:23They keep track of numbers and prices and names and email addresses and dates,
00:28and these pieces of data are stored in memory locations called variables, and
00:32each piece of data can have a type, which is used to declare a variable.
00:39In some languages, such as JavaScript, you can declare variables and you can
00:44change their types around.
00:45You can do all kinds of great stuff. And you can't do that with C#.
00:50So for example, in JavaScript you can just do this.
00:52You can say myData = true; that's okay in JavaScript.
00:56You can't do that and C#; you have to actually declare the variable.
01:00In JavaScript if you just use a variable about declaring it, JavaScript
01:03assumes it's a global variable. Well, C# doesn't have a global variables, so this wouldn't work.
01:08You have to actually declare it, so you declare it.
01:11In JavaScript you can do things like var myData = 123456.
01:13And in fact, you can do this in to C# too.
01:18C# does support the var keyword, but it's a little bit advanced for C#, and we're
01:23not going to cover it in this course.
01:25However, in JavaScript you can do things like this: once you declare the
01:28variable and you've assigned it a number, later on in life you can say, hey, you
01:32know what, myData is a text string now.
01:34Again, that's okay in JavaScript, but you can't do that in C#.
01:38Your variable can't change type once you've declared it and once
01:42you've initialized it.
01:44So that's an example of things that work in some other languages
01:47that don't work in C#.
01:49So how do you declare and name a variable in C#?
01:52Well, let's take a look at that.
01:53To declare variable, you simply indicate a type and then you give it a name, and
01:59optionally you can give the variable an initial value.
02:03So all of these are valid ways of declaring, and in some cases initializing, C# variables.
02:10C# variable names can start with a letter or an underscore. And after that, you
02:16can have letters, numbers, and underscores up to 255 characters.
02:22Now you can't start a variable name with a number.
02:25It has to be a letter or underscore, and the letter can be upper- or lowercase.
02:28Remember that C# is case sensitive.
02:31So, uppercase and lowercase variable names are different, so you have to keep that in mind.
02:36This will sometimes lead to bugs for newer C# developers who've come from
02:40languages where things are not case sensitive.
02:43They're case insensitive.
02:44That's not the case here with C#.
02:45You do have to remember that.
02:46C# has a number of primitive data types that are built into the language, and the
02:53reason they're called primitive data types is because they are the basic
02:57building blocks that you use to build other data types.
03:00For example--and you've probably seen me using some of these throughout the
03:04course so far, as we built some of our examples--
03:06there is the int data type, which is an integer.
03:09That's 4 bytes. And it holds numbers from about -2.1 billion up to about +2.1 billion.
03:18There are date data types. The date is 8 bytes, and it represents January 1st
03:24from the year one, up through midnight on December 31st of the year 9999, which
03:30is a very long time.
03:31There's also a char data type, which is a single character, and that's 2 bytes,
03:35because it's Unicode.
03:36Unlike other languages where character is 1 byte, in C#, it's 2 bytes.
03:40There are strings. Strings can hold from about 0 to 2 billion characters.
03:45That's a very, very long string.
03:47There is also an object type. And in this case the object is actually defined by
03:52your program, although C# and .NET does provide a base object definition for
03:58you. And it takes up as much memory as its structure and as memory allows.
04:03So you can have all kinds of data fields inside your objects.
04:06And then rounding out the primitive data types are a whole bunch of other types
04:10like Boolean and bytes and decimals and doubles, and all kinds of other numeric
04:16data types and Boolean other non numeric data types.
04:19There is also a special kind of data type in C# called a nullable type.
04:24A nullable type can represent the full range of values of the normal underlying
04:29data type, along with the additional value of null.
04:35And normally when you declare a variable, like an integer, it has to be a number;
04:38you can't set that variable to null like you can in JavaScript.
04:42In C#, if you want to be able to do that, you have to declare what's called a nullable type.
04:47This is a little bit advanced, and we won't see very much of it in the course,
04:50but I wanted to point it out to you, because you will occasionally run cross
04:53it in your C# travels, so I wanted make sure that you know what it is.
04:57So, a nullable type, like I can said, it can be null along with whatever its
05:01normal data type is.
05:02So for example, if we declared a Boolean variable with the name of B, that can
05:07be either true or false.
05:09If you try to do this, however, set it to null, that's an error.
05:12You can't set B to null.
05:13If you want to do that, you'll have to declare the Boolean variable as a
05:18nullable type, and the way you do that is you declare as a bool with a question mark
05:22at the end.
05:23And that tells the compiler, hey, this is a variable that can be either true or false or null.
05:29You can do the same thing with integers.
05:31If I put question mark on the end of the integer,
05:33it can be an integer value or it can be null.
05:37Using these kinds of primitive data types, you can build all kinds of C#
05:42variables and higher-order objects which we will see a little bit later in the course.
05:46For now though, now that we've seen primitive data types, there is one other
05:49thing we just need to look at and understand, and that is how C# deals with
05:52the notion of objects.
Collapse this transcript
(Almost) everything is an object
00:00One of the things that I said earlier on in one of the course is that almost
00:02everything is an object in .NET and in C#. And the way that that works is that
00:08at the base level of the .NET library is a base type called System.Object.
00:14All of the other types that we talked about so far, such as ints and doubles and
00:18characters and bytes and so on, all of these are primitive types, but C#
00:22actually derives all of these base primitive types from System.Object.
00:28What's interesting about this is that even though the int data type is built
00:32into .NET and C#, int actually maps to a System.Int32. int is just a shorthand
00:40way of saying, use the class System.Int32. The same thing goes for char.
00:45A char data type is actually a System.Char object.
00:49Same thing with strings; strings are System.String objects.
00:52These all derive from System.Object, and the same is true for all the other
00:56objects that you see listed here, and all the primitive data types.
00:58Date, bytes, doubles, all of those are actually objects.
01:02They derive from System.Object.
01:04So why is this important?
01:05Well, it lets you do some pretty neat things.
01:07If I were to declare a variable int i = 0,
01:11I could do the same thing by saying int i = new int.
01:15Other languages don't let you do this because they don't understand it, but in
01:18C# and .NET, because pretty much everything is an object, you can do this.
01:22These are functionally equivalent to each other. Declaring the variable as an
01:26integer, initializing it to 0, and saying new is pretty much the same thing.
01:32It also means that the built-in objects have some pretty cool features.
01:36So for example, this integer is really an object, and it has functions that
01:40I can call on it. So I can do things like i.GetType, and that will return System.In32.
01:46That's the kind of object that it is.
01:48I could say, i.ToString, and that would return a string.
01:51Now remember, I'm doing all this on a basic integer.
01:53I can do things like i.Equals, and give it an argument, and that returns whether
01:58two objects are equal.
01:59So once you get around the idea that everything pretty much in .NET and C# is an object,
02:05it gives you a certain amount of freedom in your programs and some really great
02:09functionality that other languages don't provide.
02:11Let's take a look at an example.
02:13Let's return to our old friend, the is operator.
02:16Now I briefly talked about the is operator earlier on in the course, but now
02:20let's take a look at how you might use it.
02:21Suppose I had a function that took an object as an argument. And again, remember
02:27here that that word "object" is really an alias.
02:30It is a shorthand way of saying System.Object.
02:33So here I have a function that's taking an object as an argument and it returns
02:37an integer data type.
02:39Inside this function I would be able to do things like say, hey, if the obj
02:43argument that I'm being given is an int, and then I can convert that object to
02:48an integer and then operate on the argument as if it were an integer. Or I could
02:52say, hey, if the obj is a string, then convert the object to a string and then
02:57operate on it as if it were a string.
02:59This gives me a lot of flexibility in the way that I write my code.
03:02I can write some C# code that's very flexible,
03:04takes different kinds of arguments in one large container, and then convert
03:09between them as I need them.
03:11So what's so great about this?
03:12Well, first, the fact that pretty much everything is an object provides a
03:16unified way of working with all the variable types. You don't have to
03:21treat primitive types one way and objects another way like you do in other languages.
03:26Basic variable types in C# have some pretty cool automatic features built in,
03:31and we'll see more of this as we work with each one of the other data types in depth.
03:35All the C# types can be converted to and from objects, so they can be passed to
03:40functions that take objects as parameters, as you saw it earlier.
03:44So now you can write code that's very flexible.
03:46You can write functions that take objects and take variables of different types
03:50and work on them as if they were each with their own types.
03:54So for example, I can write a function that takes an object or a series of
03:57objects, pass them all kinds of variables, like strings and integers and doubles
04:01and floats, find out what kinds they are, and then work on them as I would in
04:05ordinary variable of that type.
04:07And will see examples of this as we move through the course.
Collapse this transcript
Working with numbers
00:00Let's talk a little bit about working with integer numbers in C#.
00:03Up until now you've been seeing me use the int data type throughout all the
00:07examples that we've encountered up until now, but there are plenty of other
00:10ways of working with integer numbers. And the only real difference between the
00:14various data types for working with integers is the size of the variable
00:19container, which basically dictates the range of numbers that that variable can hold.
00:23For example, there is bytes, which are 8 bits in size, and they are unsigned by default.
00:31They are 0 to 255.
00:34That's just 8 bits, and 255 is the largest number that you can hold inside of a byte.
00:40Along with a byte is the sbyte, which means signed byte, that's also 8 bits, and
00:46it can hold the number from -128 to 127.
00:51So byte and sbyte are both the same size.
00:53It's just a question of which one you want to use when you know that the number
00:56is only going to be positive, or if the number might be signed.
00:59Similarly, there is a data type called the short. The short is 16 bits, or 2 bytes,
01:04and that can hold -32,768 up to 32,767.
01:10Now notice unlike byte, shorts are signed by default.
01:14So if you want to use an unsigned version of this, you have to use the ushort,
01:18which stands for unsigned short. It's also 16 bits, and it can hold the
01:22number from 0 to 65,535.
01:24The next step off from there is of course the int, which is what you've been
01:29seeing we use all this time.
01:30It's 32 bits, and it can hold from -2.1 billion to 2.1 billion. And there is of
01:36course an unsigned version of it, which is uint, for unsigned integer. It's also
01:4032 bits, and since it's unsigned, it can hold from 0 up to about 4.3 billion.
01:48That's a pretty good range of data, but suppose we want to handle numbers that
01:52are larger than 4.3 billion.
01:54Well, no, we are not out of luck.
01:55There are other data types that we can use.
01:58There is of course the long, which is 64 bits, and it has a range of well really,
02:04really, really, really big.
02:06You can see those numbers right there.
02:08It goes from that -9 up to the 9, whatever that number even is.
02:11I have no idea what the name of that number is, but it's really, really huge.
02:15In addition to the long, there is the unsigned version of this, which is the ulong.
02:21It's also 64 bits, and it can handle from 0 to well, even really, really bigger.
02:27But of course there's also floating point numbers, not just integers. Usually we
02:31use floating-point numbers for things like decimals and other kinds of
02:35fractional numbers. And to do that there is a float number type and when you
02:39declare a float number, you have to put a lowercase f on the end. And you can
02:43see here I am declaring a floating point number of 123.45, and it has 7 digits
02:48of precision from the range that I have shown there.
02:50There is also a double, which is another type of floating-point number, but it
02:55has 15 to 16 digits of precision. And you can see that when you declare it you
02:59have to put a little d on the end to distinguish it from the float. Floats have
03:02fs; doubles have d. So in this case I've got a double number which has much
03:08higher precision than the floating-point.
03:10And then finally there's the decimal number.
03:13The decimal number is an interesting beast because it actually works in base 10
03:18and not base 2, like the other kinds of floating-point number types that C# works with.
03:24And to declare a decimal number, you simply say decimal and then the name of the
03:27variable. And here I've got 123.45, and you put the little lowercase m on the end
03:33which indicates that it is a decimal number.
03:35Decimal numbers have 28 to 29 digits of precision, making them very, very
03:40highly accurate numbers.
03:42In addition to these data types, there are some special floating-point values that
03:47you should be aware of.
03:48The first of these is NaN, which means Not a Number. If a floating-point
03:53variable gets into a state where you either try to divide by 0, or some other
03:56kind of error happens, then the variable is set to NaN which means not a number.
04:02There is also a PositiveInfinity and a NegativeInfinity setting.
04:06For example, if you have a variable f defined to be of type float, you can do
04:11things like say, hey, if f is less than float.PositiveInfinity. You can also
04:16check to see if float is equal to not a number.
04:19You can do things like float is PositiveInfinity, or is NegativeInfinity, and
04:24these are useful for things like sorting algorithms.
04:26You can also check to see if the float is not a number. Again because these
04:30floating-point data types, along with all the other primitive data types, derive
04:33from System.Object they have all these great methods and properties built into the language.
04:39Okay, let's talk a little about why you'd use floating points, such as floats or
04:44doubles, versus something like decimal, because one of the things you will find
04:47is that with floating point numbers-- and I am not going to go too deep into
04:51this because it's a bit of a advanced subject--but because of the way computers
04:54work, computers calculate values using base 2 notation rather than base 10 like we humans do,
05:01and that can lead to a loss of precision for certain kinds of transactions.
05:06So let's take a look at a piece of code that explains how that happens.
05:10So I have got my DoubleVsDecimal project open here, and here's the program file,
05:16and I've got my snippets open as well.
05:18So what I am going to do is copy these lines of code over to my main function.
05:25So what we are going to do in this example is compare how double precision works
05:30with decimal precision. And like I said earlier, internally, computers represent
05:35numbers having to do with base 2 notation.
05:39This is the famed 0s and 1s you've probably heard about if you've ever worked
05:43with software before.
05:44But what it essentially means is that because of the way numbers are calculated
05:47on a microprocessor, you can sometimes lose precision when working with certain
05:51data types. And I am going to show you a difference of how decimals are handled
05:56versus how doubles are handled.
05:58So right here at the top of my function I have got two variables, twentieth and
06:02one. And you can see that I defined twentieth and one to be types double and
06:07so I have got 0.2f and 1.0f. And what I am going to do is write out what one - twentieth is.
06:16So 1.0 - 0.2, you would expect that to be equal to 0.8, right?
06:21So let's see how the double data type and decimal data type compare when doing the
06:26same kind of option, because down here, I have got two variables, decimals, which
06:30are one twentieth and the real one.
06:33So now I have got the same kind of calculation.
06:35I have got 1.0, subtracting tracking off 0.2 each time.
06:38The only thing that's different is in one case they are doubles; in one
06:41case they are decimals.
06:43So let's save this, and let's run it. And you can see that in the first case the
06:481.0 - 0.2 when using a double results in 0.799999...whatever, a whole bunch of,
06:56like, you know high-precision numbers here. But obviously there is a loss of
07:01precision when using a double number, whereas in the case of the decimal the 1.0
07:07- 0.2 did fact result in 0.8, as you would expect.
07:13And again, that's because the decimal data type works with base 10 numbers
07:17naturally, whereas doubles work with base 2 numbers.
07:20Now you might be saying to yourself, oh my God!
07:22Is this some kind of a bug in .NET?
07:23Is this a huge shortcoming of C#? It's not.
07:26You will find this in lots of different computer languages that work with
07:29floating-point numbers. Whether it's C or Objective-C or Java, it doesn't really matter.
07:33This is just one of the ways that computers keep track of numbers internally.
07:37So let's go back and take a look at the chart of when you want to use double
07:39versus when you want to use decimal.
07:41Let's take a look at why double and decimal are different from each other.
07:44First, in the nature of precision, doubles are 15 to 16 figures of precision,
07:49where decimals are 28 to 29 figures, so you've got double the amount of
07:52precision in a decimal number as you do a double.
07:55In internal format, in other words how the microprocessor on the computer
07:58works with the number, in doubles it's base 2; in decimals it's base 10.
08:04So, so far it's looking like you might never want to use a double, right?
08:07After all you've got higher precision using base 10.
08:10Speed, however, is a important factor to consider.
08:13Because doubles are native to the CPU-- in other words they are native in the
08:17fact that they use base 2 notation--the speed when using doubles is very, very, very fast.
08:22Decimals, on the other hand, because they work in base 10 and have to be
08:26conferred to and from the native processor format, can be up to 10 times slower
08:30than using doubles.
08:32So what are they good for?
08:33Well, scientific calculations can usually be executed quite accurately and quite
08:37fast using doubles, so they're good for scientific calculations, whereas decimal
08:42numbers are good for financial calculations.
08:45When you're dealing with hundreds of millions or billions of dollars, or even
08:48small amounts but many, many, many times, these differences in precision and
08:52accuracy on the CPU can add up to real money.
08:56So because decimals work in base 10 and are very highly accurate when
08:59working with floating-point numbers, they are ideal for being used in
09:03financial calculations.
09:05You can use doubles and other floating-point numbers for
09:07scientific calculations.
Collapse this transcript
Working with characters and strings
00:00C# also has built-in data types for working with characters and strings.
00:05They're the char and string data types, not surprisingly.
00:08The character data type, or char, in C# represents a single Unicode character, and
00:13that's 16 bits or 2 bytes.
00:15So the way we declare is char
00:18and then the name that you want to give the variable, and you can initialize if you want to.
00:23And it's important in C# to recognize that, unlike languages like JavaScript,
00:26when you declare characters you have to use a single quotes, and for strings
00:31you use double quotes. And in JavaScript you can use either single or double
00:35quotes for the characters or full strings,
00:36it doesn't matter; in C# it does matter.
00:39So, for the character data type use single quotes; for strings use double quotes.
00:42If you're not familiar with Unicode, don't worry too much about it.
00:45It's basically an international standard for representing a wide variety of
00:49characters from a wide variety of languages, and it supersedes the old ASCII
00:53data set that were used in computers up until just recently.
00:57So here we have an example of a character being declared, and this is a
00:59lowercase letter a. And as I mentioned it's 16 bits, or 2 bytes, but you are not
01:04limited to lowercase letters.
01:05You can use things like numbers.
01:07You can even use punctuation. All of these are legitimate characters.
01:11For strings, you use the string data type, and a string is a series of
01:17Unicode characters.
01:18And unlike other languages, like, say, C or languages based on it, like
01:22Objective-C, C# provides a native built-in data type for working with strings
01:28and it's just called the string.
01:29So to declare a string, you use the string data type, again the name of the
01:33variable that you want, and you can initialize it, and you can see I'm using
01:36double quotes to initialize my string, which is part of the C# syntax rules.
01:42strings can also have escape characters in them. In this case, for example, \n
01:47represents a new line character, and these are handled automatically for you by C#.
01:52If you make a string that has an escape sequence, which is basically a backslash
01:56followed by a special character code, such as a T for tab or an R for a
02:01carriage return or N for a new line, C# will simply convert that for you.
02:05Now this provides some rather interesting side effects for working with things
02:09like directory paths.
02:10So for example, if I wanted to make a string that contained a directory path,
02:15I'd have to escape out the backslashes by putting a backslash in front of them.
02:20And this can get a little cumbersome and tiresome to read,
02:23so C# provides a special way for telling the compiler, hey, don't worry
02:28about escape characters.
02:29I just want every character that's in the string to be what it really is.
02:32And the way you do that is you put an @ symbol in the front of the string.
02:36So in the case of declaring the myDirectory variable, in the first case I had
02:40to escape out the backslashes; in the second case, by putting that little @
02:43symbol in front of the string, I'm telling the compiler, hey, those backslashes
02:46aren't escape characters;
02:47they are just real backslashes-- please treat them as such.
02:50But the fun doesn't stop there.
02:52Remember that characters and strings are objects.
02:55The character data type is really a system.char object, and the string data type
03:00is really a system.string object, which basically means that each one of these
03:05data types has some really cool features and methods built in.
03:09So for example, if I define a character variable as the lowercase letter a
03:13right here, I can do some really cool things on it.
03:15I can ask the character, hey, is it an uppercase letter, or it is it a digit, or
03:20is it a letter? Is it punctuation or a white space?
03:24I can do things like convert the character to uppercase or to lowercase.
03:29The same is true of things like strings.
03:31If I declare a variable that holds a string, I can do some really
03:35interesting things on it, because remember, it's an object, and the objects
03:38have built-in methods.
03:39So for example, I can do things like convert the string to upper- or lowercase.
03:44I can search the string to see where a substring appears in the string.
03:49I can do that searching forward or searching backwards.
03:52I can take strings and trim white space off of them.
03:55We already saw how to do things like string.formatting using
03:57the Console.WriteLine.
03:59You can see if a string is null or is empty. And all of these features come built in
04:06to the language, simply because these data types, even though they're primitives,
04:10derive from System.Object.
04:12One of the things to keep in mind is that strings are what's called immutable.
04:17They can't be changed once they are created.
04:20Now you might be saying, well, wait a second Joe.
04:21I've seen you change strings throughout this course so far. What you're talking about?
04:25Well, the thing is that operations that appear to change a string actually
04:29create a new string, and the thing is, this can cause a pretty significant
04:34performance penalty if you're not careful.
04:37So let's take an example. Suppose we had a string variable called Result and we
04:42initialize it to be an empty string, and then we have a loop that executes, say, a
04:46thousand times, and then inside that loop we're saying, result += "some other
04:49strings", you know some kind of thing that we calculated.
04:54Well, even though that += appears to be modifying the string, what's really
05:00happening is, each time this loop executes, a new string is being created that
05:06holds the temporary results of concatenating the string on the end, and then
05:10that new string is assigned to the result variable, and then the old string that
05:16used to be there is just simply discarded.
05:18Now, if you do this a lot in your programs, you're going to hit a pretty
05:22significant performance penalty.
05:23So if you're doing a whole a lot of string manipulation, sometimes it's better
05:27to use some of the built-in classes to do this.
05:29C# provides one of these called the stringBuilder. So what you do is you would
05:33instead of just declaring a variable named result,
05:36you'd build a stringBuilder object.
05:39In this case, I'm using the stringBuilder class to declare a variable called sb.
05:43And then instead of doing a concatenation in the loop, like you see there, I'll
05:46simply use the stringBuilder's Append method. And we will cover objects such
05:50as this later on, but the point here is that I'm not just using a straight string to do this.
05:55At the end, if I wanted to get the whole result of the stringBuilder as one long
05:59string, I'd simply call the Tostring method on it and assign it to a string
06:03variable that called result.
06:05Let's take a look at some examples of using some of the features that we've seen
06:08here for characters and strings in real code.
06:10So I'm over here in my code, and I've got my charsAndstrings project open, and
06:16I've also got my ExamplesSnippets open. Over here in the ExampleSnippets, you
06:21can see that I've scrolled down to the chars and strings sections.
06:25So let's go ahead and copy some of this, so I'm going to copy these lines
06:27right here. Paste those in. So I'm going to save, and don't worry about the little warning.
06:36I am not using the string.
06:37We'll get to that in a second.
06:39So you can see here that I've declared a variable called mychar, which is a char
06:43type, and it's a lowercase letter a. And essentially what I'm doing is
06:47exercising some of the methods that the character class provides for me.
06:50So I'm going to do a whole bunch of WriteLines and write out the results of a
06:55whole bunch of these methods, things like IsUpper, IsDigit, and so on.
06:58So it starts off as the lowercase letter a. So let's go ahead and run the code
07:03and see what happens.
07:05So you can see that the results for these tests are, well, is lowercase letter
07:10a upper? No, that's false.
07:11It's obviously not a digit. It is a letter.
07:14It's not white space or punctuation. And you can see here the results of calling
07:18ToUpper and ToLower on it.
07:20Okay, so let's change it.
07:23Let's change it to say the number 8, and we will save and we will rerun it.
07:27Well, in this case you can see that ToUpper and ToLower have the same result,
07:32because there is no such thing as an upper- and lowercase 8, but in this case the
07:35IsDigit function returned as true.
07:37And I'll leave this as an exercise for you to play with.
07:40What I'm going to now, though, is go back to the Snippets.
07:41I'm going to copy those string tests.
07:48Let's just do some of the string tests.
07:54So in this case you can see I've got my string variable.
07:57It says, "This is a message with a new line," and you can see it's got some leading
08:00and trailing spaces on the front and back. And we are going to do things like
08:04call Trim and ToUpper and ToLower and IndexOf and LastIndexOf.
08:09So let's go ahead and save this and run it. And you can see here that this is a
08:17string with a message and new line and spaces in it.
08:19You can see that the spaces have been cut off. Here the result of ToUpper is
08:24that all the letters have been converted to uppercase.
08:27Here they've all been converted to lowercase, and then we found the indexes of
08:31the letter a and the substring end.
08:32So you can see that even though we've got primitive data types for characters
08:36and strings, they're really pretty powerful, just again, because they derive
08:40from the base System.Object class in C#. And because they are objects, they have
08:45a whole bunch of really useful features that just come built in.
Collapse this transcript
Understanding variable scope
00:00One of the other common "gotchas" that you have to watch out for when you're using
00:04languages like C# or Objective-C or Java or anything else that's a compiled
00:08language is the notion of variable scope.
00:11All variables have what's called a scope.
00:13This is where the variable is visible to the code and can be used.
00:18So let's take a look at an example, and then I'll explain it.
00:21So suppose I had a function named myFunction and inside that function I had a
00:25variable called X, and I've declared the variable X and I've assigned it a value of 10.
00:29And suppose I also have a for loop and inside the for loop I've got a variable
00:34named Y which I'm declaring inside the for loop and the value of Y is being set
00:38to the value of X+20.
00:41That's okay because I can refer to the value of X inside the for loop.
00:44I can declare the Y variable inside the for loop as well.
00:48Now I can also refer to the X variable here if I wanted to use the increment
00:53operator on X outside the for loop; that's fine. And I can also increment X
00:59outside the for loop after the for loop; that's fine too.
01:02What I can't do, however, is refer to the Y variable outside of the for loop. Why?
01:08Because it's not available there.
01:09I've declared it inside the for loop. And in this case when you declare
01:14the variable inside those curly braces, that variable is only valid inside
01:20those curly braces.
01:21That's because in languages like C# variables have what's called a block scope.
01:28Those curly braces define a block of code the same way that the curly braces
01:33near the function define a block of code.
01:35This is not the case in a language like JavaScript, and the reason is because in
01:40languages like JavaScript variables have function-level scope.
01:45When the JavaScript interpreter goes to interpret the function, it first looks
01:49through the function to find variable declarations, and then it lifts them to
01:54the top of the function.
01:56It does that internally;
01:57it doesn't modify your script code.
01:58But it gives all the variables inside the function the same function-level scope.
02:03That is not true in a language like C#.
02:07In a language like C# or language like C or Objective-C or Java, the variable
02:12is only available to you in the block where it is declared.
02:16So let's take a look at this in action, and we can see how it works.
02:21Over here in the code I've got my VariableScope project open, and here in the
02:24Snippets I've scrolled down to the Variable Scope. And I'm going to copy these lines.
02:29I'm going to paste it in right here.
02:32So here I have my loop, and you can see inside the loop I'm declaring a
02:38variable named int var1.
02:41So when I run this program--let's just write it really click--you can see that what's
02:44going to happen is I'm going to WriteLine, the value of var1 at pass whatever I
02:49is is whatever the value of var1 is.
02:51So I'm going to run it, and you can see that it's staying the value of 20 all the
02:55way through the loop.
02:56So now let's take a look at what happens when I try to uncomment this line of code here.
03:00I'm going to try to WriteLine the last value of var1, but I'm going to do it
03:05outside the for loop.
03:07I am going to save, and you can see that I'm getting a little red
03:11squiggle there which basically says, hey, the name var1 does not exist in
03:15the current context.
03:16That's because it's declared inside this for loop.
03:19So if I wanted to do this, I would have to cut that and move it up here and save,
03:25and now everything works fine.
03:27So let's go ahead and undo that. Put it back where it was.
03:30You might be wondering, hey, you know, in other languages I can re-declare
03:35variables in different scopes and they're just given different meanings.
03:38So for example, the C and Objective-C languages let you do something like this.
03:47And what I've done here is I've declared the variable var1 in a separate scope
03:51than the other var1 that's inside the for scope.
03:55Inside the for loop you'd think that this variable would have its own scope and
03:59this will have a different one, but that's not the way C# works.
04:03This can be very confusing to someone who's reading code, and it's also the
04:07source of a lot of bugs in other languages.
04:10So the designers of C# explicitly don't allow variables to be declared in
04:15separate scopes with the same name.
04:17You can see that when I try to do this there is a little squiggle down here
04:20that says, hey, a local variable named var1 cannot be declared in this scope,
04:24because it would give a different meaning to var1, which is already used in a
04:28parent or current scope to denote something else.
04:31So these two variables conflict with each other,
04:33so I can't do this.
04:36It's important to note that this kind of scope-level referencing only works
04:41from the inside out.
04:43So if I declare the variable var1 in here, I can refer to it within the scope;
04:48but if I declared it out here then I would be able to refer to it in this
04:54current function-level scope, as well as all the other scopes that are contained
04:58within the function.
04:59So for example, I could do something like this, and that works just fine
05:06because the for loop scope is contained within the scope for the Main function.
05:12So in fact if I save this and I run it, you'll see that var1 is getting
05:17incremented by 10 each time and now that last little console, that WriteLine that
05:21I've got that says, what the last value of var1 was, is working just fine.
05:26Understanding variable scope is a pretty important part of writing good C#
05:31code, and it's something that you should pay close attention to, especially if
05:34you're coming from a language like JavaScript that does not enforce these kinds of rules.
05:38This kind of thing can bite you, so pay attention to it.
Collapse this transcript
Understanding type conversion
00:00There is one more important concept that we have to understand in working with
00:04C#, and that is understanding type conversion.
00:07If you've come from a language like C or C++ or Java, you've seen this before.
00:12Converting one type of variable to another is called casting, and this is the
00:17kind of thing that pops up in languages that require you to give types to your variables.
00:22You're probably wondering, or at least you soon would be, well, how do I share
00:26data between variables that are different types?
00:29The way that you do this is by casting one type of variable to another.
00:34It's how you convert data types among different kinds of data-type variables.
00:39So for example, suppose I had an integer named i and it is set to the value of
00:4410, and I also had a float and that was set to the value of 20.0.
00:50Suppose I wanted to set f to the value of i. I can just do f=i, and that's okay,
00:57because that's an implicit cast, or a conversion from an int to a float.
01:03Since an int is 4 bytes and a float is larger, there is no risk of data loss here.
01:08The integer can simply be converted into a float and all is well.
01:12The reverse is not true.
01:14If I said i is equal to f, that causes an error, because you need to explicitly
01:20cast from the float to the int, because data might be lost.
01:25You can't fit all the precision of a float into an integer automatically.
01:30However, if I did this, if I said i is equal to, and then in parentheses I put
01:35the word int in front of the variable that I'm casting from, that's now okay.
01:41I've explicitly cast, or converted, from the floating-point value to the integer value.
01:48You'll see this all over languages like C and C++ and Objective-C and Java, and now in C#.
01:55So let's go over to the code and actually see it in action. So here I am!
01:57I've got my Conversion project open, and I'm going to open up my Snippets file.
02:03That's right there.
02:04So let's go ahead and scroll down to the Conversion section, and that's right
02:10here, Type Conversion.
02:12So I'm going to copy those lines, and I'm going to paste them in here. A couple of things.
02:20You can see that I've got an integer, a short, and a float.
02:24So in this case, the integer starts out as 10 and the short starts out as 5.
02:31Now, you'll notice that I can simply assign the value of x to the value of i. Why?
02:36Because x is a short. It's 16 bits, whereas the int is 32 bits, so there is
02:41no loss of data here.
02:42That's okay; the complier doesn't complain.
02:44However, if I try to go the other way, if I try to set the value of i into x,
02:51well, there is data loss here, or there's potential data loss here.
02:54What's going to happen is I've got 32 bits trying to go into a 16-bit bucket, and
02:58you can see that little squiggle is saying, hey!
03:00Error, cannot implicitly convert type 'int' to 'short', are you missing a cast? Well, yes, I am.
03:05All I'm going to do is say--if I put the word short in front of the i variable
03:13inside parentheses, that says to the compiler, hey,
03:16compiler, take the value of i and explicitly convert it into a short.
03:21Now, you notice that that little red squiggle has gone away, and everything is just fine.
03:26So let's go ahead and put a Console.WriteLine in here.
03:36We'll write value x, and we'll write out x. So let's put a Console.ReadLine at
03:49the bottom, and let's also comment out that error for the moment.
03:56So let's save it and run it.
03:58You can see that the value of x is 5. Why?
04:01Because here we put x into i, and then we just put i back into x, and since x
04:07started out as 5, that's what's happened, so now x is back to being 5.
04:11So let's suppose we comment this line out and we make i something that a
04:18short can't handle,
04:20so something like 800,000.
04:23So now when we run this, you'll see that the value of x is 13,568. Why?
04:30Because some of the bits of the integer got stripped off.
04:34Remember, the integer is 32 bits, but the short is 16 bits.
04:38So 16 bits of information got stripped off, and what was left over was what could
04:43fit in those 16 bits, and that worked out to be 13,568.
04:48So that's the kind of thing you need to watch out for when you're working with
04:51type conversion because some types of containers are larger than others.
04:55Let's go back to the code here.
04:57Let's go ahead and get rid of these two lines. And let's look at the floating-
05:02point versions instead.
05:04So here you can see I have the floating-point number f, which is equal to 20,
05:11and here I've got the i, which is now 800,000.
05:14Again, I can assign the value of i into the value of f. Why?
05:18Because floats are larger than integers; that works just fine.
05:21Same story down here.
05:22I'd have to actually cast the float to be an integer, and in order for that
05:29to work, I simply put the word int inside parentheses, and now that converts
05:34the value of the float into an integer, which can be stored inside the integer variable.
05:39You'll see this kind of thing all over C# code, and you'll see it in
05:43other languages as well.
05:44It's important to understand how conversion and casting works because you'll be
05:47using it in your own code.
Collapse this transcript
5. Custom Classes and Objects
Object orientation refresher
00:00Up until now, I have been talking how C# is an object-oriented language, and
00:05you've been seeing me use objects throughout some of the previous examples.
00:08And we've reached the point now in the course where we actually need to learn how to
00:11define and use our own objects in C#.
00:13If you are going to be a C# programmer, there's no getting around the
00:16object-orientedness of the language, and now is as good a time as any to take
00:20a look at how to get started with the object orientation in C#.
00:24So as I have mentioned many times C# is of course an inherently object-oriented
00:28language. There's no getting around this, and in fact, everything that we have
00:31been doing up until now has involved objects in one way or another.
00:35The variables that we've been defining, those are objects--those integers and
00:38strings and everything else.
00:40We have been using the console object to write output to the console window, and
00:45even the program itself that we've been using is itself an object.
00:49So objects are everywhere in C#, and your programs will not be any different.
00:54Programs are basically collections of objects.
00:56So objects contain data, and they contain the logic that operates on that data.
01:01It's a way of keeping related data and logic in the same place.
01:05And of course objects can communicate with each other, because if they didn't
01:08communicate with each other, not a whole lot of useful work would get done. And of
01:11course not only do the objects communicate with each other, they communicate with
01:15the program that hosts them, because the program itself is an object, and this is
01:19how your programs communicate with the .NET framework as well.
01:22In C# there are three main terms
01:24you are going to have to keep track of:
01:25there is class, there's interface, and there is object.
01:29Interface is a little bit advanced, so we are not going to focus on that right now.
01:33We are just going to focus on the class and object terms for the remainder of
01:37this section, and we'll see a little bit about interfaces later on.
01:41Classes in C# are one of the most common type that you will come across, and a
01:45class essentially provides a blueprint, or a description, of what an object looks
01:51like and what it does.
01:52The blueprint, or description if you will, defines things like what kinds of data
01:57that an object of a certain type holds, and it also defines what kinds of things
02:01that an object can do.
02:03It's important to keep in mind, however, that a class is just a definition.
02:06It's a description.
02:07It's not the actual object itself. For example, when you have a blueprint of a
02:11house, the blueprint you can think of as being a class, but it's not the actual house.
02:16When you build the actual house, that's the object; the blueprint just provides a
02:20description of how to do that.
02:22In your C# programs, you'll usually defined your own classes to do whatever
02:27custom work you need to get done, as well as using the classes that are provided
02:32by the .NET framework.
02:33The .NET framework is pretty full featured.
02:35It provides hundreds of classes for doing all different kinds of things, and
02:39you'll take advantage of these classes as you build your own applications. For example,
02:43suppose we were building an application that managed the list of to-do items.
02:48You can imagine that we would have a class to handle the to-do items;
02:51we would probably have another class to group all of those to-do items in a to-do list.
02:56And these are classes that your program would define. But there's a whole bunch
03:00of other classes that the .NET framework would provide for you, things like
03:03dates and times and array lists and classes for working with strings and
03:07communicating with the Internet.
03:09These are all provided by the .NET framework, and as you build your applications
03:13and learn more about C# and .NET, you'll use more and more of the .NET classes to
03:18round out your applications' functionality.
03:20So what do classes define?
03:22Classes essentially define two major things, and these are called the members.
03:27The first set of things is fields and properties and the second set of things are
03:32methods or functions.
03:34Nowfunctions and methods are pretty much the same thing, but the word method
03:38is what's commonly used in object-oriented terminology, so that's what I am going to use here.
03:42The fields and properties are the kinds of data that the object holds and works with.
03:47The methods are what the object can do;
03:50this is their logic, the functionality that contains in the object.
03:54Again, if you go back to our to-do list item example, you can imagine that a
03:57to-do item might have a name, a description and a priority, then something
04:02like a due date, and then we would need to have methods to operate on that
04:05data--for example, setting the description and changing the priority, and marking items complete.
04:10These are what classes defined and as you build your own classes, you will define
04:14your own fields and properties, and you will write your own methods to work on
04:17those pieces of data.
04:19Classes can also inherit attributes and methods from other classes, and this is
04:26a very important concept in object-oriented programming, so it's important that you understand this.
04:31For example, let's imagine that I have a class that I want to define called class A, and class
04:36A contains a couple of fields like name and age and it has a function in it--in
04:41this case it called sayHello().
04:42Now you've probably already seen examples like this, and in C# you would refer to
04:47these fields and functions by using the dot notation. So you would say A.name,
04:51A.age for the fields, and A.sayHello() to call the method.
04:56I can also define a class that inherits from class A, and in object-oriented
05:01terminology this is called creating a subclass.
05:04So if I want to create a class B that inherits from class A, I would define
05:09class B, put a colon after its name, and then put the name of the class that the
05:15class inherits from.
05:16So here you can see the class B with the colon and the A means this class B and
05:21it inherits from class A. And in class B, I've defined a couple of things. I've
05:25got another property called address and a function called sayGoodbye.
05:29So again you would refer to this using standard.notation for the class B, like
05:34B.address and B. sayGoodbye. But because the class B inherits from class A, it
05:39also has all of the fields and properties that class A has.
05:42So class B also has a sayHello function and the name property, even though I
05:46haven't defined it in class B; it just gets all those things because it
05:50inherits from class A.
05:52So in object-oriented terminology, we say that class B is a subclass of class A,
05:58and class A is class B's superclass.
06:02You'll see these terms used throughout object-oriented documentation whenever
06:06you read documentation on web. Especially in MSDN, you'll see terms like that.
06:11You can think of C# objects as being a kind of stamping machine.
06:17So classes, as I mentioned earlier, are used to create individual objects, and each
06:22object that is created from a class is called an instance.
06:25So you can think of this as some kind of machine that stamps out physical parts.
06:28Suppose I had a class definition called person and the Person class had the name and age
06:33and SayHello function.
06:35Each time I made an object, that's called creating an instance of class person.
06:41So here I've got three instances of the Person class.
06:44I have got person A, B, and C, and each one of these real objects has actual data
06:49that's filling out the class.
06:51So we're using the class definition, or the blueprint, to actually make
06:55instances of that class.
06:57So why would you use classes and objects?
06:59Well, using classes and objects, especially in C#, which is objected-oriented
07:03language, really makes it easier to maintain and build applications.
07:07First, it helps abstract ideas away from a specific implementation, which allows
07:12you to focus on the core parts of the program.
07:15Since the .NET framework provides a whole bunch of classes that cover common
07:19areas of functionality that you don't have to write yourself, you can focus
07:22on building the specific parts of your program that are only pertinent to
07:26your business logic.
07:27You can then reuse all the classes that .NET provides for you, which really makes
07:31developing applications a lot faster and a lot easier.
07:34Using classes and objects also helps encapsulate the programs functionality
07:38into understandable pieces, because each object has its related data and logic
07:43all kept in one place.
07:45To go back to want to-do list item example, each to-do item would have not only
07:49the information about that particular to-do item, but the logic that operates on it.
07:53So you wouldn't have different pieces of logic scattered all over the place in
07:56different locations without knowing where each one is.
07:59It just makes it easy to understand the way that an application works.
08:03It also helps organize a program into natural parts that could be easily
08:06extended, and this is sometimes referred to in the object-oriented world as factoring.
08:11Once you have factored your application into its natural parts, the object
08:15itself and the program comes to mirror real-world constructs and ideas.
08:19Again, taking a page from out to-do list example from earlier, when you make
08:23objects that mirror real-world constructs like a to-do item and the to-do list and so on,
08:29that makes the program a lot easier to understand and go back in and
08:31maintain years later.
08:33So using classes and objects is a really fast and easy way to build applications
08:38that you can maintain in the future and other people can work on as well and get
08:41up to speed on quickly.
08:43So we reach the point now where we've completed our refresher into the world of
08:47object-oriented programming, and we are going to spend the rest of this section
08:50seeing how to define classes in C# and build our own object-oriented programs
08:56in .NET and C#.
Collapse this transcript
Defining a class
00:00Probably the best place to start when we define our own classes in C# is to see
00:04how we define a class before we can start using them.
00:07So we are going to take a look here at how to define a class using C#, and
00:11then we are going to take a look at how to use it as we move through the rest of the section.
00:16So to define a class in C# you use, surprise, the class keyword.
00:21So you say the word class, and then you have to give it a name. In this case, I
00:25am going to use myClass. And you can use whatever combination of letters and
00:30numbers you want, as long as it starts with a letter and is a valid C# class
00:33name--you can have special characters or anything like that.
00:36So I've got class myClass, and then I am going to define some curly braces, which
00:41are going to define the code for this class.
00:44Once we have got the class definition laid out here, we can start adding some
00:49fields and some methods.
00:51You can add fields and methods in whatever order you like.
00:54You can define field and then method and then field and then method if you want to.
00:58My practice that I use is and I define all the fields upfront near the top, and
01:03then I put all the methods at the bottom.
01:06So let's define some fields.
01:07I have got two fields here:
01:08one is called myInteger; one is called myMessage.
01:11We have got an integer and a string.
01:13We could use whatever data types we'd like.
01:15In this case, I have just got a couple for examples.
01:18Then I am going to define a method.
01:20And here I have defined a function called myFunction, or method--whatever word
01:25you want to use--and it returns an integer.
01:28In this case, it returns the myInteger field. So when the code that uses this
01:33class calls myFunction, it will simply return the value of myInteger.
01:37For the moment, don't pay too much attention to that word "public" that's in
01:41front of the word "int."
01:42We are going to get into what that means a little bit later in this section.
01:46For now, just assume that the word public means we have to put it there so that
01:50the rest of the world can see this function.
01:53This is pretty much a complete class definition;
01:55we could just stop here if we wanted to. But it's customary in C# to define
02:00what's called a constructor.
02:01A constructor function has the same name as the class.
02:06So to define the constructor-- you can see I have done that here--
02:09I've got a method call myClass, and in this case is this method is taking a
02:13string argument which uses the value of the argument to set the initial value of
02:17the myMessage member field. And again,
02:21I have got the work public in front of it, and I don't want to pay too much
02:23attention on that right now--we will get into that.
02:25But what I have done here is defined what's called a constructor, and the
02:29constructor takes the same name as the class itself. And you can give it however
02:34many arguments you want, or you can give it no arguments at all.
02:37Now, if you don't define a constructor, the C# .NET framework will automatically
02:42put one in for you. But it is customary to define one, because you use
02:46constructors all the time to initialize the value of class fields.
02:50So now that we've done that, we can go ahead and take a look at how we might
02:54create and use an object using a class that we've defined.
02:58So in C#, the way that you create, or to use object-oriented terms instantiate, an
03:05object is to use the keyword "new." And it's an operator,
03:08so the way that you do this is use you use the type of myClass, and that's the
03:12class that we defined earlier.
03:14Then you give it a variable name, myObj.
03:16So here instead of saying int and then some myInteger, which is a built-in C#
03:21.NET type, we are using the type that we've defined called myClass. And we have
03:25got a variable called myObj, and then we simply say = new myClass.
03:30And in this case we're passing in a string to the constructor function--
03:34this is how the constructor gets called-- so that string will become the initial
03:38value of that myMessage field.
03:41To use the fields and methods of a class that you have instantiated, you use the dot operator.
03:46And again, we've seen this throughout the course so far, but let's just make it official.
03:49So let's imagine I have an integer called myResults and this is some variable I have created.
03:54I can then refer to the methods or fields of the object by using the dot notation.
04:00So in this case, I'm calling some imaginary function called AddNumbers on my object.
04:04We haven't defined it yet, but we could. And you can see it takes two
04:07arguments, and then it returns an integer result.
04:10So use the dot operator to reference the fields and methods of the class.
04:14Classes can also have special members called static members.
04:19Static members don't require you to create, or instantiate, an object's instance
04:24in order to use them.
04:26That may sound kind of weird, but we've actually seen this throughout the course so far.
04:30Every time we've used the console object, for example, you notice that we
04:34haven't had to say "new console."
04:37We simply use the name of the class, which is console, and then dot and then
04:41the word WriteLine.
04:42So we are calling what's called a static, in this case, a member method, called
04:47WriteLine, and it belongs to the entire class.
04:50You don't have to have it be part of a specific instance of that class.
04:55So let's take a look at the difference between instance members and static members.
04:59Instance members of a class--
05:01whether it's a field or a method--get copied each time a new object is created.
05:07Static members, however, belong to the entire class, and there is only one of them.
05:11So let's take a look at an example.
05:13Let's imagine we have a class that defines the notion of a bottle of wine.
05:17For each bottle of wine, you are going to have something like a year and name
05:21to go along with it, and you would have a constructor function that looks
05:25something like this, where when you create a new instance of the wine bottle.
05:29you will pass in the name and the year. But suppose we wanted to keep track of
05:33how many bottles we had in our cellar.
05:35Well, it seems a little silly for each instance of the wine class to keep track of
05:38its own bottle count; we only need one variable to do that.
05:41So we would have a static member called bottleCount. And in this case,
05:46bottleCount belongs to the entire wine class, and each instance of the wine
05:50bottle will be able to reference this member, but it doesn't belong to any one of them;
05:54it belongs to the entire class.
05:56So here in the constructor, we don't need to refer it to using the class name,
05:59because we are in the constructor for the class. But if we're using code that
06:03was outside the class--again, think back to the Console.WriteLine example--
06:08we would simply put the name of the class in front of the function, and that
06:11says to the C# compiler, hey, I'm calling the static member called this
06:15function, or whatever it is--
06:17in this case, its not a function at all; it's a member of variable--
06:20and I am referring to the variable that belongs to the entire class.
06:24So let's take a look at some code that makes all this work, and then it will
06:28become a little bit clearer.
06:30So over here in C# Express, I've got my DefiningAClass example open. I have
06:35also got my ExampleSnippets.txt file open, and I've scroll down to the
06:39DefiningAClass section.
06:40So I am going to start off by copying some of this code over.
06:43So we will copy over the class definitions, just a few of these lines right here.
06:48And the nice thing about C# is you can put the code anywhere in the class file.
06:51Now I could make a separate file to contain the wine class, but we will do that
06:55a little bit later. For now in this example, I am going to have the two classes
06:58be in the same file.
07:00So now we have defined the class called myClass and we've got a couple of members here.
07:04We have an integer and a string member, and you can see that we have declared
07:07a static integer called myStaticInt. And again, don't worry about that public keyword for now;
07:12we'll just get to that a little bit later.
07:14Okay, let's go back over here, and let's copy over the functions, and we'll put those in the class.
07:27So now we have a complete class definition.
07:30We have our member variables;
07:32we have a function called myFunction, which returns an integer--in this case,
07:36it's the myInteger member; and we have the myClass Constructor.
07:40When we call the myClass constructor, we're initializing the values of myInteger
07:44and myMessage to some initial values.
07:47And we also have the myStaticInt, which is being initialized to the value of 100.
07:52So now let's copy some code over that actually exercises the class and see what happens.
07:58I will just copy these lines right here, scroll down to the main function and put them in.
08:11So let's take a look at the code and see what's happening.
08:16The first thing that we are doing right here on line 30 is we are instantiating
08:20a new instance of the myClass object, and once we've done that, we can then use
08:26the various members of the class.
08:29So on line 32, you can see that we are using the console to write out the
08:33results of myFunction. And in this case, we are using the instance, which is the
08:38myC variable, to call the myFunction member function. And in the next line, line
08:4333, we are going to use the static member. But instead of using the myC
08:47variable, we are going to use the myClass name, because it's a static member, and
08:52we need to refer to it on the class name itself.
08:55So we are going to go ahead and build and run this, and what we should see is the
08:59result of calling myFunction. Let's just scroll back up here.
09:03So myFunction is going to return myInteger, which you can see on line 21 is being
09:08initialized to 50, and then we have the value of myStaticInt, which is 100.
09:12So let's go ahead and run this, and you can see that the results of calling
09:16myFunction is 50 and using the static member is 100.
09:20Let's go back to the code.
09:22Using this example, you can see how we have defined member variables which are
09:27both local to the instance of an object and the static member which belongs to
09:31the entire class, and we've seen how to define and instantiate a new class
09:36using the new operator.
09:37As we move through the rest of the course, we will be doing a lot more of this.
Collapse this transcript
Using access modifiers
00:00The C# language provides a feature called access modifiers, which allow you to
00:05control how the member variables and methods of your classes are seen by the
00:10outside world--in others words code that uses your objects.
00:14And if you're coming for the language, like Java or C++, you've probably
00:18seen something similar.
00:19JavaScript does not have this kind of idea in it, so if you're coming from
00:24JavaScript, you might want to pay attention to this.
00:26So by default when you define data and methods in your class, those data fields
00:32and methods can only be used inside of that class itself.
00:36You have to choose to expose them to other code that's going to consume your classes,
00:42and this is what access modifiers let you do.
00:44They let you specify how programs-- including your own--that use your classes can
00:49access their data and their methods.
00:52So let's take a look at how this works.
00:54Suppose we had a class and I have a class here called myClassName, and we've
00:59got some fields in it.
01:00So we have got an integer, and we've got a string, and we have some method called myFunction.
01:05By default, all of these are what's called private. Only the class that
01:10defines these can use it.
01:13We need to change that in order for code that wants to consume our class to be
01:17able to access the members of this class.
01:21The way that we do that is by using what's called access modifiers.
01:24And if you watch the preceding the movie, you'll have probably noticed me
01:28using the word "public."
01:29Well, there are a couple of different ways to expose members of the class to
01:33code that wants to use them.
01:34So let's take a look. The first one is called the private modifier.
01:39When you use the private access modifier, it means that the member of the class
01:44who is marked as private can only be accessed within the class itself.
01:48Now this is the default setting, so if you don't specify private, the C# compiler
01:54defaults to making a member variable or a member method as private.
02:01The next one is public. A public class member can be accessed by any other
02:07object that uses the class, and this is why I was using the public keyword in
02:11the previous examples so that our code can consume that particular member of the class.
02:17The next one is called protected.
02:20A protected class member can only be accessed within this class or any subclass--
02:26in other words a class that inherits from this class.
02:30So we have got private, we have got public, and we have got protected.
02:33So there is one more, and it's called internal, and this is a class member that
02:37could be accessed by any class in what's called a same assembly. An assembly
02:42is a package of code, like a library or another program, but this is an advanced feature of
02:47C#. I am not going to cover it here in this course. Just know that you might see
02:51the word "internal" every now and then.
02:53It's sort of like protected, but it means that only a group of related code
02:57can use it. But for the purpose of this course we are going to use private,
03:00public, and protected.
03:02So in order to see how his work, let's jump over to the code and define a class
03:07that uses these, and you can see what happens when you try to use code that uses
03:10each one of these access modifiers.
03:12So over here in the code I have got my ExampleSnippets open for the
03:16access modifiers example, and over here I have got my program file.
03:21So here is what we are going to do. First, we are going to define a new class, and
03:24in this case we are going to put the class in a separate file.
03:27So what I am going to do over here is I am going to right-click on the project
03:31name called AccessModifiers, and I am going to go down to the Add submenu, and you
03:36can see that I can add items to my project.
03:38What I am going to do is I am going to add a class, and the Add class
03:42dialog comes up. And you can see there is a whole bunch of things that we can
03:45add, all kinds of classes.
03:46What I am going to do is just make sure that the default one here in the list
03:49called Class is selected, and then I am going to give my class a name. And in
03:53this case I am going to call it my Wine class. I'm going to click Add,
03:59and you can see that the file for Wine.cs got added, and you can see that the C#
04:07Express application has done a whole bunch to work for us. First of all, it's
04:10automatically put the Wine class into the same namespace as our example.
04:13It's included the using statements for the .NET framework that we are going be
04:17using. And right here you can see it has provide a definition for class Wine.
04:21So let's go back to Snippets.
04:22What we are going to do now is fill out that wine class with some default code.
04:29So I am going to copy these lines here.
04:31I will go back to my Wine class, and I am going to paste them in.
04:35So now in our Wine class we have a couple of different members.
04:38We have the wine name,
04:40we have the wine price, and we have the wine description. And you can see that all
04:43of those are public,
04:44so any code that wants to use this Wine class will have access to those member variables.
04:50We have a decimal variable here called discount, and that's marked as private.
04:56So nobody outside this class can see what that is. And then we have a public
05:00constructor, which takes a wine name and a price. And inside the constructor you
05:05can see that we've got the name and price public variables that are being set to
05:10the arguments that are being passed to the constructor, and then we give the
05:13discount variable and initial value as well.
05:16And we can do that here because this is our class and we can refer to our own
05:21private members within our own class.
05:23So let me save this, and let's go back to the snippets.
05:28Now let's go ahead and copy over some code.
05:30I want to copy these two lines first, and we are going to go to the main function,
05:33and I am going to paste tem in.
05:35So here you can see that I have got two instances of the Wine class being
05:40created, and I am passing in some default values for names and prices.
05:44So let's write some code now that exercises some of the fields of the class.
05:48So for example, if I wanted to refer it to the name of one of the wines, I
05:52could simply write string and give it a variable name, =, and I could say w1.
05:57And now watch what happens when I press dot.
05:59Now when I press the dot, C# Express is looking at the class description and
06:03saying, okay, what can the code in this particular area see inside that class?
06:08And we have got a couple of default things, because we always derive from the
06:11base system object, but here's the name and the price fields that I've defined.
06:16Here is the description field, because those were all public, and you can see that
06:19this is an alphabetized list. What's missing? Well, the discount field is missing. Why?
06:24Because it's private, and because it's private, my code can't see it.
06:28So I can go ahead and refer it w1.Name all I want to, but if I try to refer to
06:33the discount field--let me make a decimal and we'll call it dsc--
06:38if I say w2.discount, now watch what happens. I am going to save this. See, that
06:45little red squiggle showed up and if we mouse over that little squiggle, we say
06:49error. It says the AccessModifiers. Wine.discount is inaccessible due to its
06:54protection level. Go back over to the wine code.
06:57You can see that this is private, so private members can't be referred to
07:01outside of the class that defines them.
07:04Now we could also have made it protected, and protected would also result in an
07:08error, so let's just change that.
07:09Let's just make this private and make this protected, and we will save, and we
07:14will go back over to the program, save and compile. And you can see that we still
07:19have that same error there, right, even though we made it protected, because in
07:22this case we don't have a class that descends from wine, so it's not inheriting
07:28the discount field, and because its protected, only subclasses can see it.
07:32So this is how you use the various access modifiers of C# to selectively expose
07:39member variables and member functions to code that's going to consume their
07:42objects. And the reason you want to do this is because in good programming
07:46practices, you don't want to just make everything public.
07:48You want choose how you expose your code to consumers of your code. That way you
07:53can change the way things are implemented inside your class without breaking
07:57people that are consuming the class in other programs.
08:00So using access modifiers, you can selectively expose parts of your program
08:05to other consumers.
Collapse this transcript
Defining properties
00:00Okay, I promised you we would get to some really cool features of C#, and we're
00:04about to do that right here with defining properties.
00:05Properties are a really neat feature of the C# language, and I really like using them.
00:11In this section, we're going to explore what they are and how they work.
00:13Properties are essentially like data fields, but they have logic behind them.
00:18And from the outside, they look like any other member variable, but they act
00:23like a member function.
00:25They actually have code behind them.
00:26Now you define them like you would a member variable, but they have a get and a
00:32set section of code added.
00:34And they can use access modifiers just like member fields and member methods can,
00:40and we explored those earlier.
00:43Let's take a look at an example of what a property looks like.
00:47So let's imagine we had a class called myExample and we had some private member
00:50variable called someValue.
00:52Now because this is private, there is no way for someone who's consuming this
00:57class to get at that data.
00:59Now we could make it public, which exposes the implementation of the class to the
01:04outside world, which is not a very good programming practice.
01:06You really want to keep the inner workings of your class private and then choose
01:10to selectively expose data.
01:12We could also just make a member function, which would allow an external consumer
01:17of this class to get the value and set the value.
01:19Or we could make what's called a property.
01:22A property is defined like this. I'm making a public integer property called
01:28CurrentValue, and instead of making it look like a member of function with
01:33parentheses and arguments and so on, all I have to do is define the name of
01:38the property with two curly braces and inside I put the word get. And
01:43the word get here is essentially going to return the value of that private
01:48integer that I have.
01:49And then to set this value, I have the word set.
01:53And in the set code, I'm setting the internal someVal property to this word value.
02:00And value is implicit.
02:01C# just simply generates that for you.
02:03Let's see how this actually works when you consume this.
02:06So to do this, I would define myEX variable, which is an instance of the
02:11myExample class. And I'm creating a new myExample object there.
02:15If I wanted to get the value, I would just do this.
02:17I have an integer i, and I say myEX.CurrentValue.
02:22That will trigger the get logic.
02:24And in this case, the get logic is pretty simple.
02:26It's returning the value of that internal private variable.
02:29And if I wanted to set it, I would do this:
02:31myEX.CurrentValue = 5, and that will trigger the set logic.
02:35And the value of that special value keyword there in the set logic would be set
02:40to an integer whose value is 5.
02:43The C# language and .NET just takes care of all that for you.
02:46You don't have to declare some argument called value;
02:48it just magically shows up.
02:51So you can have automatic properties.
02:54Let's suppose, for example, I had my class, which I declared up above in the
02:58previous example. So I've got myExample class here with my private someVal int,
03:02and I've got the get and the set.
03:04Since all that this example is doing is getting and setting the value of that
03:09private internal variable,
03:10I can rewrite this very simply, just like this.
03:14I have my class, and then I have my property, and all I do is have the words get
03:19and set, and that's all I need to do.
03:21This is called an automatic property.
03:25You can also have read-only properties, and you can have write-only properties.
03:29Read-only properties and write-only properties are properties that can only be
03:31read and can only be written.
03:33So let's take a look at an example.
03:35Using the same example we've been using up until now, I have my example class
03:38with my private variable. And inside my public int CurrentValue, I have get
03:44and return someVal.
03:45Now if I don't define a set, then the property is read-only because there is no way to set it.
03:50All I can do is get the property.
03:52Alternately, I can define just a set.
03:55If I don't define a get, then the property is write-only.
03:59You'll very rarely see write-only properties.
04:01Properties are pretty useless.
04:02You can't actually get their value.
04:04But you can do this.
04:05So if you don't define a get, or you don't define a set, then the property is
04:09either read-only or write-only.
04:12All of this is pretty fun, but why would you use properties? A couple of reasons.
04:16First, properties can be calculated on the fly.
04:19So if you wanted to expose a property that looks like a member variable but has
04:24some logic behind it that actually gets calculated on the fly whenever it gets
04:27accessed, read, or set, then you can use a property for that.
04:31Properties also provide complete control over the data field access, because the
04:35logic is hidden from the object's consumer.
04:38The consumer of the object's property doesn't need to know how it's calculated,
04:41or what's being calculated.
04:42And if later on down the line you go back and you change the way this object
04:46works and the way that that property is calculated changes, then the people who
04:51are consuming your object don't need to worry about that.
04:52They just simply go ahead and keep on referring to that property, but the logic can change.
04:58Properties also promote the idea of encapsulation.
05:01We've talked about this a couple times before in this course.
05:03What you're doing is you're taking the logic that implements that property and
05:06you're hiding it from the consumer.
05:08So they don't need to worry about how it works.
05:11Let's take a look at an example of how you'd have a property whose value is
05:14calculated on the fly.
05:16Let's imagine I had a class that represented a wine, and in that class, I have a price.
05:23I could define the price as just a public member variable, like I've done here.
05:28And I've got some private ones, like say that there is a wholesalePrice and
05:32there is a retailMarkup.
05:33So when a wine store buys wine, they don't pay the retail.
05:36There is a wholesale price they pay, and then there is a markup that they apply
05:40to the wholesale price which is what the real price is.
05:43So rather than having a public member variable, I could expose a public property.
05:48And you can see here I've only defined a get;
05:51there is no set here.
05:53And when the consumer of this Wine object wants to know what the price of the
05:56wine is, you can see that the logic inside the getter is simply multiplying the
06:01wholesalePrice times whatever the retailMarkup is.
06:04So I can have some code that goes out and figures out what my retail markup is
06:08based on some other parameters I've got in my business,
06:10and the consumer of this Wine class has no idea how or why I'm doing that.
06:15They just simply ask what the retail price is by accessing the property and it's
06:19calculated for them on the fly.
06:21Let's jump over to the code and define some properties in one of our classes
06:24and see how this works.
06:26I'm here in my DefiningProperties example, and I've got my ExampleSnippets open
06:32right here. And I've scrolled down to the Properties section, and I've got a Wine class here.
06:38So what I'm going to do is go back over to the program code, and I'm going to
06:42make a separate class file for my Wine class. And this just promotes the idea of
06:46encapsulation. And we've already done this once before, but if you skipped over
06:49that part, or you need a refresher, just follow along.
06:51So I'm going to right-click on the project name, and I'm going to click Add, and
06:56then at the bottom of the Add menu, I'm going to add a class. And I'm going to
06:59call this my Wine class.
07:00First, I'm going to make sure that the Class option is selected there,
07:04and then I'm going to come down here and type in Wine.cs, and I'm going to add that.
07:11Visual C# Express has made a new Wine class for me.
07:14Let's go back over to the Snippets, and let's just copy this class in its entirety over.
07:23Copy this into the Wine class, and let's save that.
07:29So now we have our Wine class defined.
07:31Let's go back over to the program, and let's copy in some other code from the
07:35Snippets, which is right here.
07:43First, let's just copy these few lines, and we can explain what's going on.
07:51Let's take a look at the Wine class to see what we've done, before we go any further.
07:56Here is my custom-built object.
07:57It's a class that encapsulates the notion of a wine bottle. And you can see I've
08:02got several private members here.
08:05And because they're private, code that is not inside this class can't see them. So I have a Name.
08:10I have a Year.
08:11I have an appellation, which in the wine world is where the wine comes from.
08:15I have a wholesalePrice, and then I have a retailMarkup of 1.35, so I've got 35%
08:20markup on whatever wine I buy.
08:23Then I've got a property called Price, and you can see that the price is
08:27being calculated on the fly by multiplying whatever the wholesalePrice is
08:30times the retailMarkup. And in the setter case, I'm setting the
08:34wholesalePrice to the value.
08:36So I'm not actually setting an internal price variable;
08:39I'm just setting the wholesalePrice which would have been calculated by the retailMarkup.
08:44I also have a property which is a string called the menuDescription.
08:47And if you've ever been in a restaurant, you've probably seen this. Wines are
08:50usually described on wine lists as having the year, followed by the name, and
08:54sometimes where they've come from.
08:56So I've got a string property that's being built up on the fly right here from
09:00the private internal properties that I have.
09:02And then I have my public constructor, and the constructor is what creates a new
09:07instance of the Wine object.
09:09And it's just taking a bunch of arguments and setting them into the private
09:13internal member variables.
09:14So let's go back over to the program, and you can see here that I'm instantiating
09:19a couple of instances of the Wine class.
09:21I've got a year for each one, I've got a name, and then I've got a string that
09:25explains what the origin is, and then I have a wholesale price which is going to
09:30be used to calculate the retail price.
09:32So let's go back over to the Snippets.
09:34Let's do some exercising here.
09:35We're going to write out some of these property values.
09:37I'm going to just copy these lines of code right here.
09:39I'm going to go back over and paste them in.
09:44In the first case, I'm going to write out the menuDescription and the Price of the two wines.
09:52So I've got Wine 1 and Wine 2.
09:53And remember, back in the Wine class, each one of these properties is
09:57being built on the fly.
09:58So I'm going to save, I'm going to build, and I'm going to run this.
10:04And you can see that I've got Wine 1 is a 2003 Chateau Ste.
10:07Michelle Merlot, from Seven Hills, and it's $31.72. And then I've got a
10:12Mark Ryan Dissident that's from Ciel du Cheval, and that's $54.
10:16But remember, those aren't the numbers that I put into the constructor.
10:19If you look at the constructor, I've got 23.50 and 40.
10:22The reason why those numbers are coming back differently is because--let's go
10:25back over to the Wine class--is because of this logic right here on line 20.
10:31On line 20, I'm taking the retailMarkup and multiplying it by
10:34the wholesalePrice.
10:35But from the point of view of the code's consumer--let's go back to the program--
10:39you can see all I'm doing is accessing this Price property.
10:41I don't have any knowledge of how that's being generated behind the scenes.
10:45Let's go ahead and change the wholesalePrice of one of the wines using the
10:48setter, and then we'll write out the new price. Paste that in here.
10:57What we're doing now is using the setter logic of the Price property.
11:01Here I'm changing the wholesalePrice of Wine 2 to $45,
11:06and then I'm going to write out the wine description, and notice how the retail
11:10price has automatically changed because of that calculation logic.
11:14So I'm going to just run this.
11:16And you can see that in the first case
11:18it's $54, but because of the price that I set here in the setter, the new retail
11:24price is being calculated as $60.75.
11:26Okay, let's go back to the code.
11:29The reason why I use properties is because you want to encapsulate some logic
11:33inside your class, give it the appearance of a member variable, but it has logic
11:38behind it that determines how that property is calculated on the fly.
11:42And you can use this technique to expose private internal data in your class in
11:46a controlled fashion, and you can get really creative with this.
11:50Suppose, for example, I wanted to log every time somebody changed the
11:54wholesale price of a wine.
11:56Well, here in the setter logic, I could just simply add some code that would
12:00write out to a log file when the price was changed. Or let's suppose I wanted
12:04to use my debugger to set a breakpoint on whenever a value of the property was changed.
12:10You can't do that on a private internal variable, but you can do it on a property.
12:14So properties are really versatile, and they make your code a lot easier to
12:17encapsulate and expose and make consumers use the classes in a way you feel best
12:21they should be used.
Collapse this transcript
Understanding value and reference types
00:00Now that we've learned how to create our own classes in C#, we've come to an
00:04important point in the course where we need to learn the difference between
00:07value types and reference types.
00:09C# has two main types:
00:11there's value types and there's reference types.
00:14Value types are all of the primitive types that we've learned about so far,
00:19things like integers and longs and shorts and decimals and chars and
00:23booleans and so on.
00:24And there's also a thing called struct, which we haven't covered yet, but we
00:28will cover later on in the course.
00:30Anyway, those are the value types.
00:32Reference types are classes, arrays, and a couple of things called delegates and
00:37interfaces which, again, we haven't yet covered, but we will cover later.
00:41So why is there this difference, and what's so important about it?
00:45The main difference between value types and reference types is how they
00:49are handled in memory.
00:51And the best way to learn this is to see an example.
00:54So we're going to compare the value types with the reference types.
00:57Now, for a value type, let's take a really simple example.
01:00Let's suppose I have a variable i and I declare it as an integer and I set its value to 5.
01:06Now, when I do that, the C# compiler goes out in memory and makes a little box
01:09called i and it puts the value 5 in it.
01:12If I declare another variable called j and I set it equal to i, then the
01:17compiler sets aside another little box, and this little box is called j, and it
01:20also gets the same value as i, which is 5.
01:24Now, the important thing to remember here is that j is a copy of the value
01:28that's stored in i right now.
01:30So if I go back and change the value of i to 3, the value of i gets changed,
01:35but the value of j does not get changed, because these are different memory locations.
01:39Now, let's compare that with how reference types works.
01:42So suppose I made a class called Point,
01:45and inside my Point class I had two integer member variables
01:49X and Y, which represent the coordinates of the point.
01:53To create a new Point, I would declare a Point class variable named P1, and I
01:59would use the new operator to create a new instance of the Point object.
02:03Then I could do something.
02:04Now since these are public member variables, I could say P1.X and P1.Y are equal to 10.
02:11Let's watch what happens in memory.
02:12Well, in memory, that little location called P1 for the variable gets created,
02:17but what also gets created is a set of bytes somewhere else in memory that
02:21actually hold the member variables.
02:23And P1 is not actually containing that data.
02:27It contains a reference to that data.
02:30There's this little reference that goes out into memory and knows where X and Y are stored.
02:35So let's suppose I made another variable called point P2.
02:39And rather than doing new Point, I say point P2 = P1.
02:44Well, that creates a little local variable there called P2.
02:47But watch what happens.
02:48The reference gets set to the same reference as P1.
02:52They're sharing the same reference to the same location in memory, because I
02:57didn't make a new instance of Point; I simply set P2 to be equal to P1.
03:02And when you do that with a reference type, you're sharing the same reference.
03:05What does that mean?
03:06Well, if I then do something like this where I set P1.X =20, it changes for the both of them.
03:12So even though I didn't do anything to mess with P2, P2.X is now having the
03:17value of 20, the same way that P1.X is.
03:20This is an interesting side effect of how reference types works, and you need to
03:24watch out for it in your code.
03:25Let's go over to the code environment and take a deeper look at this.
03:29So I'm here in my ValAndRefTypes example file, and I've got the Program.cs file
03:35open, and I've got my Snippets here.
03:37So what I'm going to do is back here in my code, I'm going to put some code in
03:41here that exercises both the reference and value types that we saw earlier.
03:47So let's go back over here.
03:48What I'm going to do is copy this line right here, which is the Point
03:51definition, put it into my file over here.
03:54I'll just put right in front of the Program class. I'll save that.
03:57And then I'm going to copy over this function right here called testFunc1.
04:03And this is the first test that we'll run. So I'm going to copy that.
04:06I'm going to put that in my program down here.
04:10So now let's copy over some of the logic to see what's happening.
04:13Go back to my Snippets.
04:15I'm going to scroll down a little bit, copy these few lines right here, starting
04:20with this variable and down through this WriteLine.
04:22I'm going to copy that and paste it into my Main.
04:27So let's take a look at the code that we have here.
04:30We'll use point a little bit.
04:31I just want to make sure we have it in place.
04:32For now, I'm just going to concentrate on this code right here.
04:35In my Main function I've got a variable called i, and I'm setting it to be the value of 10.
04:40And then I call this function, testFunc1, with the i variable.
04:43So let's scroll down and see what testFunc1 is.
04:47You can see it takes an integer argument.
04:49And the first thing it does is it adds 10 to the argument that's passed into the function.
04:56When this Console.WriteLine gets executed, it's going to write out the value
05:00of whatever arg1 is.
05:02And then when the function completes and goes back up, we're going to write out
05:05whatever the value of i is.
05:07Go ahead and place your wagers and let's see what happens.
05:11Build this, and we're going to run it.
05:13So you can see that what happened was we passed the 10 into the function, and
05:19arg1 was set to 10, but then we added 10 to it, so now it's 20.
05:23But when we come back out of the function, the original variable i is unchanged.
05:27It's still 10, even though we added 10 to it inside the function.
05:31So let's go back and take a look at the code.
05:33The reason why this works is because for primitive value types, like
05:36integers, when you call a function and you pass in the value as an argument to the function,
05:42it is passed as a copy.
05:44When you pass value types, you pass a copy of their original values.
05:50So even though we changed the value in here on line 29, since we're passing in
05:54a copy of the local i variable from Main, we're not actually changing the i variable;
06:00we're only changing the local copy that testFunc1 is working with.
06:04Let's go back and copy in the rest of our code.
06:09And I'm going to copy in these lines here, put them in my Main function.
06:19And I need to copy over my other test function, which is this one right over here.
06:27And I'll put that down below here, and now we'll save everything.
06:33Now, let's go ahead and run our next test. And for this I'm going to get rid of
06:36these lines of code because we don't need them.
06:39So here I'm using the Point class, which I've defined up above my Main.
06:43Here's the Point class. It's got an x and a y value.
06:46So on line 19, I'm creating a new point, and I set p.x and p.y to both be 10.
06:52Then here on line 22 I write out the value of the X property. Then I call this
06:58testFunc2 with p--that's the point-- and then I write out p.x again.
07:04Let's see what testFunc2 is doing.
07:06Well, testFunc2 takes a Point argument, as you'd expect,
07:10it writes out the value of pt.x, then it adds 10 to the value, and then it
07:14writes out pt.x again.
07:16So we're going to write out four things here.
07:19We're going to write out the value of the Point's x field, both inside the test
07:22function and outside the test function.
07:24So let's go ahead and compile this and run it.
07:27And you can see that before we call the function, the value of p.x is 10.
07:32Then we go into the function and pt-- that's the local variable inside
07:36that function--is 10.
07:38Then we add 10 to it, which gives us the value of 20, and we write that out.
07:41So inside the function, pt.x has been changed to 20.
07:44Then we exit the function and go back into Main and you can see that the value
07:48of p.x has been changed to 20.
07:50So in this case the value was changed. Let's go see why.
07:55Remember that Point is a class,
07:59and the class was one of those things that we looked at earlier was a reference type.
08:04So when you make a new point like this here on line 19, and then you pass
08:08it into a function,
08:09you're not passing a copy; you're now passing it by reference.
08:14And because testFunc2 has a reference to the original point, if you change it
08:19inside the function, it will change outside the function as well.
08:23This is the fundamental difference between value types and reference types, and
08:27it's something you'll come across in C# on a regular basis.
Collapse this transcript
6. Collections
Working with arrays
00:01In this section, we're going to cover some of the data structures that .NET
00:06provides for you, and specifically we're going to focus on collections.
00:10Collections are essentially classes that help you keep track of and manage a
00:14whole bunch of data, and since a lot of programming involves keeping track and
00:19managing data, it seems like this is a pretty good place to start.
00:23We're going to start off by looking at C# arrays.
00:26Now in C#, arrays hold a fixed number of elements, all of the same type.
00:32An array is basically just a list of items and values.
00:37So for example, if I declared an integer variable called oneValue and set it to
00:42be equal to 100, we've already seen this. Somewhere out in memory the C# compiler
00:47and the .NET framework creates a little box called oneValue and puts the value
00:52inside that little variable box.
00:54Now an array is a little bit different than that, and the way you declare them as a
00:58variable is also a little bit different.
01:00When you declare an array you specify the type that you want the array to hold,
01:05so here it's an integer just like always, but then you put these two square
01:08little brackets next to the type definition.
01:11So you have the opening square bracket and the closing square bracket with
01:15nothing in it, and then you give it the variable name, just as you always would.
01:19And this just tells the Compiler, hey,
01:20we're not declaring one integer.
01:22We're declaring a whole bunch of integers.
01:24And then you complete the sentence by saying = new and then the type that
01:29you're creating, in this case an integer, and then inside the square brackets you
01:33put the number of slots that you want to create.
01:36So this line of code right here int, square brackets, manyValues creates a variable called
01:42manyValues, which is an array of, in this case, four integers.
01:46And out in memory what's going to happen is the .NET framework is going to
01:50create some space and it's going to create a variable called manyValues and
01:53there will be four little boxes all initialized to 0.
01:57The .NET framework takes care of initializing the array for you so that they are all 0.
02:01Now arrays are zero-based indexes. So that first element in the array there is not element 1;
02:07it's actually element 0, and it counts up from 0 up to 3.
02:10So there are four elements, but it goes from 0-3.
02:13So if I wanted to reference one of the elements in the array, I would simply
02:17use manyValues and then inside the square brackets the index number of the one I want to change.
02:22So if I wanted to change the first element in the array to a value of 100, I
02:25would say manyValues, subzero, =100, and lo and behold, the value changes.
02:30If I wanted to change the last one, I would do manyValues and then 3 in the
02:34square brackets and that works.
02:37Just like other variables in C#, I can also initialize array variables just like
02:42I can initialize other variable types.
02:44So in this case, I'm declaring an integer array called manyValues and rather
02:49than creating the new memory using the new operator, I'm using curly braces and
02:53then just putting the array values inside the curly braces, separated by commas.
02:57This will create an array of four integers, just like we saw in the previous example.
03:02And of course, I can do this with strings too.
03:04I can say string array myStrings = and then inside the curly braces just four strings.
03:09One of the cool things about C# is that unlike other languages, like say
03:12Objective-C, C# provides what's called automatic bounds checking for arrays.
03:17So in programming, if you try to reference an array index that's outside of the
03:22bounds, or the size of the array, some languages don't check that for you and it
03:26can lead to code problems and bugs down the road.
03:29But in C# if I tried to do this, manyValues and then 100 inside the little
03:34brackets as an index, if I try to set that value, that's going to cause an error. Why?
03:38Because there is only four elements inside the manyValues array, so there is no
03:43element 100, and that's going to cause a problem.
03:45The good news is, C# catches that for you.
03:48Now arrays are fixed in size.
03:50Once you declare them, that's just how big they are.
03:52There are other data structures that we'll get to that allow you to change
03:56the size of the array, but when you declare arrays like this, that's just how big they are.
04:00Why? Because this allows them to be contiguous somewhere in the computer's memory,
04:04which is very efficient for the processor to access and change them.
04:09The other thing you need to realize is that array elements are all the same type,
04:12so you can't have an array to clear like you see it here that has numbers and
04:16strings and floats and different data types.
04:18When you declare an array using either int brackets or string brackets or float brackets or whatever,
04:24choose your data type brackets, they're all going to be the same type.
04:28Arrays can also be multidimensional.
04:31Now in the previous example we saw a single dimensional array.
04:34It was just one list of numbers. But you can make arrays multidimensional, and
04:38the way that you do that is you declare the type, so for this case, integer.
04:41Then inside the brackets you put a little comma.
04:43This is going to have two dimensions.
04:45It'll have the name of the variable called multiDimArray. Inn this case I'm saying new int and 3,3.
04:50So that's going to make a 3x3 matrix of memory locations somewhere out in the
04:56computer's memory, and it's going to initialize them all to 0.
04:59And then to round out the picture here, the first number in the index there is
05:04going to represent the row number, and the second number in the index
05:07represents the column number.
05:08So if I wanted to refer to a specific box inside the memory of the array here, I
05:14would say something like multiDimArray, 0,1, = 10.
05:18That means row 0, column 1 and that's the one that gets changed to a 10;
05:22and just like other arrays, you can initialize these too.
05:25So to do that, I would have the int, the type declaration, along with my little
05:30brackets with the comma inside, and then I would just give the variable a name.
05:33And in this case I have new int, comma, withinside the curly braces a set of curly
05:39braces, each one representing a row of data.
05:42This would create a 3x3 array with all of the boxes set to (0,1,2), (3,4,5), (6,7,8).
05:50So you can initialize them and you can make multidimensional arrays with set values.
05:56Now arrays, of course, are, just like everything else in C#, objects.
06:00So, for example, if I had this declaration here for int manyValues = 100, 200
06:06and so on, that gives me an array object with four entries in it.
06:11So I can then do something like this.
06:13I can say manyValues.
06:15and then call a function called GetLength(), and that will come back with a
06:18number four, because how many there are.
06:20I can also call some static member functions. Remember, we talked about
06:23static items earlier on.
06:25I can do Array.Clear and then give it the name of the array and a couple of indexes.
06:30Then starting at 0, it'll clear out the four elements.
06:33I can do Array.Sort.
06:35It will sort the given array, assuming that the members of the array are sortable.
06:39Same thing with Reverse.
06:41I can just reverse the given array.
06:43Because arrays are objects, you get access to a whole bunch of built-in features.
06:47So let's exercise some of these features.
06:48Okay, here in the code I've got my Arrays example open, and I've got my Snippets
06:54here. Scroll down to Arrays, and here's my program code.
06:57So let's just go ahead and copy some of these over.
06:59I'm going to do the first couple of lines right here, and we'll paste that in.
07:04And here what we're doing is we're just declaring an array called manyValues
07:07that has a whole bunch of values in it, and then we're going to write out the
07:10value of the fourth number.
07:12And remember, to do that, since this is the fourth number and it's a 0-based index,
07:15we use the number 3, and set right here on line 13.
07:18So let's hit F5 to run this, and the fourth number is 34.
07:22Okay, that's pretty simple and straightforward. Let's keep on going.
07:25In this case, we'll do the same thing with strings.
07:29So here I have an array of strings.
07:31I've got four strings: Joe, Marini, Teaches, C#.
07:34And what I'm going to do here is use a for loop to write out the values of each
07:38one of the elements.
07:39So I have a for loop going from 0, and notice I'm using <4 here, not < or =,
07:45because it has to stop at 3.
07:46I'm going to write out each one of the strings using the i variable here to
07:52index into the array.
07:53So once again I'll hit F5, and you can see that works just fine.
07:57Okay, so let's keep on going because this is getting interesting.
08:00Let's go back over here.
08:02We'll copy and paste this and put that down here.
08:06So here you can see that I've created an integer array called otherValues and
08:10I've set it equal to manyValues, and now I'm changing the last item in the
08:16otherValues array to 0.
08:17But what I'm writing out over here is the manyValues array, or at least the last
08:23element of the manyValues array.
08:25Now see if you can guess what's going to happen.
08:28If we look at the item here, you can see that manyValues(3) is 0, 1, 2,
08:313; it's currently 34.
08:34Let's see what happens when we change the otherValues array or sub three to zero.
08:38I get it set to 0. Why?
08:40Because remember arrays are reference types.
08:43We passed in a reference to the array; therefore we actually changed the value of
08:48both manyValues and otherValues.
08:50And if you skipped the section earlier on value types versus reference types,
08:54you should go back and review it now.
08:55Let's try something else. Let's try some sorting.
08:57I am going to copy this.
08:58I'm going to paste it over here.
09:02So now I'm calling the array class's Sort static member function on
09:08my manyValues array.
09:09And when I do that, we're going to write out what the fourth number is.
09:12So let's go ahead and build that, and you can see that the fourth number is 16.
09:18So we sorted the array going from smallest to largest, and that's a
09:22built-in feature of .NET.
09:24Arrays are really useful collection objects to use in C#.
09:27You will find yourself using arrays for all kinds of things.
09:30Arrays are used for processing lists of information and so on. What we'll take a
09:34look at next is a collection type called ArrayList, which has some added
09:37benefits on top of arrays themselves.
Collapse this transcript
Using array lists
00:00All right. The next collection class that I am going to cover here is ArrayLists.
00:05Now ArrayLists are like arrays, but there are a couple of unique features to them.
00:10First, they can be dynamically resized as needed.
00:13Recall from the previous movie that arrays are set in size once you create them;
00:18ArrayLists aren't like that.
00:19Now the way you create an ArrayList is by using the ArrayList class. And here
00:25I've got an ArrayList with a variable named myAL, and I just say new ArrayList.
00:31And we'll see how to do this in a bit in the code.
00:34You have to include another namespace in order to use these, but the class name is ArrayList.
00:39And in this case, I'm just calling the constructor that doesn't take any
00:43arguments, but there is a version that does take an argument.
00:45I could also just declare this variable by saying new ArrayList and then give it
00:49some number, which is the capacity that I wanted to start off with.
00:52If you don't do this, it starts off with some default capacity, and I don't
00:56remember what is on the top of my head. I think it's like 10 or 50 or
00:58something like that.
00:59But you can say new ArrayList with a hundred or a thousand if you know you're
01:02going to start off with a number that's that large.
01:05So to add and remove items from the ArrayList, you use the functions that go
01:11along with the ArrayList class.
01:13So for example, to add an object to the ArrayList, you would simply call myAL.Add.
01:19And notice that items get added as objects.
01:22It takes an object as its argument.
01:24But remember, everything in C# is an object--
01:27well, almost everything anyway. Certainly all of the primitive data types and
01:31any of the classes that you're going to come up with.
01:33So you can add objects into your ArrayList.
01:36Now you can add, which puts them at the bottom, or you can use the Insert method,
01:40which takes an object and puts it in at a specific index. And then to remove
01:44things you can use the Remove and RemoveAt.
01:46So the Remove function takes the object that you're passing as an argument,
01:50finds it in the ArrayList, and removes it.
01:52RemoveAt removes the object that is at the index that you pass in, and remember
01:57indexes here are zero-based.
01:58There is also an easy way to find out how many things there are in the ArrayList.
02:03There is the myAL.Count, which is a property on the ArrayList that tells you how
02:08many items are currently in the ArrayList.
02:11You can also do indexing with ArrayLists the same way that you would do them
02:14with regular arrays. You can do things like myAL subzero.
02:16You can even set values this way, which I guess is okay to do, but my preference
02:23is to use the functions that come with the class.
02:25Okay, let's take a look at ArrayLists and loops.
02:29So suppose we had an ArrayList that we declared like this and we added a whole
02:34bunch of items, items 1, 2, 3 and 4.
02:36Out in memory this goes ahead and creates an ArrayList with four items in it.
02:41Now if we want it to loop over the contents of this array, there is a couple
02:45ways we could do it.
02:46We could use the for loop, which we've seen in the past. And in this case, we
02:50would have an integer variable named i and we would loop i up to being less than
02:55the count of the items in the array, and we would increment the loop counter.
02:59Now this is a perfectly valid way of doing this;
03:01however, there is another way to do this.
03:04And of course we could operate on the contents of the ArrayList.
03:06We could write things out.
03:07But my preference when working with things like this is to use the foreach loop.
03:13Now we didn't talk about this earlier in the course, but I'm going to introduce it now.
03:16The foreach loop construct loops over all of the elements in a collection, and
03:21you can use it with arrays and other things throughout C#.
03:24We're going to do it with ArrayList right here.
03:27So foreach doesn't take a loop counter. What you do is you declare a variable
03:31inside those parentheses; in this case it's an object because ArrayLists contain objects.
03:36So you would say foreach (object obj in, and then the name of the collection.
03:41In this case it's myAL. That's my ArrayList.
03:44And then we can go ahead and operate on each object inside the loop.
03:47So rather than doing the myAL sub-I that you see there in the loop, we would change
03:52that to Console.WriteLine and then obj, because obj is going to be set to a
03:57different object each time through the loop.
03:59That's basically how foreach works.
04:01It's really nice because there's no loop counters to keep track of.
04:04There is no comparisons to make. The foreach construct just knows how to loop
04:09over all the elements of a collection and put it into an object's variable
04:14that you declare here.
04:15Well, in this case it's an object; it could be other things too.
04:18But in this case it's an object because ArrayLists keep track of objects.
04:21ArrayLists can also have mixed content, unlike arrays. So if we declare an
04:27ArrayList that looks like this, and then we go and add content to it using the
04:32Add, remember each one of these is added as an object.
04:36So I've got strings. I've got numbers.
04:38I can put anything I want in here, as long as it derives from system.object,
04:42which all the primitive value types do and all the reference types that we've
04:46talked about, they do as well.
04:48So I can do things then like this.
04:49I can have an integer variable named result, and once again, I'm going to use my
04:53foreach construct. And in this case, remember they are all objects,
04:57so for each object in the ArrayList, I can then do something like this.
05:02If the object is an integer--remember the is operator from earlier on in the course--
05:09I can then say result +=, and then I cast, or convert, the object to an integer by
05:15putting the word int in parentheses in front of it.
05:18So this is going to loop over each object in the ArrayList,
05:21see if it's an integer, and if it is an integer, add it to a running total.
05:25So ArrayLists are really nice and flexible.
05:27Let's go ahead over to the code and see some of this in real action.
05:30Okay, here in the code I've got my ArrayLists example open, and I've got my
05:35ExampleSnippets file. I'll scroll down to the ArrayLists section, and I'm going to copy
05:39these lines right here, and I'm going to paste them into my program.
05:44Put those into Main.
05:45All right, so let's go ahead and take a look at the lines of code and see what they are doing.
05:50Here on line 13 I'm declaring a new ArrayList object, then putting it into the
05:55myAL variable, and then I add some stuff to the ArrayList.
05:59I've got a string, integer, another string, another integer, and then a
06:02floating-point number.
06:04Then I have my foreach construct right here on line 20, and I've got my object o
06:10variable, and that's going to be set to whatever the current object is each time
06:15through the loop. And then I'm checking to see if o is an integer, and if it is
06:19an integer, I write out the value of o using the Console.WriteLine construct.
06:25So let's run this, and you can see that 2 and 4 are being written out.
06:30Okay, let's go back and make a quick modification.
06:33Let's say for each object, if o is an integer or o is a float, then we'll write it out.
06:45In this case, we'll run it again,
06:47you can see that the floating-point number as well as the integers are being written out.
06:51So ArrayLists are really nice flexible alternative to using arrays in C#.
06:56If you find yourself needing an array construct that is flexible, can contain
07:01mixed content, and so on, consider using ArrayLists rather than just fixed-
07:05sized arrays.
Collapse this transcript
Working with stacks
00:00The next collection class that we are going to look at is called the stack.
00:05Stacks maintain a list of items just like arrays and ArrayLists do, but they
00:10operate on a slightly different paradigm called push-on and pop-off, and you can
00:15think of a stack as, like, in fast food restaurants they have those cup stacks
00:20where they push all the cups into the holder and then each time a person takes a
00:24cup, it pops off the top.
00:26Stacks are pretty much the same way.
00:28Stacks are declared by using the stack class.
00:31So to declare a stack, I will use the stack class, and then mystack is the
00:34variable name. This is probably familiar by now. I say new stack.
00:38That will create a stack object out in memory.
00:41To put data on the stack, I use the push method to push data on the stack.
00:47Remember, these are objects,
00:48so I can pass any primitive type or any reference type, anything I can come up with.
00:54In this case, I will just push a string called a string 1.
00:56What that will do is that will put string 1 onto the top of the stack.
01:01If I then push another piece of data, say string 2, what will happen is string 1
01:05will slight down and string 2 will now be the new top.
01:08And I can keep on doing this with successive pieces of data.
01:11I can have strings 3, 4, 5, and so on.
01:14To get the data off the stack, instead of using push, I use pop.
01:18So I would declare an object variable.
01:22In this case, it's called o, and then I would call mystack.Pop.
01:25This would get the top value on the stack.
01:28So after calling pop, string 2 pops off and then string 1 slides back on up and
01:33now the value of o is the string 2.
01:36If I wanted to just see what was on top of the stack without changing it, I
01:40would use the Peek method.
01:42This looks at the top value, but doesn't actually pop it off.
01:47Then finally I can see how many things there are on the stack by asking the
01:50stack's count property how many things there are.
01:53In this case, it will tell me that there is one item on the stack.
01:56Stacks are commonly referred to as LIFO,
01:59Last In, First Out, data structures, because the things that you push onto
02:04the stack earlier get pushed down towards the bottom and later elements are nearer the top.
02:09So as you pop them off, those items are going to come out first.
02:12So it's Last In and First Out.
02:14Again, stacks are one of the common data structures you will find throughout
02:17programs for various purposes.
02:19Let's go ahead and jump over to the coding environment and actually exercise
02:23this to see how it works.
02:25So here in the code I have scrolled down to my Stacks section in my
02:29ExampleSnippets, and I have got my Stacks project open over here with my Main function.
02:36Let's go ahead and copy some code over.
02:38So the first thing I am going to copy over is this setup code right here, and I
02:42am going to paste that in.
02:45Right there on line 13 you can see that I am declaring a new stack variable, and
02:50then I am pushing some data on the stack.
02:51I am Pushing strings, items 1, 2, and 3.
02:54Then I am just going to write out how many items there are on the stack by using
02:57the mystack.Count property.
03:00So we are going to run this, and you can see that sure enough, there are
03:03three items on the stack. So far so good.
03:06Let's go back over to the code.
03:08Now let's have a peek at what the top item is.
03:11So we are going copy that, and we will paste that below here.
03:16Now remember Peek is non-destructive.
03:19In other words, it doesn't actually change the stack;
03:21it just shows me what's on the top.
03:22So we will run this and you can see that items 3 in on the top. Why?
03:26Because item 3 was the last item pushed on; therefore, it will be at the top of the stack.
03:33So far, things are operating the way they are supposed to.
03:35Let's go ahead and try popping something.
03:37I will go ahead and paste that code in down here.
03:44So now here on line 23 you can see I am calling the Pop function, which is
03:48going to pop item 3 off the top of the stack, which means that item 2 will now be the top item.
03:54So when I write this out, it should say item 2. So let's run this.
03:57Yeah, sure enough item 2 is now on the top of the stack.
04:00Let's go back to the Snippets over here. One more thing.
04:04We'll paste that code in here.
04:11So now I am going to call these stacks Clear function right here on line 27, and
04:15that will get rid of everything on the stack here.
04:17It will clear out the contents and then when I call mystack.Count, I should have the value 0.
04:23So let's press F5 and sure enough, I have got 0 items on the stack.
04:30You will find stacks used throughout C# programs and other programming
04:33languages in general.
04:34They are pretty useful for keeping tracks of certain kinds of data structures,
04:37mathematical expressions, evaluations, and so on.
04:40There are a couple of great examples.
04:41So that's how you use stacks.
Collapse this transcript
Working with queues
00:00Well, continuing on with the cavalcade of collection data structures, we are now
00:04going to look at queues.
00:06Queues maintain a list of items kind of like stacks do, but they are different
00:10than stacks in that they're FIFO, or First In, First Out--kind of like a line of
00:15people waiting at a counter.
00:16In fact, if you've ever spent any time in UK, you will probably hear lines
00:19referred to as queues, and queues in programming work pretty much the same way.
00:25Something enters the queue, and it's the first one in. It's also the first one out.
00:28And items move in the queue in an orderly fashion, or at least they should.
00:33Using queues in C# is similar to using stacks, only instead of having Last In,
00:39First Out, it's going to be First In, First Out.
00:42To declare a queue, you use the Queue class name and here I have got a queue
00:47named myQ and I create a new queue.
00:49Then to put things on the queue, instead of using push and pop, we are going to
00:52use Enqueue and Dequeue.
00:55So in this case, I am going to create my new myQ variable.
00:58I will call Enqueue. And in this case I am passing a string, but it's an object,
01:02so it can be anything; it could be a number or whatever.
01:04So I am passing in a string.
01:05When I do that, string 1 will be placed in the queue.
01:08If I then Enqueue string 2, string 1 will move down and then string 2 will now
01:12be at the back of the queue.
01:15Instead of using Pop, I am going to use Dequeue.
01:18So when I say Dequeue, the first item will come off of the queue like this.
01:24That leaves string 2 as the current first item.
01:28Just like using stacks I can do things like Peek, and Peek is non-destructive.
01:32In other words, it's does not take things off the queue;
01:34it just shows me what's at the front of the queue.
01:36In this case, it's now string 2. And also like stacks, I can use the Count
01:40property to see how many items are actually on the queue.
01:44So since this is so similar to stacks, let's just go ahead and waste no time and
01:47get over to the code so we can see this working in action.
01:50Here we are in the code.
01:52One of the things that I haven't pointed out up until now, which you
01:55probably have noticed, is that you need to include a name space in order to
01:58use the collection classes.
02:00Up until now we've had a Collections.Generic which has been included for us by
02:04default, but in order to use things like stacks and queues and ArrayLists, you
02:08need to include this guy right here using System.Collections.
02:11This is the namespace you need to include in order to use the classes we have
02:15been talking about so far.
02:17So to use queues and stacks and ArrayList and so on, just make sure you have that included.
02:21So let's jump over to the Snippets, and you can see I have scrolled down to the
02:25queue section. And I am going to go ahead and copy these lines and this is the
02:30setup code right here.
02:31I'll just paste this in.
02:36So right there on line 13, creating a new queue, and then I am Enqueuing four
02:40items. And I am going to write out how many items there are in the queue and sure
02:44enough, there four items, just like you would expect there to be.
02:48Now let's go back to the Snippets.
02:50Just to show you that you can use other kinds of loop constructs with these
02:54collection classes, I am going to use a while loop.
02:57And if you have been watching along with me so far, you've probably noticed
03:00I've used for loops.
03:01I have used for each loops.
03:03It's time to give the while loop its turn.
03:05So here I am going to say while myQ.Count > 0 we are going to Dequeue items--
03:13you can see they're on line 23--and then in the following line 24 we are just
03:15going to say Dequeuing object whatever and write it out to the console.
03:21Each time we Dequeue something the Count property is going to automatically
03:25be decremented for us.
03:26We don't have to worry about taking care of that.
03:28The class keeps track of how many items there are in the queue. And since Dequeue
03:32takes things off of the queue, the Count will change for us.
03:35So I am going to go ahead and compile this and build this, make sure it works, and it did.
03:38Now let's just go ahead and run this.
03:42You can see that we are Dequeuing items in the same order that they were put o to the queue.
03:47So item 1 was the first one in, and it's the first one out, followed by items 2, 3, and 4.
03:52So queue is similar to stacks, only they operate more like a Line.
03:55If you find yourself in need of a collection class where the order is
03:58important and you need to process things in the same order that they come in,
04:02use queues instead of Stacks.
Collapse this transcript
Using dictionaries
00:00The last example of a collection class that we are going to look at is the dictionary.
00:05And dictionaries are used to associate a particular key with a given value,
00:11and you can think of them as lookup tables. Essentially, you use a key to look up a value.
00:16So if I have a dictionary object then I essentially have a key that's associated
00:21with a value inside that dictionary.
00:24And some examples of that might be a product ID with a product name, or I could
00:28associate say an abbreviation for a state name with its full name.
00:32But really I can associate any object with any other object.
00:37This is what hashtables are essentially used for.
00:40They are probably one of the most useful collection classes out of all of them.
00:44Keys have to be unique.
00:46You can't have duplicate keys, and dictionaries don't have any sense of order.
00:52So unlike other collection classes, like stacks or queues or arrays, there is no
00:57sense of order here.
00:58You simply put in keys, associate them with values, and there's no notion of who
01:04is first or who is last.
01:06Probably the most common example of a dictionary is the hashtable
01:11or associative array.
01:13You probably heard it called many different names depending on what other
01:16programming language you may have come from.
01:18If you've never heard of it before then I will introduce it to you now.
01:22The hashtable is an example of a dictionary, and the Hashtable class in C# is
01:28declared the same way you declare any other collection class;
01:30you simply have the Hashtable class, and in this case I'm declaring a variable
01:34named myHT, which is of type Hashtable, and then you just use the new operator
01:39like you would in any other class.
01:41So this will create a new hashtable named myHT, and then we can start adding
01:46things to the hashtable. And the way you do that, well, there are a couple ways
01:49to do it, but the first way to do it is to use the Add function.
01:52When you add something to a hashtable you give it the key that you want.
01:56So for example, I could give a three-letter airport code, like SEA, and then I
02:01give it the value, which might be something like Seattle Tacoma Airport.
02:05Then over in a hashtable I would have a little key named SEA and would be
02:08associated with a value.
02:10And I could do the same thing for say SFO, and that associates it with
02:14San Francisco Airport.
02:15I can also use bracket notation.
02:18For example, I can say myHT, and then in brackets I can have the three-letter
02:22code for IAD, which is Washington's Dulles Airport. And using the bracket
02:28notation, I will simply use the equals, or assignment operator, to say myHT sub
02:33ID is Washington Dulles Airport, and that would also put something into the hashtable.
02:38That's how you get data into the hashtable.
02:41The way that you get data out of the hashtable is to use the Remove function.
02:45In this case, I would call myHT.Remove, and then I give it the name of the key
02:49that I want to be removed.
02:50So if I want to remove San Francisco Airport, I would simply say Remove SFO and
02:54that will cause SFO to be removed from the hashtable.
02:58Just like other collection classes, there are a couple of utility
03:01properties and so on.
03:02For example, I can see how many things there are in the hashtable by using the
03:06by now ubiquitous Count property.
03:07This will tell me in this particular case there are two things in the hashtable.
03:11I can also see if hashtables contains certain values by using a test.
03:15I can, for example, declare a Boolean variable name b and call the ContainsKey
03:21function on a given hashtable. And I can pass in a key name, in this case SFO,
03:26which will return false now, because it's gone. Or I can also use the
03:30ContainsValue version as well.
03:32So I can say, hey, hashtable, do you contain the value San Francisco Airport?
03:36In this case, it's now false, but if it was still there, it would be true.
03:39So let's just jump over to the code and make ourselves a hashtable and exercise this.
03:45So here I am in code.
03:47Once again you'll notice I am using the System.Collections using statement up
03:51here that includes the name space for the collections class, which includes
03:56things like dictionaries and hashtables and queues and stacks and all the
04:00examples we have been using so far.
04:02So jumping over to the Snippets code, you can see I have scrolled down to the
04:05Dictionary section, and I am going to copy the setup codes over here.
04:08I am going copy that and it will paste it into the Main.
04:17You can see on line 13 I have created a new hashtable, and then I've added some
04:21data to the hashtable.
04:22I have added airport codes SFO, SEA, and IAD, and I have set their associated
04:28values to the full names of their airports.
04:31Then we can test this out by saying, hey, let's do a Console.WriteLine to see
04:35the value for key, whatever is this.
04:39And we are going to pass in the name of that key. In this case I will look
04:42up the value by using the bracket notation.
04:44So you can see here on line 16 I use the bracket notation to set the value.
04:48I can also look up the value by using the bracket notation, but without an
04:52assignment operator.
04:54So I am going to do a build.
04:55You could see the build succeeded, and we are going to run it.
04:59And you can see it worked fine.
05:02The value for key SEA is Seattle Tacoma Airport. That's great.
05:07Let's continue on with the exercise.
05:09I am going to copy this line here, which simply tells me how many items there
05:14are in the hashtable.
05:15So I'll save that and run it.
05:18And as you expect, there are 3 items in the hashtable. So far so good.
05:24Let's do our last exercise right here.
05:27Copy and we'll paste this in.
05:31In this case, we are going to exercise the Remove functionality, but before I
05:35uncomment that Remove line--let's just go ahead and write it out that right now--
05:41you can see that the value for key SFO is San Francisco Airport.
05:45That's because SFO is still in the table;
05:47I haven't removed it yet. But if I uncomment this line right here, I'm going to
05:53remove the SFO key, and then the next line is the if statement on line 22 that
05:58says, hey, if myHT contains the key SFO then write it out.
06:03Now that condition is going to be false, because we've moved it.
06:05So let's run it again, and you can see that this time there was no WriteLine for
06:11the SFO key, because it's not there anymore.
06:14Hashtables are probably one of the most useful of the collection classes, and if
06:19you're coming from a language like JavaScript you've probably used these a lot.
06:23In fact, they are used all over the world of programming, and in C# it's no different.
06:27You can use hashtables to associate keys with objects, or any other kind of data
06:32that you can think of.
06:33They're pretty useful.
06:34They are also pretty efficient.
06:36If you find yourself in need of having a lookup mechanism, a hashtable
06:39usually fits the bill.
Collapse this transcript
7. More Complex Classes
Overloading methods
00:00We have reached the section of the course now where we are going to start
00:02learning about some of the more advanced object-oriented features of C#.
00:07The information in this part of the course is going to build on the
00:11information that we learned about earlier in the chapter on creating custom
00:15classes and objects.
00:17Go ahead and watch that content if you haven't already, and then pick it up here.
00:21We are going to start with method overloading, and method overloading is when
00:25you define methods that have the same name but different ways of calling them.
00:30So let's look at a real example.
00:32Let's go back to our ubiquitous Wine class example, and you can remember from
00:37earlier examples I've got a class here called Wine. And I can declare some
00:42member variables like Year, Name and Price, as I have done in the past. And you
00:45have probably seen me do something like this where I declare a constructor
00:49function called Wine, which is the same name of the class, and in this case it
00:54takes a string argument and it sets the value of the Name variable to whatever
00:59argument was passed in.
01:00That's great, but what if I also wanted to give people that are using this
01:03class a way to initialize the class, or construct the class, with both a name and a year?
01:11Well, I could simply just define another Wine constructor function like this,
01:16and in this case I have got a Wine constructor which takes a string and takes a Year.
01:20You might be saying, well, wait a minute.
01:21You have already got a constructor function called Wine.
01:24Isn't this a problem? Aren't you redefining something? No, not really.
01:27What I am doing here is I'm overloading the Wine constructor, and this doesn't
01:33just work with constructors.
01:34You can do this with any function.
01:35I just happened to be doing with the constructor function here.
01:38And the reason this works is because the signatures of the two methods are different.
01:44In other words, the parameters that each one of these constructor takes is unique.
01:49So for consumers who wanted to call the constructor for the Wine class using
01:54just a name, they can do that.
01:56If they want to use both the name and a year in their code, they can do that too.
02:00As long as you define the function with the same name and a different set of
02:05parameter lists, that's fine. That's legal C#.
02:08Let's take a look at an example that doesn't work.
02:12If I have a class and I wanted to provide two functions of the same name, here I
02:17have got a function that takes an integer and returns an integer and I've got
02:21another function that takes an integer but returns a float.
02:23The problem is this is an error.
02:26The return type of the function is not part of the signature.
02:29It's the parameter list.
02:31These methods are not considered different by the compiler. And you can imagine
02:36in the code I would call out a function with an integer argument,
02:39the compiler wouldn't know which one to call. So you can't do this.
02:43You can't have functions that defer only by the return type.
02:46The parameter list has to be different.
02:49So let's take a look at some real code to see how this works.
02:52So in the MethodOverloading example I've got my program, opened and here's my
02:57Snippets code, and I've scroll down to the overloading methods section.
03:01So I am just going to go ahead and copy this entire class right here for Wine.
03:07And we are going to need this to set up the example, so I will just copy this in,
03:10and I will put it above the program class.
03:15Before I copy the rest of the code, let's take a look at what's going on here.
03:18I have my Wine class and I have got my member variables here, and then I've got
03:23a set of constructors.
03:24You can see that I've got a constructor for the Wine class that takes just a string,
03:28I have got one that takes a string and a year, and I've got one that takes a
03:32string, a price and a year.
03:36So I have got three different constructor functions, so I am overloading this
03:39function three times.
03:40Okay, now let's go back to the Snippets and let's copy in some code that
03:45actually exercises this.
03:47I will copy that and put it into the Main function, and we will just put it in right there.
03:56You can see here, starting on line 35, I am creating three Wine objects, w1, w2
04:03and w3, and I am calling the constructor in a different way each time.
04:07For w1 I am just passing in a string by putting in a name, for w2 I have got a
04:11name and a year, and for w3 I've got the name, the price and the year, and
04:17then I've got three lines here that's going to write out the various parts of the objects.
04:23So for Wine 1 I am going to write the name, and so on.
04:25Let's go ahead and try this code out and see what happens.
04:29So you can see that when I run the code for w1, I am writing out just the name;
04:33for w2 I have the year and the name; and for w3 I have got the year, the name, and the price.
04:41Now, because I've overloaded these functions, I can call them with different
04:46values and different parameters.
04:47So, for example, I have given the consumers of this class three different ways
04:51to build their Wine class objects:
04:54so just the name, the name and the year, and the name and the year and the price.
04:58I want to go back and change the way that I constructed w1,
05:02I can put my cursor in here and type comma. And you can see that when I type the
05:07comma, C# Express gives me a little pop-up that says hey, there are three
05:12different ways you can call this function.
05:14You can see right here it's on 2 of 3, but I can cycle through all of these.
05:181 of 3 is to call the Wine constructor with just a string.
05:22Here is the version with just a string and an integer. And you can see, since I
05:27have put the comma in there, it's highlighting the integer in bold saying, hey,
05:30that's where I think you are going to type next. Or in the third case,
05:35I've got the string, the price, and the year. And again I am on parameter number
05:39two right now so it assumes I am going to type a price in here.
05:42But the point is that C# Express is looking at my constructor list and helping
05:47me choose the one that I want, and it's showing me what's available.
05:50I can choose to use either this version or this version.
05:53So let's go ahead and use the second version.
05:55I am going to just type in 2007. I need to change the Console.WriteLine as well.
06:04So I will put this in here w1.Name, and now I will do w1.Year. And when I save
06:15and I rerun this, you can see I have got the name and the year that's being written out.
06:21Just to recap, overloading a method is when you declare a method with the same
06:27name but with a parameter list that's different each time.
06:30In this example I showed you how to do it with the constructor, but you can do
06:34this with any method. It doesn't have to be the constructor.
06:37You can't do this with properties. You can't do this with fields.
06:39You can do this with methods.
Collapse this transcript
Overriding methods
00:00A very close cousin of overloading methods is called overriding methods.
00:05In overriding methods, you basically get to change or augment the behavior of
00:10methods and classes, and this is called overriding their logic.
00:14It's one of the most powerful things of object-oriented programming and it
00:18really, really helps you when you want to encapsulate your logic in your objects
00:22and separate the behaviors of different objects from each other.
00:26Let's suppose you have a phone. And a phone knows how to do something, like ring,
00:32but of course you just have a phone.
00:35You have a particular type of phone.
00:36You might have a landline.
00:38You might have a cellular.
00:39You might have a satellite phone.
00:40Well, each of those knows how to ring as well.
00:43In fact, they have got their own custom ways of ringing.
00:46Now when you get a phone call the person calling you doesn't necessarily know
00:50what kind of phone you have; all they know is that you have got a phone.
00:54When they make a phone call the system looks up your phone and tells your phone
00:57to ring. And when the phone is told to ring it figures out what kind of phone
01:02you have, and it tells that particular kind of phone to go ahead and do its
01:06ringing. And this is the same kind of concept that we will do in object-oriented programming.
01:12You will have a class, a subClass, and the baseClass, or the superClass, to use
01:18object-oriented terminology,
01:20will have some method in it, and you want to either completely replace the
01:24logic that's in that method, or you want to augment it somehow.
01:29You use overriding in order to do this.
01:31Now there are three important things you have to understand.
01:34There are three keywords in C#.
01:36The first one is virtual.
01:38The virtual keyword tells the compiler that it can be overridden.
01:43The override keyword is another important one, and then there's the base keyword.
01:48To use the overriding mechanism, there are three things you have to do.
01:51First, you have to mark a method as being virtual.
01:55This tells the compiler that this particular method can be overridden by derived classes.
02:00If you're coming from other languages like JavaScript or C++, this may look
02:05somewhat familiar, but it's a little bit different.
02:08You have to specifically mark a function as being over overridable.
02:12So here you can see I have got a function called myFunction.
02:14It returns an integer. And I have got the public keyword in front of it, but I
02:19have inserted the word virtual between the public and the return type.
02:24This tells the compiler, hey, somebody might want to override this.
02:27Now they don't have to, but they might want to.
02:29To actually override the method, in the subClass, I tell the compiler that a
02:35particular method is going to override the same method in the baseClass by using
02:39the override keyword.
02:41So in this case instead of virtual, I use override.
02:44You can see I have done the same thing here: between the return type and the word
02:47public, I've used the word override.
02:51And these two go hand in hand when you want to override methods.
02:55Then finally, there is the base keyword, and you can use this in your subClass to
02:59call the baseClass's method. And you use this because you don't necessarily
03:04always know what the name of the baseClass is.
03:07Instead of you actually using the name of the baseClass, you simply say base, dot,
03:11whatever the function is. And this will call into the code in the superClass
03:16instead of your subClass.
03:18Now there is a little bit complex.
03:21It's probably helpful to see an example of this in action,
03:24so let's jump over the code and see it work.
03:29So here I am in my example.
03:31This is for method overriding. And I am going to go over to my Snippets, and you
03:35can see in my Snippets I have scrolled down to the Overriding Methods section.
03:39The first thing I am going to do is copy over my class definitions.
03:42I have two classes:
03:43I have one that's a baseClass and I have one that is a subClass of that baseClass.
03:47Let's go ahead and copy these over, and I will put these in my program definition here.
03:56So now I am going to scroll back over here down a little bit. I'm going to copy this
04:02code and put it into my program.
04:08Before we run this, let's take a look at the class definitions, so we can
04:13see what's going on.
04:16In my baseClass, you can see here on line 10 I have got a function called
04:21doSomething. And it doesn't return anything, so it's a void return type and it's
04:26public. And I have declared it as a virtual method.
04:29What that means is when I create a subClass that descends from this baseClass
04:34the subClass has the opportunity, if it wants to, to override this method.
04:38Now the baseClass method for doSomething just simply writes something out to the
04:42console. It says, hey, this is the baseClass saying "hi."
04:44Go down to the subClass. On line 18 you can see that I've got the same
04:49method, doSomething.
04:51In this case I've got the override keyword.
04:54So this tells the compiler, hey, I'm overriding whatever the baseClass does.
04:59In the doSomething method for the baseClass I am calling the baseClass's version
05:03of doSomething, which will call the Console.WriteLine method. And then I can put
05:08on whatever additional programming logic I want to.
05:12I can do another Console.WriteLine.
05:14I can put it before or after the baseClass call.
05:18I can put it here if I want to.
05:19I will just leave it there for now.
05:22So let's go back down to the program. And you can see that what I am doing is I
05:25am creating an object.
05:27I have got a subClass object.
05:31I have created a new subClass object called obj1, and I am going to call doSomething.
05:35So let's see what happens when I run this.
05:39Two things get written out:
05:41"This is the baseClass saying hi!"
05:43and "This is the subClass saying hi!"
05:45So why did that happen?
05:46Well, in obj1 we called doSomething.
05:48obj1 is a subClass, so we will look in the subClass. And you can see that in
05:55doSomething the first thing we do is call the baseClass's version of doSomething,
06:01which will be this right here.
06:02The baseClass saying hi!
06:04gets called first, and then that returns and then the subClass gets called.
06:08We can reverse that order.
06:10We can cut this line and put it up here, and let's run it again, and now you can
06:14see that the subClass says hi first instead of the baseClass.
06:18Let's go back to the code.
06:19We can actually just take this call out.
06:21We don't have to call the baseClass if we don't want to.
06:23Now we've completely replaced the functionality that the baseClass provides, and
06:28we are only doing what the subClass says to do.
06:31So we are going to save this and run it and now you can see that only the
06:34subClass's version of that function is running; the baseClass's version is not
06:38getting a chance to run. Hit Return.
06:41Let's try something else.
06:44Since subClass is a version of the baseClass object, I can do something like this.
06:52I can say baseClass obj1 = new subClass.
07:00Now that may seem strange at first, because wait a second. Shouldn't I be
07:03creating a new subClass?
07:05No, I'm actually going to create a baseClass object.
07:07Let's see what happens here. Ah!
07:10"This is the subClass saying hi!"
07:12Why did that happen?
07:13Why is it that when I created an object of type baseClass, or I gave it a
07:18name of baseClass, and I created a new type of subClass, why did it not call
07:23the baseClass's version? Why?
07:25Because when you create a virtual function C# is actually going to look up what
07:29the lowest descendent is and call that version of the function.
07:33Since I actually created a new instance of subClass, even though I arranged it to
07:38be assigned to a variable named baseClass type, it's still going to look down in
07:42the functions and say, oh, you know what?
07:44That subClass object is actually overriding this function,
07:46so I am going to call that version instead.
07:48Let's change this so that instead of creating a new subClass type, I am creating
07:53a new baseClass type.
07:55Now let's see what happens.
07:57I am going to run it.
07:59Now it's the baseClass's version saying hi. Why?
08:01Because it's not a subClass anymore;
08:03it's a baseClass now.
08:05That's how you override methods.
08:07You use the keyword "virtual" to indicate that a method can be overridden and then
08:12use the "override" keyword to indicate that you are overriding it in a baseClass.
08:17And you can use this to augment the functionality provided by baseClasses in
08:22your own programs, as well as other programs that you might be adding on to.
08:26It's a really great way of segmenting your program so that pieces of
08:31functionality don't have to be changed in baseClasses in order to provide new
08:35pieces of functionality in classes that derive from them.
Collapse this transcript
Creating abstract classes and methods
00:00All right, in this section we are going to talk about abstract classes, and
00:04abstract classes tend to be one of those subjects that trip people up who
00:06are learning object-oriented programming for the first time, so I'll try to make this easy.
00:11Essentially, an abstract class can't be instantiated by itself.
00:14You have to create a subclass, and you have to instantiate that instead.
00:18In other words you've got to derive a class from an abstract class and make
00:22that class instead;
00:23you can't instantiate an abstract class.
00:25abstract classes have abstract members and these are members that have to be
00:30overridden by subclasses in order to provide functionality.
00:34So, okay, why would you do this?
00:36Well, there are going to be times in programming where you define a class that
00:39describes an abstract idea, but it doesn't make sense by itself.
00:43It has to have an actual physical implementation, and that physical
00:46implementation is going to change among different versions of that class.
00:50And we'll take a closer look at that in a moment.
00:52First, let's see how to actually describe an abstract class.
00:55Abstract classes are indicated by putting the word abstract in the class definition.
01:00So if I normally describe a class like this using public class, myClass, and then
01:06declare the class normally like you see me do throughout the course,
01:09what I would do here instead is put the word abstract inside the class definition.
01:13That tells the compiler that this is an abstract class.
01:16Then once I've done that, I can declare an abstract member function, like you see here.
01:22Now I don't provide an implementation for this function here.
01:26Remember, I'm forcing the subclass to do that.
01:29The subclass has to provide an implementation.
01:33So let's take a look at a real-world scenario where you would do something
01:38with abstract classes.
01:39Consider an example where you've got a car dealership or some kind of dealership
01:43where you sell different types of vehicles.
01:46Now vehicles, depending on what they are, have unique characteristics, but some of
01:51them might be common among all different kinds of vehicles. For example, they
01:55might have properties like what kind of fuels they use and what their licensing
01:59code number is, right?
02:01But you don't actually go down to the dealership to buy a vehicle.
02:05What you do is you buy something like a motorcycle or a car or a truck or a boat.
02:10These are real-world implementations of this abstract notion of a vehicle.
02:16Even though they may all share some of the same characteristics, there is no
02:20such thing as actually making a vehicle. So in this case if the vehicle, the
02:25class you see in the dotted line there, is an abstract class and the classes you
02:29see in the thick lines are real subclasses that derive from the vehicle
02:35subclass, you could do something like this.
02:37I could say class Car c = new Car. That works great.
02:41It's a real class that derives from the abstract class.
02:44What I can't do is this:
02:45I can't actually instantiate the abstract class, because the rules of object-
02:51oriented programming in C# is that abstract classes have to be derived from.
02:55So I would have to instantiate one of the real classes, the motorcycle, the car,
02:58the truck, the boat.
02:59And I could add more real classes as time goes on.
03:03So let's just go over to the code and see this in action.
03:06Okay, I've got my abstract classes example opened.
03:11Let's go over to the snippets.
03:13You can see I've scrolled down to my Abstract Classes and Methods section. And I
03:16am just going to copy these two class definitions and I am going to paste them
03:20in my program over here.
03:23So now I have my abstract class, which is myBaseClass, and in there you see I've
03:28got my abstract method called myMethod.
03:31And then if we scroll down a little bit, you'll see here starting on line 13,
03:34I have a derived class which inherits from myBaseClass. And it overrides--again I
03:42am using the word override here to override the abstract member function called
03:47myMethod--and in this case it just takes two arguments and returns the sum of
03:51those two arguments.
03:53So if we go down into the Main function, I could do something like this.
03:57I can say myDerivedClass = new myDerivedClass, and then I can say int result =.
04:09Actually, I have to make it a variable there. I can say mdc.
04:15and then I can call myMethod right here. And I'll just give it two numbers, 5 and 6.
04:23And then we'll just write out the result there, and then we'll have the program
04:31wait for us so we can see the results.
04:34So let's save this, and let's run it.
04:36And you can see that the results here is 11. Why? Because 5+6 equals 11.
04:42So we can see that the real derived class from the abstract class provides
04:47implementation and actually works.
04:49Let's comment this code out so that we don't have to deal with any errors in it.
04:54Okay, let's see what happens when we take the myMethod implementation out of
05:01the derived class. I am just going to cut this code and save it, and now I am
05:05going to hit F6 to build.
05:07And you can see that we get an error.
05:09There is little blue squiggle underneath myDerivedClass, and if you look down
05:13here in the error list, it says "abstractClasses.myDerivedClass does not implement
05:19inherited abstract member myMethod."
05:22So you can see that because I declared myMethod to be an abstract method, I have
05:27to override it in my base class.
05:30So let's undo that. Put that back in, and the error goes away.
05:34Let's try another little experiment. Let's do this.
05:37Let's say myBaseClass mbc = new myBaseClass, and we'll save and we'll build, but another error.
05:49What's the error this time?
05:50It says, "Cannot create an instance of the abstract class or
05:55interface myBaseClass."
05:57Abstract classes, as you can see, cannot be instantiated by themselves, and this
06:01is enforced by the C# compiler.
06:05So let's go ahead and delete that code.
06:09So abstract classes are a way of defining abstract ideas that group together
06:15some common properties and functionality of real instances of that class,
06:21but it's just abstract.
06:22You can't actually instantiate that class.
06:24That's a way for you to write your programs such that you can group together the
06:29related pieces of functionality
06:30but force people who want to use your classes to override them and make real
06:35physical instances of them.
Collapse this transcript
Using sealed classes
00:00The next somewhat advanced and somewhat esoteric subject we're going to look at
00:05in advanced C# is sealed classes and methods.
00:08Now sealed classes and methods are essentially the opposite of abstract classes.
00:13Whereas abstract classes force you to derive a subclass in order to use them,
00:19sealed classes actually prevent you from deriving from them.
00:22So there is no way to make a subclass from a class that has been sealed.
00:27It's also possible to mark individual methods in classes as being sealed, which
00:32prevents them from being overwritten in some classes. But it is far more common
00:37to seal entire classes than methods.
00:40And the way that you create sealed class is by using the sealed keyword.
00:44So if I define a class like this, I have a public class myClass.
00:47If I wanted to seal this class, I'd just simply put the word sealed inside
00:51myClass, and then at this point I can no longer create a subclass.
00:56So before the sealed keyword was in there I can make my subclass off of myClass,
01:00but now that the sealed keyword is in there, this is an error;
01:02I can't derive from myClass anymore.
01:05So let's actually see this in action.
01:07I'm actually going to go over to my Snippets here in my SealedClasses example,
01:12and I'm going to copy these lines of code right here, and I'll paste them in.
01:20So here I have my class, and let me just take this guy out for a moment.
01:25So I have a class called myExampleClass and I have my subclass which derives
01:31from myExampleClass. And if I hit F6, you can see that everything works fine;
01:36the Build succeeds.
01:37Let's put the sealed keyword back in there. Save.
01:41Now let's try to build. Oh!
01:42We get an error, and it says that the subclass right here cannot derive from
01:47sealed type myExampleClass.
01:50So by sealing this class, I prevent any further subclasses from being created.
01:55You'll do this when you create classes that you don't want people messing with.
01:59It's not a particularly common thing that you'll see a lot of.
02:02The .NET Framework does this in a couple of places where it doesn't want you
02:05messing with things like the Math class or other things.
02:09Basically, if you create a class where you want it to behave a certain way and
02:13you don't want authors to be able to override methods in your class, you can
02:17create a sealed class.
02:19So pretty quick simple example of how you can create classes in C# that cannot
02:23be derived from or sub-classed.
Collapse this transcript
Defining structs
00:00If you're coming from a language such as C or C++, you're probably familiar with
00:05the notion of a struct.
00:08If you're not, don't worry about it. I'll explain it here.
00:10But structs essentially are similar to classes, but there are some important
00:15differences that you're going to find.
00:17First, structs don't support inheritance.
00:19When you define a struct you define its members and its data types and so on,
00:24but you can't derive one struct from another.
00:28Structs are also value types, while classes are reference types. And if you
00:32haven't yet watched the movie where I explain the difference between value
00:35types and reference types, you should probably go watch that, because it'll make a lot more sense.
00:40You also can't initialize the fields of a struct inside the definition.
00:44So, for example, when you have a member variable inside of a struct, you can't
00:49put a little equal sign after it and initialize it to a value.
00:52You have to do that outside the definition.
00:54Structs are usually used when you just want some small and simple data
00:58structure to represent some piece of information and you don't want all the
01:02overhead of a class.
01:04Now structs can have properties and methods just like a class can.
01:08You just have to remember that they're not really classes.
01:10You can't have inheritance.
01:12There are all kinds of things you can't do.
01:14So let's take a look at real example.
01:15Suppose we wanted to define a data type for representing a point on a
01:20two-dimensional surface.
01:21Well, we could do that with a class.
01:23We'd say public class Point and we would have an X coordinate and we would have a Y coordinate.
01:27We could also have a constructive function.
01:31So when someone said new point, they could pass in a value for the X and the Y,
01:36and that would set the X coordinate and Y coordinate to whatever the values are.
01:39We could also just simply declare this to be a struct, in which case it's not a
01:44class anymore, but everything still works.
01:46We've got member variables, we have a constructor function, and everything is fine.
01:51So let's go jump over to the code and exercise this.
01:55Right, here I'm in my structs example, and I've got my Snippets scrolled down to
01:59the part on Defining Structs.
02:01So over here in the code I'm going to just copy these lines right here.
02:05I am going to copy this structure definition, copy that, and I want to paste it over here.
02:13So now I've got my struct which defines a point, and it's got these two private
02:19number variables for X coordinate and for the Y coordinate.
02:23Then you can also see that just with the class, I've got my constructor
02:27function for the Point, and I've also got a property for setting X and a
02:32property for setting Y.
02:34So let's go back over here and copy some code.
02:37So the first thing I am going to copy is this one right here.
02:41I'll scroll down to my main function and paste that in. And what I'm doing here
02:45is I'm creating a point, and the variable name is p1, and I'm creating new point
02:50with an X coordinate and a Y coordinate both equal to 100.
02:55From the outside looking in, this doesn't look any different than creating a class.
02:59It's so happens that this is a struct.
03:02So let's go back, get some more code.
03:07I can also do the same thing this way.
03:09Point p2 is s new point, and then I can set p2.x to 50 and p2.y, and this will
03:16invoke the getters and setters the same way that I'd with the class.
03:20Let's go ahead and hit F6, and you can see that the Build succeeded.
03:25So if we scroll back up, you notice that pretty much the only thing is
03:28different here is that I'm using the keyword struct instead of using the keyword
03:32class right there on line 8.
03:34So then you are probably asking yourself, okay, well, why would I want to use a
03:36struct versus using a class?
03:38Well, the main reason is because you've got some small data type.
03:41In this case, I've got a point which only contains really two properties that I
03:44really care about setting.
03:45So if you got something small and you don't want all the overhead of a class, or
03:50you don't have to worry about things like inheritance and overwriting stuff,
03:54you can define a struct.
03:55You can also use a struct when you don't want to have to worry about things
03:58being passed by value or passed by reference.
04:02Again, I explained that earlier in the section on value types versus reference types.
04:07Structs are value types,
04:08so you can pass these around as value types, and the values will be copied, and
04:12you don't have to worry about references being changed without you knowing about it.
04:15So anyway, that's a quick lesson on using structs.
04:18You'll find that in many cases if you're define a small data structure, you
04:22can use a struct in places where you would normally use a class.
Collapse this transcript
Using interfaces
00:00The last subject that we are going cover in this section on building some more
00:04advanced classes in C# is using interfaces.
00:09Interfaces are a really neat little feature of C#.
00:12They essentially provide a way for grouping a set of common behaviors in a
00:18single place where more than one class can use them.
00:22Now an interface is sort of like a class, but it provides a specification, or
00:28you might think of it as a contract, rather than an implementation.
00:33You can think of interfaces as an alternative to using abstract classes.
00:40One of the nice things about interfaces is that classes can implement
00:44multiple interfaces.
00:46Now C# doesn't have the notion of multiple inheritance, like some other
00:50languages do, but classes in C# can implement multiple interfaces.
00:57One of the best ways of thinking about interfaces as opposed to classes is that
01:00classes tend to be things, whereas interfaces tend to be behaviors.
01:07So what I can do is I can group a whole bunch of functionality into an interface
01:11and then that sort of becomes a contract.
01:14If my class says that it implements an interface, then that class has to go
01:20ahead and providing implementations for all of the functions that the
01:23interface contains.
01:25The nice thing about that is that my class can then advertise to the world,
01:30hey, these are the interfaces that I implement and then in code that use my
01:35class, the code can check my class to say, hey, are you able to implement this kind of interface?
01:41And if it is, then the code that's using my interface can just say, hey, I know
01:45that you know how to do this,
01:47so I'm going to go ahead and call that method.
01:49So let's take a look at how using interfaces makes grouping behavior more easy
01:55to understand and implement.
01:56So let's imagine I had a few classes.
01:58I've got class A, B, and C. Now let's imagine further that these classes
02:03all knew how to do something, like save their data out to some persistent storage place.
02:10Well, they could all just implement a function name SaveData.
02:15The problem is, without some interface to enforce this, class A might call it
02:20SaveData, class B might call it something else, class C might call it something
02:24else, but by grouping the notion of saving data into an interface called
02:30ISaveable--and interfaces don't have to begin with a capital letter I, but it's
02:35a nice convention that Microsoft has come up with for interfaces;
02:38That way when you see it in a class definition you know that it's an
02:42interface rather than class.
02:43If I said, hey, I'm going to make an interface called ISaveable and anybody who
02:48implements the interface called ISaveable has to have a function in their class
02:52somewhere that's called SaveData.
02:55So then I could do something like this.
02:57I could say, you know what? Each one my classes, class A, B, and C, all implement
03:01an interface called ISaveable.
03:03Well, that enforces what's called a code contract.
03:07So now everybody has to name their function that saves the data the same
03:12thing, because they're all implementing from the same interface.
03:16Now if I wanted to go a step further and say, you know what, not only do my
03:19objects know how to save their data, they also know how to do something like
03:23compress their data,
03:25well, I could implement an interface called IShrinkable. And inside IShrinkable,
03:30I might have a function called CompressedData.
03:34Now notice in the interface there's no implementation of this function.
03:38All that the interface says is, hey, if you implement me, you've got to have a
03:42function named this. And the implementation is actually saved for the classes that
03:47choose to implement it.
03:48So if classes A, B, and C decided to implement both the ISaveable and
03:54IShrinkable interfaces-- you separate them with a comma--
03:58well, now each one of these classes has to have a function named SaveData, and
04:03they all have to have a function named CompressData as well.
04:06Now if one of these classes decided not to have shrinkable or saved or whatever,
04:10they could choose not to implement the function. But if you say that you
04:14implement an interface, you have to implement the members of that interface.
04:19So let's take a look at this working in real code.
04:22So here in the code I've got my UsingInterfaces example open, and I've got my
04:27ExampleSnippets open and scrolled down to the Interfaces section.
04:31So let's go ahead and copy over this line of code right here and paste
04:37it into my program.
04:39Now to declare an interface, you use the word interface and then you give
04:44your interface a name.
04:45It's kind of like declaring a class, although you'll notice that inside my
04:48interface definition, I am not providing any implementation for these methods.
04:52I am just saying that this interface contains two functions: one is called
04:55SayHello, one is called SayGoodBye. And anybody who chooses to say that
04:59they support the ITalkative interface has to provide implications for those two methods.
05:06So let's go back over to the Snippets, and let's copy over this example
05:09class right here called myExampleClass, and we'll paste that into my program over here.
05:16So now I've declared a class called myExampleClass, and it says, yes, I am using
05:22the ITalkative interface.
05:24So here's the constructor for myExampleClass starting on line 16. And you'll see
05:28that on lines 20 and lines 25, I've got implementations for the SayHello and
05:34SayGoodBye functions.
05:36Let's watch what happens really quickly if I take these out.
05:39So I am going to cut this and save it and then build using F6.
05:44You will see that if I try to build this, I'm now getting an error, why?
05:47Because the errors say, hey, my example class does not implement interface
05:51members SayGoodBye and does not implement interface member ITalkative.SayHello.
05:57Well, that's because my class claims to implement ITalkative, but it's not
06:02actually doing that.
06:03There's no implications for the SayHello and SayGoodBye functions.
06:06So let me just go ahead and paste those back in and save, and then we will hit
06:10Build again using F6, and now everything is fine.
06:14So let's go ahead and exercise this code, and we'll do that by copying these
06:20lines of code right here and we'll paste them in there.
06:26So now in my Main function I am declaring a variable, myEC, which is of type of
06:33myExampleClass, and I am using the new operator to create that object. And once
06:37I've created that object, I can say, all right, well, since you are a
06:41myExampleClass and myExampleClass implements the ITalkative interface, I know
06:47that you've got functions called SayHello and SayGoodBye.
06:50So I can call each one of those.
06:52So let's build and run.
06:54We are going to hit F5 here, and you can see that sure enough, when we run the
06:58program the functions for SayHello and SayGoodBye get executed and produce their output.
07:05Let's go back to the Program here.
07:07So once again, interfaces are a way of grouping together common points of functionality.
07:14The interfaces are not things.
07:16You don't instantiate an interface necessarily, although in certain esoteric
07:21circumstances you can do that in C#, but we are not going to get to that in this course.
07:25It's a little bit advanced.
07:26What you do here is you simply create a class that says, I implement this
07:30interface. And if you find yourself building classes that all have similar
07:34behavior, it's probably a sign that you might want to make an interface that
07:38groups that behavior into a common place and then have each one of those classes
07:43implement that interface.
07:45That way you can be sure that they're all getting the same behavior and that the
07:48consumers of your class know that
07:50that behavior can be counted on.
Collapse this transcript
8. Exceptions
Understanding exceptions
00:00At some point in your C# coding experience you're going to have to learn how to
00:04deal with error conditions.
00:06Yes, I know, shock of all shocks.
00:08Sometimes your code isn't going to work the way you thought that it would, or
00:11something is going to happen to cause a problem in your program.
00:15The way that we deal with that in C# and .NET is through the use of
00:19exceptions, and that's what we are going to see how to use in this
00:22particular section.
00:24An exception is basically an error that happens during your program's execution,
00:29whether it's because the user put in some data value that you weren't expecting
00:34or the system runs out of memory or something else that happens.
00:38So let's take a look at an example of an exception, and then we will learn about
00:43how to handle exceptions in your code.
00:47Let's imagine I have two variables, x and y.
00:49They're both integers and I declared them as you see here.
00:53Then I declare another variable called result, and I divide x by y. Well,
00:57dividing 10 by 5, that's okay.
00:59The result is 2. But what happens if I set y to 0, and then I try to divide x by
01:05y, and oh, that's a problem: I'm dividing by 0.
01:09What happens here is the .NET Framework raises what's called an exception.
01:14In this case, it's a DivideByZero exception, and we'll learn about these terms
01:19a little bit later, but the point is that an exception, just generically,
01:23speaking is a problem in the code or somewhere in the system that you have to
01:29anticipate and handle.
01:31So before we go any further, let's learn about some exception terminology.
01:36Exceptions are raised--or using object-oriented nomenclature,
01:42they are thrown--when an error is encountered. When an exception happens the
01:48normal flow of the program is interrupted, and the control is transferred to the
01:55nearest exception handler.
01:57You might say that the handler catches the exception.
01:59So, the exception is thrown somewhere, and then it is caught somewhere else.
02:05Now if there is no exception handler to process that exception and the exception
02:11happens to be a fatal one, then the program just terminates with an error code.
02:16Now not all exceptions are fatal, but some of them are and if the exception that
02:20gets raised is fatal, then your program is going to stop working.
02:24Now, exceptions don't just come from the .NET Framework.
02:27You can build your own exceptions and then raise them yourself.
02:31In other words, you throw your own exceptions using the throw instruction, and we
02:36will see how to do that.
02:38Let's take a look at an example of how exceptions are handled in code.
02:43Now there are three main keywords you're going to have to learn about when
02:47you're working with exceptions.
02:49The first one is try.
02:51Code that is placed inside the try block. Inside those curly braces is a bunch
02:57of code that attempts to do something.
02:59It doesn't matter how many lines you have in there. It could be one, it could five,
03:02it could be 25,000; it doesn't matter.
03:04The point is that inside that try block you're going to do a whole bunch of code.
03:08You're going to assign a catch block.
03:12Now this is actually optional, but you assign a catch block where you think an
03:16exception might happen.
03:18So if the code inside the try block might cause a problem then you assign a
03:22catch block, and this is where exceptions are handled.
03:25So if something goes wrong inside the code that's inside the try then the code
03:29that's inside the catch is going to happen.
03:31Then last, there is finally keyword.
03:34And this code is always run.
03:36It doesn't matter if things were great or things were bad,
03:39if the code in the try section is completely just fine or if there was a problem
03:43and the code in the catch section had to run, the code in the finally section is
03:47always going to run.
03:49So let's take a look at an example.
03:50Suppose we had our example from earlier.
03:53We have those two integers, one is 10, one is 0, and we have the result.
03:57Well, if we try to divide x by y-- in this case we got 10 divide by 0--
04:01that's going to cause an exception, in which case the program flow will be
04:06transferred to the catch block. And here we are going to just write out, hey,
04:11look at error happened, and we do a whole bunch of things in here. In
04:14this case, we are writing out an error message, but there is other code that we
04:17could've written here to try to handle the exception.
04:19Maybe we could ask the user to try putting a different value, or we can just
04:22try something else.
04:24The point is that the code in the catch block is going run when the problem happens.
04:28So let's take a look at some real code to see how to write this.
04:31So I am in my UsingExceptions example, and in my Snippets you see I've scrolled
04:38down to the Exceptions section.
04:41So let me copy the setup code, and we'll paste it here into main. And we'll go
04:49back to the sample, and we'll scroll down a little bit, and we'll take this entire
04:54piece of try, catch, and finally, and we will paste that in as well.
05:01So what I've done here is I've defined three different blocks of code:
05:05one is called try, one is called catch, one is called finally.
05:09Now if I run this code in its current state, I've got 10 being divided by 5
05:15on line 18 right here, and that should just be fine.
05:19What should happen is the Console.WriteLine for The result is, is going to be
05:23executed, and it will show me the result.
05:24So let's go ahead and run this and see what happens. And you can see that the
05:28result is 2, and you can also see that a line is being written out there that
05:31says, "Just proving that this code always runs."
05:34And if we go back to the code, you'll see that
05:35that's in the finally section down here.
05:37Remember earlier I said that the code in the finally section always gets run;
05:41it doesn't matter what happens in the try or the catch block.
05:44So now let's change the code so that we have an error happen. So let's do this.
05:48We are going to change y to 0.
05:51So now we are going to 10 divided by 0, and that's going to cause a problem.
05:56So we are going to get to line 18.
05:57We are going to try to divide 10 by 0, and an exception is going to happen.
06:01What that means that the code at line 19, this Console.WriteLine statement, is
06:06never going to get run.
06:08What's going to happen is the code is going to be transferred, the program flow
06:12is going to be interrupted, and we are going to jump down here into this catch
06:15block where this line of code, the An error occurred!
06:19Better check the code line, is going to be run.
06:21So now let's try this.
06:24You can see that what happened was we tried to divide 10 by 0, which is a math
06:28error, and you can see the Console. WriteLine inside the catch block is writing
06:33out An error occurred!
06:34Better check the code. And also we can see that the code in the finally block
06:39always runs, because that Console.WriteLine also got executed.
06:44So that's a quick introduction on how to use exceptions and as we move through
06:47the rest of this section, we will learn more about how to create our own
06:51exceptions and work with exceptions in a more advanced fashion.
Collapse this transcript
Introducing the Exception object
00:00Exceptions are in fact objects, and in fact the exception object is defined and
00:06derived from System.Exception.
00:09That is the base class for all the exception objects in .NET. And the .NET
00:14Framework actually defines a pretty large number of exception classes.
00:19For proof of that, let's just quickly jump over to the MSDN web site and you can
00:22see what I am talking about.
00:24This is the Exception Class definition here on msdn.microsoft.com. And if you do
00:30a search for System.Exception or if you go to the URL up there in the URL bar,
00:34you'll see the exception class.
00:35Now as we scroll down a little bit, you'll see that just like other objects,
00:40there are constructors.
00:42In this case, we've got four different constructors and there are some properties.
00:47So these are the properties that exceptions make available.
00:50There's Data and HelpLink and Message, and we'll explore some on these later on
00:53as we through the exceptions, but what I really want to point out is as we
00:56scroll all the way down, you'll see that System.Exception is the base class for a
01:02pretty large number of exceptions throughout .NET.
01:05Look at how large this list is.
01:07This isn't even a complete list.
01:08This is a list of a lot of the exceptions that descend directly from
01:12System.Exception, but the one that we're most interested in is right here,
01:17System.ApplicationException.
01:19This is probably one of the most common exceptions that you will come in contact
01:23with as a C# developer. And in fact, I've opened that window right over here.
01:28So this is the ApplicationException class, and this class encapsulates all the
01:33exceptions that are thrown when non-fatal application errors happen.
01:38So once again, we can scroll down.
01:41You can see that there is Properties, and there are all kinds of ways you can
01:44create application exceptions. But once again we get down to the Instance
01:48Hierarchy or the Inheritance Hierarchy.
01:50You can see that a lot of other exceptions happen to descend from
01:54ApplicationException. And this is true throughout .NET.
01:57You've got exceptions that are descendents of other exceptions. And you might be
02:02wondering, well, with all these different types of exceptions is it possible to
02:07write catch handlers that only catch certain kinds of exceptions?
02:12So to catch specific exceptions, you can put inside parentheses for each one of
02:16the catch handlers the kind of exception that you're looking for.
02:20So in the case that you see here, I've got a try block where I'm going to try a
02:25whole bunch of code and then I have several catch handlers all in a row.
02:29So I've got a catch handler for an exception that's DivideByZero.
02:32I've got a catch handler for ArithmeticException.
02:34I've got a catch handler in case we run OutOfMemory.
02:37There are all kinds of stuff that I can put here, and I can put a generic catch
02:41at the bottom of all these too that catches exceptions that don't get caught by these.
02:45So let's jump over to the code and see how we can handle catching specific
02:50types of exceptions.
02:51So here we are in the example.
02:52This is the ExceptionObject example.
02:54I've got my program file open, and down in the Snippets I scroll to the
02:57Exception Object section.
02:59So let's go ahead and copy the set of code, and we'll paste that it into Main.
03:04All right, now let's copy the try and catch, all the way down to the finally,
03:10okay, and we'll paste that in.
03:13You know what? Since we already know that the finally always runs, I am just
03:17going to comment this line out.
03:18We don't really need it for this example.
03:20So let's comment it out.
03:22All right, so this is pretty much the same example as I showed previously.
03:26We've got two numbers.
03:27We've got x here which is 10.
03:28We've got y which is 0.
03:30We have an integer for holding the result. And you can see here that we are
03:33going to try to divide by zero.
03:35The only difference from the previous example is that here I am now catching a
03:39DivideByZeroException, and this is an arithmetic exception. And since I know that
03:46it's a DivideByZeroException I can say, hey, you tried to divide by zero.
03:52I can also write out members of the exception object that's passed in.
03:57So when you catch a specific exception, you get an argument;
04:00in this case I've named it e, but you can name it whatever you want to.
04:03This will be passed into your catch handler, and this is the exception object
04:07that caused the exception.
04:09So we can do things like introspect that object and see things like what the
04:13message that goes along with it is and so on and so forth.
04:16So let's save this and let's build. Build succeeded.
04:20All right, let's go ahead and run it and try to divide by 0 and see what happens.
04:24Sure enough, you can see that You try to divide by zero.
04:27Now that first sentence there, "Whoops!
04:28You tried to divide by zero!"
04:30is what I'm writing out, and the "Attempted to divide by zero!"
04:33string is being written out from the message property of the exception object.
04:38All right, let's go back to the code, and let's try something else.
04:43Let's copy this catch handler and paste it down here.
04:47Now what I am going to do is instead of looking for a
04:51System.DivideByZeroException, I'm going to look for an ArithmeticException.
04:55So I am going to hit dot and scroll down here, and I've got an
05:01ArithmeticException right here.
05:03So now I'm going to save, and I am going to build, and you can see that the build
05:08succeeded. And what I am going to do is run this.
05:13Now because I have the DivideByZero handler already in place, that's the first
05:17one it's going to jump to.
05:19The exception is going to jump to the first catch handler that makes the most sense.
05:22So even though this is an ArithmeticException, it's going to jump to the
05:26DivideByZero version, because that's more specific to the kind of exception I am seeing.
05:31Let's try something else.
05:33Let's take the ArithmeticException and cut it and put it in front of the
05:37DivideByZeroException.
05:39Now you'll notice that when I do that I get a little red squiggle on the
05:41DivideByZeroException.
05:44Let's see what that error is saying. It says, "Error:
05:48A previous catch clause already catches all exceptions of this or of a super type."
05:54What this basically means is because DivideByZeroException is a subclass of the
06:01ArithmeticException object, this is never going to be called.
06:05What's going to happen is a DivideByZeroException is going be thrown, but since
06:10it's a subclass of this guy right here, this catch block is going to catch all
06:15the math problems that might come up, including DivideByZero. And since it
06:20occurs first, this code will never get executed.
06:23So the C# compiler is catching that situation for me and saying, hey, you sure
06:28you want to do this?
06:29Why would you put in a catch handler that's never going to be called? So let's do this.
06:33Let's take that WriteLine out, cut that line.
06:36Let's put that in there instead. Let's see what the message is for
06:39ArithmeticException, and let's just take out the DivideByZeroException.
06:43So now I am catching the more general case.
06:46I'm catching the ArithmeticException now, not just specifically the
06:49DivideByZero, although DivideByZero is an ArithmeticException.
06:54So let's run this, and you can see that we're getting the same message in this case.
06:58So even though we got an ArithmeticException, it knows specifically what
07:01happened, and the message in this case is an "Attempted to divide by zero."
07:05So by using the ExceptionObject, your code can look for and catch specific
07:10exceptions. And if you don't want to catch a specific exception, you can use the
07:15catch handler. That just catches any exception that comes its way.
07:19This is way for your code to be on the lookout for specific kinds of exceptions
07:23so that it can take corrective action and try to prevent the user from having a
07:26bad experience while using a program.
Collapse this transcript
Creating your own exceptions
00:00Now I mentioned earlier that exceptions don't just simply come from .NET;
00:04you can create your own custom exceptions--and in this movie we are going to
00:08see how to do that.
00:09Essentially, by sub-classing the exception object from the system namespace you
00:15can create your own exceptions.
00:17And then when you're ready to raise an exception, you use the throw instruction.
00:22So for example, you can do things like throw a new System.Exception, or you can
00:27throw a new MyCustomException.
00:28You have to have the new in there because you've got to create the exception object
00:33that you are going to throw, and then the throw keyword will cause the exception
00:36to be thrown, and then the catch mechanism will go into effect.
00:41So let's go over to some live code to see how we define our own exceptions and
00:45then throw and catch them.
00:47So I have my Custom Exceptions example here, and here is my Snippets. I've
00:51scrolled down so they are creating exceptions section.
00:54What I am going to first is just scroll down here and I am going to copy some of
00:58the setup code, copy this, and I am going to paste this in my program. And then
01:05I'm going to go back and I am going to ignore the catch section for a moment;
01:08I'm just going to get the finally section, put that in here.
01:12Now one of the first things you realize is that you don't actually need to have
01:16a catch section at all.
01:17You can just have try and finally if you want to.
01:20So what I've got here is some code. I've got a string variable called the name,
01:24and then in my try block I've got a function called getName.
01:28Well, actually, I haven't defined it yet. That's why there is a little squiggle there.
01:31But the getName function is going to ask the user to input a name, and it's
01:35going to return it in the form of a string. And then I've got code on line 17
01:40which simply writes out "Hello" and then whatever the name that you put in. And
01:44then in the finally block, which remember always runs, we have a string that says, "Have a nice day!"
01:48So let's go back to the snippets and get that getName function. And what I am
01:53going to do is get this right here, copy that, and I am going to paste that
01:59function in right up here. And for the moment I am going to just take this part out of it.
02:05So what we are going to do in getName is use the Console.ReadLine function to
02:10read a string, and then we are going to return that string.
02:14So let's go ahead and run the code that we have and see how well it works.
02:18So I am going to just build. It ran.
02:21So now it's waiting for me to enter a name, and I am just going to type in the name scott.
02:26It says, "Hello scott. Have a nice day!"
02:27Great, okay everything is working fine.
02:29Let's suppose we wanted to catch a certain name though and have that cause an exception.
02:35So let's go back to the getName function, and what we are going to do is we are
02:41going to say you know, if the string that was entered equals Joe, we're not going
02:45to allow the word Joe to be put in.
02:47So we are going to throw an exception called the NoJoesException.
02:50Now we have to define the NoJoesException, which you see right here on line 14.
02:56So let's go back to the Snippets and scroll up.
03:00Here we have our definition for the NoJoesException.
03:03Let's copy that, and we'll paste it in. And it's a class,
03:07so I am going to paste it outside my program class.
03:10So you can see on line 8, I've got a definition here for public class
03:14NoJoesException, and there's the colon, which means it inherits from the exception
03:19class, which is contained in the system namespace.
03:22And remember, since I'm using the system namespace up here, I don't have to write
03:26out System.Exception.
03:27I can just use the word exception here.
03:29So inside my NoJoesException, I've got my constructor, and my constructor is a
03:34public NoJoesException constructor. And what I'm doing here is I'm calling the
03:40base exception constructor with a string.
03:44So before I go any further, let's just jump back over to the MSDN documentation
03:48to see what the system exception looks like.
03:52So here we are, in the documentation for the exception class.
03:55Let's scroll down, and you can see that there are four different ways I can
03:59construct an exception class.
04:02There is a constructor that takes no arguments.
04:05There is a constructor that takes an argument that's a string, and it says
04:08here, "Initializes a new instance of the exception class where they specified error message."
04:14Well, that sounds pretty much like the one I want. Let's just make sure.
04:18Next one is exception with serialization and info and streaming context,
04:22whatever that is, because it's obviously wrong.
04:24And there's the exception here with a specified error message and a reference to
04:28the inner exception. Okay, that's pretty advanced. I am not going to use that one.
04:32Looks like number two is the one I want.
04:34So I have to initialize a new instance of the exception class with the
04:37specified error message.
04:39Okay, that sounds great. Let's go back to the code.
04:41Well, the way that I do that in C#--
04:43well, there is a couple of ways I can do it.
04:45First, I am just going to call the base-level constructor with the string here.
04:49Now you might be wondering, why am I not just simply inside my constructor doing
04:53something like this?
04:54this.Message = No Joes allowed.
05:00I am going to save that and I am going to build. Wait, we've got an error.
05:04It says, "Property or indexer System.Exception. Message cannot be assigned to--it is read only."
05:10Oh! So I can't actually make an assignment to that.
05:13Looks like the only way to do it in this case is through the constructor. Okay,
05:17well, I guess I won't do that then.
05:20So it looks like this base method is the only way to do that.
05:22So I'm passing in an error message to initialize the exception with "We don't
05:25allow No Joes in here!"
05:27However, I can give the user some help . And there is a field, or a property in
05:33this case, called HelpLink. Again let's just jump over to the documentation very quick.
05:38So if we scroll down, you'll see there is a property called HelpLink, and it
05:42says, "Gets or sets a link to the help file associated with this exception." Oh cool!
05:48Okay, so I can tell the user what to do in case an exception like this happens.
05:53Let's go back to the code.
05:55So what I am going to do is initialize my HelpLink here on line 13 to be a
05:59link to my web site.
06:01So back down here in the program--let me close this error window so we have more space--
06:06you can see that when we get the input from the user, we are going to see if the
06:11string is equal to Joe and if it is, we are going to throw the NoJoesException.
06:16Now there's one more thing we have to do:
06:18we have to implement the catch block for the NoJoesException. So let's go back
06:21to the code, and down here in the Snippets we've got my catch handler.
06:26I am going to copy that,
06:28go back over here, and in between try and the finally, I am going to paste that in.
06:31So you can see here what I am doing is I'm going to catch specifically a
06:36NoJoesException, and I've named the variable nje.
06:40So what I am going to do is write out the message, which is what I initialized
06:44it with up in the constructor, and then another line I am going to write out "For
06:48help, visit," and then I am going to write out the HelpLink field that's in my NoJoesException.
06:52All right, it looks like everything is ready to go.
06:57Let's hit F6. Okay, the build succeeded.
06:59Let's hit F5 to run it.
07:01All right, so I am going to type in "scott," "Hello scott Have a nice day!"
07:06That seems to work okay.
07:07Let's try it one more time with Joe. Oh!
07:10Now, we get an error. It says "We don't allow no Joes in here! For help, visit:"
07:14and then use the help link that I put into my help message for the user.
07:19And of course in the finally block it says, "Have a nice day!"
07:22All right, so this is how you can create your own exceptions, throw your own
07:26exceptions, and use some of the fields provided by the base system exception
07:31object to give your users some help and some detailed messages for when
07:34those errors occur.
Collapse this transcript
Re-throwing exceptions
00:00The last subject that we're going to examine in the area of exceptions is
00:05that of rethrowing exceptions. And what that means is when an exception happens
00:10inside your catch handler, you can do some processing, but if you handle the
00:15exception, the exception pretty much stops with you.
00:18You can keep it going by throwing it again, or hence the term 'rethrowing' the exception.
00:24Now, why would you want to do this?
00:25Let's take a look at an example, and hopefully that will make it a little bit more clear.
00:29So here in my RethrowingExceptions example what I am going to do is go to my
00:32Snippets and I am going to copy some code in over here.
00:37So first, I am going to start with these lines down here, and I am going to copy
00:41those and paste them into my Main function.
00:46So I've got some code that calls a function called DoSomeMath, and it catches an
00:53ArithmeticException and writes out a message that says hey!
00:56Look, something went wrong in there.
00:58You might want to be careful, or something like that. All right!
01:00Now let's go back to the Snippets.
01:04Let's copy the DoSomeMath function. All right and that's going to go up here.
01:11So starting here on line 10 I've got my DoSomeMath function, and this is the
01:16example that we've been working with up until now.
01:18So what DoSomeMath is going to do is the same thing we've seen up until now,
01:22which is try to divide by 0.
01:24So here I've got my two variables on line 12.
01:26I've got my result on line 13.
01:27Here on line 15 I've got my try block, and I am going to try to divide 10 by 0.
01:33Now, of course, what's going to happen is that's going to cause an exception.
01:37So the catch handler will execute here, and I will write out something like hey!
01:43You know, there is an error in DoSomeMath.
01:45But I don't want the exception to just die here with me;
01:48I want the exception to continue on and have other exception handlers do their
01:54thing, because there might be some additional work that needs to be done.
01:58So inside my catch handler, I am going to throw a new ArithmeticException.
02:04Now, if I want to just rethrow the same exception, I wouldn't do this.
02:07What I would do is I would just simply do this;
02:09I would take out this new and just say throw.
02:12What that means is, take the same exception that I am currently handling and
02:16just rethrow it again. And that would be the same exception objects. Things
02:21would just continue on as they were, and my catch handler would just be one and
02:25a line of catch handlers.
02:27But what I am going to do here is--let me put that code back in--I am actually
02:30going to throw an entirely new exception called an ArithmeticException, because
02:35remember, what I am catching here is a divide-by-0 exception.
02:38So let's go ahead and save, and I am going to run this.
02:41So you can see that what happened here is both catch handlers executed.
02:46There's the catch handler inside the DoSomeMath function, and then there was the
02:51catch handler that was in my Main program.
02:54So let's go back and take a look.
02:57You can see that this catch handler executed and this catch handler executed.
03:02If I didn't have this line of code in here--and let me just comment it out, now
03:07let's try rerunning it again--
03:09you can see that in that case, only my catch handler executed.
03:12So the other catch handler doesn't get a chance to run. The exception just gets
03:17handled and dies in the DoSomeMath function and doesn't get a chance to continue on.
03:22So by rethrowing the exception, or in this case throwing the new one, we give the
03:27other exception handler a chance to do its stuff.
03:30So why would you do this?
03:31Well, suppose you've got an exception handler whose job is to just log out
03:36whenever a particular exception happens.
03:39You don't want that catch handler to be the be-all and the end-all.
03:42You just want to insert it in the handling process so that that way your log
03:46file shows that an exception happened. And then once that exception handler is
03:49done logging out whatever information it needs to log out, it can continue on and
03:54rethrow that exception so that the other real exception handlers in the process
03:59somewhere get a chance to do their work.
04:01So let's take a look at what happens when I take out the new ArithmeticException.
04:07And I am not going to change the catch section right here.
04:10I am just going to leave it alone.
04:11So I am going to run it, and you can see that now both catch handlers are being
04:15handled again. And because a divide by 0 is an ArithmeticException, the other
04:21exception handler is being executed.
04:23So this is a really great way to segment out your catch handlers so that each one
04:28does its own little piece of work and they don't interfere with each other and
04:32they are able to pass the exception on down the chain so that all the exception
04:36handlers have the chance to do whatever it is that they need to do.
04:39Just make sure that the last exception handler in the line is the last exception
04:43handler in the line.
04:44It doesn't pass the error up through to the user.
04:47At some point, the error needs to be handled and not shown to the user--well, at
04:51least in most cases.
04:52So you're going to want to make sure that at least one of your catch handlers is
04:55where the exception eventually stops.
Collapse this transcript
9. File Management
Introducing streams and files
00:00We've reached the point now where we've seen enough C# to start doing some real
00:04stuff, and one of the more common "real stuffs" that you'll probably do when
00:09working with C# is moving information into and out of files. And the .NET
00:14Framework provides some really great utilities for working with files and
00:17information in files, and that's what we're going to cover in this section.
00:21We're going to start off with an introduction to streams and files.
00:26So let's start talking about that right off.
00:28When you want to move the data into or out of a file or across the network or
00:32over the Internet or some block of memory or some other location, the data has
00:38to be what's called streamed.
00:40You can think of a stream as an analogue to its real-world counterpart.
00:44Think of water moving between two bodies of water in the form of a stream
00:50or river or whatever.
00:51In this case, however, the stream data is a bunch of 1s and 0s that represent
00:57the information of a file, and the body of water is called the backing store.
01:03Now the backing store can be anything. It can be a file.
01:06It can be someplace on the network.
01:10It can be some place out over the Internet;
01:12it doesn't really matter what it is.
01:13The point is the backing store is where the information goes to or comes from.
01:19Streams have certain properties:
01:20they can be readable, they can be writable, or they can be both.
01:25Streams can also be what's called seekable.
01:28In other words, some kinds of streams have this notion where there is a position
01:32that you can look at and modify.
01:35Sometimes this is called a random access stream.
01:38Streams descend from the System.IO.Stream abstract base class.
01:45Now we're not going to work too deeply with streams themselves in this section;
01:49we're going to stick to the higher-level classes and utilities for working with files.
01:53But it's important to have an understanding of what they are, and it's useful to
01:57have this background so that later on, when you want to go and work a little bit
02:00more deeply with files, you'll understand what a stream is.
02:03So at the top, we have the stream class and again, this is an abstract
02:06base class. And we looked at abstract base classes a little bit earlier in the course;
02:10if you haven't watched that section, you should go do that now.
02:13This is a class that forces you to create a subclass in order to provide an implementation.
02:19So these stream abstract base class provides a whole bunch of abstract, or
02:23theoretical, things that streams need to be able to do, and then the real stream
02:27classes you work with descend from streams, such as the FileStream.
02:31This is a class for working with physical files on the disk.
02:35There is also the MemoryStream, which is locations located somewhere in
02:39the computer's memory.
02:40There is the NetworkStream.
02:42This is used to move information across the network.
02:45So actually, let's take a quick look over at MSDN so you can see what the stream
02:49base class looks like.
02:50All right, so this is the stream class documentation here on msdn.microsoft.com.
02:55You can see the URL up there in the browser if you want to go and look at it for yourself.
03:00The stream class--let's just scroll through this--
03:02you can see that there's a constructor which makes a new stream, and there
03:06are some properties, things like CanRead, and CanSeek, CanTimeout, CanWrite,
03:10that kind of thing.
03:11And if we scroll down a little bit further, there are methods,
03:14methods for reading and writing information, for copying information, so on and so forth.
03:18These are all the base-level functionality features that a stream has to
03:23provide to its users.
03:24Now remember, this is an abstract base class, so you won't actually instantiate a stream class;
03:30what you'll use is one of the subclasses. And if you continue scroll down,
03:34you'll see that underneath the System IO Stream, there is a whole bunch of other streams.
03:38There's BufferedStream, there is FileStream, there is MemoryStream, and here is
03:42the NetworkStream I talked about earlier.
03:43These are the actual stream classes that you will use.
03:46But we're not going to cover that right now;
03:48what I'm going to do is talk about the file and directory higher-level classes
03:52that we're going to use in this section.
03:55.NET provides a collection of useful classes for working with files and
04:00directories, so let's go over those right now.
04:03One is called the File class, and this provides a very simplified high-level set
04:07of functions for working with files.
04:09In fact, this is mostly a static class where you call the methods of this class
04:14using the file.notation. And if you haven't watched the section on classes, you
04:19should go do that to understand what a static class is.
04:22So file is probably the highest level example of working with files.
04:26The next one down is the FileInfo class.
04:28This provides more detailed lower-level functions that provide a little bit more
04:32control over working with files.
04:34Then there is the FileStream class, which I briefly talked about just a few moments ago.
04:38This exposes a stream object around a file, which provides very detailed
04:42control over how information gets written to and read from the file.
04:47For directories, there is a sirectory class and this is sort of the analogue to
04:51the file class. It provides very simple high-level functions for working with
04:55directories, or folders. And then there's the DirectoryInfo class which provides
04:59some more detailed lower-level functions that provide a bit more control over
05:04working with directories.
05:05So we're going to use some of these classes in the rest of the section to work
05:08with files and directories.
Collapse this transcript
Working with existing files
00:00Let's begin with something simple.
00:01We are going to see how to work with existing files.
00:04Now, the file class provides some features for working with files. And as I
00:08mentioned earlier, most of the methods in this class are static.
00:11You call them directly on the file object. And if you're not familiar with
00:15static classes, you should go back and watch the section on classes to find out
00:19what a static class is.
00:21So the file object provides some really simple functions.
00:24I am going to go over some of them here, not all of them, because it's quite a few.
00:27But, for example, there is an exists method that checks to see if a file at a
00:31given path exists or not and if a file does not exist, you can call a method
00:36called create, which, surprisingly, creates the file at the specified path.
00:40There are also functions for copying and moving and deleting files.
00:45There is File.Copy, which copies a file to another location.
00:48There is a Move function, which as the name indicates, moves a file, and there is a
00:53delete function which deletes a file at a specified path.
00:57So let's jump over to the code and exercise some of these functions and see how they work.
01:02Okay, so I'm here in my existing project with my program file open, and here is
01:09my Snippets. And I've scrolled down to the Existing Files section.
01:13So let's begin by just checking to see if a file exists. And what I am going
01:18to do is use a couple of other utilities to get a path to a special location
01:24here on my computer.
01:25So we're going be working with files in the My Documents folder, and I am going
01:29to copy these first few lines right here.
01:34So let's take a quick review of these lines of code before we do anything else.
01:38So the first few lines, I have a Boolean variable called fileExists and I
01:42initialize it to false because we are going to assume that the file doesn't exist.
01:46Then we need to build up a file path, and the path just basically specifies where
01:51on the computer the file exists or not.
01:54So here I am going to say I have string called the path, and I am going to use a
01:59special .NET class called the environment class.
02:03The environment class gives me some utilities for working with the
02:06Windows environment.
02:08So I am going to ask the environment to get me a folder path, and the
02:11GetFolderPath function can take a couple of different arguments.
02:14I'm going to use the Environment.SpecialFolder.MyDocuments property, and this
02:20will get me a path to the My Documents folder on this computer.
02:25Now I could have just hard coded this by typing in C:\users\Joe Marini, so on and so forth.
02:33That's really not a very good practice.
02:35You don't want to hard code things into your applications if you can avoid it.
02:39And windows, and in this case .NET, provides a bunch of utilities for working with
02:43special document folders. Not just My Documents, but things like the temporary
02:47directory and the trash or the recycle bin, that kind of thing.
02:51So I am using this environment class right here to get the path to the My Documents folder.
02:56So once I have the path to the My Documents folder, I'm then going to add on to
03:03the end this string right here, which is testfile.txt. And recall I put the @
03:10sign at the front of the string to prevent this \t here from being treated as a tab character.
03:17I want the backlash to be treated as a path separator.
03:21So at the end of all this I'll have a full path to a file named testfile.txt.
03:26All right, let's go bring up my, My Documents folder, so
03:29you can see what's in it.
03:31Okay this is the My Documents folder, and you can see that right now there is
03:34no file named test file.txt in here, so we're going to create it if it doesn't exist.
03:39Let's go back to code.
03:41We start off by using the File.Exists function here on line 17.
03:46So we call File.Exists. That returns a Boolean result indicating whether the file
03:50exists. And then I have an if statement and my if statement says if the file
03:55exists. Then just write out to the console that the file exists.
03:59Otherwise write out that the file does not exist and we are going to create it.
04:02Then we call the File.Create function with the path, and this will create the file for us.
04:08So let's go ahead and see what happens when we build and run this.
04:13The code compiles and runs, and you can see that we're getting a message out to
04:16the console that says, "The file does not exist. creating it."
04:19So let's go back for our My Documents folder, and you can see now that the
04:23test file has been created. And in this case, I am hiding known file extensions, so
04:29you don't see that.txt on the end there, but it is there.
04:32Okay, so test file has now been created. Let's go back and do some more work with it.
04:37Let's go back to Snippets, and we'll copy this over, copy, and we'll paste this in.
04:52Okay, so I am going to comment out these last two lines, just for a moment.
04:57So once we've determined that the file exists, we can then get some
05:00information about it.
05:01In this particular section of code here I'm saying if the file exists then let's
05:06figure out when it was created. And we are going to use the Files.GetCreationTime
05:11method and the GetLastAccessTime method for the file, and we passed in the file
05:17path both times to get information about the file.
05:20And this will tell us when the file was created and when it was last accessed.
05:23Okay, so now when I run the program again the file already exists,
05:28so this part of the If statement should execute and we shouldn't have to re-create it.
05:32So I am going to save, and I am going to run, and sure
05:36enough, you can see that I am getting the message, "The file exists."
05:39So we didn't have to re-create it, and you can see it was created on such and
05:42such a date at such and such a time, and it was last accessed on such and such a
05:46date and such and such a time.
05:48Let's finish up our exercise by moving the file to a new location.
05:51So I am going to hit return and exit on that.
05:53Now I am going to uncomment these last two lines here, and we are going to move
05:57the file somewhere else using the File.Move function.
06:01And what we are going to do is move the file from its existing path--that's the
06:05first argument--to the path, but we are just going to give it a new name.
06:09So it's going to stay in the same folder, but it's going to be renamed to newfile.txt.
06:14So we are going to save, and we are going to run, and you can see that we are
06:20still getting the original message that it exists and the creation and access times.
06:24And now we are moving the file.
06:26So let's go back to the My Documents folder, and you can see, that test file is no longer there.
06:31It is now called newfile.
06:33So you can use these functions to operate on files that are existing or create
06:37new ones on your file system.
06:40And if you feel like getting a little bit more advanced, go take a look at the
06:42file class. There is a whole bunch of other useful methods in there that you can
06:46experiment with for working with existing files.
Collapse this transcript
Working with directory and disk information
00:00As you might have guessed, just as there are ways for working with existing
00:03files, there are ways to work with existing directories. And whether you called
00:07them directories or folders, it doesn't really matter; they're the same thing.
00:11But in the .NET Framework the class is called a directory.
00:15Now working with directories is pretty similar to working with files, except that
00:20directories can also contain other files and directories, whereas files just
00:25contain information.
00:26But there are classes for working with directories.
00:28There is of course the Directory.Exists function which tells you whether a
00:32directory exist or not.
00:33You can also create and delete directories the same way you can with files.
00:38You can figure out what the current directory is for the application.
00:41This is the directory that the application is currently looking at, what it
00:45thinks is the current one, where information will be written to or read from.
00:50And just like in the other directories, they contain other things. You can get the
00:54files and get the directories that are contained within a directory. And just
00:58like files, you can move directories around.
01:00So let's jump over to the code and exercise some of these functions so we
01:04can see how they work.
01:05Here I am in my ExistingDir project, and once again I've got my Snippets file open.
01:10So I've scrolled it down to the Existing Directories part, and I'm going to just
01:15copy these first few lines right here.
01:21So this example, so far, isn't too different than the example we saw for the files case.
01:27Right here at the top, I've got the string variable called the path, which I'm
01:31using to figure out where the MyDocuments folder is.
01:35Once again, I'm using the Special Environment class, and I'm calling the
01:40GetFolderPath, which will tell me where the MyDocuments folder is. And just to
01:46show you there are lots of features on here, I'm going to just hit little
01:49dot here on special folder, and you can see there is a whole bunch of special
01:53folder I can get paths to.
01:54There is the Admintools.
01:55There is CommonDocuments.
01:56There's things like Music and Pictures.
01:59There's the Startup directory.
02:01There is the Desktop.
02:02There is a whole bunch of special paths that you can get access to.
02:06I'm just going to go ahead and leave it as MyDocuments.
02:08This will get me the path to the MyDocuments folder.
02:11Then we're going to call the Directory.Exists function right here on line 1,6 to
02:16see if that directory actually exists or not.
02:19Since it's the MyDocuments folder, I'm pretty sure it's going to exist.
02:24So we have an if clause here that says if the directory exists then write out to
02:29the console that it does; otherwise write out that it doesn't.
02:32So this is a pretty good place to start.
02:34Just go ahead and save and run this in its current form.
02:38And you can see that the result is that the directory exists. So far so good.
02:42Let's continue on.
02:44Let's go back to the Snippets and get some more code.
02:47What we're going to do now is use the GetFiles function on the directory class
02:53to write out the names of the files that are in that directory.
02:56So we are going to copy, and we are going to paste that down here.
03:05So let's save, and let's take look.
03:07So the GetFiles function that you see here on line 24 returns a string array,
03:13which is why I'm declaring this string array variable called files, which will
03:18hold the results of the GetFiles function. And I pass in the path which is now
03:24the MyDocuments folder.
03:25Then below that I'm using our newly discovered foreach loop construct, and so I'm
03:32going to loop over all the strings in that files array.
03:35So for each string--and I'm going to call each one of that S--that's in the files array,
03:40I'm going to write out to the console I found a file plus whatever the file
03:44name is right here.
03:46Now I could use the Formatting String function, but I just chose not to
03:49for simplicity here.
03:50So let's go ahead and build this, and we can see the build succeeded, and let's run it.
03:54It looks like we found a couple of files in there.
03:57We've got a couple of contents of the directory,
04:00so that seems to be working.
04:02Let's hit Return and go back to the code. Let's move on.
04:08Now we are going to do a little bit of extra credit.
04:10It turns out that there is a class called Drive Info, and I'm going to leave that
04:15up to you as an exercise to go onto MSDN and look up this class to see what it
04:20does. But I'm just going to do a really quick simple experiment here. I want
04:23to copy the code, and then we'll explain what it does.
04:28So just like you can work with files and directories, you can also work with
04:33disks or other storage devices that are attached to your computer.
04:38So what we're going to do here is get information about each one of the disk
04:41drives on the computer, as long as it is a fixed drive. You'll notice that there are
04:47different kinds of drives when you look up information about this class.
04:51There are things like removable drives and so on and so forth.
04:53So what we're going to do is write out that we're getting the drive information.
04:57You can see that up here on line 32.
04:58Then we're going to call here on line 33 the GetDrives function, and as a
05:05shorthand we're just going to loop this inside a foreach loop.
05:08So we're going to get each DriveInfo, because the GetDrives function comes back
05:14with an array of DriveInfo structures.
05:17So we're going to say for each DriveInfo D which is in the array that comes
05:22back from GetDrives,
05:24we're going to execute the code in this loop. And we're going to ask the
05:27DriveInfo if the DriveType is equal to the DriveType.Fixed.
05:33Like I said earlier, there are all kinds of examples here.
05:36If I hit the period, you'll see that there is CDRom and Fixed and Network and
05:39so on and so forth.
05:40So we're just going to stick with Fixed, and we're going to write out the
05:43information about each one of the fixed drives.
05:44We'll write out its name, how much free space it has, what type it is, and so on.
05:49So let's go ahead and save. Let's build.
05:51It works, and now let's run it.
05:55You can see now that we're writing out some information about not just the
05:58files, but the drive information.
05:59So we seem to have too fixed drives: one is called C:, one is called D:.
06:04They're both fixed and they both have a lot of free space. That's how many bytes
06:08are free in each one.
06:09That's a quick example for working with directories and drives.
06:12Now let's move on and look at some more file information.
Collapse this transcript
Using the Path class
00:00One of the things that you're going to find yourself doing over and over again
00:03as you work with files and directories and so on is that there's a lot of
00:07information contained in paths, and you'll find yourself having to parse out
00:12paths to extract file names, or just the path portion, or just the directory name,
00:17or just the file name without the extension. And it turns out that the .NET
00:21Framework provides a helper class called the path class that makes a lot of
00:25these operations really simple.
00:27So if you look at the way a typical path is built, it has a predictable
00:32structure. And here's a sample path, and this may look different based upon the
00:37files you work with, but this is just a sample.
00:39So right at the front, there's the drive name, and it can be a letter followed by
00:44a colon, followed by a backslash.
00:46The drive name is the root level of the path, and it's the disk or the
00:51location where a file is.
00:53That's followed by the path.
00:55This is the directory structure that specifies where a file is located. And this
01:00is usually a nested set of directories, or folders, whatever you want to call, them
01:05that leads down to the actual file name itself, which is right here,
01:09somefilename, which is usually followed by an extension.
01:14Now not all file systems do this, but some do.
01:17Windows, for example, does, and this also works on the Mac.
01:20But since we're working here on Windows, we can pretty much be sure that most
01:24files will have extensions.
01:25So file extensions are usually a period followed by some amount of characters,
01:30usually between three and five.
01:32So let's take a look at the path helper class to see how we can use it to
01:37help us work with paths.
01:40In the Path Operations example, I've got my snippets file open, and I've scrolled
01:45down to the Path Operations section. So let's go ahead and copy over the setup
01:50code, and we'll paste it over here.
01:55Now I'm going to be working with a path to the testfile.txt file which we
02:02created in an earlier example.
02:03So if you have deleted it, you can go just make a new file called testfile.txt
02:08in the My Documents folder. And you can see here that I'm using the code I used
02:13in the earlier examples to get a path to the MyDocument special folder here on my Windows system.
02:19Let me make this a little bit wider, so you can see that.
02:21So right here, this is the MyDocuments path, and then we're going to put the
02:25testfile.txt on the end of it.
02:27So this is the example file we'll be working with.
02:29If you don't have that already on your My Documents folder, you should just go make one.
02:33So what we're going to is save this, and I'm going to go back over to the Snippets and
02:37start copying over some of the exercises.
02:40So I'll start with this one, and I'll copy that and paste this over.
02:47So the first thing we're going to do is extract the directory name from the
02:52path information, and to do that, we're going to use the Path class. And again
02:56this is a static class.
02:57You are going to call most of these methods using the class name followed by
03:01the function name--in this case it's GetDirectoryName. And you pass in thePath as the argument.
03:07This will parse out all of the information that's not relative to the directory
03:11name and then just return the name of the directory that's inside the path.
03:15So let's save this, and let's hit F5 to run it.
03:21And you can see here that in this case the directory name is C:\Users\Joe
03:25Marini\Documents, and it's parsed out the part that is the file name.
03:29It's giving me just the directory name. And you can see here it is a
03:32fully qualified path.
03:34What I mean by fully qualified is it starts at the drive, which is the root, and
03:38goes all the way down to where the document is.
03:42So it gives me the entire, full directory structure that leads to that file.
03:46Okay, let's go back and do some more experiments.
03:50The next one I'm going to do is get the example that extracts just the file
03:55name, so this is the opposite of the example we just showed.
03:57In this case, we're only going to ask for the file name. And in this case, we're
04:00going to use the GetFileName function on the path class, and this will give me
04:04the name of the file without the directory information.
04:07So I'll save that and run it, and you can see here that now I've got the
04:13directory name, and the file name is testfile.txt.
04:17So that function parsed out all the information that was not relative to the
04:21file name and just returned the full file name with the extension.
04:24Okay, let's go back, and let's do another one.
04:30We'll copy and paste this one.
04:31In this case, we're going to get the file name without the extension.
04:36So let's scroll down here.
04:38You can see that the path class provides a function called
04:41GetFileNameWithoutExtension, and again, it takes thePath as an argument.
04:46So we'll save and we'll run, and in that case, I get just the file name without
04:52the directory and without the three-letter extension on the end.
04:55Okay, let's go back.
04:57It looks like we have one more.
04:59We're going to copy and we're going to paste and paste this in, okay.
05:07In this case, the path class is going to give us a random file name.
05:13Now you might be asking yourself, why would I ever need to get a random file name?
05:17What this is going to do is ask .NET to generate some random file name for us.
05:22It's going to consists of a certain number of characters, followed by a period,
05:25followed by three characters.
05:28The reason you might want to do this is because sometimes in your applications
05:30you'll need to save out temporary data and rather than going through the
05:34exercise of trying to figure out what file name you can come up with that
05:38doesn't conflict with a file that's already existing in a particular directory,
05:43you can just call GetRandomFileName.
05:46.NET will then figure out what file name you can use that doesn't conflict with
05:50a file that's already in the directory.
05:52You can then use that file to save out whatever temporary data you have and then
05:56get rid of the file. And this is the nice little utility to save you all the
05:59trouble of having to figure out,
06:00well, can I use this file name or can I use that file name, without conflicting
06:03with an existing file.
06:05So let's just go ahead in exercise and see what it does.
06:07I going to run this, and you can see that the random file name for the current
06:12path is this sequence of characters right here.
06:16Now if I exit the program and run it again, you can see that it come up with
06:20another set of characters here. And it will keep on doing that each time I run this.
06:24So that's a nice handy little utility for creating random file names that you
06:29know aren't going to conflict with existing file names in the current directory.
06:34So that's a quick introduction to the path class.
06:36I highly recommend you go look it up on MSDN and try some more examples on
06:40your own.
Collapse this transcript
Reading and writing files
00:00The last example that we're going to look at in this section is probably the
00:03one you've been waiting for, and that is actually writing and reading data to and from files.
00:08Now, there's lots of ways to do this in the .NET Framework.
00:11The .NET Framework provides a whole bunch of ways for writing data to
00:14and reading from files.
00:16There's probably more ways to do this than there are ways to order sushi.
00:19But we're only going to look at some of the more simple ways of doing this.
00:22I mentioned earlier that we're not going to get deep into streams;
00:24you can feel free to go do that as an extra credit exercise.
00:27What we're going to look at is the higher level order functions for reading and writing data.
00:33So for writing data, there are some really simple functions.
00:35There's File.AppendAllText, which simply takes a bunch of text content and
00:40appends it to the end of an existing file.
00:43There's the WriteAllBytes and WriteAllLines, which, as their name implies, for
00:49WriteAllBytes you can just give it an array of bytes; for WriteAllLines, you
00:53give it an array of strings. They will write out the content to the file.
00:56And then there's File.WriteAllText.
00:59Now, unlike AppendAllText, WriteAllText will replace the existing contents of the file.
01:05So if you want to just replace the content, use WriteAllText.
01:08If you want to add to the existing content, use AppendAllText.
01:13Not surprisingly, there are some counterparts for reading data.
01:16There is ReadAllBytes, and as you might have guessed, this will read all the
01:21content of a file as a bunch of binary bytes.
01:25But for the purposes of our exercise, we're going to be working with text, so
01:29we'll probably use things like ReadLines and ReadAllLines and ReadAllText.
01:33This will actually read the contents of a file as text content.
01:38So let's just jump over to the code and actually start exercising some of this,
01:42so that you can see how it works. Okay.
01:44In my ReadingWritingData example, I have got my Snippets opened, and I
01:48have scrolled down to the Reading and Writing Files section.
01:51So I am going to start off by copying over the setup code, which are these lines right here.
01:57So I will copy those and paste them in.
02:00I'll put them in my main function. All right!
02:03So before we go any further, let's take a look at what's going on here.
02:07So if you've been following the examples up until now, you're probably familiar
02:10with the first line here on line 14.
02:12This is the filePath.
02:14We're going to be using the environment class to get the path to the
02:18My Documents folder.
02:20But we're going to be doing something a little bit different this time.
02:22If you watched the section on the path helper class, which is previous,
02:26you will probably notice that they are using a path helper section here.
02:31Instead of using the backslash character hard coded into my examplefile.txt file
02:37name, I am using the Path.DirectorySeparatorChar constant, which tells me what
02:44the separate character for this file system happens to be.
02:47Now, here on this version of Windows and .NET, it will be a backslash, but it
02:51might be different based upon what platform you happen to be running on.
02:54So I am going to just use this constant right here so that I don't have to hard
02:58code a directory separator into my code, which is never a good idea.
03:04So I am taking steps here to make my code work cross-platform. All right!
03:07So now that we've got the path built up, we're going to see if the file exists.
03:13And if you watched that particular example, you will know that we use the
03:16File.Exists function do that, here on line 18.
03:20So we'll see if the file does not exist, so we'll put that little not operator
03:25right here in front of the File.Exists call.
03:29So if the file does not exist then we're going to create it by using the
03:33WriteAllText function.
03:35So we'll have a string variable here on line 20, which will be the contents of
03:40the file. And the content is going to be a string called, "This is a text file,"
03:43And once again, I am using my environment class to figure out what the new line
03:48character is for this particular platform.
03:50So once again, rather than hard coding in a /r or /n, or whatever a state
03:55sequence happens to be the NewLine character on this particular file system, I
04:00will just use the NewLine constant for this particular environment.
04:04Then I am going to write out the console that we're creating the file, and then
04:08I'll use the File.WriteAllText method. And WriteAllText takes two arguments:
04:13the first is the path to write to, the second is the text content that we are writing out.
04:18So I am going to build this, and I am going to run it. And you can see that
04:25the Creating the file... string got written out, because the file did not
04:28exist in the My Documents folder. So now we've created it, and if you want to
04:33go ahead and check your My Documents folder to see if it exists, you can go ahead and do that.
04:37I am just going to keep on moving on here. All right!
04:41So let's go back to the Snippets.
04:43Now, let's use the AppendAllText method to add content to the file.
04:49We'll copy, and we'll paste, and we'll save.
04:54Okay, so I am going to build this, and now I am going to run it.
05:00Okay, now you can see that I am adding content to the file.
05:04Let's go back and look at the code and see what happened here.
05:07The file already exists, so the if statement here on lines 18 through 23 did
05:12not need to execute.
05:13The file's content is getting appended,
05:16so this line right here, Adding content to the file... got written out, then we
05:21use the AppendAllText to add the added text string, which I am building up right
05:28here into the file, and that writes the content out to the file.
05:32So just to make sure that things are working okay, let's go ahead and open the
05:35file up so we can look at the contents.
05:37So here I am in my documents folder.
05:40Let's open up examplefile, and you can see, here is, "This is a text file" and this
05:44is "Text added to the file."
05:46Well, that's great, but I would rather not have to open up Notepad to make sure
05:49that the content is getting added correctly.
05:51So let's see if we can read the contents and display the contents into the console.
05:54All right, so back here in the code, let's scroll down. All right!
06:02Now, we're going to read the contents of the file. So I am going to copy these
06:06lines right here and back in my code,
06:11I am going to paste them in.
06:13So we're going to write out to the console that we are reading the file, and you
06:17can see right here we're writing out that The current contents of the file are:,
06:21and then it will separate a line, to separate the content.
06:23Then we're going to use the ReadAllText static method on the file class to get
06:27the current content.
06:28The current content will come back as a string.
06:30So we've got a string variable right here on line 35, which will hold the
06:34results of the ReadAllText function on the filePath.
06:38Once we have the current content, we will write out the current content to
06:42the console, and then we'll put a little line separator to increase
06:46readability right here.
06:47So I am going to build. Okay, the build succeeds.
06:51We run it, and you can see that we've now added content to the file and The
06:56current contents of the file are:.
06:58And we've got a couple of lines, "This is a text file," and then we've got "Text
07:01added to the file" twice.
07:03So I am going to hit Return.
07:04I am going to run it one more time, because each time we run it, this line right
07:08here, the "Text added to the file" is going to get added.
07:10So I am going to run it again, and you can see that now that there are three;
07:14and then I'll run it again and you can see that now there are four.
07:18Okay, let's go back to the code.
07:21One more thing I want to do here.
07:22I want to show you how to read the contents of the lines of the file using the
07:27ReadAllLines function.
07:29I want to copy this, and I am going to paste it in over here.
07:34This is just another way of reading the contents of the file, so I am going to
07:37paste that in here. And for now, I am just going to comment out these lines,
07:42and I am going to uncomment these lines, so that we can actually run the code.
07:52So whereas the ReadAllText function on the file class will read all the content,
07:58the ReadAllLines will read the lines and return an array of strings.
08:04So ReadAllText comes back with one string; ReadAllLines comes back with an array
08:09of strings, and that's this right here on line 40.
08:12So I am declaring an array of strings-- that's this contents variable right
08:17here. Then I call the ReadAllLines function, which will return an array, and
08:21then here's our old friend the foreach function.
08:24So I am going to loop over each string that is in the contents array, and I am
08:29going to call each one of those strings the variable S. And inside my loop, I am
08:34going to just write out whatever that S string is.
08:38So let's build, and I am going to run, and you can see that we get the same
08:44results, only this time, instead of reading the content as one long string, we
08:49read the contents as an array of strings. All right!
08:54That bring us to the close of this example and this chapter, so I highly
08:57encourage you to go explore the file class and do some of your own experiments
09:01working with reading and writing data to files.
Collapse this transcript
10. Some Advanced C#
Using variable parameter lists
00:00Up until now we've been working with some of the more basic features of C#, and in
00:05this section we're going to start looking at some of the more advanced features
00:08of C# that were added in some of the more recent versions.
00:11Now most of the stuff that you've seen so far you'll see in C# applications
00:16all over the place,
00:17but the ones that we're going to look at now are going to enable you to write
00:20applications that are more advanced and have more concise code in them.
00:24And we're going to start off by looking at something called variable parameter lists.
00:27Variable parameter lists are useful because there's going to be times when you
00:31want to create functions that take a number of arguments that you don't know in advance.
00:36The way that you do this is by using the params keyword.
00:40The params keyword allows you to define a parameter list for function that takes
00:44a variable number of parameters, and it looks something like this.
00:49Suppose I have a function that added a bunch of numbers together.
00:51Now, I could add a whole bunch of numbers, but the problem is, without using
00:55variable parameter list, I'd have to have a fixed number of parameters.
00:59So for example, I could supply two integers, in this case, a and b.
01:03But what if I wanted to add three integers or four integers or some
01:07unknown number of integers?
01:08Well, I could go the route of overloading methods, if you watched the movie on
01:13that section, in which case, I would just define a whole bunch of addNumbers
01:18functions and define a version of addNumbers that takes two arguments and then
01:22one that takes three arguments and then one that takes arguments.
01:25The problem is that gets really tedious really quickly and really bloats the
01:28code. Or I could just simply use the params keyword and tell my function that it
01:34takes an array of arguments.
01:36So, for example, rather than just adding two numbers, I would do something like this.
01:41And here I've used the params keyword and following the params keyword, I say int
01:47with square brackets.
01:48So this tells the C# compiler, hey, compiler, this function is going to take
01:52an array of arguments.
01:54And we don't know how long that array is going to be.
01:57So the params keyword says, just be ready for a whole bunch of arguments.
02:01Now once I've done that, I can rewrite the body of this function from just adding
02:05two numbers to adding a whole bunch of numbers. And I'll use the foreach
02:09construct to loop over each one of the integers in the nums argument that you
02:14see there in the parameter list, and just keep a running total.
02:18So let's jump over to the code and actually write this example and see it work.
02:22Here in my variable params example, I've scrolled down to the Variable
02:26Parameter Lists sections of my ExampleSnippets, and the first thing we're going to do
02:30is copy over the function.
02:32So this is the function that's going to add a whole bunch of numbers.
02:35So I'll just copy this and go over to the program code, and I'm going to paste it in.
02:40I'll paste it down here.
02:43So now I have my addNumbers function, and you can see I'm using the params
02:46keyword that takes an integer array of arguments.
02:51So let's exercise this.
02:52Let's go back up to the code. And I'm going to copy over this code here, which I'm
02:56going to paste in the Main function.
03:00So let's paste this in.
03:03So let's take a look at what's happening here.
03:04First, you'll notice that we have two different calls to addNumbers.
03:08There is one here on line 14. There is one here on line 17.
03:11The one on line 14 is passing in three arguments, 4, 6, and 8, and then the one
03:16here on 17 is passing in a whole bunch of arguments.
03:18So what's going to happen is each one of these calls to the addNumbers function
03:22is going to generate an array of integers, and then inside my addNumbers, I'm
03:26just going to loop over each one of the integers, add it to my running total,
03:30and then return the total back to the caller, which will be stored in this
03:34result variable right here.
03:36So let's just build this and run it, and you can see that in the first case the
03:42result is 18, and in the second case the result is 84.
03:45So I've been able to now define a function that takes a variable number of
03:49parameters so that I can write my code using this function and not know how many
03:54arguments I'm going to have in advance.
03:56Now there are a couple of things you need to keep in mind about the
03:58parameters function.
03:59One of the most important ones is that if you're going to use the params keyword,
04:03that has to be the last argument to the function.
04:05What I can't do is something like this.
04:09You'll see that when I try to do that I get some errors, and if I mouse over it,
04:13you'll see, "A parameter array must be the last parameter in a formal parameter list."
04:19The reason for this is because since this is variable, the compiler has no way of
04:23knowing how many arguments are in the array, and therefore, which argument goes
04:28in the array and which integer is the last one.
04:30So if I wanted to do something like this, I'd have to make sure that any other
04:36arguments, whether they be strings or integers or objects, all of those have to
04:45come before the params array.
04:48So now we see that there is no error. Well, there is an error up here because I'm
04:51not passing in the string integer object.
04:54But anyway, that's how you use variable parameters in your functions.
04:59So using the params keyword you can define functions that take a variable number
05:03of parameters which greatly simplifies code that has to work on an unknown
05:08number of arguments.
Collapse this transcript
Using function parameter modifiers
00:00Earlier on in the course I talked about the difference between calling functions
00:04and passing parameters by value and passing parameters by reference.
00:08So if you haven't watched that movie, now is probably a good time to go watch
00:11it, so you'll understand what's going on here, because I am going to be talking
00:13about function parameter modifiers which allow you to change the way that
00:18parameters are passed to and from functions.
00:22So let's just take a quick recap to see how things normally work.
00:27Suppose I had a function that takes an integer parameter, and it looks like
00:31this, and inside that function, I have a piece of code that adds the number 10
00:36to whatever that integer parameter was passed.
00:39Now, if I call it from another function that looks like this, and I have an
00:42integer named x and I initialize it to the value of 10, and then I call my
00:47function, the code that's inside my function does not change the value of the x
00:53variable in the test function down there below.
00:57However, I can use a keyword in the parameter list for the function called ref.
01:03This causes a parameter to be passed by reference, instead of having a copy of
01:08its value passed in, which is what the normal case is in C#.
01:13Now what I'd do here is I would declare my function as normal.
01:16I'd have an integer parameter named param1, but I would put the ref keyword in front
01:21of the type name--in this case integer.
01:24This causes the param1 parameter to be passed by reference.
01:29So now here I have my test function, and I've got my integer variable named x.
01:34Now, when I call the function, I also have to put the ref keyword in front of
01:39the parameter that I'm passing to the function.
01:42When I do this param1 is now a reference to the x variable and not a copy of
01:49its existing value.
01:51This line of code here, param1 += 10, will in fact change the value of x down in
01:58the calling function.
01:59X will now be equal to 20 when this function returns.
02:04The reason why I need the ref keyword in both places is so that it's really
02:07clear what's going on in the code.
02:10So you can deliberately do this when you want to be able to change the value of
02:13parameters that are passed to functions.
02:16So let's take a look at one more example.
02:19There's the out keyword.
02:21Now, normally functions return values through their return type, but the out
02:27keyword allows a return value to be passed back via a parameter, and you would
02:33use this in cases where you wanted a function to be able to pass back more than one result.
02:39So let's take a look at an admittedly contrived example.
02:43Suppose I had a function named SqrAndRoot, and SqrAndRoot takes a number as its
02:49first parameter, and I want it to return both the square of that number and the
02:54square root of that number.
02:56I could pass in a parameter named sq, which would be the square, and I put the out
03:01keyword in front of it.
03:03I do the same thing for another parameter named sqrt, and I also put the out
03:08keyword in front of that type named for that parameter.
03:12Now, inside the body of the function, I would simply assign values to the square
03:17and square root results.
03:19So for sq I'd simply multiply num by itself, and that's the square of the number,
03:24and then for sqrt I'm using the .NET Framework's math library to calculate the
03:29square root of that number.
03:31When I call this from a function, say, named test and I pass in the parameters,
03:36you'll notice that I've to put the out keyword in front of the parameters
03:40that I'm passing in.
03:41So when I call SqrAndRoot, I pass in the first parameter, which is x. That's the
03:45number I want to have the square and square root of.
03:48Now when this function completes, theSquare and theRoot are going to have the
03:52values that were calculated by the square and root function.
03:56You notice I don't have to actually initialize those values, because those values
04:00are going to be calculated for me by the function.
04:03So I don't have to assign initial values to them.
04:06Now, it's one thing to hear me yammer on about it;
04:08let's actually go over to the code and actually watch it work.
04:10Okay, so here I'm in my FuncParamModifiers project.
04:13I've got my Snippets open to the code for this example.
04:17So first, I'm going to copy this function, which is the SquareAndRoot function,
04:21copy that and put it over in my code.
04:25That's the function that we're going to call.
04:27You can see I'm using the out keyword right here on line 10 to indicate to the
04:32compiler that sq and sqrt are going to be out parameters.
04:37I'm going to copy the code, going to call it with, and we'll put that down here
04:44in the Main function.
04:45Okay, I am going to put a line there.
04:47So what we're starting off with here is a number,
04:50in this case 9.0, and it's a double, and I've got variables named theSquare and
04:56theRoot which are going to hold the results, and now I just simply call square and root.
05:00I pass in 9 and I've got my out keyword in front of each one of the parameters
05:04that are going to hold the output.
05:06Then I've got Console.WriteLine call that says, hey!
05:09The square of this number is this, and its square root is this, and I'm just
05:14passing in those results to the WriteLine function.
05:17So, everything looks good.
05:19I hit F6, and it builds just fine.
05:22Now let's run it, and you can see that the square of 9 is 81 and its square root is 3.
05:30So it works just as we expected it to, and you can use the out keyword and the
05:34ref keywords to change the way that parameters are passed to and from functions.
Collapse this transcript
Using optional and named function parameters
00:00Okay, the next advanced C # feature we are going to take a look at are optional
00:04and named parameters.
00:05Now up until now when we've been calling functions with parameters we have been
00:08supplying values for those parameters, because if we don't, then the C# compiler
00:13complains that we left a parameter out of the function call.
00:16Optional parameters allow you to define default values for parameters so that if
00:20you don't feel like passing in a value for that parameter, you don't have to.
00:24And the way that you do that looks a little bit like this.
00:27So I can define a function, and you can see that I define the function normally
00:30with two integer parameters. But I've got equals and then values after each one
00:35of those parameters.
00:36So here for my function, I don't have to supply values for a or for b, because
00:41if I don't, then a will default to 0 and b will default to 1.
00:45So, for example, it's just as valid for you call the function like this, where I
00:49have got a just defaulting to 0 and b to 1, as it is to call it like this, where
00:54a is now 10, but b retains its default value.
00:58The other feature is named parameters.
01:00Now up until the version of C#, I think it was 3.0, you had to call parameters in
01:05the order in which they were declared in the function declaration; named
01:09parameters, however, changed that.
01:11Suppose, for example, that I have a function that looks like this.
01:14I have got two integer arguments: one named a and one named b.
01:18I can actually just simply call the function by passing in the name of the
01:22parameter, a colon, and then the value, and it looks like this.
01:26So if I wanted to call this function with parameters that are out of order, I
01:29would simply say b:5 and a:3. And this would call the function normally.
01:35And you notice I don't have to do anything special to the to the function declaration.
01:38This just automatically works in C#.
01:40So I can call the functions with the parameters that are out of order.
01:44If I wanted to call the function otherwise, I could do it like this.
01:47I can call the function with just the value 3, which is now a is 3 in that case,
01:52and I'll put the name of b:7, although in this case I wouldn't have to do that.
01:57Now notice that if you don't supply a named parameter, then they have to go first.
02:02So, for example, if I wanted to this b:7 and then 3, that would cause an error,
02:07because the C# compiler would say well, wait a second. You are not supplying a
02:11name for a, and therefore I don't know which parameter you are talking about.
02:14So you have to put the non-named parameters first.
02:18Let's go over to the code and actually exercise this.
02:21So here I am in my NamedOptionalParams exercise, and in the Snippets, under the
02:26Named and Optional Parameters section, I am going to copy over the two functions
02:30I am going to be using to exercise this.
02:33So let's just copy these guys first and paste them into the code, and I will
02:38put them below the Main function here.
02:39So I have got two functions.
02:41I have got one called myoptionalParamFunc, and you can see here that I've got a param here
02:48that's -- param1, this is not optional because it doesn't have a default value.
02:52This one here is optional because it's being supplied with a default value for
02:57param2 and then for the third one, which is a string, I've also got a default
03:01value which is a string value.
03:03And it's worth pointing out here that you can provide default values for pretty
03:07much just about any parameter type you can come up with.
03:10Inside the function all we are doing is writing out what the function was called
03:15with, and we will write out the values for param0, param1, and param2.
03:20And you will notice here that I am using some escape sequences.
03:23I have a \n and \t. That basically means, do a new line and then tab in, which
03:30will make the results a little bit easier to read. All right!
03:33Next, I have mynamedParamExample, in which case I'm going to call this function
03:38with named parameters in the code from the Main function.
03:42And again, you will notice, I don't have to do anything special to the
03:45function declaration.
03:46This just works with normal C# functions.
03:48So let's go back and copy over the code that actually exercises these.
03:53Let's start with the named parameters example.
03:56So I will copy those lines and I will paste them into Main. All right!
03:59So the first thing we are going to do is call the named parameter example, and
04:05you can see I have got cityName, stateName, and zipCode.
04:08I am just going to call them in different orders.
04:10So the first example is going to call it with state, zip, and then city; the
04:14second is going to call with city then zip and then state; and then the last one
04:17is going to do zip, city, and then state.
04:20So let's go ahead and exercise that.
04:22We will build it and run it.
04:26And you can see that in each one of the cases the arguments were passed in
04:30different orders, but the output is in the right order.
04:33So each one got its city name correctly, the state name is correct, and the
04:37zip code is correct.
04:39Okay, so let's do this.
04:40Let's go back to the Snippets, and let's pass in the optional parameters example.
04:47Copy this, paste it over here.
04:50So now we are going to call the optionalParam function, and in each one of these
04:56cases we are going to pass in a different set of values.
04:59This one is going to pass in just one parameter.
05:01This one will pass in two, and this one will do three, and then we will get to
05:05this one in just a moment.
05:06So let's save and build, and now we are going to run it, and you can see that now,
05:13on the lower part of the output here, I have got Called with.
05:16In the first case, you can see that the first parameter was 15 and then this two
05:20second parameters were the default values.
05:22In the second case, I passed in two parameters, so the first two parameters
05:26are different, but the placeholder string is still the same. And in third case
05:30I passed in three parameters which are different values and all of the default ones.
05:34So let's go back to the code and see what happens when I uncomment this one right here.
05:39Actually, before I do that, let me comment these guys out to make the output a
05:41little more readable. All right!
05:42So I am going to save. And you'll see that I am getting an error here, and the
05:48reason I am getting an error is because the best overloaded method match for
05:53blah, blah, blah has some invalid arguments.
05:55What that basically means is, because I'm using optional parameters here,
06:01you'll see that there is no version of myoptionalParamFunc that takes an
06:07integer and then a string.
06:10So this is a problem here.
06:11If I'm going to pass in parameters that are being supplied instead of the
06:15defaults, I have to supply values for all the optional parameters leading up to that point.
06:21So I can't leave out the middle parameter here, because it thinks I am trying to
06:25pass in a string value to this double right here, which is not correct.
06:29So if you are going to use optional parameters and you want to supply values for
06:33parameters in different orders, you will probably have to use the
06:36named parameters and optional parameters in the same function call, which is
06:40what we are going to do right now.
06:41So let me comment that back out to get rid of the error. Now do both.
06:49So to fix the error that I had above, what I am going to do pass in the value
06:55for the first parameter, because it's mandatory.
06:58There is no default value here, so I have got to supply a value to that, but
07:01I want to skip over the middle parameter and just provide a string for the last one.
07:05So to do that, I'm combining the named parameter feature with the optional
07:11parameter feature. And now the compiler is like, oh, I see, you're trying to
07:14supply a string for param3, which is over here, and not for param2.
07:21Okay, well, that's fine with me.
07:23So let's go ahead and build, and let's run it, and you can see now that all the
07:28cases work. And this is the most recent case we just added.
07:31So we have got the mandatory value here,
07:34the default value is now being passed in for param2, and in the last case we have
07:38a different string being passed in for param3.
07:41So optional and named parameters really allow you some great flexibility in how
07:45you define your functions.
07:46They allow you to define default values for parameters that you don't want to
07:51make mandatory for the caller, and named parameters allow you to call functions
07:55with parameters in different orders.
Collapse this transcript
Using the C# preprocessor
00:00During your C# coding travels, you're probably going to come across C#
00:04preprocessor directives, and that's we are going to cover in this particular movie.
00:08The preprocessor is what its name implies.
00:11It does some pre-processing of the files before the compiler actually goes and
00:17looks at all the code and compiles the application.
00:20The preprocessor directives simply give instructions to the compiler
00:24which help the compiler do its job before the compilation process actually runs.
00:29Preprocessor directives are preceded by a hash character, or a pound character, or
00:35whatever you want to call it.
00:36So we'll take a look at some of those here.
00:38The first two are define and undef, and you can see that they have got that
00:42little--I guess you can call it sharp character, if you want to, whatever is it,
00:45it has a word preceded by that little character.
00:49In this case, define and undef allow you to define or undefine a symbol.
00:55Now, why would you want to do that?
00:56Well, we will take a look at an example that explains why you would want to
00:59do that in just a moment, but there are a few other directives we want to look at first.
01:03Using preprocessor directives, you can also do things like logic.
01:06You can use #if, #else, #elif, or #andif, and these allow you to use logic to see
01:13if a certain symbol is defined.
01:15Now if the light bulb hasn't gone off yet, don't worry; it will in just a moment,
01:18but there are two more directives we want to take look at.
01:20They are region and nregion, and these are used for documenting your code, so that
01:27the C# Express development environment allows you to do things like label
01:31regions and collapse regions and so on.
01:34But rather than just talk about them, let's actually see them in action, because
01:37slides just don't do it justice.
01:39Let's jump over to the code.
01:40I have got my preprocessor example open here, and here is my program file.
01:46The first thing I am going to do is this:
01:48I am going to do a couple of defines.
01:51Now, if you're going to define symbols, you need to do it before any other line
01:56of code in the file.
01:57So I need to put these defines up here above the using statements; otherwise, this
02:01will cause problems.
02:02So if I try to take these out and put them down here and save, you'll see
02:07that these little red squiggles show up, and that's because the compiler is complaining.
02:11It says hey, you cannot define or undefine preprocessor symbols after the
02:15first token in the file. And that's just a fancy way of saying, these got to come first.
02:20So let's go ahead and cut those and put them back up there.
02:25So now I have defined some symbols, but what exactly does that mean. Why am I
02:28defining symbols in the first place?
02:30Well, the reason for doing this will become clearer when we paste in the rest of
02:34the example. And I am going to go ahead and paste these guys in down here, copy,
02:39and I'll put these in the Main part of my program.
02:43So what you'll do here is you will notice that when I've got these #if and #else
02:48and #endif, they are checking to see if a particular symbol has been defined.
02:53So let's imagine that you're building a version of your application where you
02:56only want to include some code if it, say, in a debug configuration, or if
03:03it's in a demo mode.
03:04Suppose I wanted to have this code right here only included in my application
03:10if I'm shipping a demo version of my application, versus a fully released, fully
03:15functional version.
03:16Well, in that case I can simply change this from the DEBUGCODE to DEMOMODE or
03:21whatever it is that I want.
03:22You can see I have also defined a JOE symbol here.
03:26I can make up whatever symbol I name I want.
03:27Now, what's going to happen is the compiler is going to come across this logic
03:30and say #if DEBUGCODE. Okay, well, if there's a symbol name DEBUGCODE then the
03:36code that's in between this #if and #else is going to be included in the
03:42compilation process and code that does not meet that logic test is not going to be included.
03:47You can see here on line 18 that this code is in gray.
03:51That's because the compiler is going to ignore it.
03:53I can just write things that's not even code in here. Watch!
03:56No red squiggles, right? Why?
03:58Because the compiler is completely ignoring this code; it's not meeting the
04:02logical test to see if the DEBUGCODE symbol is present.
04:05Let me go ahead and delete that.
04:08So now if we build and run--let's just do that really quickly, build and run;
04:12we will hit F5--you'll see that the lines of code that met the logical tests of
04:18those preprocessors was included in the application and they are executing.
04:22So let me hit Return and get out of here.
04:24Now let's go back up to the top.
04:26What I am going to do is I am going to take out this #define for JOE, and we'll save.
04:31Now watch, notice how the line of code that's inside this #if, #endif section
04:37for the JOE symbol went and turned gray.
04:40That's because I've gotten rid of the JOE symbol and this line of code is no
04:44longer relevant, because this logical test on line 20 no longer evaluates to true.
04:49Similarly, I can get rid of the #define DEBUGCODE, and you'll notice that the
04:54line of code that used to be included in the compilation process when DEBUGCODE
04:59was defined is now gray and the else condition is now being included.
05:03So this bright line right here, it says:
05:06"This only gets written out in non- debug code" is going to execute.
05:09So if I run this now, you will see that that line of code is getting executed
05:13where the other lines of code are not getting executed.
05:15In fact, they are not even included in the program.
05:17If you were to disassemble this code using a disassembler, you'd notice that
05:21those lines of code aren't even present in the final application. Okay.
05:25So let's take a look at one more preprocessor directive, and that is the region directive.
05:30What I am going to do is copy this right here, #region.
05:33I am going to put that in front of the Main, and then I am going to copy the
05:40endregion. And I am going to put that below the Main function right here.
05:48Now when I save, what that does is it tells the C# compiler that this is a region of code.
05:53Now, this doesn't affect compilation.
05:55It's really just for documentation, because watch what I can do now.
05:58Over here in the C# Express IDE, I can click on this little collapse button and
06:04you can see that it collapses down, and the text that I've included after the
06:07region declaration here on line 10 is what gets included in that little label.
06:12So I can collapse that down and you can see now that all that code is hidden.
06:16So if I wanted to just collapse my code down to make it easier to read, I can
06:20separate my code into different regions and then expand and then collapse them as I see fit.
06:25Now if you're coming from other languages, such as C or C++ or Objective-C,
06:31you'll probably see sometimes these preprocessor directives used to define
06:36constants, and you'll see the #define directive used to define numbers and so on.
06:43That's not the way things are done in C#.
06:46In C# we have the const keyword, which we discussed earlier in the course
06:50for defining constants.
06:52So if you're coming from a language like C where you're used to using the
06:55#define preprocessor directive to define constant values, you are not going to do that here.
07:00You can use the const keyword instead.
07:02Here, we are going to use the #define and #undef and so on, just to affect the
07:07way that compilation happens.
Collapse this transcript
Working with delegates
00:00Next couple of subjects that we are going to take a look at are fairly advanced,
00:04and they are delegates and events.
00:07I am going to start off by taking a look at C# delegates.
00:10C# delegates are sort of like callbacks that you may have seen in other languages.
00:14If you're familiar with programming languages such as JavaScript or Java or C or
00:20C++, then you're probably familiar with the notion of a callback function.
00:25A callback function is assigned at runtime and you can change callback functions
00:29while the program is running. And the callback function is simply a way for you
00:33to provide a piece of functionality that can be switched in and out as it is
00:37needed. And delegates provide that functionality in C#.
00:40Essentially, a C# delegate decouples the caller of a function from the call
00:46function, which is essentially the same thing that callbacks do.
00:49So to declare a delegate use the delegate keyword, and you're essentially
00:53defining a type of function that is going to be called.
00:57So I use the delegate function. Then I provide the type that the delegate
01:02is going to return.
01:03So in this case I'm declaring a delegate that returns an integer. Then I need to
01:08provide a name for the delegate, and I can make it up as much as I want to.
01:12I can use whatever a legal function name would be.
01:15In this case I am just using the generic term delegateName, but you can use
01:18whatever name you want. And then you have to provide any parameters that the
01:22delegate is going to handle.
01:23In this case I'm declaring a delegate that returns an integer and takes two parameters:
01:27there is an integer and a string.
01:30Then when I want to use the delegate, I use it like any other kind of type name.
01:34So in this case I'm declaring a variable named func, which is of type
01:40delegateName, and I'm assigning it to be someFunction.
01:43So as long as I declare someFunction to be the same format as the delegate that
01:48I have declared above, I can switch that function in and out as much as I like.
01:52Then I just call the function like I would any other function.
01:55In this case I've got an integer result which is being assigned
01:59to the result that comes back from the func variable, which is now pointing at
02:03the someFunction function, and it takes the integer argument 3 and the string argument "hello."
02:09Then all we have to do is actually write the someFunction callback. And you can
02:14see here that I've got a function named someFunction, which returns an integer
02:18and takes two parameters--an integer and a string--and it has the same format as
02:23the delegate that I declared at the top of the slide there.
02:27So let's jump over to the C# code and actually implement this and see how it works.
02:32Okay, so I am here in my delegate example, and I've got the UsingDelegates
02:37project open, and I have also got the ExampleSnippets file open, and I've scrolled
02:42down to the section on using delegates.
02:45So the first thing I am going to do is copy my delegate declaration.
02:49That's this line right here, so I will copy that and I will paste it into
02:52the Main program here.
02:55Now I am going to paste this inside the namespace but outside of my program class.
03:00So I will just put it up here. And this basically says to the C# compiler, hey
03:04compiler, there's going to be this thing called a function that has the format
03:08of returning an integer and taking an integer argument, so be on the lookout for it.
03:14So I am going to save that, go back to the snippets.
03:17Now I am going to scroll down here and copy these two functions,
03:21the functions Square and Cube.
03:24So let's copy these guys, and we'll put them in the code outside of the Main function.
03:31Now notice how each one of these functions returns an integer and takes an
03:36integer argument, just like the delegate is declared up here.
03:41So this delegate returns an integer and takes an integer argument. All right!
03:45Now we can write the code that actually uses the delegate.
03:48Here is what we are going to do. To do that, we are going to go back over to
03:52Snippets and we are going to copy this piece of code right here.
03:57Let's put this in our Main function.
04:00Let me explain what's going on here.
04:02Now that I've defined my delegate as a NumberFunction--that's this guy right
04:07here--I can now declare that as a variable.
04:10So on line 15 I am creating a variable named f which is of type NumberFunction,
04:16and remember, that's a delegate.
04:17So I can assign to f the name of a function that matches the same description as the delegate.
04:24In this case, it's the Square function.
04:27So down here is the Square function.
04:29It takes an integer argument, and it just simply returns the square of that number.
04:32It takes that number and multiplies it by itself.
04:36So, on the next line, on line 16, I am doing a Console.WriteLine that says. the
04:41result of the delegate is. and then the result number is going to go in here, and
04:45then I simply call the function f with the number 5.
04:48So f is now pointing at the Square function, because I assigned it to that up here on line 15.
04:52So, I am going to call the function f with 5, and that's going to square the number.
04:58That's going to write out the number 25.
05:01So let's go ahead and run that. But before we run, that let's comment out these
05:04two lines, so we can isolate the results for the moment. All right!
05:07So we will save and we will run, and you can see that the string that's being
05:12written out is the "result of the delegate is 25," just as we expected.
05:16Okay, so far so good.
05:17Now what we're going to do is uncomment these lines. And notice I'm changing
05:21the delegate on the fly.
05:23So now, instead of the f variable pointing at the Square function, it's going to
05:28point at the Cube function.
05:30So, while the program is running, I'm changing what the function that's going to
05:34be called is, by changing the value of the f variable from Square to Cube.
05:39So now this f variable right here on line 19 is going to be pointing at this
05:44function down here to Cube.
05:45And Cube takes the number and multiplies it by itself three times, which is how
05:50you arrive at the cube of a number.
05:53So on line 20, I am going to write out the result of the delegate is, and then the result.
05:58I am going to call the function the same way.
06:00I am going to call the function f with the value of 5, but in this case the
06:04result is going to be very different.
06:06So we should see two things written out.
06:08We should see this line written out here, when f is pointing at the Square
06:12function, and then we should see a different value written out here, when f is
06:17pointing at the Cube function.
06:19So let's build, and we can see the Build succeeded.
06:21Okay, let's run it.
06:24And you can see that the result of the delegate is 25, and then the result of
06:29the delegate is 125, which is what we would expect, because we changed the
06:34delegate to point from Square function to the Cube function.
06:38Delegates are a really powerful and flexible programming construct in C#.
06:43They do the same thing as callback functions, but they do it in a more modular way.
06:48If your code calls for such flexibility, such that you need to be able
06:51to provide callback functions, the way that you accomplish that in C# is by
06:55using delegates.
Collapse this transcript
Handling events
00:00In this example we're going to see how to use C# events, and specifically we're
00:04going to create our own events and our own event handler.
00:08Now the work in this particular movie is based on the delegates movie.
00:12So if you haven't watched that one, you go back and watch it now because events
00:16need delegates to work, and it's important that you understand delegates before
00:20you attempt this movie.
00:21So there are four steps involved in declaring and triggering C# events.
00:27The first is that we have to create a delegate which is the event handler.
00:30And just like we did in the previous section, we do that by using the delegate
00:34keyword and then we declare the delegate named. In this case have got an
00:39EventHandler which returns a void value.
00:42So there's no return value from this function.
00:44And then I declare the parameter list.
00:47In this case, there is an integer parameter and a string parameter.
00:51Now inside the class that's going to implement this event, I need to use the event keyword.
00:55So what I do is I define a my class, and I do that normally with my class
01:00definition. And then somewhere in my class I do something like this.
01:03I say public and then the word event in front of the EventHandler delegate name,
01:10and then I give it a name which is going to be used by the consumer of this
01:14class to hook onto my event.
01:17So somewhere else in the code someone who is using this class is going to write
01:21something like this.
01:22They'll write myClass and then some variable name, in this case object
01:25equals new my class.
01:27So now they've created an instance of this class.
01:30Now what they want to do is listen for, or sometimes the word subscribe is
01:34used, to this event.
01:36To do that, they'll use the myEvent property which I've declared up there in myClass.
01:42They'll use the += operator to specify a handler function that will be used
01:49to handle that event.
01:51This is called subscribing to an event, and it adds the handler function to the
01:55list of functions that the myEvent is going to broadcast to.
01:58Then what all I have to do is declare that function.
02:01Here I've got a handler function, and notice that it matches the same format as
02:05the delegate that I declared in the first line up there.
02:08It say void function, and it takes two parameters, an integer and a string, and
02:13then it implements whatever code there is.
02:15Now this is the function that's going to be called whenever that event happens.
02:20And you can see that there's the += operator. That subscribes to the event.
02:24If you wanted to have your code to stop listening to an event, you would simply
02:28use the -= operator and the same name of the function that you used to subscribe with.
02:34So let's take a look at this in action in real code.
02:37All right, so I've got my UsingEvents example open, and here is the
02:42program code, and over in my snippets I've scrolled down to the using the events section.
02:46So let's just take this one step at a time.
02:48I'm going to first copy over the delegate declaration for myEventHandler.
02:52So I am going to copy that and paste it inside my namespace here, outside my
02:57program class. And this basically tells the C# compiler, hey there's going to be
03:02this thing called a delegate which is an event handler and it takes a string
03:05argument, and I'll supply that later. Don't you worry about it, but it's going
03:08to be coming along.
03:09Okay, now let's go ahead and declare a class, and this as an example class that's
03:15just going to raise an event that other people can listen to. And I'll put that
03:20class declaration up here above my program.
03:22So let's take a look at the class declaration, and then we'll go further.
03:26Here in my class I've got a member variable for this class on line 13, and
03:30it's called theValue.
03:31I've also got an event handler for valueChanged here on line 14.
03:37So whenever this string value here called the value changes I'm going to
03:42raise an event so that people who are using this class can listen for it and
03:46say, oh, the value changed.
03:48Then I've got a property right here starting on line 16. And if you are not
03:53familiar with properties, you can go back and watch the section of this course on properties.
03:58But I am exposing a public string property named val, and you'll notice that I am
04:02only supplying a setter which starts here on line 18.
04:06So the setter does two things.
04:07First, it sets the value of theValue member variable to whatever the value
04:13supplied to the property was.
04:15And then it calls the value change event here on line 21.
04:20So anyone who is subscribed to listening to this event is going to get notified
04:25that the value has changed.
04:27And it passes in the value of this private--the value member right here as
04:33the first argument.
04:35All right, so all that's left to do now is go back over to the Snippets and copy
04:41over the code here that listens for the event, and I will put that in my Main.
04:50So let's go through this line by line.
04:53Here on line 30 I am creating a new instance of my event example class, and
04:59that's this class right here-- the one that implements the event.
05:02And I have got a variable called myEvt.
05:06Then on line 32 I say myEvt.valueChanged, which is the name of the event.
05:11All right scroll back up.
05:13You can see there on line 14, that's the value changed event, +=new
05:19myEventHandler, which is the name of the delegate. And then I need to supply the
05:25name of the function that's going to handle that event. And the reason there is
05:28a red squiggle there right now is because I haven't declared the my Evt_value changed function.
05:34So let's go do that right now. Back over in the snippets I'm going to copy this
05:39function right here.
05:40This is my Evt value changed, and I am going to copy that and paste it, and I am
05:46going to paste it below the Main function.
05:49So now you can see the little red squiggle error has gone away, because now I
05:52have a function which is going to handle the event.
05:55And let's just take a quick look at the event handler.
05:57So here on line 46, you can see that in the function all we do is just write out
06:02the value of that argument that was passed to us.
06:06And if we scroll back up to the class, remember that when we call this event
06:10we are going to pass in the string that is represented by the private, the value
06:15member of my class here.
06:17So now we're pretty much about done; all we need to do is take a look at
06:21what lines 34 through 41 are doing.
06:23What I've got here is a string variable, and then I have a dowhile loop. And what's
06:29going to happen is I'm going to read a line of text from the console, and if that
06:34string is not equal to the value of exit, I'm going to set the public property of
06:40the myEvt object to that string.
06:43Let's scroll back up.
06:45That's going to cause the setter of this property to trigger.
06:48It's going to set the value of the theValue member variable to that string, and
06:54then it's going to trigger the event.
06:56And so this loop is going to just keep right on executing until I type in the word exit.
07:02And when the word exit gets entered, the program will terminate, because there's
07:05no more code after this in the Main function.
07:07All right, so let's actually run this.
07:10Okay, so now the program is waiting for me to put in the string, and I am
07:14going to put in the word Joe. And you can see that when I set the value of that
07:19string, the event handler gets triggered.
07:22My event handler gets called.
07:24The string gets passed in as the argument and we are just writing out that string.
07:28I can type in anotherstring.
07:32And once again, the event handler gets called. I can yet another string, and I can
07:37go on and on like this, but now I am just going to change the value to exit, and
07:43then the program terminates.
07:45So that's how you declare an event handler and an event in C# using
07:50delegates and the event keyword.
Collapse this transcript
11. Garbage Collection
How garbage collection works
00:00Earlier in the course, you may have heard me refer to C# and .NET as a
00:04managed-code environment.
00:05What that basically means is that the .NET Framework provides automatic
00:09memory management for you.
00:10You as the programmer are not responsible for freeing up the memory that your
00:15program's objects use during the course of the running of your program.
00:20Now, this is not like other languages.
00:22In languages like C and C++ and Objective-C, you as the programmer, when you
00:28create objects that take up memory, you are responsible for making sure that
00:31that memory gets returned to the system at some point.
00:35But languages like .NET and other language like JavaScript in Java and so on,
00:39those are managed-code environments.
00:41There are ways that the system figures out that memory is no longer being used
00:45by your program and reclaims it automatically.
00:48Now, to take a simple example, when you do something like this in your C#
00:52program, you have some object type definition, maybe you've made a new class,
00:56and you use the new operator to create a new instance of that object,
01:00that allocates memory somewhere in the system. That tells .NET, hey, you've got
01:05to go find some memory to hold my object.
01:08And the Framework will take care of figuring out when this object is no longer being used.
01:12You don't have to do anything special. .NET will just figure out that you're
01:16done using this object, and it will put the memory back in the system for you.
01:20So let's take a look at conceptually how this works.
01:23There is a big pool of memory available to the system, and we can think of it as
01:27this big purple box you see right here.
01:30Now, your program is going to use this memory during the course of its
01:34operation. And as your program runs, it's going to allocate blocks of memory and
01:39when it does that those blocks of memory are going to be taken out of the system
01:43memory pool and assigned to your program. And then in your program will do
01:46whatever it does with that memory and all these objects.
01:49At some point there is a special class in the .NET Framework called the
01:53Garbage Collector, and garbage collection is the process by which .NET figures
01:58out that memory is no longer being used by your program and can take it back into the system.
02:04So the Garbage Collector has a way of keeping track of the objects that you have
02:07allocated, and when it figures out that these objects are no longer being used,
02:11it simply puts them back in the system memory pool.
02:14This process is completely invisible to your program.
02:17You don't have to worry about doing this at all.
02:18It all just happens for you.
02:20So let's take a look at how garbage collection works.
02:23Suppose we have a function, looks like this.
02:26It's called myFunction. And inside myFunction I've got this new MyObject.
02:32Well, out in the system memory pool when I do that, a block of memory is going
02:35to be allocated that holds MyObject.
02:37That creates what's called a reference.
02:40That myObj variable that you created inside your function is now going to hold a
02:44reference to that memory location.
02:47Now, you can go and do a bunch of things:
02:49you can call a method, you can set a property, you can call SomeOtherMethod.
02:54But when that function ends, that myObj variable is going to go out of scope.
02:59And at that point there are no more references to MyObject. Because that
03:03variable is gone now, that little reference line disappears. And the Garbage
03:07Collector comes along and says, hey, no one is using that thing anymore.
03:10I can just return that object back to the memory pool.
03:14So what are some important things to know about garbage collection?
03:17First, your program does not need to initiate this process; the Garbage
03:21Collector figures out when it needs to run and reclaim memory.
03:25Now, there is a way for your program to initiate garbage collection, and we'll
03:28actually take a look at that in an example in just a bit.
03:31The Garbage Collector balances between performance and app memory usage, and the
03:38objects are not necessarily reclaimed right away.
03:41So these two things mean that you, A, don't know when Garbage Collection
03:47is going to happen.
03:48The Garbage Collector tries to figure out how your program is doing its work and
03:52how much memory is being used, and it tries to strike a balance between making
03:57sure that your application doesn't take a performance hit while figuring out how
04:02much memory is being used and trying to say, okay, well, memory use is getting
04:05kind high, maybe I should go take some of that memory back.
04:08The other thing you need to realize that when you're finished with an object,
04:11it might stick around for a while until the Garbage Collector figures out that it needs to run.
04:15Now, objects can detect that they are about to be released from memory, so
04:20when you create an object in a class, you can actually write a method called the finalizer.
04:25Now, this is rather advanced.
04:27I'm not going to cover it in this course. But you can just be aware that there
04:31are ways for your objects to figure out that they're about to be released back
04:35into the system memory pool.
Collapse this transcript
The Garbage Collector object
00:00Let's take a look at a real example to see how garbage collection actually works.
00:04So I've got my Garbagecollection project open up here, and in my Snippets file I
00:09have scrolled down to the Garbage Collection section.
00:11So let's go ahead and take a look at some of the garbage-collection routines
00:16that are available to us.
00:18So first I'm going to copy these three lines and paste them into my application.
00:24Now there is a global object in .NET called GC.
00:29You can see I'm using that right here on line 12.
00:32The GC object is the Garbage Collector, and I'm going to call a function on the
00:38GC object which is a static function here called GetTotalMemory. And it takes a
00:43parameter--I'm not going too deeply into this. Don't worry about what this does.
00:46Basically I'm saying to Garbage Collector, hey, tell me how much total memory is
00:50currently allocated to my application.
00:52So this is a pretty simple place to start.
00:54Let's just build this and run it and see what happens.
00:56So I'm going to run it, and the console is going to write out how much allocated
01:00memory there is to my app. And you can see that when I run this the amount of
01:05memory that's allocated to my application right now is 186,836 bytes.
01:10Now don't worry if this number looks different for you and your example. This is
01:14going to different for everyone's system.
01:16This is basically how much memory is currently allocated to my app.
01:20So let me hit Return, and we'll exit the app.
01:23Okay, let's go back to the snippets and paste in some more information.
01:26So the next few lines I am going to copy right here, and I'm going to paste
01:29those below these lines.
01:32So starting on line 16, I'm going to allocate 100,000 bytes in an array that holds bytes.
01:40So this is 100K of memory that I'm going to allocate, and then I'm going to
01:44basically do the same thing here on lines 18 through 20 that I do at the
01:49beginning of program. And we'll see if this makes a difference in how much memory
01:52that Garbage Collector thinks is allocated to my programs.
01:55So let's run, and you'll see that we start off with 186,000 bytes.
01:59Now let me hit Return, and this is going to cause the allocation to happen.
02:03And now you can see that the amount of memory allocated to my app is 295,060 bytes.
02:09Now notice it's not exactly 100,000 bytes more than the original size. Again,
02:15don't worry too much about that, and don't worry too much if this number looks
02:19different for you on your system.
02:21The .NET Framework keeps track of a whole bunch of overhead internally, so when
02:26I allocated those 100,000 bytes, a lot of other things happened under the hood.
02:31So it looks like more memory got allocated then I asked for, but that's just the
02:35.NET Framework doing its work.
02:36So let's go back to the application.
02:40Now what we're going to do is actually trigger the garbage-collection process,
02:44so I am going to copy these lines here, and I'm going to paste them in here.
02:49And you'll notice that on line 22 I'm calling the Garbage Collector's collect method.
02:54This will actually trigger the garbage-collection process.
02:58So we're going to start off by seeing how much memory my application gets when
03:02it starts. Then we're going to allocate a whole bunch of memory and see how much
03:06that changes things.
03:07Then we're going to call the Garbage Collector's collect function which will
03:11cause the Garbage Collector to go out and look at memory and say, hey, how much
03:14memory isn't being used and how much can I reclaim? And that's going to be this
03:19line right out here. We're going to write out what the results of that are, so
03:22let's save this and run it.
03:25Okay so we start with 186k. It goes up to 295k. Now let's watch what happens
03:32when the Garbage Collector runs and we call that collect function.
03:34Okay, it looks like the allocated memory dropped back down to about 210,000,
03:40almost 211,000 bytes.
03:42Again, I didn't get all hundred thousand bytes back, and that's because, as I said,
03:48earlier the .NET Framework has some overhead that it's working on. So it did
03:52figure out, however, that those bytes actually aren't being used by anybody.
03:56So I was able to reclaim those bytes by running the garbage-collection process.
04:01Now again, I want to emphasize that this is just an academic exercise here and
04:05shows you how the Garbage Collector works.
04:07There are going to be very few instances in your C# career when you're going to
04:11have to actually care about running the Garbage Collector, if ever.
04:15I've been working with C# for a long time.
04:17I've never actually had to do this. But it interesting to see how the Garbage
04:20Collector works and what you can do with the Garbage Collector to figure out how
04:24much memory your application is consuming.
Collapse this transcript
12. Debugging
Common compilation issues
00:00In the long, and no doubt illustrious, C# coding career that lies before you, you
00:06are going to have to deal with compiler issues and bugs, and that's what we're
00:10going to talk about in this section, debugging, and we're going to start off with
00:14dealing with common compilation issues.
00:17Now, many of these are fairly common, and they tend to trip up new C# developers.
00:22Don't feel bad if this happens to you.
00:24I personally assure you that I myself have committed every single one of the
00:28issues I am about to show you.
00:30So I've got my CompileIssues sample project opened, and what I am going to do is
00:33walk through each one of these issues and show you why each one is a problem.
00:38So I am going to start with issue number one.
00:40Let me uncomment this line of code, and we'll save. And we've got a problem.
00:45In fact, let me hit the F6 button to try to build, so we can see what the
00:48problem exactly is, and I will scroll that code into view.
00:52We can see here down in the error list it, says, ah!
00:54There is a semicolon expected.
00:57Well, a semicolon is expected at the end of every line of C# code.
01:02If you're coming from a language like JavaScript where semicolons are optional,
01:06you need to realize that in C#, that's not the case.
01:08You do have to have a semicolon that terminates every single one of your statements.
01:13Double-click on the error, and it takes us right to that point in the code.
01:17We can put in our semicolon, and save, and then we can build, and now everything
01:21is all right again.
01:22Now we're getting a bit of a warning here that says that the myString variable
01:26is assigned, but it's never used, but let's just ignore that for the moment.
01:30Go down to issue number two.
01:32So issue number two, I am going to uncomment this line of code, and once again we
01:35get a whole bunch of errors.
01:38Sometimes it's tempting to try to look for the error that's the simplest to fix
01:42and try to fix it that way.
01:43In fact, if you look in the error list, you'll see that there's a bunch of errors.
01:46One of them says "; expected," One of them says ") expected."
01:50So you might be tempted to just jump to that line and try to like put a
01:53semicolon in to fix things;
01:55that's actually the wrong thing to do here.
01:57What I suggest you do is start with the topmost error, because sometimes when
02:01you fix the topmost error, that will fix all the errors below it. And if you
02:06look really closely at this line, you'll notice that the problem is that I
02:10didn't close off the string using double quotes. And sure enough, once I do that,
02:16all the other errors go away.
02:18Before you try to figure out which is the easiest problem to solve, try to
02:22figure out what the actual error is, because now you can see that the compiler
02:25is saying, oh yeah, there is a semicolon, and oh yeah, there's the parentheses.
02:29It just couldn't see them before, because it thought they were part of the
02:32string, Hello World.
02:35In the next issue, I'm going to use an ArrayList.
02:37If you watched the section on collections, you know what ArrayLists are.
02:41They are a type of collection that works like an array.
02:44I am going to uncomment this line, and sure enough, we've got problems.
02:48If we look in the error list, it says, "The type or namespace name
02:53ArrayList could not be found (are you missing a using directive or an
02:57assembly reference?)."
02:58That's just a very long-winded way of the C# compiler saying, I don't know what that is.
03:03And there's also a visual cue.
03:05You'll notice that objects that are recognized by the C# compiler are
03:09highlighted in a certain color, like the console object right here.
03:13Now ordinarily, ArrayList would be highlighted as well, and it's not, and that's
03:17your first clue that something is wrong, along with this giant red squiggle
03:20underneath it that gives you the error.
03:23It turns out that the problem is I have not included the right namespace in
03:27order to use ArrayLists.
03:29So I have to scroll to the top of the file, and sure enough, I'm using the
03:34System.Collections.Generic namespace, but ArrayLists are contained in the
03:39System.Collections namespace.
03:42So I have to say using System.Collections. And when I put that using statement
03:49in, you can see that the problem goes away.
03:53Let's scroll back down to where that code is, and you'll see now that the
03:57ArrayList object is highlighted in light blue the same way that the console is,
04:02which means that the C# compiler is recognizing it. All right!
04:06Let's move on down to the next issue.
04:08I am going to uncomment these lines of code right here.
04:12I am going to save, and you see that we're getting a complaint that a
04:22curly brace is expected.
04:24The curly brace is actually expected way down at the end of the program. Well,
04:28clearly something is pretty wrong here.
04:31And if we scroll back up to where the error actually is, you'll notice that
04:36I've got my open curly brace here and a closing curly brace here, and those seem to match up.
04:42You can see that when I put the cursor next to the curly brace, the IDE
04:46highlights the two braces to show me they match.
04:48But the problem is that I have actually got an extra one all the way over
04:51here on the end of the for statement, and that's causing the compiler to
04:56think that all the rest of the code following that line is contained in an
05:01unclosed curly brace block.
05:03Once I get rid of that extra curly brace and I save and I hit F6, you can see
05:09that that error goes away.
05:11So the lesson here is, indentation does not necessarily mean what blocks are.
05:17You have to put braces so they match each other.
05:20Just because you put one brace up here and another brace in another line down
05:23there, does not mean that those make a block.
05:26You have to make sure that you have the same number of closing braces as you
05:30have opening braces; otherwise, you're going to get weird errors like that.
05:35Let's move on to issue number five.
05:37I am going to uncomment this string right here, I am going to save, and I am
05:41going to get a nice big red squiggle.
05:43It says down here in the error list:
05:45"Too many characters in character literal" and "Cannot implicitly convert
05:50type 'char' to 'string'."
05:53What's going on here?
05:54I've got my quotes.
05:55I've got the string defined. The problem here is that you can't use single
06:00quotes to define a string in C#;
06:03you must use double quotes.
06:05The single quotes are for individual characters. And so you see that when I put
06:12the single quotes into double quotes, the error goes away.
06:16Now, I am getting another warning that says that that string is not used, but
06:18don't worry about that for now.
06:20Scroll down to the next issue.
06:21I'm going to uncomment these two lines.
06:29So I have an integer array of values and it's called myarray = 0, 1, 2, 3, 4,
06:36so we've got 5 items in the array, and then I am trying to set the array item at
06:41index 2 to be 10, and I am getting an error.
06:44It says "'myarray' is a 'variable', but it is used like a 'method'" and the
06:49problem here is that you don't use parentheses to index into arrays; you
06:54use square brackets.
06:58Parentheses are used for calling function; brackets are used to index into arrays.
07:05You can see that once I change the brackets, everything is fine. All right!
07:08Let's go on to the next issue.
07:10I am going to uncomment this call to Console.WriteLine, and then I get an error.
07:15It says, "'System.Console' does not contain definition for 'Writeline'."
07:19What are you talking about? Sure it does.
07:20I've been using Writeline throughout this course.
07:23There's a function there called Writeline.
07:24I know that there is. In fact, I used it probably up here earlier. See, there it is!
07:28And then I realized, oh, wait a minute!
07:29No, there is a capitalization problem in there.
07:33That actually has to be a capital L. That's because C# is a case-sensitive
07:39language; case matters.
07:41This is something you'll run into probably at least once when you're
07:44writing your C# code.
07:45You need to make sure that the cases match. That's true of variables.
07:49It's true of function names.
07:50It's true of almost any type of declaration that you make in C#.
07:55Let's move on to issue number 8.
07:58In issue number 8 I have got three lines of code.
08:01I've got an integer variable that's set to 2,500,
08:04I've got a floating-point variable that's set to 35.895, and then I'm trying
08:12to set the value of f into the value of i. Now, I've got two different
08:18problems going on here.
08:19First, "A local variable named 'i' cannot be declared in this scope, because it
08:23would give a different meaning to 'i', which is already used in a 'child' scope
08:26to denote something else."
08:28That's a very, very long-winded way of saying, you know what, I've already used
08:32i somewhere else in this code block.
08:34So if I scroll back up, there it is.
08:37I've already used the i variable in this for loop.
08:41So it's not going to let me use it again down here.
08:44No problem. I will just simply call this i1, and I will call that one i1.
08:51I've got another problem. The problem here is-- let's look at the error list--"Cannot
08:55implicitly convert type 'float' to 'int'.
08:58An explicit conversion exists (are you missing a cast?)." Yes, I am.
09:04Remember, you can't implicitly cast a variable that is of a larger size into a smaller size.
09:11You have to explicitly tell the compiler that you're doing that.
09:14So what I need to do to convert a float into an int, I have to put the word int
09:19in parentheses. And what this tells the compiler is, hey compiler!
09:23Treat that floating-point number as if it were an integer, which will let me
09:27assign it to another variable that is of that same type--in this case integer.
09:32And you can see when I put that cast in front of the F, everything goes away, and we're fine.
09:37Next issue, issue number 9, I am going to uncomment these lines.
09:41I've got two integer variables: one named a, one named b. And then I've got an
09:45if statement, if (a = b) then we're going to write out, yup!
09:49They're equal numbers, and no sooner do I do that, then oops!
09:52I get an error, and it says, "Cannot implicitly convert type 'int' to 'bool'."
09:57What's the problem here?
09:58I am not trying to convert anything to anything.
10:01Well, remember that inside if statements what you're checking for is a Boolean condition.
10:06That's how the if statement knows to execute. And the problem here is that I'm
10:10not using double equals signs.
10:12I'm using the assignment operator, not the equality check operator.
10:16So once I change this to the equality check operator, the error goes away,
10:20and everything is fine.
10:22One more issue that I want to show you, and you'll run into this, and sometimes
10:27it can be pretty confusing as to what's going on.
10:29I am going to uncomment this entire function.
10:31I've got a function here called func, and it takes an integer variable and if
10:38that integer parameter is greater than 0, then it returns 0.
10:43If that parameter is less than 0, it returns -1.
10:46But I'm getting an error.
10:48It says, "CompileIssues.Program.func: not all code paths return a value."
10:55The problem here is that I've declared this function to return an integer value,
11:00and I am returning an integer value here and returning an integer value here.
11:05But what happens if the parameter a is equal to 0?
11:08Well, there's no path in here that returns a number.
11:12I have to make sure that if my function is going to return a value, then all of
11:16the possible code paths that it can take have a return statement in there.
11:20There's a couple of ways I can fix this.
11:22I could put in an if case for a is double equal to 0, but since that's
11:27the only case left, and the function would have returned by now if any other
11:31case have been encountered, I can just simply say return whatever else.
11:35I can say return 100, or I can return 1,000, or I can return whatever I want as
11:40long as it is a valid return type.
11:44Those are 10 of the most common compilation issues that you'll probably run
11:48across in your C# coding.
11:50Next, we're going to take a look at how to use the debugger to look at
11:53code while it's running.
Collapse this transcript
Setting breakpoints and examining code
00:00As useful as it is to be using the console and the Console.WriteLine methods to
00:06see what's going on inside our application while it's running,
00:09there's really no good substitute for using a good debugger which you can use to
00:14examine the code while it's actually running. And the debugger allows you to do
00:18things like place breakpoints in your code, examine the code, examine variables,
00:23change things while it's running, and so on.
00:26If you've done any kind of programming in other environments, like, say,
00:29JavaScript using either Firebug or the WebKit Developer tools or coding
00:34environments like C++ or Java, you might be familiar with using a debugger.
00:39If not, don't worry about it.
00:40I am going to show you how to use the debugger that's contained here in the free
00:44version of Visual C# Express.
00:47I am just going to use the existing example that we've already got from the
00:51section that we did on reading and writing file data, so I've got that example
00:57back open in my editor here.
01:00Take a quick look. Under the Debug menu,
01:03you'll see that there are a couple of options related to debugging.
01:07There's the Start Debugging option, which is this option right here on F5,
01:10and that's actually how I've been running our examples each time we've tried them out.
01:14I just hit F5 and that starts the debugging process.
01:18You can also start an application without debugging by doing the Ctrl+F5. But if
01:22you want to actually have debugging information, you'd use the F5 version.
01:25There are also things like Step Into and Step Over, and things like Toggle
01:30Breakpoint, and we are going to see how each one of these works.
01:33So let me close this menu. And the first thing I am going to do is show you how
01:38to place a breakpoint.
01:40Here we have our Main function, and the Main function is going to be the entry
01:45point into our application from the .NET Framework.
01:48The .NET Framework is going to find this function and then call it to start our program up.
01:51So the first thing I am going to do is find the first place where I can put a
01:56breakpoint. And it looks like this line right here, line 14 is where our program
02:00actually does something.
02:02So way over here in the left-hand side of the gutter, next to the line numbers, I
02:06am going to click, and you see that when I click, a couple of things happen.
02:10First, this little red circle shows up.
02:13That little red circle indicates that it is a breakpoint, and you'll notice that
02:17when I place that breakpoint, all the executable code that gets associated with
02:22that line--in this case, it's line 14 and 15, because I have one statement
02:27that's spanning multiple lines--gets outlined in red. And it indicates to me
02:32that that is a breakpoint.
02:34A breakpoint is a point in the program where when you're running the
02:37application, the debugger will stop execution right before it's about to
02:42execute that statement.
02:44So let's go ahead and start debugging the program.
02:47Open the Debug menu. I am going to choose Start Debugging, or you can just press F5.
02:54Now when I do that, you saw the Console window kind of momentarily come up there
02:58and then disappear behind the IDE. And now you can see this little yellow arrow
03:03inside that little breakpoint there, and it shows me where the current statement is.
03:08The breakpoint that was red is now outlined in yellow, and you can see that
03:13we've got a couple of other windows that have shown up.
03:15Down here in the bottom, on the left- hand side, we have the Locals window.
03:21We also have something called the Watch window.
03:24The Locals window shows me all of the local variables that are currently
03:29within the current scope.
03:31So inside the Main function, I can see all the local variables that I can
03:35currently have access to.
03:37Over here in the Call Stack, this shows me all of the functions that have been
03:41called leading up to this point.
03:43Now right now we are in the main function.
03:46I have only got two items on the Call Stack.
03:48I have got External Code which is the .NET Framework's execution engine, and
03:52then I've got the ReadingWritingData. exe!ReadingWritingData.Program.Main, so
03:58that's the function that I'm in.
04:00so ReadingWritingData.exe! that's my program.
04:03ReadingWritingData is my namespace. Program is the class.
04:06That's this program right up here.
04:08Main is the function, and it says I am on line 14. And sure enough, if I look
04:13over at the little arrow, yes, I am on line 14.
04:17The other thing that happens is that this little Debug toolbar showed up in my
04:21toolbars up here. And I have got buttons for Continuing, so if I hit F5 right
04:25now, the program will just continue to run until it reaches the next breakpoint.
04:29Or I can stop debugging which will stop the application, or I can restart.
04:34I can have the program go back to the beginning.
04:36I can click on this little yellow arrow here to show me what the next statement
04:39is going to be, and that's where the yellow arrow right over here is.
04:42I've also got these three icons for Step Into, Step Over, and Step Out, and we'll
04:49take a look at what each one of these is.
04:51To step over this code, I can simply choose the Step Over function.
04:56That will cause the current statement, the one that's highlighted right here, to
04:59execute. And if you look down here in the Locals window, you will notice the
05:03filePath variable right now is null.
05:07There is no value assigned to it.
05:09Watch what happens when we step over that line.
05:13First, the little yellow arrow goes to line 18, because that's where the next
05:18line of executable code is.
05:20The second thing that happens is, if you look down in the Locals window, the
05:24filePath variable now has this string in it, and it has a path to the example
05:30file.txt. And you notice also it's red, and the reason it's red is because the C#
05:36debugger is highlighting the local variable that changed.
05:41After I step again, it's going to stop being red, because it's not going to
05:45change after that point.
05:46I can scroll down a little bit here.
05:49Now if I wanted to, I actually could just simply change the value that's in
05:53this local variable.
05:54I can just double-click on it and say, you know what?
05:56I don't want it to be called examplefile.txt; I want it to be
05:59called joesfile.txt.
06:05I just changed the contents of that variable while the application is still running.
06:10So now this line of code right here is going to check to see if the file exists,
06:14and it does not. So when I step over that statement, we'll see that the brace
06:20gets highlighted, and I step again, and now we step into the if statement.
06:25So now we are going to create that file and set its contents.
06:30And once again, I can step over this, and you can see now that this content
06:34variable has changed.
06:36So I can also do things like hover over using the mouse.
06:40I can hover over things that are in the code.
06:42For example, if I hover over the Environment.NewLine statement right here, you
06:46will see I get this little pop-up window that says what the new line's value is.
06:50And you can see that it's \r\n. Or I can hover over this local variable, and it
06:55shows me what the contents of that local variable is.
06:58I can also hover over things that are built into the .NET Framework.
07:01I can hover over the file class, for example.
07:03When I hover over the file class it shows me that it's of type System.I/O.File,
07:09and I can click on this little expander here, and it shows me all the things
07:13that are inside that file class.
07:16Now, it's a built-in class, so it's not going to show me very much, because
07:19it's in native code.
07:20But I can now just use my debugger to step through this code, and I can watch
07:25the application as it runs.
07:27You will see that variables are changing.
07:30I can change the value of variables and so on.
07:33If I've gotten tired of just stepping through this, I can just go ahead and hit
07:37the little green arrow, which will cause the application to run, and we can see
07:42that the application is now running.
07:43And if I go ahead and hit the Return button, the application will stop, the
07:48debugger stops, and I am dumped back into my text editor.
07:51Let's make a slight modification to this application.
07:54What I'm going to do is make a function, and I am going to make a function down
07:59here called static void ReadAndListContents(). And it's going to read and list
08:13all the contents of the file. So basically, I am going to copy these lines of
08:17code right here, take them out of the Main function, and put them into a
08:22function And I am doing this because I want to show you how the Step Into
08:26functionality works.
08:27I'll just get rid of that comment right there.
08:30I need to pass in the filePath, and I also need to call that function,
08:37so we'll call ReadAndListContents with the filePath. And just to isolate this,
08:47we'll take out this code right here, so that we only have one piece of code,
08:52that's ReadingAndListingTheFileContents.
08:55What I am going to do is run the application again, and it's going to stop at
09:00this breakpoint right away.
09:02This time I am going to start at using this little green arrow right here.
09:06You can see that the breakpoint got hit.
09:08What I am going to do now is scroll down and I am going to place a breakpoint
09:12on this function call.
09:13So I just click there to place another breakpoint, and now I'm going to hit the
09:18little green arrow again, which is going to continue on to the next breakpoint.
09:22The application ran until it got to this breakpoint.
09:25Now I can use the Step Into function, and that's this icon right here.
09:31If I wanted to just simply execute this function without stepping into it, I
09:34could use the Step Over.
09:35That doesn't mean skip over the function;
09:38it means execute it but don't go inside. Just do whatever the work it does, and
09:43then go on to the statement at the level where I currently am.
09:46So if I stepped right now, the next statement would be this Console.ReadLine.
09:49But if I do a Step In, I will actually step into that function.
09:55And now I can do Step Over and Step Over again, and you can see now that the
10:00current line, as indicated with this little yellow arrow right here, is inside the
10:04ReadAndListContents.
10:06I could just simply keep on stepping and stepping and stepping and
10:09going through these foreach statements and so on, or I could use the Step Out function.
10:15If I click on Step Out, the execution is going to continue to the end of this
10:19function and it's going to put me back into where the calling context was.
10:23If I click Step Out, now I'm back out here where ReadAndListContents was called,
10:30but now the function has finished executing and if I step again, I'll go on to
10:34the next statement, which is the Console.ReadLine.
10:38That's a pretty quick introduction to using the debugger.
10:41The nice thing about the debugger is that it allows you to slow down the
10:44program's execution so that you can see things as they are happening.
10:47And as you saw, we were able to place breakpoints and examine variables.
10:51We were able to change the contents of variables.
10:54We were able to step into and out of functions.
10:56The debugger really will become your best friend as you're writing your code
11:00because it makes debugging of your applications so much easier.
Collapse this transcript
Using the Debug class
00:00Throughout this course I've been using the console window to write out
00:03debugging and other diagnostic information so that we can see what's going on
00:08inside the application.
00:09For examples like this, that's all well and good, but when you write your real
00:12applications, if you're writing a console application, you probably don't want
00:15to have it littered with debugging information that your users are going to see.
00:19Or if you're writing an application that doesn't use the console window at all,
00:22you're going to need to have some other way to get that output visible to you
00:26while you're debugging your app.
00:28The way that we are going to do this in this particular example is by using
00:31the System.Diagnostics namespace, which gives us access to something called the debug class.
00:38The debug class gives us a way for logging debugging information in a way that
00:42we can see it which doesn't interfere with the actual output of the program.
00:48To use the debug class, I am going to do a couple of things.
00:51See, on line 16 the System. Diagnostics namespace. This gives me access to
00:57something called the debug class, which gives us a bunch of features that are
01:00similar to what we've been using the console window for--
01:03WriteLine statement and a few other things that we'll take a closer look at.
01:07The debug class is going to log all this information to a place called the
01:11output window, and the output window is going to show up here in the IDE
01:15when we make it visible.
01:17To use the output window, there is a couple of things you are going to have to do.
01:20First, under the Tools menu, go down to the Settings submenu and make sure that
01:25the Expert Settings option is checked.
01:27Once you've done that, under the View menu, there will be an option for Output,
01:32and when you choose Output this little output window will show up here in your IDE.
01:37Don't worry about the Show output from option just yet. Tight now it's empty,
01:40but that will be filled in for us.
01:43If you are a sharp-eyed reader, you'll notice that I'm using pretty much the
01:46same code that we used in the Reading and Writing Data Files example, although
01:51I've re-organized it a little bit to use functions and so on.
01:55What we are going to do now is first build the application, so hit F6.
02:01And you'll see that down in the output window, a whole bunch of information was
02:05logged for us by the IDE.
02:07It says that the build was started, and then there is a line that says,
02:09hey, Build 1 succeeded.
02:11So everything looks pretty good.
02:13Our code can also use this same output window to log debugging information, and
02:18the way that we are going to do that is by using the debug class.
02:21Go ahead and scroll down and see how the debug class works.
02:25This code probably looks familiar to you if you watched the earlier example on using files.
02:30I'm not going to focus too much on that.
02:32What I am going to focus on instead is the information that I've put into the
02:35file to help with debugging.
02:37Here's a debug class call. And you will notice that the debug object has a
02:42function called WriteLine, which works pretty much the same way that the
02:47console's WriteLine object works as well.
02:50Only instead of sending output to the Console window, this is going to write
02:54information out into this output window down here.
02:58Here I am write-lining out some piece of information that the file was created,
03:02and so on and so forth, and we do the same thing down here.
03:06A couple of other features, though.
03:07There is a assert function call, and assert basically makes sure that the
03:13Boolean condition supplied in here is true.
03:17If it ever evaluates to false, the debugger is going to pop up and say, hey,
03:21something went horribly wrong in your program.
03:23You might want to take a look at it. And we'll see an example of that in a little bit.
03:26We also have this here, Debug Indent and Debug Unindent, and that will help us
03:32make our debug log output more visible in the output window below, which we'll
03:37see in just a moment.
03:39Let's go ahead and run this program, and we'll see what happens.
03:43Let's just take a quick refresher of the code.
03:46You can see that when the code starts
03:47we have a string variable that holds a filePath, and we are going to create a data file.
03:52We are going to write some information out to it,
03:54and then I am going to read the contents back in. And all that's going to be
03:58happening in these functions down here.
04:00We have a function for creating the file, we have a function for writing the
04:03file content out, and then we have a function for reading the content back in.
04:09So the last thing I want to point out before we run this is that unlike the
04:12console window, the debug object has a special version of WriteLine.
04:17It's called WriteLineIf.
04:19What you do here is you supply a Boolean expression. If this expression
04:24evaluates to true, then the WriteLine happens; otherwise the WriteLine doesn't happen.
04:29In this particular case, we are saying Debug.WriteLineIf the contents array
04:34length is greater than 2.
04:37Well, if that length of that array is more than 2, then this particular
04:41WriteLine will happen; otherwise it won't. So let's go ahead and run this example.
04:49We ran the file, and we added a whole bunch of content to the file, so let's
04:53go ahead and hit Return to exit, and let's go examine the output in the output window.
05:00The first thing you will notice is there is a whole bunch of output messages
05:03that were put here by the .NET Framework.
05:06You don't really need to pay attention to any of these.
05:08These are messages that the debug version of .NET Framework is sending out for
05:13you to look at as a programmer, but for now, we are just going to ignore that.
05:16What we are going to do is look for our first examples of debug output, and
05:20they are right here.
05:21For example, we have Writing File Data, File Data Written,
05:26The file has more than two lines.
05:28Well, where did those come from?
05:29Well, if we scroll down in our content, we can see right here, this did not
05:35execute, because the file already exists, but if the file hadn't existed,
05:39we would have called the WriteLine function for creating the file with content whatever.
05:43However, when we write the file data out, you'll notice that the WritingFile
05:48Data string got written out, and because it's indented, right here you can see
05:53that there is a little bit of a tab space in here, which makes the debug
05:56information a little bit easier to read.
05:59Down here we do the same thing. After the file's data has been written, we have
06:03a debug output statement that says the file data has been written, and that's
06:07also indented. And because the contents of that file had more than two lines,
06:13you can see that this WriteLineIf statement executed.
06:17Let's do one more example.
06:20Let's see if we can get this assert to trigger right here.
06:26What we are going to do is pass in an empty string content to write to the file.
06:32I've decided that here in my application that anyone who calls this function has
06:37to provide string content that's not empty.
06:41If I pass in an empty string, I want my program to raise a warning message and
06:46say that someone has tried to do something that I don't approve of. And the
06:50great thing about these debug messages is that when you build the release
06:54version of your code, none of this stuff gets included;
06:57only the debug version of your application will contain these debug calls.
07:04So let's go back up into the code here.
07:05I'm going to uncomment this call to WriteFileData, and I am going to pass in an
07:13empty string. And that's going to cause that assert to pop up.
07:18Let's see what happens when I try this.
07:20I am going to run this.
07:22When I ran this, the Assertion Failed dialog message comes up.
07:27So here the title says Assertion Failed, and then I have some options. Do I want
07:30to abort or retry or ignore?
07:33Now this is a non-fatal assert, so I can just go ahead and ignore it if I want to.
07:38But for now what I am going to do is click Abort, which will cause the
07:42application to stop.
07:43I can see where that assert was. It's down in here.
07:47You notice that there wasn't a whole lot of helpful information that came up in
07:51that Assert box, just a big stack of messages that says, hey, here's the
07:55function where things went wrong.
07:57So I can include a message in this assert.
08:01I can say, "Tried to call WriteFileData with an empty string."
08:10This version of the Assert function will not only pop up the dialog;
08:15it will give me a nice easy-to-understand message, so I can see what's going wrong.
08:19Let's try that one more time. And you can see that this time, next to that
08:24little red error message that says, Tried to call WriteFileData with an empty string,
08:28that's the message that I put into my Assert box, and it shows me all the
08:32functions that got me to the current place.
08:35So right here at the top it says, at Program.WriteFileData.
08:38That's where the assertion happened. And you can see that we got there by
08:42calling through Main, and then we came in via the .NET Framework.
08:46These are all the .NET Framework functions right here. Bt it shows me how we
08:49got to where the assert is.
08:51So I am going to click Abort. And then at this point I would go back and I would
08:56try to figure out, okay, who is calling WriteFileData, who is doing it with an
09:00empty string, and so on?
09:02This is how you can use the debug class to add some extra debugging information
09:08right into the IDE while you are debugging your application.
Collapse this transcript
Conclusion
Goodbye
00:00Well, that brings us to the end of C# Essential Training, and I want to thank
00:04you for joining me as we explored the basic concepts of the C# language.
00:08You are probably wondering where you should go next, and I have a few
00:11recommendations for you.
00:12Spend some time exploring the online documentation for the C# language and .NET
00:17Framework on the Microsoft Development Network web site at msdn.microsoft.com.
00:23This is a very good reference resource for learning more about many of
00:26the objects, classes, and language features that we were introduced to in this course.
00:31Since C# is the foundational language for other Microsoft frameworks, such as
00:36Silverlight, Windows Phone, and ASP.NET,
00:39take a look at some of the other programming resources in the lynda.com Online
00:44Training Library, such as Objective-C or JavaScript Essential Training.
00:48Seeing how other languages approach similar problems and situations can
00:53significantly increase your understanding of how each language has its own
00:56benefits and drawbacks, and will broaden your understanding of the discipline of programming.
01:01Finally, go back to some of the examples in this course and try some experiments.
01:05The more practice you have with the language, the better a C# programmer you will be.
01:09Good luck with your C# coding!
Collapse this transcript


Suggested courses to watch next:

ASP.NET Essential Training (6h 24m)
David Gassner


Silverlight 3 Essential Training (6h 50m)
Walt Ritscher


Are you sure you want to delete this bookmark?

cancel

Bookmark this Tutorial

Name

Description

{0} characters left

Tags

Separate tags with a space. Use quotes around multi-word tags. Suggested Tags:
loading
cancel

bookmark this course

{0} characters left Separate tags with a space. Use quotes around multi-word tags. Suggested Tags:
loading

Error:

go to playlists »

Create new playlist

name:
description:
save cancel

You must be a lynda.com member to watch this video.

Every course in the lynda.com library contains free videos that let you assess the quality of our tutorials before you subscribe—just click on the blue links to watch them. Become a member to access all 104,069 instructional videos.

get started learn more

If you are already an active lynda.com member, please log in to access the lynda.com library.

Get access to all lynda.com videos

You are currently signed into your admin account, which doesn't let you view lynda.com videos. For full access to the lynda.com library, log in through iplogin.lynda.com, or sign in through your organization's portal. You may also request a user account by calling 1 1 (888) 335-9632 or emailing us at cs@lynda.com.

Get access to all lynda.com videos

You are currently signed into your admin account, which doesn't let you view lynda.com videos. For full access to the lynda.com library, log in through iplogin.lynda.com, or sign in through your organization's portal. You may also request a user account by calling 1 1 (888) 335-9632 or emailing us at cs@lynda.com.

Access to lynda.com videos

Your organization has a limited access membership to the lynda.com library that allows access to only a specific, limited selection of courses.

You don't have access to this video.

You're logged in as an account administrator, but your membership is not active.

Contact a Training Solutions Advisor at 1 (888) 335-9632.

How to access this video.

If this course is one of your five classes, then your class currently isn't in session.

If you want to watch this video and it is not part of your class, upgrade your membership for unlimited access to the full library of 2,024 courses anytime, anywhere.

learn more upgrade

You can always watch the free content included in every course.

Questions? Call Customer Service at 1 1 (888) 335-9632 or email cs@lynda.com.

You don't have access to this video.

You're logged in as an account administrator, but your membership is no longer active. You can still access reports and account information.

To reactivate your account, contact a Training Solutions Advisor at 1 1 (888) 335-9632.

Need help accessing this video?

You can't access this video from your master administrator account.

Call Customer Service at 1 1 (888) 335-9632 or email cs@lynda.com for help accessing this video.

preview image of new course page

Try our new course pages

Explore our redesigned course pages, and tell us about your experience.

If you want to switch back to the old view, change your site preferences from the my account menu.

Try the new pages No, thanks

site feedback

Thanks for signing up.

We’ll send you a confirmation email shortly.


By signing up, you’ll receive about four emails per month, including

We’ll only use your email address to send you these mailings.

Here’s our privacy policy with more details about how we handle your information.

Keep up with news, tips, and latest courses with emails from lynda.com.

By signing up, you’ll receive about four emails per month, including

We’ll only use your email address to send you these mailings.

Here’s our privacy policy with more details about how we handle your information.

   
submit Lightbox submit clicked