Thursday, January 22, 2015

C# Essential Training

C# Essential Training
Introduction
Welcome
00:04    Hi! I am Joe Marini, and I'd like to welcome you to C# Essential Training.
00:08    I've been working with C# since its initial release back in 2001.
00:12    C# is a great choice for applications that run on a wide variety of
00:17    Microsoft platforms.
00:18    We will start off with the basics:
00:20    installing the free C# development tools from Microsoft, understanding the basic
00:25    structure of a C# program, and getting your first program up and running.
00:30    Then we'll move on to more advanced concepts, like defining your own C# classes.
00:35    I will also cover subjects like automatic memory management and reading and
00:39    writing data files, and we'll see how to do all of this while using the free
00:44    Visual C# Express development tools to build and debug your C# applications.
00:50    So if you're ready to take a look at the foundation language for targeting
00:53    Microsoft platforms then let's get started with C# Essential Training.
Collapse this transcript
What you should know
00:00    In this course, I am going to make a couple of assumptions.
00:03    First, I am going to assume you have some experience working with
00:06    Windows-based computers.
00:08    Second, I'm going to assume that you have some amount of prior programming
00:12    experience--not necessarily a lot of experience, and I don't expect that you've
00:16    ever even seen C# before.
00:19    But you do need to at least know what things like variables, functions,
00:23    loops, et cetera, are.
00:24    These are the basic fundamentals of any programming language, not just C#.
00:29    Just to be clear, this course is not an introduction to the fundamentals of programming.
00:33    What we are going to be focusing on are the fundamentals of the C# language itself.
00:39    Along the way, we will do some work with the .NET framework, which is
00:42    Microsoft's runtime and class library that C# uses to build and run programs,
00:47    but we will mainly focus on learning the C# language.
00:51    If you already know a programming language, like C or Java or Objective-C or
00:57    JavaScript, then many of the C# constructs will look very familiar to you,
01:02    but don't be fooled;
01:02    C# is its own language with its own way of doing some things some of which are
01:07    different from all the other languages out there.
01:10    Of course, if you're coming from a very different language, like Ruby or Python
01:15    or Perl, that's fine too;
01:17    you won't have any problem following along with this course.
Collapse this transcript
Using the exercise files
00:00    If you are a Premium member of the lynda.com Online Training Library, or if
00:04    you're watching this tutorial on a DVD-ROM, you have access to the exercise
00:09    files used throughout this title.
00:11    If you look inside the exercise files, you'll find folders that contain all the
00:16    various exercises that I'm going to use in this title.
00:19    The way that they're organized is, each one of the chapters has its own set of example files.
00:24    So for example, if I look inside the folder for Chapter 5, you will notice that
00:28    there are bunch of subfolders that are named according to the particular section
00:32    that's being described in that particular chapter.
00:35    If you look inside these folders, you will notice that there is a C# Express
00:40    project file, along with a folder that contains the code for that exercise.
00:45    When you have installed the Visual C# Express developer tools from Microsoft,
00:50    you'll be able to just simply double- click on the name of the project file,
00:54    which will then bring up the coding environment and the code that's in that file,
00:59    and you can start working right away on it.
01:01    Let me take a look back in the Exercise Files folder. You'll also notice that
01:06    there is a FinishedExamples folder.
01:09    In this folder, you will see the same folder structure, but what I've done here
01:13    is finished off each one of these examples in the finished state.
01:17    So here in the upper part of the folder, these are all the examples in the start state.
01:22    These are so that you can follow along with me as you take the course.
01:25    If you would rather just jump ahead and see how a finished example works, you
01:28    can go inside the FinishedExamples files folder and then just choose which
01:32    chapter you want to the finished example for and then go ahead and examine that code.
01:36    The last thing I want to point out is that I have included a file here
01:39    called ExampleSnippets.
01:41    If we open this text file up, you will notice that this is just a collection of
01:45    code snippets that I'm going to use in each one of these examples throughout the
01:49    title, and I have organized them in various chapters.
01:52    Here are the snippets for Chapter 3,
01:54    here are the snippets for Chapter 4, and so on.
01:57    This is so you don't have to sit and watch me type each example out.
02:01    I'm going to just simply copy and paste the code that's in these snippets files.
02:05    Now if you're a Monthly member or Annual member of lynda.com, you don't have
02:10    access to the exercise files, but you will have access to this ExampleSnippets
02:13    file because it will be made available as a free download.
02:16    So you can either follow along from scratch with your own assets, or you can use the snippets.
02:21    Let's go ahead and get started.
Collapse this transcript
1. Getting Started with C#
Installing the Visual C# Express IDE
00:00    Okay, so we are ready to start writing our C# code, but before we can do that,
00:03    we have to go get our development environment.
00:05    So to do that, we are going to go to the Microsoft web site and download the C#
00:10    Express development environment. So let's do that and go to the browser.
00:13    In the browser, I am going to type in microsoft.com/express.
00:19    This will take me to the download page for the various versions of Express
00:25    products that Microsoft makes available for free.
00:27    And this page might look a little bit different for you when you get here, but
00:31    there should be a link to download the Express products for Visual Studio, and
00:36    that's this link right here that says, "Get free Visual Studio Express products."
00:39    So I am going to click on that.
00:40    This will take me to a download page for all of the Visual Studio Express products.
00:46    And as I scroll down the list, you can see that there's one for Windows Phone.
00:49    There's Visual Web Developer. And I am just going to scroll down until I get to
00:52    this link right here, and that is Visual C# 2010 Express.
00:57    And again, when you get here, this may be newer. The point, though, is that
01:00    you want to get the most recent version of the Visual C# Express IDE.
01:04    So I am going to click on that link.
01:06    This will take me to the download page for that particular version of Visual C# Express.
01:11    So I can click on the Install Now link.
01:14    Now depending on what browser you're using, you're going to be prompted to
01:17    download and run the installer, and you can see here in IE I have got this
01:21    little download bar, but this is going to look different for you if you're using
01:24    a different browser.
01:25    Now I have already done this.
01:27    So once you have run the installer and Visual C# Express is installed, you will
01:32    find it in your Programs menu.
01:34    So if I go to the Start menu, you will see I have got Microsoft Visual C# 2010
01:39    Express, or something like it for you. And I am going to go ahead and click on the
01:42    link to make sure it's installed correctly. And you can see that Visual C#
01:46    Express fires up, and it looks like we are ready to go.
01:48    Now there is one other thing I wan to show you before we actually get started
01:51    writing some code, and that is the Microsoft Developer Network Library.
01:54    So let's jump back to the browser and head over there.
01:57    So back here in the browser, I am going to make a new tab, and I am going to
02:00    type msdn.microsoft.com.
02:04    This is the online library for the Microsoft Developer Network, and it contains
02:09    all the documentation that you'll need to build your C# and .NET programs.
02:15    And you can see when I come here it's placed me on one of these four categories.
02:18    In this case it's Tasks.
02:20    Let me click on the Platforms link.
02:21    And under Platforms, you can see that there are categories for desktop and web
02:26    and cloud and phone. And if we scroll down a little bit, there is a whole bunch
02:30    of content on here that's focused on building applications for the various
02:34    Microsoft platforms.
02:35    Let's scroll back up.
02:36    I am going to click on Tasks again.
02:39    You can see it takes me to a different pivot on the information here in the MSDN Library.
02:44    There is a section for creating code.
02:46    There is a section for testing.
02:47    There is a section for understanding code.
02:49    Let's go ahead and click on one of these links for understanding code.
02:51    You can see here, as I scroll down, there is a whole bunch of overview material
02:55    for understanding how to build .NET applications using a variety of languages.
03:00    We are going to be referring back to the MSDN Library throughout the course to
03:04    see documentation for the various kinds of code and objects we will be using.
03:08    In fact, if I click on the Library link up here, the Library link takes me
03:12    directly to the documentation for the various parts of C# and .NET. And you
03:18    can see over here under the MSDN Library section, there is links for all kinds of categories:
03:23    Development tools and Languages, .NET Development, and so on.
03:26    This is the web site that we will be referring to for Microsoft's canonical
03:30    documentation for various parts of C#.
03:33    Okay, so now that we have got the IDE installed and we know MSDN is, we are
03:37    ready to start building our first C# application.
Collapse this transcript
Creating your first C# application
00:00    Now that we have got the IDE installed and we've seen MSDN,
00:04    let's go ahead and fire up C# Express and build our first application.
00:09    So I am going to go ahead and launch C# Express. And when C# Express comes up,
00:17    you will see a start page and the application window frame.
00:22    So this right here is the start page. Over here is something called the Solution
00:25    Explorer, and we will look at that a little bit later.
00:27    What I am going to do, just really quickly, is get our feet wet by writing a C# application.
00:33    I don't expect that you're going to understand everything that I'm going to show you right
00:35    away, but I know you're probably anxious to get started.
00:38    So let's just go ahead and build a simple application. And once we've done that,
00:41    we'll take a quick look at how we did it, and then we will have an introduction
00:45    to C# Express that explains the various parts of the program that we will be
00:48    using throughout the course to build our applications.
00:52    I am going to go ahead and click on the New Project link right here. And when I
00:56    click on the New Project link, you'll notice that a dialog comes up asking me,
00:59    well, what kind of application do you want to build?
01:01    You can see there is a whole bunch of built-in ones that we can choose from:
01:05    there is Windows Forms Applications, there is WPF, there is something called a
01:09    Console Application, there's Class Library, and there is a whole bunch of other
01:12    things that we can choose from.
01:14    To keep things simple, we are going to build what's called a console application
01:17    and you may have heard this referred to in the past as something like a command-
01:22    line app, or something like that.
01:24    The point here is that we are not going to be focusing too much on fancy user
01:28    interface or anything like that.
01:29    We are going to build console applications to keep us focused on the C# language.
01:34    I could name it down here something else, but this is just an example.
01:37    So let's go and click on Console Application, and you can see that C# Express has
01:43    created a sample application for me.
01:46    It's opened up a file here called Program.cs--that's this tab right over here.
01:51    If we take a look now at the Solution Explorer, we can see the Solution Explorer
01:54    has now been filled out with a bunch of things:
01:57    There is the name of the application that we are building right here.
01:59    There is a couple of folders called Properties and References, and we will see
02:02    those in depth a little bit later.
02:04    And then this file right here called Program.cs.
02:07    Program.cs is the C# file that contains the code for our program, and it happens
02:12    to be opened in the window right here.
02:14    I am going to go ahead and just type a couple of things, and again, I don't
02:18    expect you to know this right away, but just follow along with me.
02:22    Inside the function for Main, I am going to type Console.WriteLine.
02:31    It's a bit of a tradition in programming courses that the first application you
02:36    write basically does nothing more than print "Hello World" out to whatever output
02:40    device you're using,
02:41    so I am going to type in here "Hello World," and I am going to save it.
02:49    Now what I am going to do is run it, and I can run it a couple of different ways.
02:53    What I am going to do is go up to the Debug menu.
02:56    You can see that I have got an option here for Start Debugging and I have got
03:00    something called Build Solution.
03:01    I will just quickly choose Build Solution to make sure that everything is right,
03:06    and you can see down here in the status bar there is a little piece of text
03:08    that says, "Build succeeded."
03:10    So everything looks okay.
03:12    Now I am going to run it.
03:13    And instead of going back to the Debug menu, I am going to click on this little
03:16    green arrow right here that says Start Debugging.
03:18    So I am going to click on that and you can see that some window came up very
03:22    quickly and went away, and that's because the Console Application came up, the
03:28    text was written out, and then the program ended.
03:30    The .NET Library said, "Oh, I guess we don't need the console window anymore.
03:33    Might as well send it away."
03:34    So to keep that from happening, I am going to add one more piece of code down
03:38    here, Console.ReadLine, and now I am going to save that.
03:45    Now this is going to have the console window wait for us to give it a line of text.
03:49    This is just a way for me to keep the console window from going away as I show
03:54    how this program works.
03:55    So let's try it one more time.
03:56    Let's go ahead and click on Run. All right!
03:59    You can see that the console window comes up, the words "Hello World" got printed
04:03    out, and now it's waiting for me to give it a line of input, and it's going to sit
04:07    there until I do that.
04:08    You can see in the background the UI for C# Express has changed somewhat.
04:14    The Program.cs window has been expanded, and we've got these two other windows
04:18    down here called Locals and Call Stack-- and we'll get into this later on when
04:22    we look at debugging.
04:23    This is C#'s way of showing me what the program is doing while it's running.
04:27    So let's bring this back up here, and you can see now that when I give it a line
04:31    of text and the ReadLine function completes, the Console window goes away and C#
04:36    Express goes back to the state where it first launched.
04:40    That's how we build our first C# program and to get further into the course, we
04:44    will explain how all of these things work.
Collapse this transcript
Introduction to Visual C# Express
00:00    Since we're going to be spending a lot of time using C# Express to build our
00:03    applications, we should probably take a few moments and get familiar with the
00:06    IDE and see how it works.
00:08    So I'm going to go ahead and launch the C# 2010 Express,
00:14    and you'll see that when the application comes up, it's a very simple UI.
00:17    There's the start page right here on the left-hand side,
00:20    and then over here there's something called the Solution Explorer.
00:24    A couple things you need to know about C# right upfront.
00:26    C# Express organizes everything into projects.
00:31    Projects are what applications are made from.
00:33    And you might sometimes hear the word project interspersed or interchanged
00:37    with the word solution.
00:39    That's not completely true.
00:40    Solutions are basically top-level projects that can contain other projects.
00:45    When we build a project, it will appear in the Solution Explorer here on the
00:49    right-hand side of the screen.
00:51    So let's go ahead and create a new project,
00:54    and we can do that one of two ways:
00:55    we can click on the New Project link here in start page, or we can go up to the
01:01    File menu and choose New Project.
01:03    So I'm going to choose New Project,
01:06    and the New Project dialog launches and we can choose what kind of project we want to build.
01:11    Throughout this course we'll be working with console applications, because
01:15    it gets the user interface out of the way and just let's us concentrate on the language.
01:19    So I'm going to go ahead and click on the Console Application to select it.
01:23    If it's not already done so, you should do the same thing.
01:25    Down here in the bottom of the dialog, there is a place where we can enter the
01:29    name of the project.
01:31    And I'll just type in something;
01:32    I'll just call it MyProject.
01:34    And I'm going to click the OK button.
01:37    This is going to create the project for us. All right!
01:41    Now that we have the project built, let's take a look at C# Express and see
01:46    what's going on here in the UI.
01:48    So over here in the Solution Explorer you'll notice that the window has been
01:52    filled out with some information, and we will get back to that in just a moment.
01:56    The project code is over here opened in the editor.
02:00    And the new project isn't actually saved yet.
02:02    It is fully functional. You can go ahead and run it. You can edit it.
02:05    You can do all kinds of things.
02:06    But it's sitting out in temporary space right now.
02:09    If we wanted to actually put all this work onto disk, we would go the File menu
02:13    and we would choose Save MyProject or Save All.
02:17    And when I choose Save All, you'll see that I get a dialog that says hey, here's the name.
02:21    Here's where it's going to be saved.
02:22    Here's what the solution name is.
02:24    I have the option to create a directory for the solution.
02:26    And at this point I can choose to name it something else if I don't like the
02:30    name that I originally came up with.
02:32    And I'm just going to go ahead and choose Save.
02:35    That will put the project on disk for me in the Documents folder, or whatever
02:39    path I selected in the Save dialog.
02:42    Let's go ahead and take a look at the project files over here in the Solution Explorer.
02:46    You'll see that underneath the top-level MyProject heading there are a couple of folders.
02:51    There's the Properties folder and References.
02:53    Let's go ahead and expand those.
02:56    Underneath Properties there's a file called AssemblyInfo.cs.
03:00    Now I'm just going to quickly open this up so you can see what's inside it.
03:02    We won't be going through this in this course, because this is a little bit of
03:05    advanced information.
03:06    But this is the information that C# Express will save, along with your
03:10    application, that describes to the .NET Framework what the application is, how
03:14    it works, various pieces of information that .NET needs to know about the
03:18    program in order to run it.
03:20    So let me go ahead and close that.
03:22    Under the References folder you'll see a whole bunch of things, like Microsoft
03:25    and System and so on.
03:27    These are the actual .NET Framework libraries that get associated with your
03:31    project when you make a new one.
03:33    These will change based upon what kind of project you're creating.
03:37    In this case, we've built a console application, so these are the .NET libraries
03:41    that the console application needs to run.
03:44    Some of them are optional; some of them are not.
03:46    The .NET Framework just goes ahead and includes them in case you need to use them later.
03:51    So let's go ahead and close those folders up.
03:53    The Program.cs file,
03:55    this is the default file that gets created, along with your application, that
03:59    contains your main code for the application.
04:02    And you can choose to add new C# files as you go along, depending on how complex
04:06    your application is.
04:07    We're not going to do that right now.
04:09    Let's just take a trip through the user interface of C# Express, so we can see how it works.
04:14    I've already shown you the File menu.
04:16    That's up over here.
04:17    This is where we create projects and save things.
04:19    Pretty standard file-menu stuff.
04:21    Let's move over to the View menu.
04:23    In the View menu, you'll see it's pretty simple.
04:25    I can choose to view the start page again.
04:27    There's other windows that we'll be looking at.
04:29    I'll just go ahead and choose one right now.
04:31    This one is the Error List.
04:32    This window down here shows you if there are any errors or warnings or
04:36    anything else in your code.
04:37    And we'll get back to that later, so let's go ahead and close that.
04:40    Also under the menu, there are toolbars, and you can see that I've got
04:43    some toolbars showing.
04:45    The Project menu is where we control what's in our project.
04:48    So we can add items to the project, we can add references, and so on.
04:52    We're not going to do that right now, but we'll probably do it later.
04:54    Under the Debug menu, this is how we run the application in order to test it out.
04:59    We can also build our solution right here.
05:02    This will build the program without actually running it.
05:04    I'm going to skip over the Data menu and go to Tools.
05:08    Under the Tools menu, I'm going to show you a couple of things.
05:10    First, under Settings, there's a couple of ways that you can use C# Express.
05:14    There's Basic Settings and there's Expert Settings.
05:17    I've left it on Basic Settings right now because we are not going to be using
05:20    any of the Expert Settings for now in our application.
05:23    What I'm going to do, though, is show you under Options.
05:25    Now under the Options dialog, there are a couple things I've changed that
05:29    you might want to change along with me to make some of the examples a little
05:32    bit easy to follow.
05:33    You can see that under Fonts and Colors I've changed the Size and the Font to
05:37    make things readable.
05:38    Now there's a check box down here that says Show all settings.
05:42    So I'm going to check that for a moment.
05:44    You can see that when I do that, a whole bunch of other settings show up.
05:46    What I'm going to do is, under Text Editor, I'm going to choose C#.
05:51    And you can see that there's an option under Display for Line numbers.
05:54    Now that's not there if I turn off the Show all settings function.
05:58    So turn on Show all settings and then go down to the C# option here and check
06:04    the Line numbers option to show line numbers in your code. Click OK.
06:09    And that pretty much completes our tour through the UI for using C# Express.
06:14    We'll see more of this as we go throughout the course,
06:17    but for now that should be a nice overview introduction to the application
06:20    and how it works.
Collapse this transcript
2. C# Language Fundamentals
Overview of the C# language
00:00    C# is a language that was built by Microsoft for working with Microsoft's .NET
00:06    application platforms.
00:08    It is a language that's very similar to other languages you may have seen, such
00:12    as JavaScript or Java or C, C++, Objective-C.
00:17    If you've used any of these languages in the past, you're going to feel right at
00:21    home pretty much in C#.
00:23    Syntactically, the language is very similar.
00:26    C# is what's called a managed-code environment.
00:29    Memory management is automatic.
00:32    So if you've worked with other languages, like C or Objective-C, then you've
00:37    probably come across situations where you have to create and destroy objects on your own.
00:43    C# does all of that for you.
00:45    When you create an object, the C# interpreter, or compiler, actually takes care of
00:50    making sure that that memory is returned to the system at some point, and you
00:54    don't have to worry about it.
00:55    C# is a compiled language.
00:58    Unlike some other languages you may be familiar with, like JavaScript or Perl,
01:01    you must first build a C# program before you can run it,
01:05    and this step is called compiling the application.
01:09    JavaScript and Perl are interpretive languages.
01:12    In other words, the execution engine-- in the case of JavaScript, for example,
01:16    that would be the browser--actually interprets the language line by line, as it
01:20    goes through the program and runs it as it discovers new statements and other
01:25    things in the language.
01:26    C# isn't like that.
01:27    In C#, you write your code, then you have to go through the compilation step,
01:31    and then you can run the application.
01:34    Now at its heart, C# is an object-oriented programming language.
01:38    In C# pretty much almost everything can be treated as an object.
01:42    I've underlined the word "almost" there, because there are a couple of esoteric
01:46    cases where not everything is an object.
01:48    But for our purposes in this course, you can pretty much think that everything
01:52    in C# is an object and can be treated that way.
01:56    In fact, in C# there are no global functions or variables;
01:59    everything is in classes.
02:01    And that might be different from other languages you might be familiar with, like
02:04    JavaScript or like C. But in C# everything has to be inside of a class, and
02:09    we'll come across that as we go further into the language.
02:12    Now as I mentioned earlier, C# is a foundation for working with many different
02:17    Microsoft platform technologies.
02:20    At the bottom of the stack is something called the Common Language Runtime.
02:24    This is the execution engine, or virtual machine, or whatever you want to call it,
02:28    that actually interprets all the various bytes that the program gets compiled
02:33    down to and is what runs your code.
02:36    On top of that are the Microsoft .NET Framework Libraries.
02:40    This is the code that is provided to you by .NET that performs a whole bunch of
02:45    common things that applications have to do, such as reading and writing from
02:48    files, working with the web, and all that kind of stuff.
02:51    That's all contained in the .NET Framework Libraries.
02:55    On top of that is the C# language, which we will be working with today.
02:59    But the thing about .NET is that it was designed to work with lots of languages.
03:03    There are other languages like VB.NET, such as Visual Basic, or Python, and so on.
03:08    But we're not going to concentrate on those;
03:09    we're going to be using C# throughout this course.
03:12    What this allows you to do is use one language to target many
03:16    different platforms.
03:17    So using C# and .NET, you can build applications that will run on Windows,
03:22    Windows Phone, Silverlight, SharePoint, ASP.NET, Xbox, and a whole bunch of others.
03:29    So just by learning this one language, you can build applications that run in
03:32    many, many different places.
03:34    C# got its start way back in 2001.
03:38    This was when Microsoft released the first version of .NET--that was .NET 1.0.
03:43    That was where C# burst on to the scene, and it continued along for a couple
03:48    of happy years, until 2003 came along, which was when Microsoft released .NET version 1.1,
03:54    and that was when C# 1.2 was released.
03:57    Not a whole lot of different changes between the initial C# release and 1.2--
04:01    a couple of cleaning up things they did in the language.
04:03    But 2005 was when things began to get interesting.
04:06    That was when .NET 2.0 came out.
04:08    And .NET 2.0 introduced some neat little things into C#,
04:13    things like generics and anonymous methods and iterators and nullable types.
04:17    Some of these things are advanced and we won't be covering them in this course,
04:21    but we will be looking at things like nullable types a little bit later on.
04:24    In 2007, that was when .NET 3.0 was released.
04:28    And in .NET 3.0 along came C# 3.0, which introduced concepts such as object
04:34    initializers, anonymous types, and so on.
04:37    Again, some of these are advanced, like lambda expressions--
04:40    we won't be looking at those--but we will be using things like object
04:43    initializers later on.
04:44    And then that brings us to 2010, which was when the .NET 4.0 Framework was released,
04:50    and along came C# 4.0, with things like dynamic binding and named and
04:55    optional arguments.
04:56    And we'll be again--as you may have detected by now, a bit of a pattern--
05:00    we will be looking at some of those later on in the course.
05:03    Now as I mentioned earlier, C# is a compiled language, and that means a couple of things.
05:08    In C#, you have to declare your variables before you use them.
05:12    There's no way around this.
05:14    You have to actually say here's the variable I'm going to use and I have to
05:17    say what type it is.
05:18    Now if you're used to a language like JavaScript, you simply use the keyword var
05:22    to declare a variable in JavaScript.
05:24    And you can also do that in the newer versions of C#.
05:28    But we're not going to be doing that now;
05:29    we're going to see how typing actually works.
05:31    So when you declare a variable, you have to supply a type and supply a name.
05:36    So, for example, I would say int myCounter or string message.
05:40    In this case, myCounter is an integer variable for integer numbers and the
05:45    message variable is a string.
05:47    The reason you have to do this is because it helps the C# compiler optimize the
05:51    program for knowing what kinds of data it's going to work with.
05:54    It doesn't have to figure it out on the fly.
05:56    You can also initialize variables when you first declare them.
06:00    I could've written, for example, "int myCounter = 200," or "string message = "Hello World!""
06:07    And this assigns an initial value to the variable when it is declared.
06:12    The other thing you need to know about C# is the concept of namespaces.
06:16    Again, other languages have something like this.
06:19    In Java you may have seen something like packages.
06:22    JavaScript doesn't really have something like this.
06:25    There are some efforts to kind of fake it up using things called modules.
06:29    But a namespace is basically just a way to organize a bunch of information into classes,
06:36    and .NET uses namespace to organize all the classes that it provides for you.
06:41    Essentially, it's a way of naming related classes and other namespaces within the
06:46    namespace such that you can group them together into logical formations that
06:50    make sense for various pieces of functionality.
06:53    And to take an example, .NET provides a namespace called System, which we will
06:58    be using a lot in this course.
07:00    And inside System, there will be classes, so just Console and Environment
07:04    and Math, and so on.
07:05    So each of those little boxes there represents classes and the keyword System
07:09    represents the namespace.
07:11    And in fact, you and your applications can create their own namespaces, and
07:15    we'll see that a little bit later in the course when we start creating our own applications.
07:18    But this is an important concept to understand.
07:20    C# and .NET in general uses namespaces to organize classes.
07:25    And this is how applications get organized and it makes things a lot easier when
07:29    you're writing your code in C#.
Collapse this transcript
Understanding the structure of a C# program
00:00    Let's take a look at the basic structure of a C# program.
00:04    Now, I've gone and fired up the C# Express development tool.
00:07    I'm going to create a new project by clicking the New Project link here on
00:11    the left-hand side.
00:13    The New Project dialog comes up.
00:14    Throughout this course, we're going to be using console applications to build
00:19    our examples, because they are one of the simplest applications to create and
00:23    they allow us to focus on just the C# language without having to worry about all
00:28    the user-interface-related code that other projects require.
00:32    I'm going to select the Console Application option, and I'm going to give it a name.
00:36    I'll just call this one StructureCSharp, and I'm going to click OK.
00:45    At this point, C# Express will create a new project and open it for me, and it
00:50    will drop me in the editor, into a file called Program.cs.
00:53    C# code is stored in files that have the .CS file extension. And right now, we
00:59    only have one of these, but your application can use as many of these files as you like.
01:04    And 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:14    just type thousands of lines into one file.
01:16    For now we've only got one, so let's go through this file line by line.
01:21    Right at the top here we have a bunch of using statements.
01:26    These statements tell the C# compiler which pieces of the .NET Framework that my
01:31    project will be using, and they allow me to write my code using a bit of a
01:36    shorthand notation that we'll see more of in a few minutes.
01:41    Now, if you're familiar with other languages, like, say, Java or C or C++, these
01:48    using statements are sort of analogous to things like import statements or
01:54    include statements, and so on.
01:56    But in C#, we use the using statement to indicate which pieces of the .NET
02:01    namespaces I'm using in my program.
02:04    The next line down is the namespace declaration for this project.
02:09    That's here on line 6.
02:10    Now, I mentioned earlier that C# uses something called namespaces to organize
02:15    code into related groups, or modules, and your program is no different.
02:20    Namespaces are basically just an organizational tool.
02:24    They keep related code together, and they prevent certain kinds of problems.
02:29    For example, if your program were to define a class that has the same name as a
02:34    class in some other .NET library, either from Microsoft or some other third
02:39    party, your program's namespace would keep those two classes from colliding with
02:44    each other and causing a whole bunch of compile problems.
02:47    Now, the C# editor creates the namespace for you when you create your project,
02:52    and it defaults to the name of the project, and we're just going to leave this as it is now.
02:57    Next, we have something called a class definition.
03:00    You can see that here on line 8.
03:02    It's the keyword "class" followed here by the word "Program."
03:07    Again, I mentioned earlier that in C#, almost everything is an object, and
03:10    again, your program is no exception.
03:12    In C#, the way that you define and create objects is by using the "class" keyword,
03:18    which we'll see more of later in the course.
03:20    And again, we're just going to leave this as it is for now.
03:24    Inside the class definition is the most important part of our C# program, the Main function.
03:30    You can see that here on line 10.
03:32    Now if you're already familiar with languages like C, Java, Objective-C, and so
03:37    on, then this will look familiar to you.
03:40    If not, let me explain.
03:41    When .NET goes to run your C# program, it needs to know where to start.
03:46    The Main function is that starting point.
03:49    It doesn't matter how many functions or lines of code your application contains;
03:53    somewhere in your program .NET expects to find one special function called Main,
03:58    and that's where it begins running your program.
04:01    It has to be written as you see it here.
04:03    It needs to be called Main, and the first letter must be uppercase because C# is
04:08    a case-sensitive language.
04:10    Case does matter here, because if you try to ignore case in C#, whether it's
04:14    for function names or variable names or anything else, you are in for a bunch of problems.
04:19    Now, it's important to note that not all C# project types have a Main function,
04:25    for example ASP.NET pages, but many of them do.
04:29    This isn't something that you'll ever have to worry about though, because when
04:32    you're using the visual C# programming tools to create projects, it will create
04:37    the Main function for you if it's needed.
04:40    Don't worry for now what the words "static" or "void" mean, or the stuff that's
04:45    inside the parentheses;
04:47    we're going to cover those later.
04:49    Let's take a look at some of the syntax rules of C#.
04:51    Now first, notice these curly braces on line 7, and 9, 11, 12, 13, and 14.
04:59    These braces are used to group related lines of code together in what are called
05:05    statement blocks of code.
05:06    You can see that they come in pairs.
05:08    There's an opening brace and there's a closing brace, and they must match up.
05:12    Now, they define starting and ending points for things like functions and
05:17    classes and loops, all of which we will see later in the course.
05:22    If you have experience in languages like JavaScript or C or Java, then
05:26    you've seen these before.
05:27    And if not, then all you need to know is that they group lines of code together.
05:32    Now, you'll notice that the Main function is empty, and that's okay, because
05:35    technically, this is a complete C# program.
05:38    But let's look at some basic examples of C# statement syntax.
05:43    To declare a variable, I need to specify a type and a name.
05:48    So for example, I can type "int" and then "myVariable."
05:54    This is different from languages like JavaScript where you don't need to specify
05:59    a type for your variable.
06:01    Now note, also, that every statement in C# must end with a semicolon, as I've done here.
06:08    Some other languages, like JavaScript for example, don't require this, but C# does.
06:13    Every time you type a statement, whether it's a variable declaration or you
06:16    call a function or any kind of statement that you write in the code, it has to end with a semicolon.
06:23    That's a really great practice because it really makes it clear where statements end.
06:28    Now, in C#, I can use some of the built-in .NET objects, since I've included
06:33    them in those namespaces using the using statements--for example, the Console object.
06:39    So let me just show you a quick example.
06:41    I'm going to start typing the word "Console," and you can see that as I'm typing,
06:45    the Visual C# Express development tool is helping me out here by trying to guess
06:50    what it is I'm going to type, and you can see it's centered on the word "Console"
06:53    there in the little pop-up.
06:54    So if I hit Return, it'll put the word "Console" for me.
06:58    Console is one of the built-in objects in .NET when you're using
07:02    console applications.
07:03    For example, to write something out to the console, I can use the WriteLine
07:07    function. So I'm going to type dot, and once again that little code hinter comes
07:12    up, and I'm going to start using word Write.
07:14    You can see that it zeros in on some of the functions available to me.
07:19    I'll just choose the WriteLine function.
07:23    I will just simply write out something like this.
07:26    Once again, notice that I've got a semicolon at the end of my statement.
07:30    The other thing that you should notice is that in C#, strings are contained
07:35    within two double quotes.
07:37    We'll cover a lot of this a little bit later in the course.
07:39    But if you're coming from languages where strings can be specified using either
07:43    single or double quotes, that's not the case in C#;
07:46    you have to use double quotes.
07:46    Now, notice how the word Console is in light blue.
07:50    That's because the Compiler notices that I'm using a built-in object in C#.
07:55    The Console object is contained within the System namespace.
07:59    Watch what happens when I go up here and I comment out the using System
08:04    statement up here on line 1.
08:05    Notice now I've got a little red squiggle down here on my Console object.
08:11    It says, "The name 'Console' does not exist in the current context," when I mouse over it.
08:16    So now I've gone from being able to use this object to not being able to use this object.
08:21    The reason for this is, when I commented out the System namespace, if I want to
08:25    be able to use that object now, I have to write what's called a fully
08:28    qualified path name.
08:30    So I would have to write out "System.Console.WriteLine" if I wanted to use this
08:36    now. 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:43    So by using these using statements, I can write my code using shorthand, rather
08:49    than having to write out these big, long, fully qualified paths to all the objects in .NET.
08:55    So it makes writing your code a lot easier.
08:57    So I'll go back up to the top here and uncomment that line.
09:03    You notice even when I have it uncommented, I can leave it fully qualified if I want to.
09:07    But now, I have the ability to take out that System statement and now Console
09:11    goes back to being recognized.
09:14    White space doesn't really matter in C#.
09:16    Now, some languages consider the indentation level of lines of code to be
09:20    important, but C# does not.
09:22    You can put as much or as little white space in your program statements as you like.
09:27    For example, I could put this statement all the way over here, and I can just
09:31    put this statement all the way back over here.
09:33    It doesn't really matter; this is all good.
09:35    Obviously, there are places where white space is going to matter.
09:38    So for example, inside of a string, if I do this, well, that's
09:41    pretty significant.
09:42    That's going to affect the way that that string is written out.
09:44    But within lines of code, white space does not matter.
09:49    So if you're coming from a language where white space matters, you don't have to
09:52    worry about that here.
09:53    Indentation in C# is just used for maintaining readability.
09:58    So we've seen enough C# where we can now start writing our programs, and we can
10:02    go on to the next part of the course.
Collapse this transcript
Compiling and running your code
00:00    One last thing that we need to look at before we jump in and start writing our
00:04    C# code and learning how to do all kinds of great things, like writing programs
00:08    and using variables and objects and so on, and that is compiling and running the code.
00:14    I realized I've done this a couple of times so far, but I want to get a little
00:17    bit deeper into this.
00:18    That way, as you're working through the course, you can see how the building
00:22    process works and the various tools that you'll need for when errors happen in
00:27    your code. And I say when and not if because errors are going to happen and you
00:31    need to be prepared for that and to see how to recover from these situations and
00:35    how to build your code correctly.
00:38    So as I said earlier, C# is a compiled language.
00:41    You have to compile it before you can run it, so we're going to cover some
00:45    tips on how to do this.
00:47    Now, the term for compiling and creating your finished application is "build."
00:52    So let's just make a new project, and we're going to call it BuildAndRun and make
00:59    sure it's a console application.
01:01    I'm going to click OK.
01:03    Now, what I'm going to do first is I'm going to click the Save All icon here.
01:09    I can also just choose Save All from the menu here.
01:12    I'm going to save this application in my Documents folder.
01:16    Now, this folder will be different for you based upon the computer that you're
01:20    using and where your Documents folder is, but I'm going to save it in the
01:23    default location, which is the visual studio 2010/Projects folder, and we'll go
01:28    out to the file system and see this in just a minute.
01:30    But I'm going to save.
01:33    Now that I've saved it, I've actually put the project onto a physical
01:38    location on my disk.
01:39    It's no longer sitting out there in temporary space.
01:42    So recall that the way that we build that application is by using either F6, or
01:46    up here in the Debug menu, we can choose Build Solution.
01:50    So I'm going to choose Build Solution and you can see down here in the toolbar,
01:54    there's a little message that says "Build succeeded."
01:57    So let's go out to the file system and see where the application is actually built to.
02:03    I'm here in my Documents folder, and you can see that there's a folder here
02:07    called Visual Studio 2010.
02:09    This might be slightly different based upon which version you're using.
02:12    But I'm going to go into Visual Studio 2010.
02:15    There's a folder called Projects.
02:17    Here's the project that I just built called BuildAndRun.
02:20    So let's take a look in there.
02:21    You'll see that inside BuildAndRun, this is the solution, the top-level project
02:25    for our code, and then there's a folder that goes along with it.
02:29    And inside the folder, there's the Program.cs file.
02:32    This is where our code is kept.
02:34    This is the project file.
02:35    There's also a folder in here called bin.
02:38    bin is short for binary.
02:40    This is where the application is kept.
02:42    Inside there, there are two folders:
02:43    there's Debug, and there's Release.
02:46    If we look in the Debug folder, you'll see that there's some information here
02:50    about the application's debug information.
02:53    If we go into the Release folder, you'll see that there's a couple of things in here.
02:57    First, there is BuildAndRun, and you can see that that's an application.
03:00    This is the actual finished application that gets built when you create the
03:05    application using Build inside the C# Express environment.
03:08    So this is the finished application.
03:10    That little PDB file is called the program database.
03:14    It contains some information that .NET needs to use in order to debug and run
03:18    the application that we've built.
03:20    But for now, all you need to know is that when you build an application, this is
03:24    where it actually gets placed.
03:25    When you create a project and you save it in whatever folder you save it in, the
03:29    C# IDE will build this subfolder structure for you.
03:34    Let's go back to the IDE.
03:36    Now, we're going to take a look at how we can build errors and warnings and fix
03:42    things and so on like that.
03:43    Here in my Main function, what I'm going to do is write some code.
03:48    I'm going to say int myInt = 50.
03:55    Don't worry too much about following along with this code.
03:58    We're going to cover variables and stuff later.
04:00    I'm going to make one more line.
04:08    This is code that we've been working with in a couple of examples now. Let me save this.
04:14    Now, I'm going to hit F6, and you can see that everything built just fine.
04:18    However, you can see that there's a little squiggle here under myInt.
04:21    What I'm going to do is go up to the View menu, and in Other Windows, I'm going
04:29    to choose Error List.
04:31    When I choose the Error List, you can see here that there is a warning, and the
04:35    warning is that the variable myInt is assigned, but its value is never used.
04:40    Warnings are not necessarily as bad as errors; your application will still run
04:44    just fine without it.
04:46    And just to show it to you, let me you put one more line of code in here.
04:54    Now, when I press F5 to run the application, or if I choose this little
04:58    triangle up here, or if I go to the Debug menu > Start Debugging--that's
05:03    where I run the program; I'll just use F5--
05:06    you can see that the program ran just fine, even though I had a warning there.
05:09    But that's no excuse for having warnings.
05:12    If you've got a warning somewhere in your code, you should really pay attention
05:15    to it because the compiler is trying to tell you something.
05:18    And in this case, the warning is a little bit benign.
05:19    I just created a variable that I never used.
05:22    But warnings can actually be pretty serious, and they usually indicate something
05:25    is wrong with your code.
05:26    So if you get warnings in your code, go look them up in the error list here and go fix them.
05:30    The next thing I want to do is make an error.
05:34    So what I'm going to is I'm going to remove the double quotes from the end
05:38    of that line there.
05:40    You can see that when I do that, I get a red squiggle which says that there's
05:44    some kind of error going on.
05:45    And if I try to hit F6, there's a whole bunch of build errors.
05:50    You can see down in the error list,
05:53    there are now three errors and the warning for the variable that I had before.
05:57    You can see that the errors are hey!
05:59    There's a new line in the constant. There is no semicolon.
06:01    There is no closing parenthesis.
06:04    All of these errors are occurring because I left off that closing quote.
06:08    When you get an error like this and the error list pops up, you can just
06:11    double-click on any one of these guys, and it will take you right to the line
06:15    where the error occurs.
06:17    Now, in this case to fix this, I just need to put the double quotes back.
06:21    But if I don't do that and I leave it and I ignore these warnings and I try to
06:25    run, by pressing F5, you'll see that there are build errors.
06:29    And C# is telling me, hey!
06:30    There were build errors, but if you like, you can continue and run the last time
06:35    that this was successful.
06:36    But I'm not going to do that.
06:37    What I'm going to do is click No and I'm going to say, okay, let's go ahead and
06:40    fix that problem, so I'll put the quotes back in.
06:42    Now everything is fine.
06:45    Once I press F5, you can see that the code is now working again.
06:49    The next thing I want to do is see away that I can get more information about my build.
06:55    Under the Tools menu, I'm going to switch over to Expert Settings.
07:00    Don't be intimidated; this really isn't a very big deal.
07:03    What I'm going to do is choose the View menu.
07:07    I have the Error List still, but now I have a new window here under Expert
07:11    mode called Output.
07:12    You can see that when I choose it, there it is right there.
07:15    So the Output window shows me a lot more detailed information about the
07:18    build-and-run process.
07:20    So, for example, if I now hit F6, you'll see that the output window is giving me
07:24    a whole bunch of information about the files that got compiled, any warnings or
07:28    errors that popped up.
07:29    You can see that whether the build succeeded or not.
07:32    You can see that where the output of the application was built.
07:36    You can see that BuildAndRun.exe was placed in this path down here at the bottom.
07:40    By using the Output window, you can get more information about where the build
07:44    process is and what it's doing and what the results are.
07:48    The last thing I want to do is show you how you can find out more
07:51    properties about your project.
07:54    Under the Project menu, I'm going to choose BuildAndRun Properties.
07:58    This menu item will change based upon whatever your project is called.
08:02    It'll be project name and then the word Properties here.
08:05    When I choose this, I get a whole bunch of properties about what my program is
08:09    and how it's being built.
08:11    So here under the Application tab, I can see that this is what my Assembly name is.
08:16    An assembly is basically just a generic term that says this is some physical
08:20    piece of code on the disk somewhere and it's the name of my project.
08:23    Same thing for the namespace.
08:25    I can also see what target framework I'm going after.
08:28    In this case, I'm using the .NET Framework 4.
08:31    But if I click on this, you can see I can build my application to target other
08:34    versions of the .NET Framework, all the way from 2.0 up through 3 and through 4,
08:39    and there are other frameworks I can install as well.
08:42    Under the Output type dropdown, this controls what kind of application I'm building.
08:46    Now, it's currently set to be a console application, but I can change it to be a
08:49    Windows app or a class library, and so on.
08:52    The last thing I want to show you is under Build, there are ways that I can
08:57    control how the application is built.
09:00    We'll see a little bit of these later on, but I can change how the errors and
09:04    warnings are reported.
09:05    I can say what the warning level is and there are four warning levels, all the
09:09    way up from very verbose down to not very detailed at all. So I can choose what
09:13    warning level I want.
09:14    I'm going to leave it on 4.
09:15    I can also suppress individual warnings that I don't want to know about.
09:19    Now, I don't suggest that you do this, because it's really good idea to know
09:23    about all the warnings in your code, but it is possible to do this.
09:27    You can also set a little preference over here that says Treat warnings as errors.
09:31    I can say None or All or Specific warnings.
09:34    If I changed this to All, for example, and then went back to my application,
09:40    you can see that when I hit up 6, now the warning that was hey!
09:44    The variable 'myInt' is assigned, but its value is never used, it's an error now.
09:48    It's no longer a warning.
09:50    So I'm going to go back and change that back to the way it was.
09:55    Now, I'm going to hit F6, and you can see that we're back to being a warning.
10:00    This is how you can control how your application is built, and it's how you get
10:04    more information about the process by which Visual C# Express builds your
10:08    application and runs it and fixes errors.
10:11    Now that you know how applications are actually built, we can dive right in and
10:15    start doing some more interesting stuff.
Collapse this transcript
3. Program Flow
Reading and writing from and to the Console
00:00    So now that we've got the foundational stuff out of the way, we can dive in and
00:03    start writing some real C# code. And what we're going to do in this particular
00:07    example is see how to read information from, and write information to, the console window.
00:14    And this is important to know how to do because for the rest of the course
00:17    we're basically going to be building examples that use the console as the place
00:21    where we write information to and read information from.
00:24    So we need to get a fundamental understanding of how the console works in order to do that.
00:28    So I've opened up, under Chapter 3, the HelloWorldProject in the example files
00:33    folder. And if you don't have that, you can just simply create a new project and follow along.
00:38    The other thing I've opened up is the ExampleSnippets.txt file, and this contains
00:44    the code that I'm going to be copying and pasting from so that you don't have to
00:47    sit there watch me type.
00:49    So let's go back to the program. You can see that we have our HelloWorldProject,
00:54    and down here in our Main function, this is where we're going to be filling the code in.
00:58    So let's go ahead and do something really simple, which we've already done a
01:02    couple of times, but just for refresher, let's write some information out to the console.
01:05    So I'm going to copy this line right here that says Console.WriteLine. I'm going to paste that in.
01:12    So the console object has a series of functions that read and write data, and the
01:17    most common ones are WriteLine and ReadLine. And you can guess what they do.
01:21    WriteLine writes out a string of text followed by a carriage return, which takes
01:26    the cursor back to the new line.
01:28    Now we could use Write which writes out the string and does not put a carriage
01:31    return on there, but for readability, we'll just WriteLine. And then there is the
01:35    ReadLine function which reads a string of text.
01:39    In this case, I'm using it just to keep the console window up, so you can see
01:42    the example working, but it will return a string if we want it to.
01:46    So let's just go ahead and save this, build it--
01:49    you see the Build succeeded--and run it, and no surprise, the string "Hello World!"
01:55    gets written out to the console.
01:56    So let's go ahead and make a couple of changes here.
01:59    What I'm going to do now is go back to the Snippets, and this time we're going to
02:03    read information from the console window and then write it out.
02:08    So I'm going to copy these three lines, paste them in.
02:13    So now what we're going to do is write out a string that says, "What is your name?"
02:18    And then we're going to use the ReadLine function to read a string of data from
02:22    the console and then write out a message that says, "Hello there" plus whatever
02:27    name the person gave us.
02:28    So you can see here that we've got a string variable that is being assigned to
02:32    the result of the ReadLine function.
02:35    Down here, we're just not using the result, which is why the window is
02:38    staying up. But here we're actually going to read the result and use it in the next string.
02:43    So I'm going to save, I'll build, and we'll run.
02:47    You can see it says, "Hello World! What is your name?"
02:49    And I'm going to type in "joe," hit Return and it says, "Why, hello there joe."
02:54    Let's go take and look at the code and see why that works.
02:56    You can see that the string variable here that gets returned from ReadLine
02:59    contains my name, and then in the WriteLine statement we're writing out the
03:04    string "Why, hello there" and then plus the string here.
03:09    Writing strings out to the console window takes many forms.
03:12    It's something that you'll probably do a bunch.
03:14    And although you can use the plus operator, there is actually other ways
03:17    to write strings out.
03:18    So let's take a look at how those work.
03:21    To build strings in C# for the purposes of displaying to the user or formatting
03:26    them for output, there is a couple of ways you can do this.
03:28    Now you've already seen the example where we use the plus operator.
03:31    This is something that you're probably familiar with if you done this in JavaScript.
03:35    It works in JavaScript and as you've seen,
03:36    it works in C# too.
03:38    However, it's not the most efficient way to build strings in C#, for
03:42    reasons we'll see later on.
03:43    There are other ways to format strings for display to the user, and the way that
03:48    we do that is by using the String.Format method.
03:52    And that method takes an argument, which is the string you want to write out
03:55    along with data that you want to put into that string.
03:59    So 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:07    year" and then an argument, which is probably a number.
04:11    The way that you format a string is by using those curly braces with an integer
04:15    number in there that serves as a placeholder for data that's going to be
04:19    inserted into the string for you.
04:21    And as you might have guessed, if you had more than one piece of data you wanted
04:24    to do this with, you would use more than one curly brace.
04:28    So in this example, it says String.Format.
04:30    There are something seconds in a year, and that little i is going to be
04:34    substituted where the 0 is in those curly braces--and in fact, it
04:38    substitutes entire thing.
04:39    The curly braces and the 0 don't appear in the finished string;
04:42    it gets substituted with the value of the data.
04:45    If you had more than one, you'd simply use more than one curly brace, and you'd
04:48    increment the number for each one of the variables.
04:51    So in this case, if I had two arguments that I wanted to format into the string,
04:55    I would simply supply those as arguments and use two sets of curly braces in the
04:59    String.Format argument.
05:01    So let's go back to the code and see how this works.
05:03    So I want to go back to my Snippets, and I'm going to copy this line right here.
05:07    Now I'll paste it in.
05:12    So now we have a variable called mySeconds, which we are calculating.
05:15    So there is 60 seconds in a minute, times 60 minutes in an hour, times 24
05:20    hours in a day, times 365 days in a year, and that gives us the number of
05:25    seconds in one year.
05:26    So you can see here that we have our Console.WriteLine, and we have our string
05:31    with the curly brace.
05:32    Now notice we're not using the String.Format method, and that's because the
05:35    WriteLine method of the console object knows how to use the String.Format method internally.
05:41    So we pass it what is called a format string, which has this little escape
05:45    sequence, or code sequence in it. And we're passing in the mySeconds variable and
05:50    when we run this, if everything goes well, then we should have the number that's
05:53    calculated inserted into the string.
05:55    So let me go up here and just comment out the code that we're not using, and we'll save.
06:03    This time I am also not going to use F6;
06:05    I'm just going to hit F5, which builds the program for me and runs it.
06:11    So I'm going to collapse two steps down to one and press F5 and you can see
06:16    that the number of seconds in one year has been substituted where those curly
06:20    braces were in the string.
06:22    We were going to be using Console.WriteLine and Console.ReadLine to write and
06:27    read information to the console throughout this course.
06:30    And after following the example here, you can see how to do it for yourself.
Collapse this transcript
Writing conditional statements
00:00    One of the things that any application has to be able to do is make decisions.
00:05    Decisions are inescapable.
00:07    They are an important part of pretty much any nontrivial program that
00:11    you're ever going to make.
00:12    Decisions are made when your program flow is chugging along nicely and suddenly
00:16    you come into a situation where you have to make a decision, and there is also
00:19    the decision of either true or false.
00:22    And this is, of course, built in classical programming using the if statement.
00:26    The if statement takes a Boolean condition and if that condition is true then
00:31    the code that is inside the if statement is executed.
00:35    Now, of course, there is a case for when the condition is not met, and that is the else case.
00:40    If the condition is not met and you have an else case on your if statement,
00:43    because they are after all optional, then the code for the condition where the
00:48    condition is not met is run instead.
00:50    In C# you can also have the else if statement, so we could replace that else
00:55    with an else if on another condition.
00:57    And in fact we can chain a bunch of these together to make a whole bunch of if,
01:01    else if, else if, else if, and so on. And if you want, you can have a trailing
01:06    else condition to handle everything else.
01:08    So let's jump over the code and see this in action.
01:11    Here in the code, I've opened up my ConditionalCode example file, and I've got my
01:16    Program.cs code open.
01:18    I've also got the ExampleSnippets file open right here. And I'm going to scroll
01:22    down to the Conditional Statements section, because these are the statements
01:25    that we're going to be using.
01:27    So back over here in the code, let's put together an if statement and see how it works.
01:32    So I'm going to copy these lines right here in my variable declaration, along
01:38    with the if statement. I'll copy and we'll just paste that in.
01:44    And you can see here that we have a variable, named theVal, which is initialized
01:48    to 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:57    Notice that there is two equal signs in here.
02:00    If I just tried to put one equal sign in here, I would get an error.
02:04    You can see the little red squiggle shows up, and it says, hey, you can't do a
02:07    conversion. And it's not important what that error means;
02:10    the point is that you can't do that.
02:12    So to test for equality it's two equal signs.
02:15    One equal sign does assignment; two equal signs tests for equality.
02:20    So if (theVal == 50) then we'll write out this data, so it's firstVar is 50.
02:27    And actually, let me change that because it's misspelled. There we go; theVal is 50.
02:32    So we'll save this, and we'll run it.
02:34    I'll use F5 to do that. And you can see that "theVal is 50" is being written out.
02:40    So let's go back to the code and change the value.
02:43    Let's make it 51, and we'll save and run it again.
02:47    And you can see this time nothing is being written out because the
02:50    condition is not being met.
02:51    Let's go back to the code.
02:53    Let's change this back to 50.
02:54    The other thing I want to point out on the if statement is you'll notice that
02:58    I'm using these curly braces to contain the code that's being executed in the
03:02    case of the if condition.
03:04    If all you have is one line of code for your if condition, you actually can
03:09    technically leave these braces out and that will work just fine.
03:13    However, for the sake of readability, and because if statements are very rarely
03:19    limited to one line, I always use the braces.
03:21    I always put them in there. it's a good idea to do so.
03:24    It helps readability of code.
03:25    It helps keeping your statements together.
03:27    So my suggestion is to always use the curly braces, even if you only have one line.
03:32    Let's go back to the Snippets, and let's bring a couple of other lines in here now.
03:38    We're going to try the else if condition this time.
03:42    So I'll copy this, and we'll paste it in below the if.
03:46    So now we have a condition that says if (theVal == 50) then write out this
03:50    statement; otherwise else if it's 51, write out something else. And once again,
03:54    I'll just change that.
03:56    Okay, so let's run this.
03:57    Okay, so you can see that the first condition is being met.
04:02    Now let's change it to 51, save and run, using F5.
04:09    And you can see that this time the else if condition ran, because the value was
04:14    51 instead of the 50. So this time, this condition was executed instead.
04:18    One more test to try.
04:20    Let's go back and copy this code over.
04:23    I'll now copy this and paste at the bottom of my else. And in this case, this
04:32    code is going to run when none of the conditions are met.
04:36    So we have if (theVal == 50), else if (theVal == 51), and the last else condition
04:41    catches everything else.
04:43    So let's just change this to, I don't know, something like 75.
04:46    We'll save and hit F5.
04:49    And you can see that in this case "theVal is something else" is being written
04:52    out, because the last else condition is triggering because the value was not
04:56    equal to 50 or not equal to 51.
04:58    So none of these if conditions right here fired.
05:02    You can have more than one condition in the if statement.
05:06    So for example, if I wanted to have this if condition execute if theVal was
05:11    equal to 50, or something else, I would simply put this one in parentheses,
05:17    and then I would use the OR operator, which is the two vertical bars--and we'll learn
05:24    about this a little bit later, but just bear with me for now.
05:27    So if ((theVal == 50) or (theVal == 49)) then you can write out "theVal is 50 or 49."
05:39    We'll save and now this if condition will execute if theVal is equal to one
05:45    of those two numbers.
05:46    So we'll change it to 49, hit F5, and you can see that the first if condition is
05:51    now being set, so that code is executing.
05:55    Let's go back. If we wanted to change it to AND instead of OR, I am going to
05:58    just use two ampersands.
06:00    Again, we'll learn about that in a little bit. But just for sake of example, I
06:03    want to show you how this works.
06:05    Now in this case, theVal is something else. Why?
06:08    Because here theVal is 49, but for this entire condition right here to be
06:12    true, both of those statements have to be true: theVal has to be 49 and theVal has to be 50.
06:19    And since that's clearly impossible, that first statement is not going to execute.
06:23    So you can see here that we're using if statements to create tests for
06:27    conditions in our code, and we can chain a whole bunch of these things together
06:31    using if, else if, and else. But if you find yourself running into situations
06:36    where you have a lot of different conditions to test for, using the whole bunch
06:39    of ifs and else ifs gets really hard to read and really hard to manage, and
06:44    there'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:00    For cases where your code has to check a lot of different conditions in order to
00:05    execute different parts of your code, it's usually not very efficient to have a
00:08    whole lot of if and else if statements.
00:11    It makes the code harder to read, and in that particular case
00:14    it's usually better to use something called the switch statement.
00:17    And the switch statement can be thought of as a whole bunch of if and else if
00:21    statements, but with a slightly different way of writing it.
00:25    The way you use a switch statement is you write the word "switch" and there is a
00:29    value that you pass to the switch statement, and then inside the switch
00:34    statement, you use a whole bunch of cases.
00:36    So you have a case for some value, which will then run some code, and you have a
00:41    break statement which says okay that's the end of this case. And then you can do
00:45    this as many times as you need it.
00:46    So you can have a case for a whole bunch of different values that all
00:49    run different code.
00:50    Now in the case where none of the values map to a particular case, you can
00:55    have a default case, which will run some code, or do nothing--
00:59    it's up to you. But the default case will be executed when none of the
01:03    other values match.
01:04    Now if you're coming from some other languages like C or Objective-C, for
01:08    example, they let you do things like this.
01:10    You can take that break statement out, in which case, when value1 or valueN are
01:16    met, the code will run.
01:18    And in the case of value1, the code for value1 will run as well as the code for
01:23    valueN, because there is no break statement in there to stop it.
01:26    Now, this is not legal in C#.
01:29    In C#, every case has to have a break command at the end.
01:33    Your code can't fall through to next case like in some other languages.
01:38    And the reason for this is because the designers of C# did a whole bunch of
01:42    studying of where bugs come from in programming logic.
01:45    And it turns out that a lot of bugs can be traced back to developers mistakenly
01:49    leaving out break statements in their switch cases when they probably shouldn't have.
01:54    So the C# language enforces this.
01:56    You have to have a break at the end of each one of your cases.
02:00    There is ways to get around this, but they're kind of esoteric, and I'm not
02:02    going to show you how to do them in this course, because they're not good
02:04    programming practices.
02:05    Just suffice it to say that you have to have a break at each one of your cases.
02:10    So let's go ahead over to the code and see how a switch statement works.
02:12    Here I have my SwitchStatement project open, and in my ExampleSnippets, I've
02:18    scrolled down to my Switch area.
02:20    So what I'm going to do is copy some code. I'll just copy the first part of the
02:25    switch case here, and I'll paste it in, and I'll close off the switch right
02:32    there, and I'll save.
02:33    So in this case, what we're going to do is write some code that does pretty much
02:37    the same thing that a whole bunch of if else statements would do, but using
02:41    switch case instead.
02:43    So here you can see I've got an integer variable called theVal, and it's being
02:47    set to a value of 50. And then the switch statement says hey what's the value of
02:52    theVal? And for case of 50, the Console will write line, The value is 50.
02:59    So let's save this and run it, and you can see, sure enough, "The value is 50"
03:03    is being written out.
03:04    So if we go back and change it to, say, something like 51 and we save that and run it,
03:08    well, now nothing is happening.
03:10    Okay, let's go back to the code and make some changes.
03:13    Go back to my Snippets, and I'm going to copy the rest of the cases in.
03:17    I'll save that, and now you can see that we have a whole bunch of cases:
03:24    there is 50, 51, 52, and a default case.
03:28    So in the case where I change theVal to be 52, then I save it, and then I run it,
03:34    in that case, the case for 52 is being run.
03:37    If I change it to something else, say 99 in this case, none of these cases is
03:43    going to match, so the default case should be run instead. And sure enough, that's
03:47    exactly what's happening.
03:49    So let's see what happens when you try to take out this break right here.
03:52    And you can see that when I take out the break, the little red error squiggle
03:57    appears under this case. And specifically, it says, "Control cannot fall through
04:01    from one case label to another."
04:03    So you can see here that C# is explicitly enforcing the rule that you have to
04:08    have breaks in your cases.
04:09    So let me just undo that, and we'll save, and we'll run it again, and you can see
04:14    that everything is working just fine.
04:16    So the switch statement provides a pretty handy replacement for a whole bunch
04:21    of nested if else, and I think you can agree with me that reading code that
04:25    looks like this with a whole bunch of cases is a lot nicer than reading a whole
04:29    bunch of ifs and elses.
Collapse this transcript
Using operators and expressions
00:00    Any nontrivial program that you write is going to be full of calculations.
00:04    You are going to be calculating things like scores and prices and all kinds of things.
00:08    And in order to do that, you need expressions, and you need operators to
00:12    build those expressions.
00:14    An expression is essentially just a collection of operators and operands, which
00:19    are the things that operators work on, that produce a result.
00:23    So for example, if we had an expression like this, we had 5 + 2 * the absolute
00:29    value of x, that is an expression.
00:32    And the plus and the star, those are operators.
00:37    Operators are simply symbols and functions that determine how expressions are evaluated.
00:43    So for example, we of course have the arithmetic operators.
00:47    These are pretty common in almost every programming language.
00:49    There's addition, subtraction, division, multiplication, and the percent sign--
00:54    maybe something you have not seen before,
00:55    but it exists in a lot of other languages, like C and JavaScript and
00:59    Objective-C and C++.
01:01    It's the remainder, or modulus, operator.
01:04    Basically it gives you the leftover results of a division operation.
01:10    So for example, 5 modulus 2 would be 5 divided by 2 but what's left over, so it would be 1.
01:16    There's also the assignment operator.
01:19    The assignment operator is the equals sign.
01:21    So take an example: if we had two variables, x and y, and we wanted to add them
01:26    together using the plus operator, or the addition operator,
01:29    we can then take the result of that expression and assign it to a third variable
01:33    called result, using the equal sign.
01:36    If we had a variable named distance and we wanted to add a number to it, we
01:40    could do distance = distance + 10.
01:43    This takes the existing variable, adds 10 to it, puts the result back in the same variable.
01:49    In fact, this is so common that there is a shorthand notation for doing this.
01:53    You can write distance = distance + 10 the same way by just doing distance += 10.
01:59    And in C# that means, take the variable and add to itself the number on
02:04    the right-hand side.
02:05    It also works of course for the minus, the multiplication, the divide, and the
02:10    modulus operators as well.
02:11    In addition to the math operators, there are also comparison operators.
02:16    So for example, we can check to see if things are equal to or not equal to each
02:21    other by using the equality check operators.
02:23    The two equal signs together say, hey, is a equal to b?
02:27    Do they have the same value?
02:29    We can check for things that are not equal by replacing the first equal sign
02:33    with an exclamation point.
02:34    In this case, this says a not equal to b. And as you might expect, there are also
02:39    operators for comparison testing to see if there are a larger or smaller numbers.
02:44    We can do things like a > b, a < b, a >= b, and a <= b.
02:54    The logical operators, such as AND and OR, allow you to combine more than
02:55    one condition.
03:01    So, for example, the AND operator, we can use to see if a=b and c=d. We use
03:09    two ampersands together.
03:10    There is no space in there.
03:11    We just put them next to each other and that is a logical AND operator.
03:15    We can do the same thing for OR.
03:17    The OR operator is just two vertical bars.
03:20    So in this case, if a=b or c=d, then the code inside those curly
03:26    braces would execute.
03:27    We can also do a NOT operator.
03:30    The NOT operator you can place in front of any Boolean expression to produce
03:35    the opposite of what that value evaluates to.
03:38    So for example, in this case, we are saying if not some Boolean value.
03:43    So if we set a to true for a certain Boolean value, then if we use bool b = !a,
03:50    that gives us the inverse value of a. So b is now false.
03:54    That's what the NOT operator does.
03:56    There are also operators for incrementing and decrementing, because again, this
03:59    happens a lot in programming.
04:01    The increment operators are, as you might expect, the addition operator, where you
04:05    simply take a and add 1 to itself.
04:07    We've already seen how to reduce that down using shorthand notation, to take the
04:11    value of a variable and add a value to itself.
04:14    But there's even a shorter hand way of doing this, because this is so common.
04:18    So there's the ++, and the ++ operator, postfix and prefix.
04:24    So when the ++ comes after the variable, that's postfix; and when ++ comes
04:29    before the variable, that's prefix.
04:31    They both do the same thing:
04:33    they both add 1 to whatever the variable is. But they do it in a certain way
04:38    that's slightly different from each other, and we'll see why in just a moment.
04:41    As you might expect, there's also decrement operators.
04:44    So for a + 1, we also have a = a - 1.
04:48    And we've already talked about how we can do the -= operator.
04:51    But there's also post and prefix versions of decrement as well, where you
04:55    simply put two minus signs next to the variable rather than two plus signs.
04:59    So what's the difference there?
05:01    The difference is this:
05:02    Suppose we had a variable whose value is 10.
05:04    If we use this statement, Console.WriteLine ("The value of a is:
05:08    and using our string formatting, we put the value of a into that replacement
05:13    curly braces expression there, the ++ prefix notation would execute first before
05:20    putting the value into the string.
05:22    So in this case, the output would be 11, because a gets incremented before it
05:27    gets put into the value of those curly braces.
05:30    If we use the postfix notation, that increment would get done after the
05:35    substitution took place.
05:37    So in that case, the output would be 10, even though a would then be incremented
05:42    and would be equal to 11.
05:44    So that's the main difference between prefix and postfix increment.
05:47    There's also type testing operators.
05:49    There's the is operator and the as operator.
05:53    And we'll learn more about these as we go through the object-oriented part of the course.
05:57    But essentially, what happens here is the is operator returns true if a given
06:02    object is a certain type.
06:04    The as operator takes a given object and converts it to another type if
06:09    it's possible to do so.
06:10    So let's just take a quick example--and I understand if you don't follow along
06:14    right away with this, but as we get to the chapter on object orientation, this
06:17    will become more clear.
06:19    So suppose we had a function that takes an object,
06:21    a generic object type.
06:23    We can say something like if obj is the type of Employee object.
06:29    So the is operator will return true if the object is of type Employee.
06:34    And if that's the case, we can then use the as operator, which will convert the
06:39    object to the type that we give it.
06:41    And if it can't be done, it will return null.
06:44    So in this case, we are taking the Employee emp and we are saying obj as Employee.
06:50    So it's converting the obj to an employee object which we can then operate on.
06:55    There's also an operator called the ternary operator.
06:57    Now most operators we have seen so far are binary operators.
07:00    So for addition, for example, you have two operands.
07:03    You have the two operands that are being added together.
07:05    The ternary operator works a little bit differently.
07:08    It actually has three operands, and it's written using the question mark and the colon.
07:13    It operates as if it were a very compact if else statement.
07:18    So it works like this:
07:19    You have a condition which evaluates to true or false just like any other statement.
07:24    You then put the question mark next to it and then the value that you want to
07:29    be assigned in the case that the condition is true, and then a colon, and the
07:33    value that you want to be assigned in case the condition is false.
07:36    So let's take a real example.
07:37    Suppose we had a couple of prices and we wanted to find out which of price1 and
07:42    price2 was the low price.
07:44    Now we could write it like this:
07:45    we could say if price 1 < price2 then the lowPrice = price1; otherwise
07:51    lowPrice is price2.
07:52    Or we could write it like this:
07:54    we could say lowPrice = and then the condition.
07:57    The condition here is price1 < price2.
08:01    Now if that evaluates to true--we put the question mark there--price1 would be the low price.
08:06    That's the true case. And then a colon
08:09    and then the value for the false case.
08:10    In this case, it will be price2.
08:11    So you can see we've taken the if statement and compacted it down to just one line of code.
08:17    Finally, there is operator precedence.
08:20    Most programming languages have the notion of operator precedence.
08:23    Operators are operated on in a particular order, based upon what the operator is.
08:28    So let's take a look at an example.
08:30    Suppose I had this expression.
08:32    I have an integer variable named result, and there's a whole bunch of numbers
08:36    being operated on, 2 + 3 * 6 / 2.
08:40    The temptation of course is to execute this expression going from the left and
08:43    traveling to the right, just like you probably learned in school.
08:46    And if you did that, you probably say, okay, well 2 + 3 is 5 and then 5 * 6 is
08:51    30 and then 30 / 2 is 15, so hey, the answer must be 15, right? Well, wrong.
08:56    And the reason it's wrong is because those operators are executed in order based
09:01    upon what the operator is.
09:03    This is what operator precedence means.
09:05    So that's actually wrong.
09:07    What happens is the multiplication operator gets executed first, because that
09:11    comes first in the precedence order.
09:14    So 3 * 6 would be 18.
09:16    Then the division operator would execute, and 18 * 2 would be 9.
09:22    Then we would go back and we would do the addition, because 9 + 2 is now 11.
09:27    So the real result would be 11.
09:29    Now you can change the order of precedence by using parentheses.
09:33    So if we put parentheses around the 2 and the 3 then things would execute in
09:37    the order that you thought they would.
09:38    In this case, the (2 + 3) would be executed first because it's in parentheses.
09:42    Then *6 is 30, divided by 2 is 15,
09:44    so the answer in that case would be 15.
09:47    So how do you know which operators come first?
09:49    Well, let's take a look.
09:50    The operator precedence operates in a very predictable order.
09:53    First, there is the Multiplicative operators, which are things like
09:57    multiplication, division, and the modulus operator.
10:00    Next comes the Additive operators, which in this case are + and -.
10:04    Then there is the Comparison and Type Testing, so things like >, <, >=, <=, the
10:11    is, the as operators.
10:13    Then the Equality tests come, so == and !=.
10:17    That's followed by a Conditional AND, which is followed by Conditional OR.
10:21    Then the Ternary operator comes.
10:23    And then finally, the last operator to execute is the Assignment operator.
10:27    Keep these rules in mind, because this is the source of a lot of bugs in programs
10:32    of beginning developers.
10:34    And once you realize that the operators execute in an order of precedence, this
10:38    will save you a lot of headaches down the road.
Collapse this transcript
Using constants and enumerations
00:00    In this example, we are going to look at using constants and enumerations.
00:04    Constants and enumerations are basically C# programming constructs that make
00:09    your code easier to understand and easier to maintain.
00:13    So let's take a look at what we mean by that.
00:16    Suppose we had some code that looked like this.
00:19    So we have some if statement and we've got some variable, and we are comparing it
00:23    to the constant number 32.
00:26    And if that condition evaluates to true then some code is going to run.
00:30    The problem is this is a bad practice. First of all, what does 32 even mean?
00:33    I mean if I am a programmer, I am writing the code,
00:35    I might know what it means, but two years from now, I might not know what it means.
00:39    Somebody goes to look at my code, but has no idea what that means.
00:42    Worse yet, what if it changes in the future?
00:44    If I am using this 32 value all over my program, I am going to have to change it
00:48    if for some reason in the future that 32 is no longer applicable and the test
00:53    needs to test for some other number.
00:55    Well, the way that we fix this problem is by using constants and enumerations.
01:00    So we can write the same thing by writing if (someVar == FREEZING), then the code runs.
01:07    That's much better.
01:08    It's clear what the code is trying to do.
01:10    It's testing for some freezing value of some liquid.
01:14    And if we ever decide to switch it, we just change the constant definition in one place.
01:19    And the way you define that constant freezing is by using the const structure.
01:24    So here I am saying const and then the int, and then the name of the constant
01:29    that I want to use is equal to some number.
01:33    So constants are used for numbers whose value is not going to change over the
01:38    life of the program.
01:40    So here you can see I have got a definition for const int FREEZING = 32.
01:45    That's the freezing point of water.
01:47    The freezing point of water is very unlikely to change in the future,
01:50    so therefore, I define a constant for it.
01:53    So if I want to change this constant to something else in the future, or change
01:57    it to some other definition, I just do it in one place and the rest of my code
02:01    just picks up the change,
02:03    and people reading my code in the future know what that means.
02:06    Enumerations are a close cousin to constants.
02:09    And what you'll probably find in many situations is that you'll use a whole
02:14    bunch of constants that are related to each other.
02:16    For example, if we had a constant for the freezing point of water, we might have
02:20    a whole bunch of other constants that go along with it.
02:22    There might be one for LUKEWARM and for HOT and for BOILING.
02:25    Well, it seems kind of silly to have all these separate constants defined for
02:30    different values that are really all related.
02:32    So the way you solve that problem is using what's called an enumeration.
02:37    In this case, we can build what's called an enumeration for temperatures, and
02:41    we just simply group them altogether.
02:43    So, for example, we would group the value of FREEZING and LUKEWARM and HOT and
02:48    BOILING all into one enumeration.
02:51    This way if we wanted to add a new one in the future--like say we want to add
02:54    one for ROOMTEMP--all we would do is make room for it in the enumeration, add
02:59    the value for it, and then we are done.
03:01    So now we have a whole bunch of temperatures that are grouped together logically,
03:05    instead of having a whole bunch of different const int definitions.
03:08    Enumerations start off at 0 by default if there is no value assignment.
03:13    So for example, if we have our temperatures enumeration and we put something at
03:17    the front of it, like, say, REALLYCOLD, that's going to default to the value of
03:21    0, unless you explicitly assign a value to it.
03:24    So to build an enumeration, you simply have the values that you want to assign
03:28    to words which are easy to read.
03:30    And if you don't assign it, then it defaults to 0.
03:34    If you also don't make a definition after one that's already been defined, then
03:38    that defaults to one more than whatever the previous definition was.
03:42    So for example, if we were to put another definition in here right after
03:46    FREEZING which would be, say, JUSTBARELYABOVEFREEZING and we didn't put an
03:50    equal sign, then it would default to the value of 33 in this case.
03:54    Now enumerations by default are integer types, but you can specify other
04:00    types if you want to.
04:01    Now we'll learn a little bit more about types in the next section, but just bear
04:05    with me here for a second.
04:06    So if we have temperatures and we have all of these values assigned to our
04:11    temperature enumeration, those default to integers.
04:14    But if I wanted to, say, assign them to the value of a byte in order to save space
04:18    in my program for some reason, then I could put a colon there and the name of
04:22    the type that I want the temperature enumeration to be.
04:25    So for example, in this case, if I know the value is never going to go above
04:27    255, which is the maximum value that one byte can hold, I can just define this to be a byte.
04:34    To define enumerations, you can use types that are numeric in nature, such as
04:38    byte and shorts and ints and longs.
04:41    And again, we'll learn what these are a little bit later in the course.
04:44    But I just wanted to point this out here, that you can define enumerations
04:48    that are not integers by using a colon and then the type that you want the enumeration to be.
04:53    So let's go ahead and jump over to the code and see some constants and
04:56    enumerations in action.
04:57    Here I have got my ConstAndEnums project open in my editor, and I've got
05:03    my Snippets.txt file.
05:05    And I've scrolled down to the Constants and Enumerations section.
05:08    So let's go ahead and copy some code over and see how things work.
05:11    So I am going to start with these lines right here, copy those, and put them in
05:17    my program, right here in Main.
05:20    So I have now defined constants for the freezing point of water and the
05:24    boiling point of water.
05:25    You can see I am getting a little warning that says, hey, you've defined this
05:28    constant, but you've never used it, so let's go ahead and fix that.
05:31    I am going to save, go back over to my Snippets, and I am going to copy
05:36    this code right here.
05:37    So now I have copied in some code that's going to use those constants.
05:47    So here, let's go down a little bit.
05:49    I've got an integer variable named myTemp, and I am setting it to be 65.
05:53    And then I have an if else condition for if myTemp is greater than freezing
05:58    point and it's less than the boiling point, then we write out, hey, at this
06:02    temperature, water was liquid;
06:04    otherwise we write out, hey, water is not liquid at this temperature.
06:07    So let's save and let's run it,
06:11    and we can see that at 65 degrees, water is a liquid.
06:14    And if we change this to, say, 30 and run it, then we say, aah!
06:20    At this temperature, water is not a liquid.
06:24    So let's do the same thing now, only using an enumeration, because you can see
06:27    here, I've got two different constants for freezing and boiling.
06:30    Let's go back to my Snippets.
06:31    What I am going to do is up here I have an enumeration for my temperature,
06:36    so I am going to copy that back over to my program.
06:42    Now I am going to put this definition outside the Main function.
06:45    I am going to put it in my class definition up here.
06:48    Paste that in, so now I have an enumeration for my temperatures. So you can see
06:51    here that the syntax highlighting is showing me that everything looks right.
06:55    So I have enumeration for FREEZING, LUKEWARM, ROOMTEMP, HOT, and BOILING.
06:59    Go back to my snippets. And now I am going to use these two lines down here instead.
07:07    Copy. And we'll go back to Main. And what we'll do is we'll get rid of these
07:14    guys, and we'll paste these in.
07:17    So now you can see I am using temperatures enumeration instead of the constants
07:21    that I've got defined here.
07:22    And in fact, since I am not using them anymore, let's just get rid of them.
07:25    The nice thing about enumerations is that, because they are part of your program
07:29    and the C# interpreter can look at them and see what they are,
07:32    when you type, it will actually help you type the value out.
07:36    So for example, suppose this piece of code wasn't there.
07:41    I can start writing the word Temperatures,
07:43    and you can see that the Temperatures IntelliSense is showing up right there.
07:46    So I am going to double-click that and it's going to get inserted.
07:48    Then when I hit the period, you can see that it's introspecting the
07:52    enumeration for me.
07:53    So I can scroll down to the one that I want, and that's FREEZING.
07:58    So I am going to have to just do this. Bear with me for a second while I do this,
08:03    because we'll learn about conversion in the future, but I have to tell the
08:07    interpreter that the Temperatures enumeration is an integer.
08:11    And now I can say okay, if the temperature is greater than FREEZING and is less
08:16    than BOILING, then we are doing the same thing.
08:18    At this temperature, water is a liquid or it's not.
08:21    So let's change this to 65 and run it,
08:24    and you can see that water is a liquid at 65.
08:28    The nice thing about this is that the code here is much easier to read than
08:31    having some numerical value that you don't know what it is.
08:35    And in the future, if I ever wanted to, I could change these numbers up here,
08:39    and I would not have to change them all over my program wherever they are being used.
08:43    Just make the change in one place.
08:45    So that's the argument for using constants and enumerations to make your code a
08:49    lot easier to read and a lot easier to maintain.
Collapse this transcript
Using loops
00:00    Along with some pretty basic stuff, like constants and enumerations and
00:05    conditional statements and operators and expressions, loops are one of the most
00:09    basic building blocks of any kind of programming language.
00:13    Loops are essentially blocks of code that execute over and over again.
00:18    And there are two different basic kinds of loops:
00:22    there are loops that execute while a condition is met and there are loops that
00:26    execute a set number of times.
00:29    So for example, you might have a loop that's running some piece of code for as
00:33    long as a certain condition is true, like the user has not logged out, or the end
00:38    of a file has not yet been reached, or something like that.
00:41    You might also have a loop that runs a set number of times: the number of people
00:45    attending a concert or something like that.
00:48    The way that you write loops is by using a couple of different constructs.
00:52    For loops that execute while a condition is met, you have a while loop,
00:57    and the while loop is written as you see it there.
00:59    It can have the keyword while.
01:01    And then inside some parentheses, you have a condition that is true.
01:05    And then inside the curly braces, you've got some code that's going to execute
01:09    as long as that condition is true.
01:10    There's also a close cousin of the while loop, which is the do-while loop.
01:15    And in this case, the while goes at the bottom of the loop instead of the top.
01:20    And the main difference here is that the while loop is only going to execute
01:25    when that condition is met.
01:27    If that condition test is not met, nothing inside the while loop is going to
01:31    run and that condition is evaluated before the while loop ever even gets a chance to run.
01:36    The do-while loop is a little bit different.
01:38    The code that is inside that loop is going to execute at least one time.
01:43    And that's because it executes once-- then the while is executed at the end of
01:48    the loop to see if things should keep going.
01:51    So in the case where you want to have a loop that runs only while a condition is
01:55    met and no other times, use the while loop.
01:57    If you have a condition where you want to execute some code just one time and
02:02    then check to see if you should keep going, that's the do-while loop.
02:05    For the set number of times case, there is the for loop.
02:10    And the for loop executes a given number of times and it runs the code that's
02:15    inside the curly braces.
02:16    A close relative of the for loop is the for-each loop,
02:21    but we're not going to cover that one in this particular movie because it has to
02:25    do with something called enumeration.
02:27    And we'll look at it a little bit later in the course.
02:30    For now we're going to concentrate on the while, do-while, and for loops.
02:35    Let's take a look at the code to see how this works.
02:38    I've got my example here opened.
02:41    This is my Loops project.
02:43    And over in my Snippets, I've got my code, and I'm scrolled down to the Loops section.
02:49    So let's take a look at how the basic while loop works.
02:52    So I am going to copy these lines of code here.
02:54    I am going to copy that, and I'm going to paste into my Main.
03:01    So I've got here an integer variable named myVal, and we have a basic while loop.
03:07    We're first going to write out a string of text that says Basic while() loop.
03:11    And then you see here, here's the while definition:
03:14    so while (myVal < 20). We're going to write myVal is currently and we're going
03:21    to use the console's WriteLine method with some string formatting here to write
03:25    out what the current value of myVal is.
03:28    As always with loops, you want to make sure that the loop has some way to exit;
03:32    otherwise, you'll end up with what's known as an infinite loop.
03:36    An infinite loop is a loop of code that just keeps going and going and going and
03:39    going and never has any way to get out of it.
03:42    So you want to make sure that you've got some code inside your loop, such that at some point
03:47    this condition up here is going to become false, and therefore your loop can
03:50    terminate, and your program can continue on its merry way.
03:54    So what we're doing here is, at the bottom of this loop, we're taking myVal and
03:59    we're adding 3 to it each time.
04:01    And recall that the += notation there means myVal = myVal + 3.
04:07    So when myVal becomes greater than 20, that condition will no longer be true if
04:11    they're in the while loop, and the loop should stop.
04:13    So let's save this, and we're going to go ahead and run it.
04:17    And you can see that the string gets written out, Basic while() loop, and myVal is
04:23    15, and then we add 3, so myVal is currently 18.
04:27    And then we add 3 and myVal becomes 21.
04:30    So when the code executes and goes back to the top of the loop, that test is no
04:35    longer true, and the loop stops.
04:38    So right here. So the code executes in this line, from top to bottom. The last
04:43    statement is the myVal += 3 right here.
04:46    When that executes, it gets to this curly brace,
04:49    it will go back up to the top of the loop, and then this condition gets tested, and it fails the test.
04:54    And that's what terminates the loop. Okay.
04:56    Let's take a look at another example.
04:59    In this case, we're going to look at the do-while loop. And I am going to copy
05:05    these lines of code right here.
05:07    Okay, let's get rid of this one. And paste.
05:19    In this case, we have a do-while loop, and remember that in the case of
05:22    the do-while loop, the code inside the braces gets executed once before
05:26    this condition gets met.
05:28    So in this case we have pretty much the same code.
05:30    We're writing out the Console.WriteLine value there.
05:33    We're adding 3 each time.
05:34    But let's see what happens.
05:36    So this time we're going to save, and we're going to run it.
05:40    You can see here that the do-while() loop, myVal is currently 15, myVal is
05:44    currently 18, and then we add 3 and then myVal is 21, and the condition no longer
05:50    is true and therefore the loop executes right here.
05:53    So right here when we add the myVal += 3. This is no longer running.
05:57    But let's watch what happens when I set this up at 20 to begin with.
06:02    I am going to save it.
06:03    I am going to run it.
06:05    And you see even though myVal is not less than 20,
06:08    it still goes through the loop at least one time.
06:12    So that code is going to get executed once before the while condition has a
06:15    chance to be evaluated.
06:17    So even though the condition is false, the code got executed one time.
06:22    So that's the do-while loop.
06:23    Let's take a look at our friend, the for loop.
06:25    Here's the code for the for loop right here.
06:31    I am going to copy that, and we're going to paste it.
06:37    A for loop is set up using three compact statements within the for statement itself.
06:43    So here's the for right here.
06:46    And then the first statement is the initialization of the counter variable.
06:51    In fact, I could expand that out and do something like this, where I say int i,
06:57    and then I wouldn't need to do this here.
06:59    I would simply say for (i = 0).
07:01    What I was doing there was just concatenating one with the other.
07:05    So this is the initialization, or setup, of the counter variable.
07:08    Then we have the test to see if i is less than myVal.
07:12    This is the condition that gets evaluated each time.
07:15    And then this is the statement that gets evaluated when the loop is complete. So this is setup,
07:20    this is the condition, and then this is what happens each time through the loop.
07:24    So i is going to start out at 0.
07:26    We're going to test to see if it's less than myVal, which is 20 right here, and
07:30    we're going to add 5 each time.
07:32    And each time through the loop we're going to write out i is currently
07:35    whatever its value is.
07:36    So I am going to save and we run it.
07:38    And you can see that i starts out at 0, then it's 5, then it's 10, then it's 15,
07:44    and then it gets to be 20, and that condition no longer needs to be true.
07:49    So 20 is not less than 20.
07:52    If we change this to be less than or equal to, then 20 will actually match the condition.
07:57    So if we run it again, you'll see that in this case i is less than or equal to
08:02    myVal, because 20 matches the less than or equal to part of the condition.
08:08    So that's the for loop, and that's how you get a loop to execute a certain number of times.
08:13    Let's take a look at some other keywords we can use with loops.
08:15    There are two special keywords that can be used with loops.
08:18    There's the break keyword, which breaks out of the loop at the current point,
08:23    regardless of whether the test condition has been met or not.
08:27    And there's the continue keyword, which basically says, hey, skip the rest of the
08:32    code in the loop and then just jump back to the top of the loop code as if you
08:37    had it completed one of the loops.
08:39    So let's take a look at how these work.
08:41    So I am going to erase the code from my previous example, and we're going to
08:45    go back to the Snippets, and I am going to copy over the last part of the
08:49    example right here.
08:50    I am going to copy, and I am going to paste.
08:56    So in this case, we're going to use the continue and break keywords.
09:00    So here I have a for loop that's starting off at 0, and it's going to run until i
09:06    is less than 10, and we're going to increment i by 1 each time.
09:10    We're using the postfix increment operator here.
09:13    Now, there are two special conditions in here.
09:16    When i is equal to 5, I am going to use the continue keyword.
09:21    continue basically says, hey, skip everything from here on down, go down to the
09:25    last brace, and then go back to the top again and execute whatever the third
09:29    statement over here is--
09:31    this part of the increment loop right here.
09:33    And then in the case where i is equal to 9, I am going to use the break keyword,
09:38    which basically means, hey, you know what?
09:40    Just stop the loop.
09:41    It doesn't really matter where we are.
09:43    It doesn't matter what the condition test up here. Just stop.
09:46    So let's save and we will run it.
09:49    Let's take a look at the output.
09:50    So you can see that i starts off at 0, Then it goes to 1, then 2, then 3, then 4.
09:56    But remember, for the 5 case, we use the continue keyword.
10:01    So we skipped over the line of code that said Console.WriteLine, so that line of
10:05    code never got executed.
10:07    The loop just continued as if it had run, but it skipped passed all the logic
10:11    that put where the continue keyword was.
10:14    And then we continue incrementing, so i is now 6, then 7, and then 8.
10:19    And then remember, when we got to the 9 case, we used the break keyword, which
10:24    stops the loop in its tracks, as if the condition had failed.
10:28    So let's go back to the code, and let's take this statement out.
10:32    I am going to comment this out and run it again.
10:37    And you can see, in this case, the loop does make it to 9, and then the value of i
10:41    becomes 10, which is where it triggers the condition, and the condition is no
10:45    longer met and the loop stops.
10:47    So if we go back to the code and we uncomment this, put the code back in, if I
10:52    change this to say 7 and save and then run, you'll see that in this case, the
10:57    loop only makes it as far as 6 because as soon as i gets to be 7, we're calling
11:02    the break command, which stops the loop.
11:05    Loops are a very powerful part of programming, and you can see that C# loops are
11:10    pretty versatile and pretty powerful in their own right.
Collapse this transcript
Using functions and methods
00:00    The last major piece of program flow that we're going to take a look at in this
00:03    section are functions.
00:05    Functions are a nice mechanism for breaking up large sections of code into
00:12    smaller pieces that are reusable, and make your programs easier to understand and
00:17    maintain. And one of the things you'll find when you're doing your C#
00:21    development, or development in any language, really, you'll find that any
00:24    nontrivial program that consists of many lines of code starts to get really
00:29    unwieldy and is really hard to change and maintain, and functions really make
00:33    that process a lot easier.
00:35    Now the reason why I included the word "methods" is because C# is an
00:40    object-oriented language and in object-oriented parlance, functions are
00:44    typically called methods, because in C# a function has to be part of an object.
00:50    There are no global functions, which I covered a little bit earlier.
00:53    So the word function and method are pretty much interchangeable in this context.
00:59    So anywhere you see me use the word functions, you can just mentally hear me
01:03    using the word methods, and/or vice versa.
01:06    To define a function, it's a pretty straightforward process.
01:11    We start off by giving it a name.
01:14    So to create a function, the function has to have a name, and you can use
01:17    whatever uppercase, lowercase rules you want to use. In this case, I am starting
01:20    off with a lowercase letter and I am using what's called CamelCase, and I am
01:24    capitalizing the interior words of the function.
01:28    But that's up to you.
01:29    You can use letters.
01:30    You can't use special symbols, like dollar signs or parentheses or anything like that;
01:34    it's got to be alphanumeric.
01:35    So here I have a function and I have given it a name.
01:38    Then I have to give it what's called a parameter list.
01:41    There are two parentheses and inside those parentheses, these are the arguments
01:47    that the function takes.
01:49    This is the data that the function is going to operate on. And inside the
01:53    function, I have the code of the function.
01:56    This is the stuff that the function does.
01:59    In this case, the function is simply calling Console.WriteLine.
02:03    In the parameter list, where the arguments go, I can supply one or more arguments,
02:09    or parameters, to the function.
02:11    So for example, if I want to pass in an integer, I would pass in int x. In
02:16    some other languages, like JavaScript, you don't have to declare the type in
02:20    front of the argument.
02:21    You simply give the argument a name, and you pass it into the function, and C# doesn't work like that.
02:27    In C# you have to tell the function, here's the kind of argument that's going to be coming in.
02:32    In this case, it's an integer.
02:34    If I wanted to pass in more than one, I would use a comma to separate them.
02:38    And in this case I am passing in an integer named X and a date argument named D.
02:44    Now in addition to the name of the function and the arguments, I have to say
02:49    what the return type of the function is. What kind of value does the function pass back?
02:55    I can say, for example, that the function passes back an integer.
02:58    Now, notice I don't name what the function is passing back.
03:01    I am just simply saying here that the function returns an integer. And it
03:04    can return an integer; it can return a string;
03:07    it can return any other kind of data type. And we'll learn a little bit more
03:10    about data types later on in the course.
03:11    But for now, just follow along with me here. I am saying that this function
03:15    returns an integer, and it takes an integer and a date as an argument.
03:20    If I didn't want to pass in any argument, I can simply leave the area inside the
03:24    parentheses blank and not pass in any arguments at all. But in this case, I've
03:29    got a couple of arguments.
03:30    And then finally, there is the code inside the curly braces for the function, and
03:34    that's what the function actually does.
03:36    In cases where functions return a value--in this case, this function is
03:40    returning an integer--
03:41    I have to make sure that the function actually does that, and I do that by using
03:44    the return statement.
03:46    In this case, I am returning a variable named someValue, which is probably
03:52    defined somewhere in this function as an integer.
03:55    The value that I am returning has to match the type of the return value for the function.
04:01    So if I declare this someValue variable in my function somewhere, it would have
04:05    to be an integer just like the return type of the function.
04:08    Functions don't have to return values.
04:10    I could just simply say void, in which case I've defined a function that takes a
04:14    couple of arguments but doesn't return anything. And in that case I don't need a
04:19    return statement at all.
04:20    I can just simply get rid of that, because there is no return value for the function.
04:25    I can also just simply use the word return with a semicolon by itself, but in
04:29    this case I've just got rid of it because it doesn't return anything.
04:32    So let's actually jump over to the code and see how to write a function that
04:36    does what we have described here.
04:38    So in my FuncsAndMethods project I've also got my Snippets file open, and I have
04:44    scrolled down to the Functions and Methods part.
04:46    So let's go ahead and copy some of this code and paste it in.
04:49    I am going to copy these three lines.
04:52    I will paste that, and let's take a look at what I've pasted in.
04:58    I have got an integer variable named result1, and then I am assigning
05:02    result1 the result of a formula function. And you can see here there are some
05:08    red squiggles there.
05:09    It says, "The name 'formula' does not exist in the current context."
05:12    That's a function that apparently takes an integer argument which I have not defined yet.
05:18    So let me go get the code for the formula function, and that's it right here.
05:24    I am going to copy that, and I am going to paste it.
05:30    So now, I have defined a function named formula which takes an integer argument
05:35    and returns an integer.
05:36    For the moment, you've probably noticed this word static right here. Just bear
05:40    with me about why we need that.
05:42    I am not going to cover it right now.
05:43    We'll get to that when we get to the section on object-oriented programming
05:46    a little bit later. It's just something we need right now for the function to work.
05:50    So don't worry about that right now. Let's pretend it's not there.
05:53    What's important is the return type right here of int, and the argument it takes
05:57    is an int, and this is the name of the function right here.
06:01    In some languages, for example C or Objective-C, the order in which you define
06:06    your functions is somewhat important.
06:08    So for example, if this were C and I put the definition of this function down
06:13    below where I am calling it up here,
06:15    I would have to have some type of code statement up here that says, "Hey!
06:20    program, there is going to be this function called formula that you're going to come across.
06:23    Don't worry about it."
06:24    I am just telling you about it now.
06:26    In C# you don't need to do that.
06:28    In C# you can just declare this function wherever you like and you can call it
06:31    from over here, and the C# interpreter is smart enough to realize oh, okay,
06:35    well, there must be a function named formula coming down, so I will just wait till I see it.
06:39    So here's what we're going to do.
06:40    We're going to call the formula function with an argument--in this case, it's
06:44    14. The function is going to do its work.
06:46    It's going to return an integer value and that value is going to be set into
06:50    result1, and then this statement right here Console.WriteLine is going to write
06:55    out whatever the result is.
06:56    So let's go ahead and save that, and let's run it. And you can see that the
07:02    result being written out is 24.
07:05    So the result of the formula inside the function evaluated to be 24.
07:10    So I'll say, okay. Let's go back up here.
07:12    Let's change this to something else.
07:13    I am going to type a new variable, and I am going to call it arg1. And I am going
07:22    to give it a value of 25. And now instead of passing in the hard-coded value of
07:32    14, I am going to copy arg1 and I am going to paste it in the calling place
07:38    where I am calling formula.
07:39    I am going to save it, I am going to run it, and you can see that now we've
07:43    produced a different result.
07:45    So that pretty much brings us to the close of this section.
07:48    In this section we've seen how program flow works.
07:50    We've covered things like functions, and we've seen constants and enumerations.
07:53    We learned how to write conditional statements, and we have learned about
07:56    operators and expressions.
07:58    We've got to the point now where we continue on and learn more about C# and
08:01    learn how to do things like declare variables and use objects and so on.
08:05    But this chapter should have given you a good foundation for a lot of the
08:08    basic parts of C# that you're going to come across in any program that you
08:12    decide to write, or work on.
Collapse this transcript
4. Variables
Understanding data types
00:00    Earlier in one of the course, I mentioned that C# was a strongly typed
00:04    language, meaning that you can't just simply declare variables and not tell the
00:10    system what the types are.
00:11    You'll find that as you build your C# programs, this actually becomes quite an
00:15    advantage, rather than the encumbrance that it sounds like.
00:19    Program store and keep track of all kinds of data.
00:23    They keep track of numbers and prices and names and email addresses and dates,
00:28    and these pieces of data are stored in memory locations called variables, and
00:32    each piece of data can have a type, which is used to declare a variable.
00:39    In some languages, such as JavaScript, you can declare variables and you can
00:44    change their types around.
00:45    You can do all kinds of great stuff. And you can't do that with C#.
00:50    So for example, in JavaScript you can just do this.
00:52    You can say myData = true; that's okay in JavaScript.
00:56    You can't do that and C#; you have to actually declare the variable.
01:00    In JavaScript if you just use a variable about declaring it, JavaScript
01:03    assumes it's a global variable. Well, C# doesn't have a global variables, so this wouldn't work.
01:08    You have to actually declare it, so you declare it.
01:11    In JavaScript you can do things like var myData = 123456.
01:13    And in fact, you can do this in to C# too.
01:18    C# does support the var keyword, but it's a little bit advanced for C#, and we're
01:23    not going to cover it in this course.
01:25    However, in JavaScript you can do things like this: once you declare the
01:28    variable and you've assigned it a number, later on in life you can say, hey, you
01:32    know what, myData is a text string now.
01:34    Again, that's okay in JavaScript, but you can't do that in C#.
01:38    Your variable can't change type once you've declared it and once
01:42    you've initialized it.
01:44    So that's an example of things that work in some other languages
01:47    that don't work in C#.
01:49    So how do you declare and name a variable in C#?
01:52    Well, let's take a look at that.
01:53    To declare variable, you simply indicate a type and then you give it a name, and
01:59    optionally you can give the variable an initial value.
02:03    So all of these are valid ways of declaring, and in some cases initializing, C# variables.
02:10    C# variable names can start with a letter or an underscore. And after that, you
02:16    can have letters, numbers, and underscores up to 255 characters.
02:22    Now you can't start a variable name with a number.
02:25    It has to be a letter or underscore, and the letter can be upper- or lowercase.
02:28    Remember that C# is case sensitive.
02:31    So, uppercase and lowercase variable names are different, so you have to keep that in mind.
02:36    This will sometimes lead to bugs for newer C# developers who've come from
02:40    languages where things are not case sensitive.
02:43    They're case insensitive.
02:44    That's not the case here with C#.
02:45    You do have to remember that.
02:46    C# has a number of primitive data types that are built into the language, and the
02:53    reason they're called primitive data types is because they are the basic
02:57    building blocks that you use to build other data types.
03:00    For example--and you've probably seen me using some of these throughout the
03:04    course so far, as we built some of our examples--
03:06    there is the int data type, which is an integer.
03:09    That's 4 bytes. And it holds numbers from about -2.1 billion up to about +2.1 billion.
03:18    There are date data types. The date is 8 bytes, and it represents January 1st
03:24    from the year one, up through midnight on December 31st of the year 9999, which
03:30    is a very long time.
03:31    There's also a char data type, which is a single character, and that's 2 bytes,
03:35    because it's Unicode.
03:36    Unlike other languages where character is 1 byte, in C#, it's 2 bytes.
03:40    There are strings. Strings can hold from about 0 to 2 billion characters.
03:45    That's a very, very long string.
03:47    There is also an object type. And in this case the object is actually defined by
03:52    your program, although C# and .NET does provide a base object definition for
03:58    you. And it takes up as much memory as its structure and as memory allows.
04:03    So you can have all kinds of data fields inside your objects.
04:06    And then rounding out the primitive data types are a whole bunch of other types
04:10    like Boolean and bytes and decimals and doubles, and all kinds of other numeric
04:16    data types and Boolean other non numeric data types.
04:19    There is also a special kind of data type in C# called a nullable type.
04:24    A nullable type can represent the full range of values of the normal underlying
04:29    data type, along with the additional value of null.
04:35    And normally when you declare a variable, like an integer, it has to be a number;
04:38    you can't set that variable to null like you can in JavaScript.
04:42    In C#, if you want to be able to do that, you have to declare what's called a nullable type.
04:47    This is a little bit advanced, and we won't see very much of it in the course,
04:50    but I wanted to point it out to you, because you will occasionally run cross
04:53    it in your C# travels, so I wanted make sure that you know what it is.
04:57    So, a nullable type, like I can said, it can be null along with whatever its
05:01    normal data type is.
05:02    So for example, if we declared a Boolean variable with the name of B, that can
05:07    be either true or false.
05:09    If you try to do this, however, set it to null, that's an error.
05:12    You can't set B to null.
05:13    If you want to do that, you'll have to declare the Boolean variable as a
05:18    nullable type, and the way you do that is you declare as a bool with a question mark
05:22    at the end.
05:23    And that tells the compiler, hey, this is a variable that can be either true or false or null.
05:29    You can do the same thing with integers.
05:31    If I put question mark on the end of the integer,
05:33    it can be an integer value or it can be null.
05:37    Using these kinds of primitive data types, you can build all kinds of C#
05:42    variables and higher-order objects which we will see a little bit later in the course.
05:46    For now though, now that we've seen primitive data types, there is one other
05:49    thing we just need to look at and understand, and that is how C# deals with
05:52    the notion of objects.
Collapse this transcript
(Almost) everything is an object
00:00    One of the things that I said earlier on in one of the course is that almost
00:02    everything is an object in .NET and in C#. And the way that that works is that
00:08    at the base level of the .NET library is a base type called System.Object.
00:14    All of the other types that we talked about so far, such as ints and doubles and
00:18    characters and bytes and so on, all of these are primitive types, but C#
00:22    actually derives all of these base primitive types from System.Object.
00:28    What's interesting about this is that even though the int data type is built
00:32    into .NET and C#, int actually maps to a System.Int32. int is just a shorthand
00:40    way of saying, use the class System.Int32. The same thing goes for char.
00:45    A char data type is actually a System.Char object.
00:49    Same thing with strings; strings are System.String objects.
00:52    These all derive from System.Object, and the same is true for all the other
00:56    objects that you see listed here, and all the primitive data types.
00:58    Date, bytes, doubles, all of those are actually objects.
01:02    They derive from System.Object.
01:04    So why is this important?
01:05    Well, it lets you do some pretty neat things.
01:07    If I were to declare a variable int i = 0,
01:11    I could do the same thing by saying int i = new int.
01:15    Other languages don't let you do this because they don't understand it, but in
01:18    C# and .NET, because pretty much everything is an object, you can do this.
01:22    These are functionally equivalent to each other. Declaring the variable as an
01:26    integer, initializing it to 0, and saying new is pretty much the same thing.
01:32    It also means that the built-in objects have some pretty cool features.
01:36    So for example, this integer is really an object, and it has functions that
01:40    I can call on it. So I can do things like i.GetType, and that will return System.In32.
01:46    That's the kind of object that it is.
01:48    I could say, i.ToString, and that would return a string.
01:51    Now remember, I'm doing all this on a basic integer.
01:53    I can do things like i.Equals, and give it an argument, and that returns whether
01:58    two objects are equal.
01:59    So once you get around the idea that everything pretty much in .NET and C# is an object,
02:05    it gives you a certain amount of freedom in your programs and some really great
02:09    functionality that other languages don't provide.
02:11    Let's take a look at an example.
02:13    Let's return to our old friend, the is operator.
02:16    Now I briefly talked about the is operator earlier on in the course, but now
02:20    let's take a look at how you might use it.
02:21    Suppose I had a function that took an object as an argument. And again, remember
02:27    here that that word "object" is really an alias.
02:30    It is a shorthand way of saying System.Object.
02:33    So here I have a function that's taking an object as an argument and it returns
02:37    an integer data type.
02:39    Inside this function I would be able to do things like say, hey, if the obj
02:43    argument that I'm being given is an int, and then I can convert that object to
02:48    an integer and then operate on the argument as if it were an integer. Or I could
02:52    say, hey, if the obj is a string, then convert the object to a string and then
02:57    operate on it as if it were a string.
02:59    This gives me a lot of flexibility in the way that I write my code.
03:02    I can write some C# code that's very flexible,
03:04    takes different kinds of arguments in one large container, and then convert
03:09    between them as I need them.
03:11    So what's so great about this?
03:12    Well, first, the fact that pretty much everything is an object provides a
03:16    unified way of working with all the variable types. You don't have to
03:21    treat primitive types one way and objects another way like you do in other languages.
03:26    Basic variable types in C# have some pretty cool automatic features built in,
03:31    and we'll see more of this as we work with each one of the other data types in depth.
03:35    All the C# types can be converted to and from objects, so they can be passed to
03:40    functions that take objects as parameters, as you saw it earlier.
03:44    So now you can write code that's very flexible.
03:46    You can write functions that take objects and take variables of different types
03:50    and work on them as if they were each with their own types.
03:54    So for example, I can write a function that takes an object or a series of
03:57    objects, pass them all kinds of variables, like strings and integers and doubles
04:01    and floats, find out what kinds they are, and then work on them as I would in
04:05    ordinary variable of that type.
04:07    And will see examples of this as we move through the course.
Collapse this transcript
Working with numbers
00:00    Let's talk a little bit about working with integer numbers in C#.
00:03    Up until now you've been seeing me use the int data type throughout all the
00:07    examples that we've encountered up until now, but there are plenty of other
00:10    ways of working with integer numbers. And the only real difference between the
00:14    various data types for working with integers is the size of the variable
00:19    container, which basically dictates the range of numbers that that variable can hold.
00:23    For example, there is bytes, which are 8 bits in size, and they are unsigned by default.
00:31    They are 0 to 255.
00:34    That's just 8 bits, and 255 is the largest number that you can hold inside of a byte.
00:40    Along with a byte is the sbyte, which means signed byte, that's also 8 bits, and
00:46    it can hold the number from -128 to 127.
00:51    So byte and sbyte are both the same size.
00:53    It's just a question of which one you want to use when you know that the number
00:56    is only going to be positive, or if the number might be signed.
00:59    Similarly, there is a data type called the short. The short is 16 bits, or 2 bytes,
01:04    and that can hold -32,768 up to 32,767.
01:10    Now notice unlike byte, shorts are signed by default.
01:14    So if you want to use an unsigned version of this, you have to use the ushort,
01:18    which stands for unsigned short. It's also 16 bits, and it can hold the
01:22    number from 0 to 65,535.
01:24    The next step off from there is of course the int, which is what you've been
01:29    seeing we use all this time.
01:30    It's 32 bits, and it can hold from -2.1 billion to 2.1 billion. And there is of
01:36    course an unsigned version of it, which is uint, for unsigned integer. It's also
01:40    32 bits, and since it's unsigned, it can hold from 0 up to about 4.3 billion.
01:48    That's a pretty good range of data, but suppose we want to handle numbers that
01:52    are larger than 4.3 billion.
01:54    Well, no, we are not out of luck.
01:55    There are other data types that we can use.
01:58    There is of course the long, which is 64 bits, and it has a range of well really,
02:04    really, really, really big.
02:06    You can see those numbers right there.
02:08    It goes from that -9 up to the 9, whatever that number even is.
02:11    I have no idea what the name of that number is, but it's really, really huge.
02:15    In addition to the long, there is the unsigned version of this, which is the ulong.
02:21    It's also 64 bits, and it can handle from 0 to well, even really, really bigger.
02:27    But of course there's also floating point numbers, not just integers. Usually we
02:31    use floating-point numbers for things like decimals and other kinds of
02:35    fractional numbers. And to do that there is a float number type and when you
02:39    declare a float number, you have to put a lowercase f on the end. And you can
02:43    see here I am declaring a floating point number of 123.45, and it has 7 digits
02:48    of precision from the range that I have shown there.
02:50    There is also a double, which is another type of floating-point number, but it
02:55    has 15 to 16 digits of precision. And you can see that when you declare it you
02:59    have to put a little d on the end to distinguish it from the float. Floats have
03:02    fs; doubles have d. So in this case I've got a double number which has much
03:08    higher precision than the floating-point.
03:10    And then finally there's the decimal number.
03:13    The decimal number is an interesting beast because it actually works in base 10
03:18    and not base 2, like the other kinds of floating-point number types that C# works with.
03:24    And to declare a decimal number, you simply say decimal and then the name of the
03:27    variable. And here I've got 123.45, and you put the little lowercase m on the end
03:33    which indicates that it is a decimal number.
03:35    Decimal numbers have 28 to 29 digits of precision, making them very, very
03:40    highly accurate numbers.
03:42    In addition to these data types, there are some special floating-point values that
03:47    you should be aware of.
03:48    The first of these is NaN, which means Not a Number. If a floating-point
03:53    variable gets into a state where you either try to divide by 0, or some other
03:56    kind of error happens, then the variable is set to NaN which means not a number.
04:02    There is also a PositiveInfinity and a NegativeInfinity setting.
04:06    For example, if you have a variable f defined to be of type float, you can do
04:11    things like say, hey, if f is less than float.PositiveInfinity. You can also
04:16    check to see if float is equal to not a number.
04:19    You can do things like float is PositiveInfinity, or is NegativeInfinity, and
04:24    these are useful for things like sorting algorithms.
04:26    You can also check to see if the float is not a number. Again because these
04:30    floating-point data types, along with all the other primitive data types, derive
04:33    from System.Object they have all these great methods and properties built into the language.
04:39    Okay, let's talk a little about why you'd use floating points, such as floats or
04:44    doubles, versus something like decimal, because one of the things you will find
04:47    is that with floating point numbers-- and I am not going to go too deep into
04:51    this because it's a bit of a advanced subject--but because of the way computers
04:54    work, computers calculate values using base 2 notation rather than base 10 like we humans do,
05:01    and that can lead to a loss of precision for certain kinds of transactions.
05:06    So let's take a look at a piece of code that explains how that happens.
05:10    So I have got my DoubleVsDecimal project open here, and here's the program file,
05:16    and I've got my snippets open as well.
05:18    So what I am going to do is copy these lines of code over to my main function.
05:25    So what we are going to do in this example is compare how double precision works
05:30    with decimal precision. And like I said earlier, internally, computers represent
05:35    numbers having to do with base 2 notation.
05:39    This is the famed 0s and 1s you've probably heard about if you've ever worked
05:43    with software before.
05:44    But what it essentially means is that because of the way numbers are calculated
05:47    on a microprocessor, you can sometimes lose precision when working with certain
05:51    data types. And I am going to show you a difference of how decimals are handled
05:56    versus how doubles are handled.
05:58    So right here at the top of my function I have got two variables, twentieth and
06:02    one. And you can see that I defined twentieth and one to be types double and
06:07    so I have got 0.2f and 1.0f. And what I am going to do is write out what one - twentieth is.
06:16    So 1.0 - 0.2, you would expect that to be equal to 0.8, right?
06:21    So let's see how the double data type and decimal data type compare when doing the
06:26    same kind of option, because down here, I have got two variables, decimals, which
06:30    are one twentieth and the real one.
06:33    So now I have got the same kind of calculation.
06:35    I have got 1.0, subtracting tracking off 0.2 each time.
06:38    The only thing that's different is in one case they are doubles; in one
06:41    case they are decimals.
06:43    So let's save this, and let's run it. And you can see that in the first case the
06:48    1.0 - 0.2 when using a double results in 0.799999...whatever, a whole bunch of,
06:56    like, you know high-precision numbers here. But obviously there is a loss of
07:01    precision 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:13    And again, that's because the decimal data type works with base 10 numbers
07:17    naturally, whereas doubles work with base 2 numbers.
07:20    Now you might be saying to yourself, oh my God!
07:22    Is this some kind of a bug in .NET?
07:23    Is this a huge shortcoming of C#? It's not.
07:26    You will find this in lots of different computer languages that work with
07:29    floating-point numbers. Whether it's C or Objective-C or Java, it doesn't really matter.
07:33    This is just one of the ways that computers keep track of numbers internally.
07:37    So let's go back and take a look at the chart of when you want to use double
07:39    versus when you want to use decimal.
07:41    Let's take a look at why double and decimal are different from each other.
07:44    First, in the nature of precision, doubles are 15 to 16 figures of precision,
07:49    where decimals are 28 to 29 figures, so you've got double the amount of
07:52    precision in a decimal number as you do a double.
07:55    In internal format, in other words how the microprocessor on the computer
07:58    works with the number, in doubles it's base 2; in decimals it's base 10.
08:04    So, so far it's looking like you might never want to use a double, right?
08:07    After all you've got higher precision using base 10.
08:10    Speed, however, is a important factor to consider.
08:13    Because doubles are native to the CPU-- in other words they are native in the
08:17    fact that they use base 2 notation--the speed when using doubles is very, very, very fast.
08:22    Decimals, on the other hand, because they work in base 10 and have to be
08:26    conferred to and from the native processor format, can be up to 10 times slower
08:30    than using doubles.
08:32    So what are they good for?
08:33    Well, scientific calculations can usually be executed quite accurately and quite
08:37    fast using doubles, so they're good for scientific calculations, whereas decimal
08:42    numbers are good for financial calculations.
08:45    When you're dealing with hundreds of millions or billions of dollars, or even
08:48    small amounts but many, many, many times, these differences in precision and
08:52    accuracy on the CPU can add up to real money.
08:56    So because decimals work in base 10 and are very highly accurate when
08:59    working with floating-point numbers, they are ideal for being used in
09:03    financial calculations.
09:05    You can use doubles and other floating-point numbers for
09:07    scientific calculations.
Collapse this transcript
Working with characters and strings
00:00    C# also has built-in data types for working with characters and strings.
00:05    They're the char and string data types, not surprisingly.
00:08    The character data type, or char, in C# represents a single Unicode character, and
00:13    that's 16 bits or 2 bytes.
00:15    So the way we declare is char
00:18    and then the name that you want to give the variable, and you can initialize if you want to.
00:23    And it's important in C# to recognize that, unlike languages like JavaScript,
00:26    when you declare characters you have to use a single quotes, and for strings
00:31    you use double quotes. And in JavaScript you can use either single or double
00:35    quotes for the characters or full strings,
00:36    it doesn't matter; in C# it does matter.
00:39    So, for the character data type use single quotes; for strings use double quotes.
00:42    If you're not familiar with Unicode, don't worry too much about it.
00:45    It's basically an international standard for representing a wide variety of
00:49    characters from a wide variety of languages, and it supersedes the old ASCII
00:53    data set that were used in computers up until just recently.
00:57    So here we have an example of a character being declared, and this is a
00:59    lowercase letter a. And as I mentioned it's 16 bits, or 2 bytes, but you are not
01:04    limited to lowercase letters.
01:05    You can use things like numbers.
01:07    You can even use punctuation. All of these are legitimate characters.
01:11    For strings, you use the string data type, and a string is a series of
01:17    Unicode characters.
01:18    And unlike other languages, like, say, C or languages based on it, like
01:22    Objective-C, C# provides a native built-in data type for working with strings
01:28    and it's just called the string.
01:29    So to declare a string, you use the string data type, again the name of the
01:33    variable that you want, and you can initialize it, and you can see I'm using
01:36    double quotes to initialize my string, which is part of the C# syntax rules.
01:42    strings can also have escape characters in them. In this case, for example, \n
01:47    represents a new line character, and these are handled automatically for you by C#.
01:52    If you make a string that has an escape sequence, which is basically a backslash
01:56    followed by a special character code, such as a T for tab or an R for a
02:01    carriage return or N for a new line, C# will simply convert that for you.
02:05    Now this provides some rather interesting side effects for working with things
02:09    like directory paths.
02:10    So for example, if I wanted to make a string that contained a directory path,
02:15    I'd have to escape out the backslashes by putting a backslash in front of them.
02:20    And this can get a little cumbersome and tiresome to read,
02:23    so C# provides a special way for telling the compiler, hey, don't worry
02:28    about escape characters.
02:29    I just want every character that's in the string to be what it really is.
02:32    And the way you do that is you put an @ symbol in the front of the string.
02:36    So in the case of declaring the myDirectory variable, in the first case I had
02:40    to escape out the backslashes; in the second case, by putting that little @
02:43    symbol in front of the string, I'm telling the compiler, hey, those backslashes
02:46    aren't escape characters;
02:47    they are just real backslashes-- please treat them as such.
02:50    But the fun doesn't stop there.
02:52    Remember that characters and strings are objects.
02:55    The character data type is really a system.char object, and the string data type
03:00    is really a system.string object, which basically means that each one of these
03:05    data types has some really cool features and methods built in.
03:09    So for example, if I define a character variable as the lowercase letter a
03:13    right here, I can do some really cool things on it.
03:15    I can ask the character, hey, is it an uppercase letter, or it is it a digit, or
03:20    is it a letter? Is it punctuation or a white space?
03:24    I can do things like convert the character to uppercase or to lowercase.
03:29    The same is true of things like strings.
03:31    If I declare a variable that holds a string, I can do some really
03:35    interesting things on it, because remember, it's an object, and the objects
03:38    have built-in methods.
03:39    So for example, I can do things like convert the string to upper- or lowercase.
03:44    I can search the string to see where a substring appears in the string.
03:49    I can do that searching forward or searching backwards.
03:52    I can take strings and trim white space off of them.
03:55    We already saw how to do things like string.formatting using
03:57    the Console.WriteLine.
03:59    You can see if a string is null or is empty. And all of these features come built in
04:06    to the language, simply because these data types, even though they're primitives,
04:10    derive from System.Object.
04:12    One of the things to keep in mind is that strings are what's called immutable.
04:17    They can't be changed once they are created.
04:20    Now you might be saying, well, wait a second Joe.
04:21    I've seen you change strings throughout this course so far. What you're talking about?
04:25    Well, the thing is that operations that appear to change a string actually
04:29    create a new string, and the thing is, this can cause a pretty significant
04:34    performance penalty if you're not careful.
04:37    So let's take an example. Suppose we had a string variable called Result and we
04:42    initialize it to be an empty string, and then we have a loop that executes, say, a
04:46    thousand times, and then inside that loop we're saying, result += "some other
04:49    strings", you know some kind of thing that we calculated.
04:54    Well, even though that += appears to be modifying the string, what's really
05:00    happening is, each time this loop executes, a new string is being created that
05:06    holds the temporary results of concatenating the string on the end, and then
05:10    that new string is assigned to the result variable, and then the old string that
05:16    used to be there is just simply discarded.
05:18    Now, if you do this a lot in your programs, you're going to hit a pretty
05:22    significant performance penalty.
05:23    So if you're doing a whole a lot of string manipulation, sometimes it's better
05:27    to use some of the built-in classes to do this.
05:29    C# provides one of these called the stringBuilder. So what you do is you would
05:33    instead of just declaring a variable named result,
05:36    you'd build a stringBuilder object.
05:39    In this case, I'm using the stringBuilder class to declare a variable called sb.
05:43    And then instead of doing a concatenation in the loop, like you see there, I'll
05:46    simply use the stringBuilder's Append method. And we will cover objects such
05:50    as this later on, but the point here is that I'm not just using a straight string to do this.
05:55    At the end, if I wanted to get the whole result of the stringBuilder as one long
05:59    string, I'd simply call the Tostring method on it and assign it to a string
06:03    variable that called result.
06:05    Let's take a look at some examples of using some of the features that we've seen
06:08    here for characters and strings in real code.
06:10    So I'm over here in my code, and I've got my charsAndstrings project open, and
06:16    I've also got my ExamplesSnippets open. Over here in the ExampleSnippets, you
06:21    can see that I've scrolled down to the chars and strings sections.
06:25    So let's go ahead and copy some of this, so I'm going to copy these lines
06:27    right here. Paste those in. So I'm going to save, and don't worry about the little warning.
06:36    I am not using the string.
06:37    We'll get to that in a second.
06:39    So you can see here that I've declared a variable called mychar, which is a char
06:43    type, and it's a lowercase letter a. And essentially what I'm doing is
06:47    exercising some of the methods that the character class provides for me.
06:50    So I'm going to do a whole bunch of WriteLines and write out the results of a
06:55    whole bunch of these methods, things like IsUpper, IsDigit, and so on.
06:58    So it starts off as the lowercase letter a. So let's go ahead and run the code
07:03    and see what happens.
07:05    So you can see that the results for these tests are, well, is lowercase letter
07:10    a upper? No, that's false.
07:11    It's obviously not a digit. It is a letter.
07:14    It's not white space or punctuation. And you can see here the results of calling
07:18    ToUpper and ToLower on it.
07:20    Okay, so let's change it.
07:23    Let's change it to say the number 8, and we will save and we will rerun it.
07:27    Well, in this case you can see that ToUpper and ToLower have the same result,
07:32    because there is no such thing as an upper- and lowercase 8, but in this case the
07:35    IsDigit function returned as true.
07:37    And I'll leave this as an exercise for you to play with.
07:40    What I'm going to now, though, is go back to the Snippets.
07:41    I'm going to copy those string tests.
07:48    Let's just do some of the string tests.
07:54    So in this case you can see I've got my string variable.
07:57    It says, "This is a message with a new line," and you can see it's got some leading
08:00    and trailing spaces on the front and back. And we are going to do things like
08:04    call Trim and ToUpper and ToLower and IndexOf and LastIndexOf.
08:09    So let's go ahead and save this and run it. And you can see here that this is a
08:17    string with a message and new line and spaces in it.
08:19    You can see that the spaces have been cut off. Here the result of ToUpper is
08:24    that all the letters have been converted to uppercase.
08:27    Here they've all been converted to lowercase, and then we found the indexes of
08:31    the letter a and the substring end.
08:32    So you can see that even though we've got primitive data types for characters
08:36    and strings, they're really pretty powerful, just again, because they derive
08:40    from the base System.Object class in C#. And because they are objects, they have
08:45    a whole bunch of really useful features that just come built in.
Collapse this transcript
Understanding variable scope
00:00    One of the other common "gotchas" that you have to watch out for when you're using
00:04    languages like C# or Objective-C or Java or anything else that's a compiled
00:08    language is the notion of variable scope.
00:11    All variables have what's called a scope.
00:13    This is where the variable is visible to the code and can be used.
00:18    So let's take a look at an example, and then I'll explain it.
00:21    So suppose I had a function named myFunction and inside that function I had a
00:25    variable called X, and I've declared the variable X and I've assigned it a value of 10.
00:29    And suppose I also have a for loop and inside the for loop I've got a variable
00:34    named Y which I'm declaring inside the for loop and the value of Y is being set
00:38    to the value of X+20.
00:41    That's okay because I can refer to the value of X inside the for loop.
00:44    I can declare the Y variable inside the for loop as well.
00:48    Now I can also refer to the X variable here if I wanted to use the increment
00:53    operator on X outside the for loop; that's fine. And I can also increment X
00:59    outside the for loop after the for loop; that's fine too.
01:02    What I can't do, however, is refer to the Y variable outside of the for loop. Why?
01:08    Because it's not available there.
01:09    I've declared it inside the for loop. And in this case when you declare
01:14    the variable inside those curly braces, that variable is only valid inside
01:20    those curly braces.
01:21    That's because in languages like C# variables have what's called a block scope.
01:28    Those curly braces define a block of code the same way that the curly braces
01:33    near the function define a block of code.
01:35    This is not the case in a language like JavaScript, and the reason is because in
01:40    languages like JavaScript variables have function-level scope.
01:45    When the JavaScript interpreter goes to interpret the function, it first looks
01:49    through the function to find variable declarations, and then it lifts them to
01:54    the top of the function.
01:56    It does that internally;
01:57    it doesn't modify your script code.
01:58    But it gives all the variables inside the function the same function-level scope.
02:03    That is not true in a language like C#.
02:07    In a language like C# or language like C or Objective-C or Java, the variable
02:12    is only available to you in the block where it is declared.
02:16    So let's take a look at this in action, and we can see how it works.
02:21    Over here in the code I've got my VariableScope project open, and here in the
02:24    Snippets I've scrolled down to the Variable Scope. And I'm going to copy these lines.
02:29    I'm going to paste it in right here.
02:32    So here I have my loop, and you can see inside the loop I'm declaring a
02:38    variable named int var1.
02:41    So when I run this program--let's just write it really click--you can see that what's
02:44    going to happen is I'm going to WriteLine, the value of var1 at pass whatever I
02:49    is is whatever the value of var1 is.
02:51    So I'm going to run it, and you can see that it's staying the value of 20 all the
02:55    way through the loop.
02:56    So now let's take a look at what happens when I try to uncomment this line of code here.
03:00    I'm going to try to WriteLine the last value of var1, but I'm going to do it
03:05    outside the for loop.
03:07    I am going to save, and you can see that I'm getting a little red
03:11    squiggle there which basically says, hey, the name var1 does not exist in
03:15    the current context.
03:16    That's because it's declared inside this for loop.
03:19    So if I wanted to do this, I would have to cut that and move it up here and save,
03:25    and now everything works fine.
03:27    So let's go ahead and undo that. Put it back where it was.
03:30    You might be wondering, hey, you know, in other languages I can re-declare
03:35    variables in different scopes and they're just given different meanings.
03:38    So for example, the C and Objective-C languages let you do something like this.
03:47    And what I've done here is I've declared the variable var1 in a separate scope
03:51    than the other var1 that's inside the for scope.
03:55    Inside the for loop you'd think that this variable would have its own scope and
03:59    this will have a different one, but that's not the way C# works.
04:03    This can be very confusing to someone who's reading code, and it's also the
04:07    source of a lot of bugs in other languages.
04:10    So the designers of C# explicitly don't allow variables to be declared in
04:15    separate scopes with the same name.
04:17    You can see that when I try to do this there is a little squiggle down here
04:20    that says, hey, a local variable named var1 cannot be declared in this scope,
04:24    because it would give a different meaning to var1, which is already used in a
04:28    parent or current scope to denote something else.
04:31    So these two variables conflict with each other,
04:33    so I can't do this.
04:36    It's important to note that this kind of scope-level referencing only works
04:41    from the inside out.
04:43    So if I declare the variable var1 in here, I can refer to it within the scope;
04:48    but if I declared it out here then I would be able to refer to it in this
04:54    current function-level scope, as well as all the other scopes that are contained
04:58    within the function.
04:59    So for example, I could do something like this, and that works just fine
05:06    because the for loop scope is contained within the scope for the Main function.
05:12    So in fact if I save this and I run it, you'll see that var1 is getting
05:17    incremented by 10 each time and now that last little console, that WriteLine that
05:21    I've got that says, what the last value of var1 was, is working just fine.
05:26    Understanding variable scope is a pretty important part of writing good C#
05:31    code, and it's something that you should pay close attention to, especially if
05:34    you're coming from a language like JavaScript that does not enforce these kinds of rules.
05:38    This kind of thing can bite you, so pay attention to it.
Collapse this transcript
Understanding type conversion
00:00    There is one more important concept that we have to understand in working with
00:04    C#, and that is understanding type conversion.
00:07    If you've come from a language like C or C++ or Java, you've seen this before.
00:12    Converting one type of variable to another is called casting, and this is the
00:17    kind of thing that pops up in languages that require you to give types to your variables.
00:22    You're probably wondering, or at least you soon would be, well, how do I share
00:26    data between variables that are different types?
00:29    The way that you do this is by casting one type of variable to another.
00:34    It's how you convert data types among different kinds of data-type variables.
00:39    So for example, suppose I had an integer named i and it is set to the value of
00:44    10, and I also had a float and that was set to the value of 20.0.
00:50    Suppose I wanted to set f to the value of i. I can just do f=i, and that's okay,
00:57    because that's an implicit cast, or a conversion from an int to a float.
01:03    Since an int is 4 bytes and a float is larger, there is no risk of data loss here.
01:08    The integer can simply be converted into a float and all is well.
01:12    The reverse is not true.
01:14    If I said i is equal to f, that causes an error, because you need to explicitly
01:20    cast from the float to the int, because data might be lost.
01:25    You can't fit all the precision of a float into an integer automatically.
01:30    However, if I did this, if I said i is equal to, and then in parentheses I put
01:35    the word int in front of the variable that I'm casting from, that's now okay.
01:41    I've explicitly cast, or converted, from the floating-point value to the integer value.
01:48    You'll see this all over languages like C and C++ and Objective-C and Java, and now in C#.
01:55    So let's go over to the code and actually see it in action. So here I am!
01:57    I've got my Conversion project open, and I'm going to open up my Snippets file.
02:03    That's right there.
02:04    So let's go ahead and scroll down to the Conversion section, and that's right
02:10    here, Type Conversion.
02:12    So I'm going to copy those lines, and I'm going to paste them in here. A couple of things.
02:20    You can see that I've got an integer, a short, and a float.
02:24    So in this case, the integer starts out as 10 and the short starts out as 5.
02:31    Now, you'll notice that I can simply assign the value of x to the value of i. Why?
02:36    Because x is a short. It's 16 bits, whereas the int is 32 bits, so there is
02:41    no loss of data here.
02:42    That's okay; the complier doesn't complain.
02:44    However, if I try to go the other way, if I try to set the value of i into x,
02:51    well, there is data loss here, or there's potential data loss here.
02:54    What's going to happen is I've got 32 bits trying to go into a 16-bit bucket, and
02:58    you can see that little squiggle is saying, hey!
03:00    Error, cannot implicitly convert type 'int' to 'short', are you missing a cast? Well, yes, I am.
03:05    All I'm going to do is say--if I put the word short in front of the i variable
03:13    inside parentheses, that says to the compiler, hey,
03:16    compiler, take the value of i and explicitly convert it into a short.
03:21    Now, you notice that that little red squiggle has gone away, and everything is just fine.
03:26    So let's go ahead and put a Console.WriteLine in here.
03:36    We'll write value x, and we'll write out x. So let's put a Console.ReadLine at
03:49    the bottom, and let's also comment out that error for the moment.
03:56    So let's save it and run it.
03:58    You can see that the value of x is 5. Why?
04:01    Because here we put x into i, and then we just put i back into x, and since x
04:07    started out as 5, that's what's happened, so now x is back to being 5.
04:11    So let's suppose we comment this line out and we make i something that a
04:18    short can't handle,
04:20    so something like 800,000.
04:23    So now when we run this, you'll see that the value of x is 13,568. Why?
04:30    Because some of the bits of the integer got stripped off.
04:34    Remember, the integer is 32 bits, but the short is 16 bits.
04:38    So 16 bits of information got stripped off, and what was left over was what could
04:43    fit in those 16 bits, and that worked out to be 13,568.
04:48    So that's the kind of thing you need to watch out for when you're working with
04:51    type conversion because some types of containers are larger than others.
04:55    Let's go back to the code here.
04:57    Let's go ahead and get rid of these two lines. And let's look at the floating-
05:02    point versions instead.
05:04    So here you can see I have the floating-point number f, which is equal to 20,
05:11    and here I've got the i, which is now 800,000.
05:14    Again, I can assign the value of i into the value of f. Why?
05:18    Because floats are larger than integers; that works just fine.
05:21    Same story down here.
05:22    I'd have to actually cast the float to be an integer, and in order for that
05:29    to work, I simply put the word int inside parentheses, and now that converts
05:34    the value of the float into an integer, which can be stored inside the integer variable.
05:39    You'll see this kind of thing all over C# code, and you'll see it in
05:43    other languages as well.
05:44    It's important to understand how conversion and casting works because you'll be
05:47    using it in your own code.
Collapse this transcript
5. Custom Classes and Objects
Object orientation refresher
00:00    Up until now, I have been talking how C# is an object-oriented language, and
00:05    you've been seeing me use objects throughout some of the previous examples.
00:08    And we've reached the point now in the course where we actually need to learn how to
00:11    define and use our own objects in C#.
00:13    If you are going to be a C# programmer, there's no getting around the
00:16    object-orientedness of the language, and now is as good a time as any to take
00:20    a look at how to get started with the object orientation in C#.
00:24    So as I have mentioned many times C# is of course an inherently object-oriented
00:28    language. There's no getting around this, and in fact, everything that we have
00:31    been doing up until now has involved objects in one way or another.
00:35    The variables that we've been defining, those are objects--those integers and
00:38    strings and everything else.
00:40    We have been using the console object to write output to the console window, and
00:45    even the program itself that we've been using is itself an object.
00:49    So objects are everywhere in C#, and your programs will not be any different.
00:54    Programs are basically collections of objects.
00:56    So objects contain data, and they contain the logic that operates on that data.
01:01    It's a way of keeping related data and logic in the same place.
01:05    And of course objects can communicate with each other, because if they didn't
01:08    communicate with each other, not a whole lot of useful work would get done. And of
01:11    course not only do the objects communicate with each other, they communicate with
01:15    the program that hosts them, because the program itself is an object, and this is
01:19    how your programs communicate with the .NET framework as well.
01:22    In C# there are three main terms
01:24    you are going to have to keep track of:
01:25    there is class, there's interface, and there is object.
01:29    Interface is a little bit advanced, so we are not going to focus on that right now.
01:33    We are just going to focus on the class and object terms for the remainder of
01:37    this section, and we'll see a little bit about interfaces later on.
01:41    Classes in C# are one of the most common type that you will come across, and a
01:45    class essentially provides a blueprint, or a description, of what an object looks
01:51    like and what it does.
01:52    The blueprint, or description if you will, defines things like what kinds of data
01:57    that an object of a certain type holds, and it also defines what kinds of things
02:01    that an object can do.
02:03    It's important to keep in mind, however, that a class is just a definition.
02:06    It's a description.
02:07    It's not the actual object itself. For example, when you have a blueprint of a
02:11    house, the blueprint you can think of as being a class, but it's not the actual house.
02:16    When you build the actual house, that's the object; the blueprint just provides a
02:20    description of how to do that.
02:22    In your C# programs, you'll usually defined your own classes to do whatever
02:27    custom work you need to get done, as well as using the classes that are provided
02:32    by the .NET framework.
02:33    The .NET framework is pretty full featured.
02:35    It provides hundreds of classes for doing all different kinds of things, and
02:39    you'll take advantage of these classes as you build your own applications. For example,
02:43    suppose we were building an application that managed the list of to-do items.
02:48    You can imagine that we would have a class to handle the to-do items;
02:51    we would probably have another class to group all of those to-do items in a to-do list.
02:56    And these are classes that your program would define. But there's a whole bunch
03:00    of other classes that the .NET framework would provide for you, things like
03:03    dates and times and array lists and classes for working with strings and
03:07    communicating with the Internet.
03:09    These are all provided by the .NET framework, and as you build your applications
03:13    and learn more about C# and .NET, you'll use more and more of the .NET classes to
03:18    round out your applications' functionality.
03:20    So what do classes define?
03:22    Classes essentially define two major things, and these are called the members.
03:27    The first set of things is fields and properties and the second set of things are
03:32    methods or functions.
03:34    Nowfunctions and methods are pretty much the same thing, but the word method
03:38    is what's commonly used in object-oriented terminology, so that's what I am going to use here.
03:42    The fields and properties are the kinds of data that the object holds and works with.
03:47    The methods are what the object can do;
03:50    this is their logic, the functionality that contains in the object.
03:54    Again, if you go back to our to-do list item example, you can imagine that a
03:57    to-do item might have a name, a description and a priority, then something
04:02    like a due date, and then we would need to have methods to operate on that
04:05    data--for example, setting the description and changing the priority, and marking items complete.
04:10    These are what classes defined and as you build your own classes, you will define
04:14    your own fields and properties, and you will write your own methods to work on
04:17    those pieces of data.
04:19    Classes can also inherit attributes and methods from other classes, and this is
04:26    a very important concept in object-oriented programming, so it's important that you understand this.
04:31    For example, let's imagine that I have a class that I want to define called class A, and class
04:36    A contains a couple of fields like name and age and it has a function in it--in
04:41    this case it called sayHello().
04:42    Now you've probably already seen examples like this, and in C# you would refer to
04:47    these fields and functions by using the dot notation. So you would say A.name,
04:51    A.age for the fields, and A.sayHello() to call the method.
04:56    I can also define a class that inherits from class A, and in object-oriented
05:01    terminology this is called creating a subclass.
05:04    So if I want to create a class B that inherits from class A, I would define
05:09    class B, put a colon after its name, and then put the name of the class that the
05:15    class inherits from.
05:16    So here you can see the class B with the colon and the A means this class B and
05:21    it inherits from class A. And in class B, I've defined a couple of things. I've
05:25    got another property called address and a function called sayGoodbye.
05:29    So again you would refer to this using standard.notation for the class B, like
05:34    B.address and B. sayGoodbye. But because the class B inherits from class A, it
05:39    also has all of the fields and properties that class A has.
05:42    So class B also has a sayHello function and the name property, even though I
05:46    haven't defined it in class B; it just gets all those things because it
05:50    inherits from class A.
05:52    So in object-oriented terminology, we say that class B is a subclass of class A,
05:58    and class A is class B's superclass.
06:02    You'll see these terms used throughout object-oriented documentation whenever
06:06    you read documentation on web. Especially in MSDN, you'll see terms like that.
06:11    You can think of C# objects as being a kind of stamping machine.
06:17    So classes, as I mentioned earlier, are used to create individual objects, and each
06:22    object that is created from a class is called an instance.
06:25    So you can think of this as some kind of machine that stamps out physical parts.
06:28    Suppose I had a class definition called person and the Person class had the name and age
06:33    and SayHello function.
06:35    Each time I made an object, that's called creating an instance of class person.
06:41    So here I've got three instances of the Person class.
06:44    I have got person A, B, and C, and each one of these real objects has actual data
06:49    that's filling out the class.
06:51    So we're using the class definition, or the blueprint, to actually make
06:55    instances of that class.
06:57    So why would you use classes and objects?
06:59    Well, using classes and objects, especially in C#, which is objected-oriented
07:03    language, really makes it easier to maintain and build applications.
07:07    First, it helps abstract ideas away from a specific implementation, which allows
07:12    you to focus on the core parts of the program.
07:15    Since the .NET framework provides a whole bunch of classes that cover common
07:19    areas of functionality that you don't have to write yourself, you can focus
07:22    on building the specific parts of your program that are only pertinent to
07:26    your business logic.
07:27    You can then reuse all the classes that .NET provides for you, which really makes
07:31    developing applications a lot faster and a lot easier.
07:34    Using classes and objects also helps encapsulate the programs functionality
07:38    into understandable pieces, because each object has its related data and logic
07:43    all kept in one place.
07:45    To go back to want to-do list item example, each to-do item would have not only
07:49    the information about that particular to-do item, but the logic that operates on it.
07:53    So you wouldn't have different pieces of logic scattered all over the place in
07:56    different locations without knowing where each one is.
07:59    It just makes it easy to understand the way that an application works.
08:03    It also helps organize a program into natural parts that could be easily
08:06    extended, and this is sometimes referred to in the object-oriented world as factoring.
08:11    Once you have factored your application into its natural parts, the object
08:15    itself and the program comes to mirror real-world constructs and ideas.
08:19    Again, taking a page from out to-do list example from earlier, when you make
08:23    objects that mirror real-world constructs like a to-do item and the to-do list and so on,
08:29    that makes the program a lot easier to understand and go back in and
08:31    maintain years later.
08:33    So using classes and objects is a really fast and easy way to build applications
08:38    that you can maintain in the future and other people can work on as well and get
08:41    up to speed on quickly.
08:43    So we reach the point now where we've completed our refresher into the world of
08:47    object-oriented programming, and we are going to spend the rest of this section
08:50    seeing how to define classes in C# and build our own object-oriented programs
08:56    in .NET and C#.
Collapse this transcript
Defining a class
00:00    Probably the best place to start when we define our own classes in C# is to see
00:04    how we define a class before we can start using them.
00:07    So we are going to take a look here at how to define a class using C#, and
00:11    then we are going to take a look at how to use it as we move through the rest of the section.
00:16    So to define a class in C# you use, surprise, the class keyword.
00:21    So you say the word class, and then you have to give it a name. In this case, I
00:25    am going to use myClass. And you can use whatever combination of letters and
00:30    numbers you want, as long as it starts with a letter and is a valid C# class
00:33    name--you can have special characters or anything like that.
00:36    So I've got class myClass, and then I am going to define some curly braces, which
00:41    are going to define the code for this class.
00:44    Once we have got the class definition laid out here, we can start adding some
00:49    fields and some methods.
00:51    You can add fields and methods in whatever order you like.
00:54    You can define field and then method and then field and then method if you want to.
00:58    My practice that I use is and I define all the fields upfront near the top, and
01:03    then I put all the methods at the bottom.
01:06    So let's define some fields.
01:07    I have got two fields here:
01:08    one is called myInteger; one is called myMessage.
01:11    We have got an integer and a string.
01:13    We could use whatever data types we'd like.
01:15    In this case, I have just got a couple for examples.
01:18    Then I am going to define a method.
01:20    And here I have defined a function called myFunction, or method--whatever word
01:25    you want to use--and it returns an integer.
01:28    In this case, it returns the myInteger field. So when the code that uses this
01:33    class calls myFunction, it will simply return the value of myInteger.
01:37    For the moment, don't pay too much attention to that word "public" that's in
01:41    front of the word "int."
01:42    We are going to get into what that means a little bit later in this section.
01:46    For now, just assume that the word public means we have to put it there so that
01:50    the rest of the world can see this function.
01:53    This is pretty much a complete class definition;
01:55    we could just stop here if we wanted to. But it's customary in C# to define
02:00    what's called a constructor.
02:01    A constructor function has the same name as the class.
02:06    So to define the constructor-- you can see I have done that here--
02:09    I've got a method call myClass, and in this case is this method is taking a
02:13    string argument which uses the value of the argument to set the initial value of
02:17    the myMessage member field. And again,
02:21    I have got the work public in front of it, and I don't want to pay too much
02:23    attention on that right now--we will get into that.
02:25    But what I have done here is defined what's called a constructor, and the
02:29    constructor takes the same name as the class itself. And you can give it however
02:34    many arguments you want, or you can give it no arguments at all.
02:37    Now, if you don't define a constructor, the C# .NET framework will automatically
02:42    put one in for you. But it is customary to define one, because you use
02:46    constructors all the time to initialize the value of class fields.
02:50    So now that we've done that, we can go ahead and take a look at how we might
02:54    create and use an object using a class that we've defined.
02:58    So in C#, the way that you create, or to use object-oriented terms instantiate, an
03:05    object is to use the keyword "new." And it's an operator,
03:08    so the way that you do this is use you use the type of myClass, and that's the
03:12    class that we defined earlier.
03:14    Then you give it a variable name, myObj.
03:16    So 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:25    got a variable called myObj, and then we simply say = new myClass.
03:30    And in this case we're passing in a string to the constructor function--
03:34    this is how the constructor gets called-- so that string will become the initial
03:38    value of that myMessage field.
03:41    To use the fields and methods of a class that you have instantiated, you use the dot operator.
03:46    And again, we've seen this throughout the course so far, but let's just make it official.
03:49    So let's imagine I have an integer called myResults and this is some variable I have created.
03:54    I can then refer to the methods or fields of the object by using the dot notation.
04:00    So in this case, I'm calling some imaginary function called AddNumbers on my object.
04:04    We haven't defined it yet, but we could. And you can see it takes two
04:07    arguments, and then it returns an integer result.
04:10    So use the dot operator to reference the fields and methods of the class.
04:14    Classes can also have special members called static members.
04:19    Static members don't require you to create, or instantiate, an object's instance
04:24    in order to use them.
04:26    That may sound kind of weird, but we've actually seen this throughout the course so far.
04:30    Every time we've used the console object, for example, you notice that we
04:34    haven't had to say "new console."
04:37    We simply use the name of the class, which is console, and then dot and then
04:41    the word WriteLine.
04:42    So we are calling what's called a static, in this case, a member method, called
04:47    WriteLine, and it belongs to the entire class.
04:50    You don't have to have it be part of a specific instance of that class.
04:55    So let's take a look at the difference between instance members and static members.
04:59    Instance members of a class--
05:01    whether it's a field or a method--get copied each time a new object is created.
05:07    Static members, however, belong to the entire class, and there is only one of them.
05:11    So let's take a look at an example.
05:13    Let's imagine we have a class that defines the notion of a bottle of wine.
05:17    For each bottle of wine, you are going to have something like a year and name
05:21    to go along with it, and you would have a constructor function that looks
05:25    something like this, where when you create a new instance of the wine bottle.
05:29    you will pass in the name and the year. But suppose we wanted to keep track of
05:33    how many bottles we had in our cellar.
05:35    Well, it seems a little silly for each instance of the wine class to keep track of
05:38    its own bottle count; we only need one variable to do that.
05:41    So we would have a static member called bottleCount. And in this case,
05:46    bottleCount belongs to the entire wine class, and each instance of the wine
05:50    bottle will be able to reference this member, but it doesn't belong to any one of them;
05:54    it belongs to the entire class.
05:56    So here in the constructor, we don't need to refer it to using the class name,
05:59    because we are in the constructor for the class. But if we're using code that
06:03    was outside the class--again, think back to the Console.WriteLine example--
06:08    we would simply put the name of the class in front of the function, and that
06:11    says to the C# compiler, hey, I'm calling the static member called this
06:15    function, or whatever it is--
06:17    in this case, its not a function at all; it's a member of variable--
06:20    and I am referring to the variable that belongs to the entire class.
06:24    So let's take a look at some code that makes all this work, and then it will
06:28    become a little bit clearer.
06:30    So over here in C# Express, I've got my DefiningAClass example open. I have
06:35    also got my ExampleSnippets.txt file open, and I've scroll down to the
06:39    DefiningAClass section.
06:40    So I am going to start off by copying some of this code over.
06:43    So we will copy over the class definitions, just a few of these lines right here.
06:48    And the nice thing about C# is you can put the code anywhere in the class file.
06:51    Now I could make a separate file to contain the wine class, but we will do that
06:55    a little bit later. For now in this example, I am going to have the two classes
06:58    be in the same file.
07:00    So now we have defined the class called myClass and we've got a couple of members here.
07:04    We have an integer and a string member, and you can see that we have declared
07:07    a static integer called myStaticInt. And again, don't worry about that public keyword for now;
07:12    we'll just get to that a little bit later.
07:14    Okay, let's go back over here, and let's copy over the functions, and we'll put those in the class.
07:27    So now we have a complete class definition.
07:30    We have our member variables;
07:32    we have a function called myFunction, which returns an integer--in this case,
07:36    it's the myInteger member; and we have the myClass Constructor.
07:40    When we call the myClass constructor, we're initializing the values of myInteger
07:44    and myMessage to some initial values.
07:47    And we also have the myStaticInt, which is being initialized to the value of 100.
07:52    So now let's copy some code over that actually exercises the class and see what happens.
07:58    I will just copy these lines right here, scroll down to the main function and put them in.
08:11    So let's take a look at the code and see what's happening.
08:16    The first thing that we are doing right here on line 30 is we are instantiating
08:20    a new instance of the myClass object, and once we've done that, we can then use
08:26    the various members of the class.
08:29    So on line 32, you can see that we are using the console to write out the
08:33    results of myFunction. And in this case, we are using the instance, which is the
08:38    myC variable, to call the myFunction member function. And in the next line, line
08:43    33, we are going to use the static member. But instead of using the myC
08:47    variable, we are going to use the myClass name, because it's a static member, and
08:52    we need to refer to it on the class name itself.
08:55    So we are going to go ahead and build and run this, and what we should see is the
08:59    result of calling myFunction. Let's just scroll back up here.
09:03    So myFunction is going to return myInteger, which you can see on line 21 is being
09:08    initialized to 50, and then we have the value of myStaticInt, which is 100.
09:12    So let's go ahead and run this, and you can see that the results of calling
09:16    myFunction is 50 and using the static member is 100.
09:20    Let's go back to the code.
09:22    Using this example, you can see how we have defined member variables which are
09:27    both local to the instance of an object and the static member which belongs to
09:31    the entire class, and we've seen how to define and instantiate a new class
09:36    using the new operator.
09:37    As we move through the rest of the course, we will be doing a lot more of this.
Collapse this transcript
Using access modifiers
00:00    The C# language provides a feature called access modifiers, which allow you to
00:05    control how the member variables and methods of your classes are seen by the
00:10    outside world--in others words code that uses your objects.
00:14    And if you're coming for the language, like Java or C++, you've probably
00:18    seen something similar.
00:19    JavaScript does not have this kind of idea in it, so if you're coming from
00:24    JavaScript, you might want to pay attention to this.
00:26    So by default when you define data and methods in your class, those data fields
00:32    and methods can only be used inside of that class itself.
00:36    You have to choose to expose them to other code that's going to consume your classes,
00:42    and this is what access modifiers let you do.
00:44    They let you specify how programs-- including your own--that use your classes can
00:49    access their data and their methods.
00:52    So let's take a look at how this works.
00:54    Suppose we had a class and I have a class here called myClassName, and we've
00:59    got some fields in it.
01:00    So we have got an integer, and we've got a string, and we have some method called myFunction.
01:05    By default, all of these are what's called private. Only the class that
01:10    defines these can use it.
01:13    We need to change that in order for code that wants to consume our class to be
01:17    able to access the members of this class.
01:21    The way that we do that is by using what's called access modifiers.
01:24    And if you watch the preceding the movie, you'll have probably noticed me
01:28    using the word "public."
01:29    Well, there are a couple of different ways to expose members of the class to
01:33    code that wants to use them.
01:34    So let's take a look. The first one is called the private modifier.
01:39    When you use the private access modifier, it means that the member of the class
01:44    who is marked as private can only be accessed within the class itself.
01:48    Now this is the default setting, so if you don't specify private, the C# compiler
01:54    defaults to making a member variable or a member method as private.
02:01    The next one is public. A public class member can be accessed by any other
02:07    object that uses the class, and this is why I was using the public keyword in
02:11    the previous examples so that our code can consume that particular member of the class.
02:17    The next one is called protected.
02:20    A protected class member can only be accessed within this class or any subclass--
02:26    in other words a class that inherits from this class.
02:30    So we have got private, we have got public, and we have got protected.
02:33    So there is one more, and it's called internal, and this is a class member that
02:37    could be accessed by any class in what's called a same assembly. An assembly
02:42    is a package of code, like a library or another program, but this is an advanced feature of
02:47    C#. I am not going to cover it here in this course. Just know that you might see
02:51    the word "internal" every now and then.
02:53    It's sort of like protected, but it means that only a group of related code
02:57    can use it. But for the purpose of this course we are going to use private,
03:00    public, and protected.
03:02    So in order to see how his work, let's jump over to the code and define a class
03:07    that uses these, and you can see what happens when you try to use code that uses
03:10    each one of these access modifiers.
03:12    So over here in the code I have got my ExampleSnippets open for the
03:16    access modifiers example, and over here I have got my program file.
03:21    So here is what we are going to do. First, we are going to define a new class, and
03:24    in this case we are going to put the class in a separate file.
03:27    So what I am going to do over here is I am going to right-click on the project
03:31    name called AccessModifiers, and I am going to go down to the Add submenu, and you
03:36    can see that I can add items to my project.
03:38    What I am going to do is I am going to add a class, and the Add class
03:42    dialog comes up. And you can see there is a whole bunch of things that we can
03:45    add, all kinds of classes.
03:46    What I am going to do is just make sure that the default one here in the list
03:49    called Class is selected, and then I am going to give my class a name. And in
03:53    this case I am going to call it my Wine class. I'm going to click Add,
03:59    and you can see that the file for Wine.cs got added, and you can see that the C#
04:07    Express application has done a whole bunch to work for us. First of all, it's
04:10    automatically put the Wine class into the same namespace as our example.
04:13    It's included the using statements for the .NET framework that we are going be
04:17    using. And right here you can see it has provide a definition for class Wine.
04:21    So let's go back to Snippets.
04:22    What we are going to do now is fill out that wine class with some default code.
04:29    So I am going to copy these lines here.
04:31    I will go back to my Wine class, and I am going to paste them in.
04:35    So now in our Wine class we have a couple of different members.
04:38    We have the wine name,
04:40    we have the wine price, and we have the wine description. And you can see that all
04:43    of those are public,
04:44    so any code that wants to use this Wine class will have access to those member variables.
04:50    We have a decimal variable here called discount, and that's marked as private.
04:56    So nobody outside this class can see what that is. And then we have a public
05:00    constructor, which takes a wine name and a price. And inside the constructor you
05:05    can see that we've got the name and price public variables that are being set to
05:10    the arguments that are being passed to the constructor, and then we give the
05:13    discount variable and initial value as well.
05:16    And we can do that here because this is our class and we can refer to our own
05:21    private members within our own class.
05:23    So let me save this, and let's go back to the snippets.
05:28    Now let's go ahead and copy over some code.
05:30    I want to copy these two lines first, and we are going to go to the main function,
05:33    and I am going to paste tem in.
05:35    So here you can see that I have got two instances of the Wine class being
05:40    created, and I am passing in some default values for names and prices.
05:44    So let's write some code now that exercises some of the fields of the class.
05:48    So for example, if I wanted to refer it to the name of one of the wines, I
05:52    could simply write string and give it a variable name, =, and I could say w1.
05:57    And now watch what happens when I press dot.
05:59    Now when I press the dot, C# Express is looking at the class description and
06:03    saying, okay, what can the code in this particular area see inside that class?
06:08    And we have got a couple of default things, because we always derive from the
06:11    base system object, but here's the name and the price fields that I've defined.
06:16    Here is the description field, because those were all public, and you can see that
06:19    this is an alphabetized list. What's missing? Well, the discount field is missing. Why?
06:24    Because it's private, and because it's private, my code can't see it.
06:28    So I can go ahead and refer it w1.Name all I want to, but if I try to refer to
06:33    the discount field--let me make a decimal and we'll call it dsc--
06:38    if I say w2.discount, now watch what happens. I am going to save this. See, that
06:45    little red squiggle showed up and if we mouse over that little squiggle, we say
06:49    error. It says the AccessModifiers. Wine.discount is inaccessible due to its
06:54    protection level. Go back over to the wine code.
06:57    You can see that this is private, so private members can't be referred to
07:01    outside of the class that defines them.
07:04    Now we could also have made it protected, and protected would also result in an
07:08    error, so let's just change that.
07:09    Let's just make this private and make this protected, and we will save, and we
07:14    will go back over to the program, save and compile. And you can see that we still
07:19    have that same error there, right, even though we made it protected, because in
07:22    this case we don't have a class that descends from wine, so it's not inheriting
07:28    the discount field, and because its protected, only subclasses can see it.
07:32    So this is how you use the various access modifiers of C# to selectively expose
07:39    member variables and member functions to code that's going to consume their
07:42    objects. And the reason you want to do this is because in good programming
07:46    practices, you don't want to just make everything public.
07:48    You want choose how you expose your code to consumers of your code. That way you
07:53    can change the way things are implemented inside your class without breaking
07:57    people that are consuming the class in other programs.
08:00    So using access modifiers, you can selectively expose parts of your program
08:05    to other consumers.
Collapse this transcript
Defining properties
00:00    Okay, I promised you we would get to some really cool features of C#, and we're
00:04    about to do that right here with defining properties.
00:05    Properties are a really neat feature of the C# language, and I really like using them.
00:11    In this section, we're going to explore what they are and how they work.
00:13    Properties are essentially like data fields, but they have logic behind them.
00:18    And from the outside, they look like any other member variable, but they act
00:23    like a member function.
00:25    They actually have code behind them.
00:26    Now you define them like you would a member variable, but they have a get and a
00:32    set section of code added.
00:34    And they can use access modifiers just like member fields and member methods can,
00:40    and we explored those earlier.
00:43    Let's take a look at an example of what a property looks like.
00:47    So let's imagine we had a class called myExample and we had some private member
00:50    variable called someValue.
00:52    Now because this is private, there is no way for someone who's consuming this
00:57    class to get at that data.
00:59    Now we could make it public, which exposes the implementation of the class to the
01:04    outside world, which is not a very good programming practice.
01:06    You really want to keep the inner workings of your class private and then choose
01:10    to selectively expose data.
01:12    We could also just make a member function, which would allow an external consumer
01:17    of this class to get the value and set the value.
01:19    Or we could make what's called a property.
01:22    A property is defined like this. I'm making a public integer property called
01:28    CurrentValue, and instead of making it look like a member of function with
01:33    parentheses and arguments and so on, all I have to do is define the name of
01:38    the property with two curly braces and inside I put the word get. And
01:43    the word get here is essentially going to return the value of that private
01:48    integer that I have.
01:49    And then to set this value, I have the word set.
01:53    And in the set code, I'm setting the internal someVal property to this word value.
02:00    And value is implicit.
02:01    C# just simply generates that for you.
02:03    Let's see how this actually works when you consume this.
02:06    So to do this, I would define myEX variable, which is an instance of the
02:11    myExample class. And I'm creating a new myExample object there.
02:15    If I wanted to get the value, I would just do this.
02:17    I have an integer i, and I say myEX.CurrentValue.
02:22    That will trigger the get logic.
02:24    And in this case, the get logic is pretty simple.
02:26    It's returning the value of that internal private variable.
02:29    And if I wanted to set it, I would do this:
02:31    myEX.CurrentValue = 5, and that will trigger the set logic.
02:35    And the value of that special value keyword there in the set logic would be set
02:40    to an integer whose value is 5.
02:43    The C# language and .NET just takes care of all that for you.
02:46    You don't have to declare some argument called value;
02:48    it just magically shows up.
02:51    So you can have automatic properties.
02:54    Let's suppose, for example, I had my class, which I declared up above in the
02:58    previous example. So I've got myExample class here with my private someVal int,
03:02    and I've got the get and the set.
03:04    Since all that this example is doing is getting and setting the value of that
03:09    private internal variable,
03:10    I can rewrite this very simply, just like this.
03:14    I have my class, and then I have my property, and all I do is have the words get
03:19    and set, and that's all I need to do.
03:21    This is called an automatic property.
03:25    You can also have read-only properties, and you can have write-only properties.
03:29    Read-only properties and write-only properties are properties that can only be
03:31    read and can only be written.
03:33    So let's take a look at an example.
03:35    Using the same example we've been using up until now, I have my example class
03:38    with my private variable. And inside my public int CurrentValue, I have get
03:44    and return someVal.
03:45    Now if I don't define a set, then the property is read-only because there is no way to set it.
03:50    All I can do is get the property.
03:52    Alternately, I can define just a set.
03:55    If I don't define a get, then the property is write-only.
03:59    You'll very rarely see write-only properties.
04:01    Properties are pretty useless
04:02    if you can't actually get their value.
04:04    But you can do this.
04:05    So if you don't define a get, or you don't define a set, then the property is
04:09    either read-only or write-only.
04:12    All of this is pretty fun, but why would you use properties? A couple of reasons.
04:16    First, properties can be calculated on the fly.
04:19    So if you wanted to expose a property that looks like a member variable but has
04:24    some logic behind it that actually gets calculated on the fly whenever it gets
04:27    accessed, read, or set, then you can use a property for that.
04:31    Properties also provide complete control over the data field access, because the
04:35    logic is hidden from the object's consumer.
04:38    The consumer of the object's property doesn't need to know how it's calculated,
04:41    or what's being calculated.
04:42    And if later on down the line you go back and you change the way this object
04:46    works and the way that that property is calculated changes, then the people who
04:51    are consuming your object don't need to worry about that.
04:52    They just simply go ahead and keep on referring to that property, but the logic can change.
04:58    Properties also promote the idea of encapsulation.
05:01    We've talked about this a couple times before in this course.
05:03    What you're doing is you're taking the logic that implements that property and
05:06    you're hiding it from the consumer.
05:08    So they don't need to worry about how it works.
05:11    Let's take a look at an example of how you'd have a property whose value is
05:14    calculated on the fly.
05:16    Let's imagine I had a class that represented a wine, and in that class, I have a price.
05:23    I could define the price as just a public member variable, like I've done here.
05:28    And I've got some private ones, like say that there is a wholesalePrice and
05:32    there is a retailMarkup.
05:33    So when a wine store buys wine, they don't pay the retail.
05:36    There is a wholesale price they pay, and then there is a markup that they apply
05:40    to the wholesale price which is what the real price is.
05:43    So rather than having a public member variable, I could expose a public property.
05:48    And you can see here I've only defined a get;
05:51    there is no set here.
05:53    And when the consumer of this Wine object wants to know what the price of the
05:56    wine is, you can see that the logic inside the getter is simply multiplying the
06:01    wholesalePrice times whatever the retailMarkup is.
06:04    So I can have some code that goes out and figures out what my retail markup is
06:08    based on some other parameters I've got in my business,
06:10    and the consumer of this Wine class has no idea how or why I'm doing that.
06:15    They just simply ask what the retail price is by accessing the property and it's
06:19    calculated for them on the fly.
06:21    Let's jump over to the code and define some properties in one of our classes
06:24    and see how this works.
06:26    I'm here in my DefiningProperties example, and I've got my ExampleSnippets open
06:32    right here. And I've scrolled down to the Properties section, and I've got a Wine class here.
06:38    So what I'm going to do is go back over to the program code, and I'm going to
06:42    make a separate class file for my Wine class. And this just promotes the idea of
06:46    encapsulation. And we've already done this once before, but if you skipped over
06:49    that part, or you need a refresher, just follow along.
06:51    So I'm going to right-click on the project name, and I'm going to click Add, and
06:56    then at the bottom of the Add menu, I'm going to add a class. And I'm going to
06:59    call this my Wine class.
07:00    First, I'm going to make sure that the Class option is selected there,
07:04    and then I'm going to come down here and type in Wine.cs, and I'm going to add that.
07:11    Visual C# Express has made a new Wine class for me.
07:14    Let's go back over to the Snippets, and let's just copy this class in its entirety over.
07:23    Copy this into the Wine class, and let's save that.
07:29    So now we have our Wine class defined.
07:31    Let's go back over to the program, and let's copy in some other code from the
07:35    Snippets, which is right here.
07:43    First, let's just copy these few lines, and we can explain what's going on.
07:51    Let's take a look at the Wine class to see what we've done, before we go any further.
07:56    Here is my custom-built object.
07:57    It's a class that encapsulates the notion of a wine bottle. And you can see I've
08:02    got several private members here.
08:05    And because they're private, code that is not inside this class can't see them. So I have a Name.
08:10    I have a Year.
08:11    I have an appellation, which in the wine world is where the wine comes from.
08:15    I have a wholesalePrice, and then I have a retailMarkup of 1.35, so I've got 35%
08:20    markup on whatever wine I buy.
08:23    Then I've got a property called Price, and you can see that the price is
08:27    being calculated on the fly by multiplying whatever the wholesalePrice is
08:30    times the retailMarkup. And in the setter case, I'm setting the
08:34    wholesalePrice to the value.
08:36    So I'm not actually setting an internal price variable;
08:39    I'm just setting the wholesalePrice which would have been calculated by the retailMarkup.
08:44    I also have a property which is a string called the menuDescription.
08:47    And if you've ever been in a restaurant, you've probably seen this. Wines are
08:50    usually described on wine lists as having the year, followed by the name, and
08:54    sometimes where they've come from.
08:56    So I've got a string property that's being built up on the fly right here from
09:00    the private internal properties that I have.
09:02    And then I have my public constructor, and the constructor is what creates a new
09:07    instance of the Wine object.
09:09    And it's just taking a bunch of arguments and setting them into the private
09:13    internal member variables.
09:14    So let's go back over to the program, and you can see here that I'm instantiating
09:19    a couple of instances of the Wine class.
09:21    I've got a year for each one, I've got a name, and then I've got a string that
09:25    explains what the origin is, and then I have a wholesale price which is going to
09:30    be used to calculate the retail price.
09:32    So let's go back over to the Snippets.
09:34    Let's do some exercising here.
09:35    We're going to write out some of these property values.
09:37    I'm going to just copy these lines of code right here.
09:39    I'm going to go back over and paste them in.
09:44    In the first case, I'm going to write out the menuDescription and the Price of the two wines.
09:52    So I've got Wine 1 and Wine 2.
09:53    And remember, back in the Wine class, each one of these properties is
09:57    being built on the fly.
09:58    So I'm going to save, I'm going to build, and I'm going to run this.
10:04    And you can see that I've got Wine 1 is a 2003 Chateau Ste.
10:07    Michelle Merlot, from Seven Hills, and it's $31.72. And then I've got a
10:12    Mark Ryan Dissident that's from Ciel du Cheval, and that's $54.
10:16    But remember, those aren't the numbers that I put into the constructor.
10:19    If you look at the constructor, I've got 23.50 and 40.
10:22    The reason why those numbers are coming back differently is because--let's go
10:25    back over to the Wine class--is because of this logic right here on line 20.
10:31    On line 20, I'm taking the retailMarkup and multiplying it by
10:34    the wholesalePrice.
10:35    But from the point of view of the code's consumer--let's go back to the program--
10:39    you can see all I'm doing is accessing this Price property.
10:41    I don't have any knowledge of how that's being generated behind the scenes.
10:45    Let's go ahead and change the wholesalePrice of one of the wines using the
10:48    setter, and then we'll write out the new price. Paste that in here.
10:57    What we're doing now is using the setter logic of the Price property.
11:01    Here I'm changing the wholesalePrice of Wine 2 to $45,
11:06    and then I'm going to write out the wine description, and notice how the retail
11:10    price has automatically changed because of that calculation logic.
11:14    So I'm going to just run this.
11:16    And you can see that in the first case
11:18    it's $54, but because of the price that I set here in the setter, the new retail
11:24    price is being calculated as $60.75.
11:26    Okay, let's go back to the code.
11:29    The reason why I use properties is because you want to encapsulate some logic
11:33    inside your class, give it the appearance of a member variable, but it has logic
11:38    behind it that determines how that property is calculated on the fly.
11:42    And you can use this technique to expose private internal data in your class in
11:46    a controlled fashion, and you can get really creative with this.
11:50    Suppose, for example, I wanted to log every time somebody changed the
11:54    wholesale price of a wine.
11:56    Well, here in the setter logic, I could just simply add some code that would
12:00    write out to a log file when the price was changed. Or let's suppose I wanted
12:04    to use my debugger to set a breakpoint on whenever a value of the property was changed.
12:10    You can't do that on a private internal variable, but you can do it on a property.
12:14    So properties are really versatile, and they make your code a lot easier to
12:17    encapsulate and expose and make consumers use the classes in a way you feel best
12:21    they should be used.
Collapse this transcript
Understanding value and reference types
00:00    Now that we've learned how to create our own classes in C#, we've come to an
00:04    important point in the course where we need to learn the difference between
00:07    value types and reference types.
00:09    C# has two main types:
00:11    there's value types and there's reference types.
00:14    Value types are all of the primitive types that we've learned about so far,
00:19    things like integers and longs and shorts and decimals and chars and
00:23    booleans and so on.
00:24    And there's also a thing called struct, which we haven't covered yet, but we
00:28    will cover later on in the course.
00:30    Anyway, those are the value types.
00:32    Reference types are classes, arrays, and a couple of things called delegates and
00:37    interfaces which, again, we haven't yet covered, but we will cover later.
00:41    So why is there this difference, and what's so important about it?
00:45    The main difference between value types and reference types is how they
00:49    are handled in memory.
00:51    And the best way to learn this is to see an example.
00:54    So we're going to compare the value types with the reference types.
00:57    Now, for a value type, let's take a really simple example.
01:00    Let's suppose I have a variable i and I declare it as an integer and I set its value to 5.
01:06    Now, when I do that, the C# compiler goes out in memory and makes a little box
01:09    called i and it puts the value 5 in it.
01:12    If I declare another variable called j and I set it equal to i, then the
01:17    compiler sets aside another little box, and this little box is called j, and it
01:20    also gets the same value as i, which is 5.
01:24    Now, the important thing to remember here is that j is a copy of the value
01:28    that's stored in i right now.
01:30    So if I go back and change the value of i to 3, the value of i gets changed,
01:35    but the value of j does not get changed, because these are different memory locations.
01:39    Now, let's compare that with how reference types works.
01:42    So suppose I made a class called Point,
01:45    and inside my Point class I had two integer member variables
01:49    X and Y, which represent the coordinates of the point.
01:53    To create a new Point, I would declare a Point class variable named P1, and I
01:59    would use the new operator to create a new instance of the Point object.
02:03    Then I could do something.
02:04    Now since these are public member variables, I could say P1.X and P1.Y are equal to 10.
02:11    Let's watch what happens in memory.
02:12    Well, in memory, that little location called P1 for the variable gets created,
02:17    but what also gets created is a set of bytes somewhere else in memory that
02:21    actually hold the member variables.
02:23    And P1 is not actually containing that data.
02:27    It contains a reference to that data.
02:30    There's this little reference that goes out into memory and knows where X and Y are stored.
02:35    So let's suppose I made another variable called point P2.
02:39    And rather than doing new Point, I say point P2 = P1.
02:44    Well, that creates a little local variable there called P2.
02:47    But watch what happens.
02:48    The reference gets set to the same reference as P1.
02:52    They're sharing the same reference to the same location in memory, because I
02:57    didn't make a new instance of Point; I simply set P2 to be equal to P1.
03:02    And when you do that with a reference type, you're sharing the same reference.
03:05    What does that mean?
03:06    Well, if I then do something like this where I set P1.X =20, it changes for the both of them.
03:12    So even though I didn't do anything to mess with P2, P2.X is now having the
03:17    value of 20, the same way that P1.X is.
03:20    This is an interesting side effect of how reference types works, and you need to
03:24    watch out for it in your code.
03:25    Let's go over to the code environment and take a deeper look at this.
03:29    So I'm here in my ValAndRefTypes example file, and I've got the Program.cs file
03:35    open, and I've got my Snippets here.
03:37    So what I'm going to do is back here in my code, I'm going to put some code in
03:41    here that exercises both the reference and value types that we saw earlier.
03:47    So let's go back over here.
03:48    What I'm going to do is copy this line right here, which is the Point
03:51    definition, put it into my file over here.
03:54    I'll just put right in front of the Program class. I'll save that.
03:57    And then I'm going to copy over this function right here called testFunc1.
04:03    And this is the first test that we'll run. So I'm going to copy that.
04:06    I'm going to put that in my program down here.
04:10    So now let's copy over some of the logic to see what's happening.
04:13    Go back to my Snippets.
04:15    I'm going to scroll down a little bit, copy these few lines right here, starting
04:20    with this variable and down through this WriteLine.
04:22    I'm going to copy that and paste it into my Main.
04:27    So let's take a look at the code that we have here.
04:30    We'll use point a little bit.
04:31    I just want to make sure we have it in place.
04:32    For now, I'm just going to concentrate on this code right here.
04:35    In my Main function I've got a variable called i, and I'm setting it to be the value of 10.
04:40    And then I call this function, testFunc1, with the i variable.
04:43    So let's scroll down and see what testFunc1 is.
04:47    You can see it takes an integer argument.
04:49    And the first thing it does is it adds 10 to the argument that's passed into the function.
04:56    When this Console.WriteLine gets executed, it's going to write out the value
05:00    of whatever arg1 is.
05:02    And then when the function completes and goes back up, we're going to write out
05:05    whatever the value of i is.
05:07    Go ahead and place your wagers and let's see what happens.
05:11    Build this, and we're going to run it.
05:13    So you can see that what happened was we passed the 10 into the function, and
05:19    arg1 was set to 10, but then we added 10 to it, so now it's 20.
05:23    But when we come back out of the function, the original variable i is unchanged.
05:27    It's still 10, even though we added 10 to it inside the function.
05:31    So let's go back and take a look at the code.
05:33    The reason why this works is because for primitive value types, like
05:36    integers, when you call a function and you pass in the value as an argument to the function,
05:42    it is passed as a copy.
05:44    When you pass value types, you pass a copy of their original values.
05:50    So even though we changed the value in here on line 29, since we're passing in
05:54    a copy of the local i variable from Main, we're not actually changing the i variable;
06:00    we're only changing the local copy that testFunc1 is working with.
06:04    Let's go back and copy in the rest of our code.
06:09    And I'm going to copy in these lines here, put them in my Main function.
06:19    And I need to copy over my other test function, which is this one right over here.
06:27    And I'll put that down below here, and now we'll save everything.
06:33    Now, let's go ahead and run our next test. And for this I'm going to get rid of
06:36    these lines of code because we don't need them.
06:39    So here I'm using the Point class, which I've defined up above my Main.
06:43    Here's the Point class. It's got an x and a y value.
06:46    So on line 19, I'm creating a new point, and I set p.x and p.y to both be 10.
06:52    Then here on line 22 I write out the value of the X property. Then I call this
06:58    testFunc2 with p--that's the point-- and then I write out p.x again.
07:04    Let's see what testFunc2 is doing.
07:06    Well, testFunc2 takes a Point argument, as you'd expect,
07:10    it writes out the value of pt.x, then it adds 10 to the value, and then it
07:14    writes out pt.x again.
07:16    So we're going to write out four things here.
07:19    We're going to write out the value of the Point's x field, both inside the test
07:22    function and outside the test function.
07:24    So let's go ahead and compile this and run it.
07:27    And you can see that before we call the function, the value of p.x is 10.
07:32    Then we go into the function and pt-- that's the local variable inside
07:36    that function--is 10.
07:38    Then we add 10 to it, which gives us the value of 20, and we write that out.
07:41    So inside the function, pt.x has been changed to 20.
07:44    Then we exit the function and go back into Main and you can see that the value
07:48    of p.x has been changed to 20.
07:50    So in this case the value was changed. Let's go see why.
07:55    Remember that Point is a class,
07:59    and the class was one of those things that we looked at earlier was a reference type.
08:04    So when you make a new point like this here on line 19, and then you pass
08:08    it into a function,
08:09    you're not passing a copy; you're now passing it by reference.
08:14    And because testFunc2 has a reference to the original point, if you change it
08:19    inside the function, it will change outside the function as well.
08:23    This is the fundamental difference between value types and reference types, and
08:27    it's something you'll come across in C# on a regular basis.
Collapse this transcript
6. Collections
Working with arrays
00:01    In this section, we're going to cover some of the data structures that .NET
00:06    provides for you, and specifically we're going to focus on collections.
00:10    Collections are essentially classes that help you keep track of and manage a
00:14    whole bunch of data, and since a lot of programming involves keeping track and
00:19    managing data, it seems like this is a pretty good place to start.
00:23    We're going to start off by looking at C# arrays.
00:26    Now in C#, arrays hold a fixed number of elements, all of the same type.
00:32    An array is basically just a list of items and values.
00:37    So for example, if I declared an integer variable called oneValue and set it to
00:42    be equal to 100, we've already seen this. Somewhere out in memory the C# compiler
00:47    and the .NET framework creates a little box called oneValue and puts the value
00:52    inside that little variable box.
00:54    Now an array is a little bit different than that, and the way you declare them as a
00:58    variable is also a little bit different.
01:00    When you declare an array you specify the type that you want the array to hold,
01:05    so here it's an integer just like always, but then you put these two square
01:08    little brackets next to the type definition.
01:11    So you have the opening square bracket and the closing square bracket with
01:15    nothing in it, and then you give it the variable name, just as you always would.
01:19    And this just tells the Compiler, hey,
01:20    we're not declaring one integer.
01:22    We're declaring a whole bunch of integers.
01:24    And then you complete the sentence by saying = new and then the type that
01:29    you're creating, in this case an integer, and then inside the square brackets you
01:33    put the number of slots that you want to create.
01:36    So this line of code right here int, square brackets, manyValues creates a variable called
01:42    manyValues, which is an array of, in this case, four integers.
01:46    And out in memory what's going to happen is the .NET framework is going to
01:50    create some space and it's going to create a variable called manyValues and
01:53    there will be four little boxes all initialized to 0.
01:57    The .NET framework takes care of initializing the array for you so that they are all 0.
02:01    Now arrays are zero-based indexes. So that first element in the array there is not element 1;
02:07    it's actually element 0, and it counts up from 0 up to 3.
02:10    So there are four elements, but it goes from 0-3.
02:13    So if I wanted to reference one of the elements in the array, I would simply
02:17    use manyValues and then inside the square brackets the index number of the one I want to change.
02:22    So if I wanted to change the first element in the array to a value of 100, I
02:25    would say manyValues, subzero, =100, and lo and behold, the value changes.
02:30    If I wanted to change the last one, I would do manyValues and then 3 in the
02:34    square brackets and that works.
02:37    Just like other variables in C#, I can also initialize array variables just like
02:42    I can initialize other variable types.
02:44    So in this case, I'm declaring an integer array called manyValues and rather
02:49    than creating the new memory using the new operator, I'm using curly braces and
02:53    then just putting the array values inside the curly braces, separated by commas.
02:57    This will create an array of four integers, just like we saw in the previous example.
03:02    And of course, I can do this with strings too.
03:04    I can say string array myStrings = and then inside the curly braces just four strings.
03:09    One of the cool things about C# is that unlike other languages, like say
03:12    Objective-C, C# provides what's called automatic bounds checking for arrays.
03:17    So in programming, if you try to reference an array index that's outside of the
03:22    bounds, or the size of the array, some languages don't check that for you and it
03:26    can lead to code problems and bugs down the road.
03:29    But in C# if I tried to do this, manyValues and then 100 inside the little
03:34    brackets as an index, if I try to set that value, that's going to cause an error. Why?
03:38    Because there is only four elements inside the manyValues array, so there is no
03:43    element 100, and that's going to cause a problem.
03:45    The good news is, C# catches that for you.
03:48    Now arrays are fixed in size.
03:50    Once you declare them, that's just how big they are.
03:52    There are other data structures that we'll get to that allow you to change
03:56    the size of the array, but when you declare arrays like this, that's just how big they are.
04:00    Why? Because this allows them to be contiguous somewhere in the computer's memory,
04:04    which is very efficient for the processor to access and change them.
04:09    The other thing you need to realize is that array elements are all the same type,
04:12    so you can't have an array to clear like you see it here that has numbers and
04:16    strings and floats and different data types.
04:18    When you declare an array using either int brackets or string brackets or float brackets or whatever,
04:24    choose your data type brackets, they're all going to be the same type.
04:28    Arrays can also be multidimensional.
04:31    Now in the previous example we saw a single dimensional array.
04:34    It was just one list of numbers. But you can make arrays multidimensional, and
04:38    the way that you do that is you declare the type, so for this case, integer.
04:41    Then inside the brackets you put a little comma.
04:43    This is going to have two dimensions.
04:45    It'll have the name of the variable called multiDimArray. Inn this case I'm saying new int and 3,3.
04:50    So that's going to make a 3x3 matrix of memory locations somewhere out in the
04:56    computer's memory, and it's going to initialize them all to 0.
04:59    And then to round out the picture here, the first number in the index there is
05:04    going to represent the row number, and the second number in the index
05:07    represents the column number.
05:08    So if I wanted to refer to a specific box inside the memory of the array here, I
05:14    would say something like multiDimArray, 0,1, = 10.
05:18    That means row 0, column 1 and that's the one that gets changed to a 10;
05:22    and just like other arrays, you can initialize these too.
05:25    So to do that, I would have the int, the type declaration, along with my little
05:30    brackets with the comma inside, and then I would just give the variable a name.
05:33    And in this case I have new int, comma, withinside the curly braces a set of curly
05:39    braces, each one representing a row of data.
05:42    This would create a 3x3 array with all of the boxes set to (0,1,2), (3,4,5), (6,7,8).
05:50    So you can initialize them and you can make multidimensional arrays with set values.
05:56    Now arrays, of course, are, just like everything else in C#, objects.
06:00    So, for example, if I had this declaration here for int manyValues = 100, 200
06:06    and so on, that gives me an array object with four entries in it.
06:11    So I can then do something like this.
06:13    I can say manyValues.
06:15    and then call a function called GetLength(), and that will come back with a
06:18    number four, because how many there are.
06:20    I can also call some static member functions. Remember, we talked about
06:23    static items earlier on.
06:25    I can do Array.Clear and then give it the name of the array and a couple of indexes.
06:30    Then starting at 0, it'll clear out the four elements.
06:33    I can do Array.Sort.
06:35    It will sort the given array, assuming that the members of the array are sortable.
06:39    Same thing with Reverse.
06:41    I can just reverse the given array.
06:43    Because arrays are objects, you get access to a whole bunch of built-in features.
06:47    So let's exercise some of these features.
06:48    Okay, here in the code I've got my Arrays example open, and I've got my Snippets
06:54    here. Scroll down to Arrays, and here's my program code.
06:57    So let's just go ahead and copy some of these over.
06:59    I'm going to do the first couple of lines right here, and we'll paste that in.
07:04    And here what we're doing is we're just declaring an array called manyValues
07:07    that has a whole bunch of values in it, and then we're going to write out the
07:10    value of the fourth number.
07:12    And remember, to do that, since this is the fourth number and it's a 0-based index,
07:15    we use the number 3, and set right here on line 13.
07:18    So let's hit F5 to run this, and the fourth number is 34.
07:22    Okay, that's pretty simple and straightforward. Let's keep on going.
07:25    In this case, we'll do the same thing with strings.
07:29    So here I have an array of strings.
07:31    I've got four strings: Joe, Marini, Teaches, C#.
07:34    And what I'm going to do here is use a for loop to write out the values of each
07:38    one of the elements.
07:39    So I have a for loop going from 0, and notice I'm using <4 here, not < or =,
07:45    because it has to stop at 3.
07:46    I'm going to write out each one of the strings using the i variable here to
07:52    index into the array.
07:53    So once again I'll hit F5, and you can see that works just fine.
07:57    Okay, so let's keep on going because this is getting interesting.
08:00    Let's go back over here.
08:02    We'll copy and paste this and put that down here.
08:06    So here you can see that I've created an integer array called otherValues and
08:10    I've set it equal to manyValues, and now I'm changing the last item in the
08:16    otherValues array to 0.
08:17    But what I'm writing out over here is the manyValues array, or at least the last
08:23    element of the manyValues array.
08:25    Now see if you can guess what's going to happen.
08:28    If we look at the item here, you can see that manyValues(3) is 0, 1, 2,
08:31    3; it's currently 34.
08:34    Let's see what happens when we change the otherValues array or sub three to zero.
08:38    I get it set to 0. Why?
08:40    Because remember arrays are reference types.
08:43    We passed in a reference to the array; therefore we actually changed the value of
08:48    both manyValues and otherValues.
08:50    And if you skipped the section earlier on value types versus reference types,
08:54    you should go back and review it now.
08:55    Let's try something else. Let's try some sorting.
08:57    I am going to copy this.
08:58    I'm going to paste it over here.
09:02    So now I'm calling the array class's Sort static member function on
09:08    my manyValues array.
09:09    And when I do that, we're going to write out what the fourth number is.
09:12    So let's go ahead and build that, and you can see that the fourth number is 16.
09:18    So we sorted the array going from smallest to largest, and that's a
09:22    built-in feature of .NET.
09:24    Arrays are really useful collection objects to use in C#.
09:27    You will find yourself using arrays for all kinds of things.
09:30    Arrays are used for processing lists of information and so on. What we'll take a
09:34    look at next is a collection type called ArrayList, which has some added
09:37    benefits on top of arrays themselves.
Collapse this transcript
Using array lists
00:00    All right. The next collection class that I am going to cover here is ArrayLists.
00:05    Now ArrayLists are like arrays, but there are a couple of unique features to them.
00:10    First, they can be dynamically resized as needed.
00:13    Recall from the previous movie that arrays are set in size once you create them;
00:18    ArrayLists aren't like that.
00:19    Now the way you create an ArrayList is by using the ArrayList class. And here
00:25    I've got an ArrayList with a variable named myAL, and I just say new ArrayList.
00:31    And we'll see how to do this in a bit in the code.
00:34    You have to include another namespace in order to use these, but the class name is ArrayList.
00:39    And in this case, I'm just calling the constructor that doesn't take any
00:43    arguments, but there is a version that does take an argument.
00:45    I could also just declare this variable by saying new ArrayList and then give it
00:49    some number, which is the capacity that I wanted to start off with.
00:52    If you don't do this, it starts off with some default capacity, and I don't
00:56    remember what is on the top of my head. I think it's like 10 or 50 or
00:58    something like that.
00:59    But you can say new ArrayList with a hundred or a thousand if you know you're
01:02    going to start off with a number that's that large.
01:05    So to add and remove items from the ArrayList, you use the functions that go
01:11    along with the ArrayList class.
01:13    So for example, to add an object to the ArrayList, you would simply call myAL.Add.
01:19    And notice that items get added as objects.
01:22    It takes an object as its argument.
01:24    But remember, everything in C# is an object--
01:27    well, almost everything anyway. Certainly all of the primitive data types and
01:31    any of the classes that you're going to come up with.
01:33    So you can add objects into your ArrayList.
01:36    Now you can add, which puts them at the bottom, or you can use the Insert method,
01:40    which takes an object and puts it in at a specific index. And then to remove
01:44    things you can use the Remove and RemoveAt.
01:46    So the Remove function takes the object that you're passing as an argument,
01:50    finds it in the ArrayList, and removes it.
01:52    RemoveAt removes the object that is at the index that you pass in, and remember
01:57    indexes here are zero-based.
01:58    There is also an easy way to find out how many things there are in the ArrayList.
02:03    There is the myAL.Count, which is a property on the ArrayList that tells you how
02:08    many items are currently in the ArrayList.
02:11    You can also do indexing with ArrayLists the same way that you would do them
02:14    with regular arrays. You can do things like myAL subzero.
02:16    You can even set values this way, which I guess is okay to do, but my preference
02:23    is to use the functions that come with the class.
02:25    Okay, let's take a look at ArrayLists and loops.
02:29    So suppose we had an ArrayList that we declared like this and we added a whole
02:34    bunch of items, items 1, 2, 3 and 4.
02:36    Out in memory this goes ahead and creates an ArrayList with four items in it.
02:41    Now if we want it to loop over the contents of this array, there is a couple
02:45    ways we could do it.
02:46    We could use the for loop, which we've seen in the past. And in this case, we
02:50    would have an integer variable named i and we would loop i up to being less than
02:55    the count of the items in the array, and we would increment the loop counter.
02:59    Now this is a perfectly valid way of doing this;
03:01    however, there is another way to do this.
03:04    And of course we could operate on the contents of the ArrayList.
03:06    We could write things out.
03:07    But my preference when working with things like this is to use the foreach loop.
03:13    Now we didn't talk about this earlier in the course, but I'm going to introduce it now.
03:16    The foreach loop construct loops over all of the elements in a collection, and
03:21    you can use it with arrays and other things throughout C#.
03:24    We're going to do it with ArrayList right here.
03:27    So foreach doesn't take a loop counter. What you do is you declare a variable
03:31    inside those parentheses; in this case it's an object because ArrayLists contain objects.
03:36    So you would say foreach (object obj in, and then the name of the collection.
03:41    In this case it's myAL. That's my ArrayList.
03:44    And then we can go ahead and operate on each object inside the loop.
03:47    So rather than doing the myAL sub-I that you see there in the loop, we would change
03:52    that to Console.WriteLine and then obj, because obj is going to be set to a
03:57    different object each time through the loop.
03:59    That's basically how foreach works.
04:01    It's really nice because there's no loop counters to keep track of.
04:04    There is no comparisons to make. The foreach construct just knows how to loop
04:09    over all the elements of a collection and put it into an object's variable
04:14    that you declare here.
04:15    Well, in this case it's an object; it could be other things too.
04:18    But in this case it's an object because ArrayLists keep track of objects.
04:21    ArrayLists can also have mixed content, unlike arrays. So if we declare an
04:27    ArrayList that looks like this, and then we go and add content to it using the
04:32    Add, remember each one of these is added as an object.
04:36    So I've got strings. I've got numbers.
04:38    I can put anything I want in here, as long as it derives from system.object,
04:42    which all the primitive value types do and all the reference types that we've
04:46    talked about, they do as well.
04:48    So I can do things then like this.
04:49    I can have an integer variable named result, and once again, I'm going to use my
04:53    foreach construct. And in this case, remember they are all objects,
04:57    so for each object in the ArrayList, I can then do something like this.
05:02    If the object is an integer--remember the is operator from earlier on in the course--
05:09    I can then say result +=, and then I cast, or convert, the object to an integer by
05:15    putting the word int in parentheses in front of it.
05:18    So this is going to loop over each object in the ArrayList,
05:21    see if it's an integer, and if it is an integer, add it to a running total.
05:25    So ArrayLists are really nice and flexible.
05:27    Let's go ahead over to the code and see some of this in real action.
05:30    Okay, here in the code I've got my ArrayLists example open, and I've got my
05:35    ExampleSnippets file. I'll scroll down to the ArrayLists section, and I'm going to copy
05:39    these lines right here, and I'm going to paste them into my program.
05:44    Put those into Main.
05:45    All right, so let's go ahead and take a look at the lines of code and see what they are doing.
05:50    Here on line 13 I'm declaring a new ArrayList object, then putting it into the
05:55    myAL variable, and then I add some stuff to the ArrayList.
05:59    I've got a string, integer, another string, another integer, and then a
06:02    floating-point number.
06:04    Then I have my foreach construct right here on line 20, and I've got my object o
06:10    variable, and that's going to be set to whatever the current object is each time
06:15    through the loop. And then I'm checking to see if o is an integer, and if it is
06:19    an integer, I write out the value of o using the Console.WriteLine construct.
06:25    So let's run this, and you can see that 2 and 4 are being written out.
06:30    Okay, let's go back and make a quick modification.
06:33    Let's say for each object, if o is an integer or o is a float, then we'll write it out.
06:45    In this case, we'll run it again,
06:47    you can see that the floating-point number as well as the integers are being written out.
06:51    So ArrayLists are really nice flexible alternative to using arrays in C#.
06:56    If you find yourself needing an array construct that is flexible, can contain
07:01    mixed content, and so on, consider using ArrayLists rather than just fixed-
07:05    sized arrays.
Collapse this transcript
Working with stacks
00:00    The next collection class that we are going to look at is called the stack.
00:05    Stacks maintain a list of items just like arrays and ArrayLists do, but they
00:10    operate on a slightly different paradigm called push-on and pop-off, and you can
00:15    think of a stack as, like, in fast food restaurants they have those cup stacks
00:20    where they push all the cups into the holder and then each time a person takes a
00:24    cup, it pops off the top.
00:26    Stacks are pretty much the same way.
00:28    Stacks are declared by using the stack class.
00:31    So to declare a stack, I will use the stack class, and then mystack is the
00:34    variable name. This is probably familiar by now. I say new stack.
00:38    That will create a stack object out in memory.
00:41    To put data on the stack, I use the push method to push data on the stack.
00:47    Remember, these are objects,
00:48    so I can pass any primitive type or any reference type, anything I can come up with.
00:54    In this case, I will just push a string called a string 1.
00:56    What that will do is that will put string 1 onto the top of the stack.
01:01    If I then push another piece of data, say string 2, what will happen is string 1
01:05    will slight down and string 2 will now be the new top.
01:08    And I can keep on doing this with successive pieces of data.
01:11    I can have strings 3, 4, 5, and so on.
01:14    To get the data off the stack, instead of using push, I use pop.
01:18    So I would declare an object variable.
01:22    In this case, it's called o, and then I would call mystack.Pop.
01:25    This would get the top value on the stack.
01:28    So after calling pop, string 2 pops off and then string 1 slides back on up and
01:33    now the value of o is the string 2.
01:36    If I wanted to just see what was on top of the stack without changing it, I
01:40    would use the Peek method.
01:42    This looks at the top value, but doesn't actually pop it off.
01:47    Then finally I can see how many things there are on the stack by asking the
01:50    stack's count property how many things there are.
01:53    In this case, it will tell me that there is one item on the stack.
01:56    Stacks are commonly referred to as LIFO,
01:59    Last In, First Out, data structures, because the things that you push onto
02:04    the stack earlier get pushed down towards the bottom and later elements are nearer the top.
02:09    So as you pop them off, those items are going to come out first.
02:12    So it's Last In and First Out.
02:14    Again, stacks are one of the common data structures you will find throughout
02:17    programs for various purposes.
02:19    Let's go ahead and jump over to the coding environment and actually exercise
02:23    this to see how it works.
02:25    So here in the code I have scrolled down to my Stacks section in my
02:29    ExampleSnippets, and I have got my Stacks project open over here with my Main function.
02:36    Let's go ahead and copy some code over.
02:38    So the first thing I am going to copy over is this setup code right here, and I
02:42    am going to paste that in.
02:45    Right there on line 13 you can see that I am declaring a new stack variable, and
02:50    then I am pushing some data on the stack.
02:51    I am Pushing strings, items 1, 2, and 3.
02:54    Then I am just going to write out how many items there are on the stack by using
02:57    the mystack.Count property.
03:00    So we are going to run this, and you can see that sure enough, there are
03:03    three items on the stack. So far so good.
03:06    Let's go back over to the code.
03:08    Now let's have a peek at what the top item is.
03:11    So we are going copy that, and we will paste that below here.
03:16    Now remember Peek is non-destructive.
03:19    In other words, it doesn't actually change the stack;
03:21    it just shows me what's on the top.
03:22    So we will run this and you can see that items 3 in on the top. Why?
03:26    Because item 3 was the last item pushed on; therefore, it will be at the top of the stack.
03:33    So far, things are operating the way they are supposed to.
03:35    Let's go ahead and try popping something.
03:37    I will go ahead and paste that code in down here.
03:44    So now here on line 23 you can see I am calling the Pop function, which is
03:48    going to pop item 3 off the top of the stack, which means that item 2 will now be the top item.
03:54    So when I write this out, it should say item 2. So let's run this.
03:57    Yeah, sure enough item 2 is now on the top of the stack.
04:00    Let's go back to the Snippets over here. One more thing.
04:04    We'll paste that code in here.
04:11    So now I am going to call these stacks Clear function right here on line 27, and
04:15    that will get rid of everything on the stack here.
04:17    It will clear out the contents and then when I call mystack.Count, I should have the value 0.
04:23    So let's press F5 and sure enough, I have got 0 items on the stack.
04:30    You will find stacks used throughout C# programs and other programming
04:33    languages in general.
04:34    They are pretty useful for keeping tracks of certain kinds of data structures,
04:37    mathematical expressions, evaluations, and so on.
04:40    There are a couple of great examples.
04:41    So that's how you use stacks.
Collapse this transcript
Working with queues
00:00    Well, continuing on with the cavalcade of collection data structures, we are now
00:04    going to look at queues.
00:06    Queues maintain a list of items kind of like stacks do, but they are different
00:10    than stacks in that they're FIFO, or First In, First Out--kind of like a line of
00:15    people waiting at a counter.
00:16    In fact, if you've ever spent any time in UK, you will probably hear lines
00:19    referred to as queues, and queues in programming work pretty much the same way.
00:25    Something enters the queue, and it's the first one in. It's also the first one out.
00:28    And items move in the queue in an orderly fashion, or at least they should.
00:33    Using queues in C# is similar to using stacks, only instead of having Last In,
00:39    First Out, it's going to be First In, First Out.
00:42    To declare a queue, you use the Queue class name and here I have got a queue
00:47    named myQ and I create a new queue.
00:49    Then to put things on the queue, instead of using push and pop, we are going to
00:52    use Enqueue and Dequeue.
00:55    So in this case, I am going to create my new myQ variable.
00:58    I will call Enqueue. And in this case I am passing a string, but it's an object,
01:02    so it can be anything; it could be a number or whatever.
01:04    So I am passing in a string.
01:05    When I do that, string 1 will be placed in the queue.
01:08    If I then Enqueue string 2, string 1 will move down and then string 2 will now
01:12    be at the back of the queue.
01:15    Instead of using Pop, I am going to use Dequeue.
01:18    So when I say Dequeue, the first item will come off of the queue like this.
01:24    That leaves string 2 as the current first item.
01:28    Just like using stacks I can do things like Peek, and Peek is non-destructive.
01:32    In other words, it's does not take things off the queue;
01:34    it just shows me what's at the front of the queue.
01:36    In this case, it's now string 2. And also like stacks, I can use the Count
01:40    property to see how many items are actually on the queue.
01:44    So since this is so similar to stacks, let's just go ahead and waste no time and
01:47    get over to the code so we can see this working in action.
01:50    Here we are in the code.
01:52    One of the things that I haven't pointed out up until now, which you
01:55    probably have noticed, is that you need to include a name space in order to
01:58    use the collection classes.
02:00    Up until now we've had a Collections.Generic which has been included for us by
02:04    default, but in order to use things like stacks and queues and ArrayLists, you
02:08    need to include this guy right here using System.Collections.
02:11    This is the namespace you need to include in order to use the classes we have
02:15    been talking about so far.
02:17    So to use queues and stacks and ArrayList and so on, just make sure you have that included.
02:21    So let's jump over to the Snippets, and you can see I have scrolled down to the
02:25    queue section. And I am going to go ahead and copy these lines and this is the
02:30    setup code right here.
02:31    I'll just paste this in.
02:36    So right there on line 13, creating a new queue, and then I am Enqueuing four
02:40    items. And I am going to write out how many items there are in the queue and sure
02:44    enough, there four items, just like you would expect there to be.
02:48    Now let's go back to the Snippets.
02:50    Just to show you that you can use other kinds of loop constructs with these
02:54    collection classes, I am going to use a while loop.
02:57    And if you have been watching along with me so far, you've probably noticed
03:00    I've used for loops.
03:01    I have used for each loops.
03:03    It's time to give the while loop its turn.
03:05    So here I am going to say while myQ.Count > 0 we are going to Dequeue items--
03:13    you can see they're on line 23--and then in the following line 24 we are just
03:15    going to say Dequeuing object whatever and write it out to the console.
03:21    Each time we Dequeue something the Count property is going to automatically
03:25    be decremented for us.
03:26    We don't have to worry about taking care of that.
03:28    The class keeps track of how many items there are in the queue. And since Dequeue
03:32    takes things off of the queue, the Count will change for us.
03:35    So I am going to go ahead and compile this and build this, make sure it works, and it did.
03:38    Now let's just go ahead and run this.
03:42    You can see that we are Dequeuing items in the same order that they were put o to the queue.
03:47    So item 1 was the first one in, and it's the first one out, followed by items 2, 3, and 4.
03:52    So queue is similar to stacks, only they operate more like a Line.
03:55    If you find yourself in need of a collection class where the order is
03:58    important and you need to process things in the same order that they come in,
04:02    use queues instead of Stacks.
Collapse this transcript
Using dictionaries
00:00    The last example of a collection class that we are going to look at is the dictionary.
00:05    And dictionaries are used to associate a particular key with a given value,
00:11    and you can think of them as lookup tables. Essentially, you use a key to look up a value.
00:16    So if I have a dictionary object then I essentially have a key that's associated
00:21    with a value inside that dictionary.
00:24    And some examples of that might be a product ID with a product name, or I could
00:28    associate say an abbreviation for a state name with its full name.
00:32    But really I can associate any object with any other object.
00:37    This is what hashtables are essentially used for.
00:40    They are probably one of the most useful collection classes out of all of them.
00:44    Keys have to be unique.
00:46    You can't have duplicate keys, and dictionaries don't have any sense of order.
00:52    So unlike other collection classes, like stacks or queues or arrays, there is no
00:57    sense of order here.
00:58    You simply put in keys, associate them with values, and there's no notion of who
01:04    is first or who is last.
01:06    Probably the most common example of a dictionary is the hashtable
01:11    or associative array.
01:13    You probably heard it called many different names depending on what other
01:16    programming language you may have come from.
01:18    If you've never heard of it before then I will introduce it to you now.
01:22    The hashtable is an example of a dictionary, and the Hashtable class in C# is
01:28    declared the same way you declare any other collection class;
01:30    you simply have the Hashtable class, and in this case I'm declaring a variable
01:34    named myHT, which is of type Hashtable, and then you just use the new operator
01:39    like you would in any other class.
01:41    So this will create a new hashtable named myHT, and then we can start adding
01:46    things to the hashtable. And the way you do that, well, there are a couple ways
01:49    to do it, but the first way to do it is to use the Add function.
01:52    When you add something to a hashtable you give it the key that you want.
01:56    So for example, I could give a three-letter airport code, like SEA, and then I
02:01    give it the value, which might be something like Seattle Tacoma Airport.
02:05    Then over in a hashtable I would have a little key named SEA and would be
02:08    associated with a value.
02:10    And I could do the same thing for say SFO, and that associates it with
02:14    San Francisco Airport.
02:15    I can also use bracket notation.
02:18    For example, I can say myHT, and then in brackets I can have the three-letter
02:22    code for IAD, which is Washington's Dulles Airport. And using the bracket
02:28    notation, I will simply use the equals, or assignment operator, to say myHT sub
02:33    ID is Washington Dulles Airport, and that would also put something into the hashtable.
02:38    That's how you get data into the hashtable.
02:41    The way that you get data out of the hashtable is to use the Remove function.
02:45    In this case, I would call myHT.Remove, and then I give it the name of the key
02:49    that I want to be removed.
02:50    So if I want to remove San Francisco Airport, I would simply say Remove SFO and
02:54    that will cause SFO to be removed from the hashtable.
02:58    Just like other collection classes, there are a couple of utility
03:01    properties and so on.
03:02    For example, I can see how many things there are in the hashtable by using the
03:06    by now ubiquitous Count property.
03:07    This will tell me in this particular case there are two things in the hashtable.
03:11    I can also see if hashtables contains certain values by using a test.
03:15    I can, for example, declare a Boolean variable name b and call the ContainsKey
03:21    function on a given hashtable. And I can pass in a key name, in this case SFO,
03:26    which will return false now, because it's gone. Or I can also use the
03:30    ContainsValue version as well.
03:32    So I can say, hey, hashtable, do you contain the value San Francisco Airport?
03:36    In this case, it's now false, but if it was still there, it would be true.
03:39    So let's just jump over to the code and make ourselves a hashtable and exercise this.
03:45    So here I am in code.
03:47    Once again you'll notice I am using the System.Collections using statement up
03:51    here that includes the name space for the collections class, which includes
03:56    things like dictionaries and hashtables and queues and stacks and all the
04:00    examples we have been using so far.
04:02    So jumping over to the Snippets code, you can see I have scrolled down to the
04:05    Dictionary section, and I am going to copy the setup codes over here.
04:08    I am going copy that and it will paste it into the Main.
04:17    You can see on line 13 I have created a new hashtable, and then I've added some
04:21    data to the hashtable.
04:22    I have added airport codes SFO, SEA, and IAD, and I have set their associated
04:28    values to the full names of their airports.
04:31    Then we can test this out by saying, hey, let's do a Console.WriteLine to see
04:35    the value for key, whatever is this.
04:39    And we are going to pass in the name of that key. In this case I will look
04:42    up the value by using the bracket notation.
04:44    So you can see here on line 16 I use the bracket notation to set the value.
04:48    I can also look up the value by using the bracket notation, but without an
04:52    assignment operator.
04:54    So I am going to do a build.
04:55    You could see the build succeeded, and we are going to run it.
04:59    And you can see it worked fine.
05:02    The value for key SEA is Seattle Tacoma Airport. That's great.
05:07    Let's continue on with the exercise.
05:09    I am going to copy this line here, which simply tells me how many items there
05:14    are in the hashtable.
05:15    So I'll save that and run it.
05:18    And as you expect, there are 3 items in the hashtable. So far so good.
05:24    Let's do our last exercise right here.
05:27    Copy and we'll paste this in.
05:31    In this case, we are going to exercise the Remove functionality, but before I
05:35    uncomment that Remove line--let's just go ahead and write it out that right now--
05:41    you can see that the value for key SFO is San Francisco Airport.
05:45    That's because SFO is still in the table;
05:47    I haven't removed it yet. But if I uncomment this line right here, I'm going to
05:53    remove the SFO key, and then the next line is the if statement on line 22 that
05:58    says, hey, if myHT contains the key SFO then write it out.
06:03    Now that condition is going to be false, because we've moved it.
06:05    So let's run it again, and you can see that this time there was no WriteLine for
06:11    the SFO key, because it's not there anymore.
06:14    Hashtables are probably one of the most useful of the collection classes, and if
06:19    you're coming from a language like JavaScript you've probably used these a lot.
06:23    In fact, they are used all over the world of programming, and in C# it's no different.
06:27    You can use hashtables to associate keys with objects, or any other kind of data
06:32    that you can think of.
06:33    They're pretty useful.
06:34    They are also pretty efficient.
06:36    If you find yourself in need of having a lookup mechanism, a hashtable
06:39    usually fits the bill.
Collapse this transcript
7. More Complex Classes
Overloading methods
00:00    We have reached the section of the course now where we are going to start
00:02    learning about some of the more advanced object-oriented features of C#.
00:07    The information in this part of the course is going to build on the
00:11    information that we learned about earlier in the chapter on creating custom
00:15    classes and objects.
00:17    Go ahead and watch that content if you haven't already, and then pick it up here.
00:21    We are going to start with method overloading, and method overloading is when
00:25    you define methods that have the same name but different ways of calling them.
00:30    So let's look at a real example.
00:32    Let's go back to our ubiquitous Wine class example, and you can remember from
00:37    earlier examples I've got a class here called Wine. And I can declare some
00:42    member variables like Year, Name and Price, as I have done in the past. And you
00:45    have probably seen me do something like this where I declare a constructor
00:49    function called Wine, which is the same name of the class, and in this case it
00:54    takes a string argument and it sets the value of the Name variable to whatever
00:59    argument was passed in.
01:00    That's great, but what if I also wanted to give people that are using this
01:03    class a way to initialize the class, or construct the class, with both a name and a year?
01:11    Well, I could simply just define another Wine constructor function like this,
01:16    and in this case I have got a Wine constructor which takes a string and takes a Year.
01:20    You might be saying, well, wait a minute.
01:21    You have already got a constructor function called Wine.
01:24    Isn't this a problem? Aren't you redefining something? No, not really.
01:27    What I am doing here is I'm overloading the Wine constructor, and this doesn't
01:33    just work with constructors.
01:34    You can do this with any function.
01:35    I just happened to be doing with the constructor function here.
01:38    And the reason this works is because the signatures of the two methods are different.
01:44    In other words, the parameters that each one of these constructor takes is unique.
01:49    So for consumers who wanted to call the constructor for the Wine class using
01:54    just a name, they can do that.
01:56    If they want to use both the name and a year in their code, they can do that too.
02:00    As long as you define the function with the same name and a different set of
02:05    parameter lists, that's fine. That's legal C#.
02:08    Let's take a look at an example that doesn't work.
02:12    If I have a class and I wanted to provide two functions of the same name, here I
02:17    have got a function that takes an integer and returns an integer and I've got
02:21    another function that takes an integer but returns a float.
02:23    The problem is this is an error.
02:26    The return type of the function is not part of the signature.
02:29    It's the parameter list.
02:31    These methods are not considered different by the compiler. And you can imagine
02:36    in the code I would call out a function with an integer argument,
02:39    the compiler wouldn't know which one to call. So you can't do this.
02:43    You can't have functions that defer only by the return type.
02:46    The parameter list has to be different.
02:49    So let's take a look at some real code to see how this works.
02:52    So in the MethodOverloading example I've got my program, opened and here's my
02:57    Snippets code, and I've scroll down to the overloading methods section.
03:01    So I am just going to go ahead and copy this entire class right here for Wine.
03:07    And we are going to need this to set up the example, so I will just copy this in,
03:10    and I will put it above the program class.
03:15    Before I copy the rest of the code, let's take a look at what's going on here.
03:18    I have my Wine class and I have got my member variables here, and then I've got
03:23    a set of constructors.
03:24    You can see that I've got a constructor for the Wine class that takes just a string,
03:28    I have got one that takes a string and a year, and I've got one that takes a
03:32    string, a price and a year.
03:36    So I have got three different constructor functions, so I am overloading this
03:39    function three times.
03:40    Okay, now let's go back to the Snippets and let's copy in some code that
03:45    actually exercises this.
03:47    I will copy that and put it into the Main function, and we will just put it in right there.
03:56    You can see here, starting on line 35, I am creating three Wine objects, w1, w2
04:03    and w3, and I am calling the constructor in a different way each time.
04:07    For w1 I am just passing in a string by putting in a name, for w2 I have got a
04:11    name and a year, and for w3 I've got the name, the price and the year, and
04:17    then I've got three lines here that's going to write out the various parts of the objects.
04:23    So for Wine 1 I am going to write the name, and so on.
04:25    Let's go ahead and try this code out and see what happens.
04:29    So you can see that when I run the code for w1, I am writing out just the name;
04:33    for w2 I have the year and the name; and for w3 I have got the year, the name, and the price.
04:41    Now, because I've overloaded these functions, I can call them with different
04:46    values and different parameters.
04:47    So, for example, I have given the consumers of this class three different ways
04:51    to build their Wine class objects:
04:54    so just the name, the name and the year, and the name and the year and the price.
04:58    I want to go back and change the way that I constructed w1,
05:02    I can put my cursor in here and type comma. And you can see that when I type the
05:07    comma, C# Express gives me a little pop-up that says hey, there are three
05:12    different ways you can call this function.
05:14    You can see right here it's on 2 of 3, but I can cycle through all of these.
05:18    1 of 3 is to call the Wine constructor with just a string.
05:22    Here is the version with just a string and an integer. And you can see, since I
05:27    have put the comma in there, it's highlighting the integer in bold saying, hey,
05:30    that's where I think you are going to type next. Or in the third case,
05:35    I've got the string, the price, and the year. And again I am on parameter number
05:39    two right now so it assumes I am going to type a price in here.
05:42    But the point is that C# Express is looking at my constructor list and helping
05:47    me choose the one that I want, and it's showing me what's available.
05:50    I can choose to use either this version or this version.
05:53    So let's go ahead and use the second version.
05:55    I am going to just type in 2007. I need to change the Console.WriteLine as well.
06:04    So I will put this in here w1.Name, and now I will do w1.Year. And when I save
06:15    and I rerun this, you can see I have got the name and the year that's being written out.
06:21    Just to recap, overloading a method is when you declare a method with the same
06:27    name but with a parameter list that's different each time.
06:30    In this example I showed you how to do it with the constructor, but you can do
06:34    this with any method. It doesn't have to be the constructor.
06:37    You can't do this with properties. You can't do this with fields.
06:39    You can do this with methods.
Collapse this transcript
Overriding methods
00:00    A very close cousin of overloading methods is called overriding methods.
00:05    In overriding methods, you basically get to change or augment the behavior of
00:10    methods and classes, and this is called overriding their logic.
00:14    It's one of the most powerful things of object-oriented programming and it
00:18    really, really helps you when you want to encapsulate your logic in your objects
00:22    and separate the behaviors of different objects from each other.
00:26    Let's suppose you have a phone. And a phone knows how to do something, like ring,
00:32    but of course you just have a phone.
00:35    You have a particular type of phone.
00:36    You might have a landline.
00:38    You might have a cellular.
00:39    You might have a satellite phone.
00:40    Well, each of those knows how to ring as well.
00:43    In fact, they have got their own custom ways of ringing.
00:46    Now when you get a phone call the person calling you doesn't necessarily know
00:50    what kind of phone you have; all they know is that you have got a phone.
00:54    When they make a phone call the system looks up your phone and tells your phone
00:57    to ring. And when the phone is told to ring it figures out what kind of phone
01:02    you have, and it tells that particular kind of phone to go ahead and do its
01:06    ringing. And this is the same kind of concept that we will do in object-oriented programming.
01:12    You will have a class, a subClass, and the baseClass, or the superClass, to use
01:18    object-oriented terminology,
01:20    will have some method in it, and you want to either completely replace the
01:24    logic that's in that method, or you want to augment it somehow.
01:29    You use overriding in order to do this.
01:31    Now there are three important things you have to understand.
01:34    There are three keywords in C#.
01:36    The first one is virtual.
01:38    The virtual keyword tells the compiler that it can be overridden.
01:43    The override keyword is another important one, and then there's the base keyword.
01:48    To use the overriding mechanism, there are three things you have to do.
01:51    First, you have to mark a method as being virtual.
01:55    This tells the compiler that this particular method can be overridden by derived classes.
02:00    If you're coming from other languages like JavaScript or C++, this may look
02:05    somewhat familiar, but it's a little bit different.
02:08    You have to specifically mark a function as being over overridable.
02:12    So here you can see I have got a function called myFunction.
02:14    It returns an integer. And I have got the public keyword in front of it, but I
02:19    have inserted the word virtual between the public and the return type.
02:24    This tells the compiler, hey, somebody might want to override this.
02:27    Now they don't have to, but they might want to.
02:29    To actually override the method, in the subClass, I tell the compiler that a
02:35    particular method is going to override the same method in the baseClass by using
02:39    the override keyword.
02:41    So in this case instead of virtual, I use override.
02:44    You can see I have done the same thing here: between the return type and the word
02:47    public, I've used the word override.
02:51    And these two go hand in hand when you want to override methods.
02:55    Then finally, there is the base keyword, and you can use this in your subClass to
02:59    call the baseClass's method. And you use this because you don't necessarily
03:04    always know what the name of the baseClass is.
03:07    Instead of you actually using the name of the baseClass, you simply say base, dot,
03:11    whatever the function is. And this will call into the code in the superClass
03:16    instead of your subClass.
03:18    Now there is a little bit complex.
03:21    It's probably helpful to see an example of this in action,
03:24    so let's jump over the code and see it work.
03:29    So here I am in my example.
03:31    This is for method overriding. And I am going to go over to my Snippets, and you
03:35    can see in my Snippets I have scrolled down to the Overriding Methods section.
03:39    The first thing I am going to do is copy over my class definitions.
03:42    I have two classes:
03:43    I have one that's a baseClass and I have one that is a subClass of that baseClass.
03:47    Let's go ahead and copy these over, and I will put these in my program definition here.
03:56    So now I am going to scroll back over here down a little bit. I'm going to copy this
04:02    code and put it into my program.
04:08    Before we run this, let's take a look at the class definitions, so we can
04:13    see what's going on.
04:16    In my baseClass, you can see here on line 10 I have got a function called
04:21    doSomething. And it doesn't return anything, so it's a void return type and it's
04:26    public. And I have declared it as a virtual method.
04:29    What that means is when I create a subClass that descends from this baseClass
04:34    the subClass has the opportunity, if it wants to, to override this method.
04:38    Now the baseClass method for doSomething just simply writes something out to the
04:42    console. It says, hey, this is the baseClass saying "hi."
04:44    Go down to the subClass. On line 18 you can see that I've got the same
04:49    method, doSomething.
04:51    In this case I've got the override keyword.
04:54    So this tells the compiler, hey, I'm overriding whatever the baseClass does.
04:59    In the doSomething method for the baseClass I am calling the baseClass's version
05:03    of doSomething, which will call the Console.WriteLine method. And then I can put
05:08    on whatever additional programming logic I want to.
05:12    I can do another Console.WriteLine.
05:14    I can put it before or after the baseClass call.
05:18    I can put it here if I want to.
05:19    I will just leave it there for now.
05:22    So let's go back down to the program. And you can see that what I am doing is I
05:25    am creating an object.
05:27    I have got a subClass object.
05:31    I have created a new subClass object called obj1, and I am going to call doSomething.
05:35    So let's see what happens when I run this.
05:39    Two things get written out:
05:41    "This is the baseClass saying hi!"
05:43    and "This is the subClass saying hi!"
05:45    So why did that happen?
05:46    Well, in obj1 we called doSomething.
05:48    obj1 is a subClass, so we will look in the subClass. And you can see that in
05:55    doSomething the first thing we do is call the baseClass's version of doSomething,
06:01    which will be this right here.
06:02    The baseClass saying hi!
06:04    gets called first, and then that returns and then the subClass gets called.
06:08    We can reverse that order.
06:10    We can cut this line and put it up here, and let's run it again, and now you can
06:14    see that the subClass says hi first instead of the baseClass.
06:18    Let's go back to the code.
06:19    We can actually just take this call out.
06:21    We don't have to call the baseClass if we don't want to.
06:23    Now we've completely replaced the functionality that the baseClass provides, and
06:28    we are only doing what the subClass says to do.
06:31    So we are going to save this and run it and now you can see that only the
06:34    subClass's version of that function is running; the baseClass's version is not
06:38    getting a chance to run. Hit Return.
06:41    Let's try something else.
06:44    Since subClass is a version of the baseClass object, I can do something like this.
06:52    I can say baseClass obj1 = new subClass.
07:00    Now that may seem strange at first, because wait a second. Shouldn't I be
07:03    creating a new subClass?
07:05    No, I'm actually going to create a baseClass object.
07:07    Let's see what happens here. Ah!
07:10    "This is the subClass saying hi!"
07:12    Why did that happen?
07:13    Why is it that when I created an object of type baseClass, or I gave it a
07:18    name of baseClass, and I created a new type of subClass, why did it not call
07:23    the baseClass's version? Why?
07:25    Because when you create a virtual function C# is actually going to look up what
07:29    the lowest descendent is and call that version of the function.
07:33    Since I actually created a new instance of subClass, even though I arranged it to
07:38    be assigned to a variable named baseClass type, it's still going to look down in
07:42    the functions and say, oh, you know what?
07:44    That subClass object is actually overriding this function,
07:46    so I am going to call that version instead.
07:48    Let's change this so that instead of creating a new subClass type, I am creating
07:53    a new baseClass type.
07:55    Now let's see what happens.
07:57    I am going to run it.
07:59    Now it's the baseClass's version saying hi. Why?
08:01    Because it's not a subClass anymore;
08:03    it's a baseClass now.
08:05    That's how you override methods.
08:07    You use the keyword "virtual" to indicate that a method can be overridden and then
08:12    use the "override" keyword to indicate that you are overriding it in a baseClass.
08:17    And you can use this to augment the functionality provided by baseClasses in
08:22    your own programs, as well as other programs that you might be adding on to.
08:26    It's a really great way of segmenting your program so that pieces of
08:31    functionality don't have to be changed in baseClasses in order to provide new
08:35    pieces of functionality in classes that derive from them.
Collapse this transcript
Creating abstract classes and methods
00:00    All right, in this section we are going to talk about abstract classes, and
00:04    abstract classes tend to be one of those subjects that trip people up who
00:06    are learning object-oriented programming for the first time, so I'll try to make this easy.
00:11    Essentially, an abstract class can't be instantiated by itself.
00:14    You have to create a subclass, and you have to instantiate that instead.
00:18    In other words you've got to derive a class from an abstract class and make
00:22    that class instead;
00:23    you can't instantiate an abstract class.
00:25    abstract classes have abstract members and these are members that have to be
00:30    overridden by subclasses in order to provide functionality.
00:34    So, okay, why would you do this?
00:36    Well, there are going to be times in programming where you define a class that
00:39    describes an abstract idea, but it doesn't make sense by itself.
00:43    It has to have an actual physical implementation, and that physical
00:46    implementation is going to change among different versions of that class.
00:50    And we'll take a closer look at that in a moment.
00:52    First, let's see how to actually describe an abstract class.
00:55    Abstract classes are indicated by putting the word abstract in the class definition.
01:00    So if I normally describe a class like this using public class, myClass, and then
01:06    declare the class normally like you see me do throughout the course,
01:09    what I would do here instead is put the word abstract inside the class definition.
01:13    That tells the compiler that this is an abstract class.
01:16    Then once I've done that, I can declare an abstract member function, like you see here.
01:22    Now I don't provide an implementation for this function here.
01:26    Remember, I'm forcing the subclass to do that.
01:29    The subclass has to provide an implementation.
01:33    So let's take a look at a real-world scenario where you would do something
01:38    with abstract classes.
01:39    Consider an example where you've got a car dealership or some kind of dealership
01:43    where you sell different types of vehicles.
01:46    Now vehicles, depending on what they are, have unique characteristics, but some of
01:51    them might be common among all different kinds of vehicles. For example, they
01:55    might have properties like what kind of fuels they use and what their licensing
01:59    code number is, right?
02:01    But you don't actually go down to the dealership to buy a vehicle.
02:05    What you do is you buy something like a motorcycle or a car or a truck or a boat.
02:10    These are real-world implementations of this abstract notion of a vehicle.
02:16    Even though they may all share some of the same characteristics, there is no
02:20    such thing as actually making a vehicle. So in this case if the vehicle, the
02:25    class you see in the dotted line there, is an abstract class and the classes you
02:29    see in the thick lines are real subclasses that derive from the vehicle
02:35    subclass, you could do something like this.
02:37    I could say class Car c = new Car. That works great.
02:41    It's a real class that derives from the abstract class.
02:44    What I can't do is this:
02:45    I can't actually instantiate the abstract class, because the rules of object-
02:51    oriented programming in C# is that abstract classes have to be derived from.
02:55    So I would have to instantiate one of the real classes, the motorcycle, the car,
02:58    the truck, the boat.
02:59    And I could add more real classes as time goes on.
03:03    So let's just go over to the code and see this in action.
03:06    Okay, I've got my abstract classes example opened.
03:11    Let's go over to the snippets.
03:13    You can see I've scrolled down to my Abstract Classes and Methods section. And I
03:16    am just going to copy these two class definitions and I am going to paste them
03:20    in my program over here.
03:23    So now I have my abstract class, which is myBaseClass, and in there you see I've
03:28    got my abstract method called myMethod.
03:31    And then if we scroll down a little bit, you'll see here starting on line 13,
03:34    I have a derived class which inherits from myBaseClass. And it overrides--again I
03:42    am using the word override here to override the abstract member function called
03:47    myMethod--and in this case it just takes two arguments and returns the sum of
03:51    those two arguments.
03:53    So if we go down into the Main function, I could do something like this.
03:57    I can say myDerivedClass = new myDerivedClass, and then I can say int result =.
04:09    Actually, I have to make it a variable there. I can say mdc.
04:15    and then I can call myMethod right here. And I'll just give it two numbers, 5 and 6.
04:23    And then we'll just write out the result there, and then we'll have the program
04:31    wait for us so we can see the results.
04:34    So let's save this, and let's run it.
04:36    And you can see that the results here is 11. Why? Because 5+6 equals 11.
04:42    So we can see that the real derived class from the abstract class provides
04:47    implementation and actually works.
04:49    Let's comment this code out so that we don't have to deal with any errors in it.
04:54    Okay, let's see what happens when we take the myMethod implementation out of
05:01    the derived class. I am just going to cut this code and save it, and now I am
05:05    going to hit F6 to build.
05:07    And you can see that we get an error.
05:09    There is little blue squiggle underneath myDerivedClass, and if you look down
05:13    here in the error list, it says "abstractClasses.myDerivedClass does not implement
05:19    inherited abstract member myMethod."
05:22    So you can see that because I declared myMethod to be an abstract method, I have
05:27    to override it in my base class.
05:30    So let's undo that. Put that back in, and the error goes away.
05:34    Let's try another little experiment. Let's do this.
05:37    Let's say myBaseClass mbc = new myBaseClass, and we'll save and we'll build, but another error.
05:49    What's the error this time?
05:50    It says, "Cannot create an instance of the abstract class or
05:55    interface myBaseClass."
05:57    Abstract classes, as you can see, cannot be instantiated by themselves, and this
06:01    is enforced by the C# compiler.
06:05    So let's go ahead and delete that code.
06:09    So abstract classes are a way of defining abstract ideas that group together
06:15    some common properties and functionality of real instances of that class,
06:21    but it's just abstract.
06:22    You can't actually instantiate that class.
06:24    That's a way for you to write your programs such that you can group together the
06:29    related pieces of functionality
06:30    but force people who want to use your classes to override them and make real
06:35    physical instances of them.
Collapse this transcript
Using sealed classes
00:00    The next somewhat advanced and somewhat esoteric subject we're going to look at
00:05    in advanced C# is sealed classes and methods.
00:08    Now sealed classes and methods are essentially the opposite of abstract classes.
00:13    Whereas abstract classes force you to derive a subclass in order to use them,
00:19    sealed classes actually prevent you from deriving from them.
00:22    So there is no way to make a subclass from a class that has been sealed.
00:27    It's also possible to mark individual methods in classes as being sealed, which
00:32    prevents them from being overwritten in some classes. But it is far more common
00:37    to seal entire classes than methods.
00:40    And the way that you create sealed class is by using the sealed keyword.
00:44    So if I define a class like this, I have a public class myClass.
00:47    If I wanted to seal this class, I'd just simply put the word sealed inside
00:51    myClass, and then at this point I can no longer create a subclass.
00:56    So before the sealed keyword was in there I can make my subclass off of myClass,
01:00    but now that the sealed keyword is in there, this is an error;
01:02    I can't derive from myClass anymore.
01:05    So let's actually see this in action.
01:07    I'm actually going to go over to my Snippets here in my SealedClasses example,
01:12    and I'm going to copy these lines of code right here, and I'll paste them in.
01:20    So here I have my class, and let me just take this guy out for a moment.
01:25    So I have a class called myExampleClass and I have my subclass which derives
01:31    from myExampleClass. And if I hit F6, you can see that everything works fine;
01:36    the Build succeeds.
01:37    Let's put the sealed keyword back in there. Save.
01:41    Now let's try to build. Oh!
01:42    We get an error, and it says that the subclass right here cannot derive from
01:47    sealed type myExampleClass.
01:50    So by sealing this class, I prevent any further subclasses from being created.
01:55    You'll do this when you create classes that you don't want people messing with.
01:59    It's not a particularly common thing that you'll see a lot of.
02:02    The .NET Framework does this in a couple of places where it doesn't want you
02:05    messing with things like the Math class or other things.
02:09    Basically, if you create a class where you want it to behave a certain way and
02:13    you don't want authors to be able to override methods in your class, you can
02:17    create a sealed class.
02:19    So pretty quick simple example of how you can create classes in C# that cannot
02:23    be derived from or sub-classed.
Collapse this transcript
Defining structs
00:00    If you're coming from a language such as C or C++, you're probably familiar with
00:05    the notion of a struct.
00:08    If you're not, don't worry about it. I'll explain it here.
00:10    But structs essentially are similar to classes, but there are some important
00:15    differences that you're going to find.
00:17    First, structs don't support inheritance.
00:19    When you define a struct you define its members and its data types and so on,
00:24    but you can't derive one struct from another.
00:28    Structs are also value types, while classes are reference types. And if you
00:32    haven't yet watched the movie where I explain the difference between value
00:35    types and reference types, you should probably go watch that, because it'll make a lot more sense.
00:40    You also can't initialize the fields of a struct inside the definition.
00:44    So, for example, when you have a member variable inside of a struct, you can't
00:49    put a little equal sign after it and initialize it to a value.
00:52    You have to do that outside the definition.
00:54    Structs are usually used when you just want some small and simple data
00:58    structure to represent some piece of information and you don't want all the
01:02    overhead of a class.
01:04    Now structs can have properties and methods just like a class can.
01:08    You just have to remember that they're not really classes.
01:10    You can't have inheritance.
01:12    There are all kinds of things you can't do.
01:14    So let's take a look at real example.
01:15    Suppose we wanted to define a data type for representing a point on a
01:20    two-dimensional surface.
01:21    Well, we could do that with a class.
01:23    We'd say public class Point and we would have an X coordinate and we would have a Y coordinate.
01:27    We could also have a constructive function.
01:31    So when someone said new point, they could pass in a value for the X and the Y,
01:36    and that would set the X coordinate and Y coordinate to whatever the values are.
01:39    We could also just simply declare this to be a struct, in which case it's not a
01:44    class anymore, but everything still works.
01:46    We've got member variables, we have a constructor function, and everything is fine.
01:51    So let's go jump over to the code and exercise this.
01:55    Right, here I'm in my structs example, and I've got my Snippets scrolled down to
01:59    the part on Defining Structs.
02:01    So over here in the code I'm going to just copy these lines right here.
02:05    I am going to copy this structure definition, copy that, and I want to paste it over here.
02:13    So now I've got my struct which defines a point, and it's got these two private
02:19    number variables for X coordinate and for the Y coordinate.
02:23    Then you can also see that just with the class, I've got my constructor
02:27    function for the Point, and I've also got a property for setting X and a
02:32    property for setting Y.
02:34    So let's go back over here and copy some code.
02:37    So the first thing I am going to copy is this one right here.
02:41    I'll scroll down to my main function and paste that in. And what I'm doing here
02:45    is I'm creating a point, and the variable name is p1, and I'm creating new point
02:50    with an X coordinate and a Y coordinate both equal to 100.
02:55    From the outside looking in, this doesn't look any different than creating a class.
02:59    It's so happens that this is a struct.
03:02    So let's go back, get some more code.
03:07    I can also do the same thing this way.
03:09    Point p2 is s new point, and then I can set p2.x to 50 and p2.y, and this will
03:16    invoke the getters and setters the same way that I'd with the class.
03:20    Let's go ahead and hit F6, and you can see that the Build succeeded.
03:25    So if we scroll back up, you notice that pretty much the only thing is
03:28    different here is that I'm using the keyword struct instead of using the keyword
03:32    class right there on line 8.
03:34    So then you are probably asking yourself, okay, well, why would I want to use a
03:36    struct versus using a class?
03:38    Well, the main reason is because you've got some small data type.
03:41    In this case, I've got a point which only contains really two properties that I
03:44    really care about setting.
03:45    So if you got something small and you don't want all the overhead of a class, or
03:50    you don't have to worry about things like inheritance and overwriting stuff,
03:54    you can define a struct.
03:55    You can also use a struct when you don't want to have to worry about things
03:58    being passed by value or passed by reference.
04:02    Again, I explained that earlier in the section on value types versus reference types.
04:07    Structs are value types,
04:08    so you can pass these around as value types, and the values will be copied, and
04:12    you don't have to worry about references being changed without you knowing about it.
04:15    So anyway, that's a quick lesson on using structs.
04:18    You'll find that in many cases if you're define a small data structure, you
04:22    can use a struct in places where you would normally use a class.
Collapse this transcript
Using interfaces
00:00    The last subject that we are going cover in this section on building some more
00:04    advanced classes in C# is using interfaces.
00:09    Interfaces are a really neat little feature of C#.
00:12    They essentially provide a way for grouping a set of common behaviors in a
00:18    single place where more than one class can use them.
00:22    Now an interface is sort of like a class, but it provides a specification, or
00:28    you might think of it as a contract, rather than an implementation.
00:33    You can think of interfaces as an alternative to using abstract classes.
00:40    One of the nice things about interfaces is that classes can implement
00:44    multiple interfaces.
00:46    Now C# doesn't have the notion of multiple inheritance, like some other
00:50    languages do, but classes in C# can implement multiple interfaces.
00:57    One of the best ways of thinking about interfaces as opposed to classes is that
01:00    classes tend to be things, whereas interfaces tend to be behaviors.
01:07    So what I can do is I can group a whole bunch of functionality into an interface
01:11    and then that sort of becomes a contract.
01:14    If my class says that it implements an interface, then that class has to go
01:20    ahead and providing implementations for all of the functions that the
01:23    interface contains.
01:25    The nice thing about that is that my class can then advertise to the world,
01:30    hey, these are the interfaces that I implement and then in code that use my
01:35    class, the code can check my class to say, hey, are you able to implement this kind of interface?
01:41    And if it is, then the code that's using my interface can just say, hey, I know
01:45    that you know how to do this,
01:47    so I'm going to go ahead and call that method.
01:49    So let's take a look at how using interfaces makes grouping behavior more easy
01:55    to understand and implement.
01:56    So let's imagine I had a few classes.
01:58    I've got class A, B, and C. Now let's imagine further that these classes
02:03    all knew how to do something, like save their data out to some persistent storage place.
02:10    Well, they could all just implement a function name SaveData.
02:15    The problem is, without some interface to enforce this, class A might call it
02:20    SaveData, class B might call it something else, class C might call it something
02:24    else, but by grouping the notion of saving data into an interface called
02:30    ISaveable--and interfaces don't have to begin with a capital letter I, but it's
02:35    a nice convention that Microsoft has come up with for interfaces;
02:38    That way when you see it in a class definition you know that it's an
02:42    interface rather than class.
02:43    If I said, hey, I'm going to make an interface called ISaveable and anybody who
02:48    implements the interface called ISaveable has to have a function in their class
02:52    somewhere that's called SaveData.
02:55    So then I could do something like this.
02:57    I could say, you know what? Each one my classes, class A, B, and C, all implement
03:01    an interface called ISaveable.
03:03    Well, that enforces what's called a code contract.
03:07    So now everybody has to name their function that saves the data the same
03:12    thing, because they're all implementing from the same interface.
03:16    Now if I wanted to go a step further and say, you know what, not only do my
03:19    objects know how to save their data, they also know how to do something like
03:23    compress their data,
03:25    well, I could implement an interface called IShrinkable. And inside IShrinkable,
03:30    I might have a function called CompressedData.
03:34    Now notice in the interface there's no implementation of this function.
03:38    All that the interface says is, hey, if you implement me, you've got to have a
03:42    function named this. And the implementation is actually saved for the classes that
03:47    choose to implement it.
03:48    So if classes A, B, and C decided to implement both the ISaveable and
03:54    IShrinkable interfaces-- you separate them with a comma--
03:58    well, now each one of these classes has to have a function named SaveData, and
04:03    they all have to have a function named CompressData as well.
04:06    Now if one of these classes decided not to have shrinkable or saved or whatever,
04:10    they could choose not to implement the function. But if you say that you
04:14    implement an interface, you have to implement the members of that interface.
04:19    So let's take a look at this working in real code.
04:22    So here in the code I've got my UsingInterfaces example open, and I've got my
04:27    ExampleSnippets open and scrolled down to the Interfaces section.
04:31    So let's go ahead and copy over this line of code right here and paste
04:37    it into my program.
04:39    Now to declare an interface, you use the word interface and then you give
04:44    your interface a name.
04:45    It's kind of like declaring a class, although you'll notice that inside my
04:48    interface definition, I am not providing any implementation for these methods.
04:52    I am just saying that this interface contains two functions: one is called
04:55    SayHello, one is called SayGoodBye. And anybody who chooses to say that
04:59    they support the ITalkative interface has to provide implications for those two methods.
05:06    So let's go back over to the Snippets, and let's copy over this example
05:09    class right here called myExampleClass, and we'll paste that into my program over here.
05:16    So now I've declared a class called myExampleClass, and it says, yes, I am using
05:22    the ITalkative interface.
05:24    So here's the constructor for myExampleClass starting on line 16. And you'll see
05:28    that on lines 20 and lines 25, I've got implementations for the SayHello and
05:34    SayGoodBye functions.
05:36    Let's watch what happens really quickly if I take these out.
05:39    So I am going to cut this and save it and then build using F6.
05:44    You will see that if I try to build this, I'm now getting an error, why?
05:47    Because the errors say, hey, my example class does not implement interface
05:51    members SayGoodBye and does not implement interface member ITalkative.SayHello.
05:57    Well, that's because my class claims to implement ITalkative, but it's not
06:02    actually doing that.
06:03    There's no implications for the SayHello and SayGoodBye functions.
06:06    So let me just go ahead and paste those back in and save, and then we will hit
06:10    Build again using F6, and now everything is fine.
06:14    So let's go ahead and exercise this code, and we'll do that by copying these
06:20    lines of code right here and we'll paste them in there.
06:26    So now in my Main function I am declaring a variable, myEC, which is of type of
06:33    myExampleClass, and I am using the new operator to create that object. And once
06:37    I've created that object, I can say, all right, well, since you are a
06:41    myExampleClass and myExampleClass implements the ITalkative interface, I know
06:47    that you've got functions called SayHello and SayGoodBye.
06:50    So I can call each one of those.
06:52    So let's build and run.
06:54    We are going to hit F5 here, and you can see that sure enough, when we run the
06:58    program the functions for SayHello and SayGoodBye get executed and produce their output.
07:05    Let's go back to the Program here.
07:07    So once again, interfaces are a way of grouping together common points of functionality.
07:14    The interfaces are not things.
07:16    You don't instantiate an interface necessarily, although in certain esoteric
07:21    circumstances you can do that in C#, but we are not going to get to that in this course.
07:25    It's a little bit advanced.
07:26    What you do here is you simply create a class that says, I implement this
07:30    interface. And if you find yourself building classes that all have similar
07:34    behavior, it's probably a sign that you might want to make an interface that
07:38    groups that behavior into a common place and then have each one of those classes
07:43    implement that interface.
07:45    That way you can be sure that they're all getting the same behavior and that the
07:48    consumers of your class know that
07:50    that behavior can be counted on.
Collapse this transcript
8. Exceptions
Understanding exceptions
00:00    At some point in your C# coding experience you're going to have to learn how to
00:04    deal with error conditions.
00:06    Yes, I know, shock of all shocks.
00:08    Sometimes your code isn't going to work the way you thought that it would, or
00:11    something is going to happen to cause a problem in your program.
00:15    The way that we deal with that in C# and .NET is through the use of
00:19    exceptions, and that's what we are going to see how to use in this
00:22    particular section.
00:24    An exception is basically an error that happens during your program's execution,
00:29    whether it's because the user put in some data value that you weren't expecting
00:34    or the system runs out of memory or something else that happens.
00:38    So let's take a look at an example of an exception, and then we will learn about
00:43    how to handle exceptions in your code.
00:47    Let's imagine I have two variables, x and y.
00:49    They're both integers and I declared them as you see here.
00:53    Then I declare another variable called result, and I divide x by y. Well,
00:57    dividing 10 by 5, that's okay.
00:59    The result is 2. But what happens if I set y to 0, and then I try to divide x by
01:05    y, and oh, that's a problem: I'm dividing by 0.
01:09    What happens here is the .NET Framework raises what's called an exception.
01:14    In this case, it's a DivideByZero exception, and we'll learn about these terms
01:19    a little bit later, but the point is that an exception, just generically,
01:23    speaking is a problem in the code or somewhere in the system that you have to
01:29    anticipate and handle.
01:31    So before we go any further, let's learn about some exception terminology.
01:36    Exceptions are raised--or using object-oriented nomenclature,
01:42    they are thrown--when an error is encountered. When an exception happens the
01:48    normal flow of the program is interrupted, and the control is transferred to the
01:55    nearest exception handler.
01:57    You might say that the handler catches the exception.
01:59    So, the exception is thrown somewhere, and then it is caught somewhere else.
02:05    Now if there is no exception handler to process that exception and the exception
02:11    happens to be a fatal one, then the program just terminates with an error code.
02:16    Now not all exceptions are fatal, but some of them are and if the exception that
02:20    gets raised is fatal, then your program is going to stop working.
02:24    Now, exceptions don't just come from the .NET Framework.
02:27    You can build your own exceptions and then raise them yourself.
02:31    In other words, you throw your own exceptions using the throw instruction, and we
02:36    will see how to do that.
02:38    Let's take a look at an example of how exceptions are handled in code.
02:43    Now there are three main keywords you're going to have to learn about when
02:47    you're working with exceptions.
02:49    The first one is try.
02:51    Code that is placed inside the try block. Inside those curly braces is a bunch
02:57    of code that attempts to do something.
02:59    It doesn't matter how many lines you have in there. It could be one, it could five,
03:02    it could be 25,000; it doesn't matter.
03:04    The point is that inside that try block you're going to do a whole bunch of code.
03:08    You're going to assign a catch block.
03:12    Now this is actually optional, but you assign a catch block where you think an
03:16    exception might happen.
03:18    So if the code inside the try block might cause a problem then you assign a
03:22    catch block, and this is where exceptions are handled.
03:25    So if something goes wrong inside the code that's inside the try then the code
03:29    that's inside the catch is going to happen.
03:31    Then last, there is finally keyword.
03:34    And this code is always run.
03:36    It doesn't matter if things were great or things were bad,
03:39    if the code in the try section is completely just fine or if there was a problem
03:43    and the code in the catch section had to run, the code in the finally section is
03:47    always going to run.
03:49    So let's take a look at an example.
03:50    Suppose we had our example from earlier.
03:53    We have those two integers, one is 10, one is 0, and we have the result.
03:57    Well, if we try to divide x by y-- in this case we got 10 divide by 0--
04:01    that's going to cause an exception, in which case the program flow will be
04:06    transferred to the catch block. And here we are going to just write out, hey,
04:11    look at error happened, and we do a whole bunch of things in here. In
04:14    this case, we are writing out an error message, but there is other code that we
04:17    could've written here to try to handle the exception.
04:19    Maybe we could ask the user to try putting a different value, or we can just
04:22    try something else.
04:24    The point is that the code in the catch block is going run when the problem happens.
04:28    So let's take a look at some real code to see how to write this.
04:31    So I am in my UsingExceptions example, and in my Snippets you see I've scrolled
04:38    down to the Exceptions section.
04:41    So let me copy the setup code, and we'll paste it here into main. And we'll go
04:49    back to the sample, and we'll scroll down a little bit, and we'll take this entire
04:54    piece of try, catch, and finally, and we will paste that in as well.
05:01    So what I've done here is I've defined three different blocks of code:
05:05    one is called try, one is called catch, one is called finally.
05:09    Now if I run this code in its current state, I've got 10 being divided by 5
05:15    on line 18 right here, and that should just be fine.
05:19    What should happen is the Console.WriteLine for The result is, is going to be
05:23    executed, and it will show me the result.
05:24    So let's go ahead and run this and see what happens. And you can see that the
05:28    result is 2, and you can also see that a line is being written out there that
05:31    says, "Just proving that this code always runs."
05:34    And if we go back to the code, you'll see that
05:35    that's in the finally section down here.
05:37    Remember earlier I said that the code in the finally section always gets run;
05:41    it doesn't matter what happens in the try or the catch block.
05:44    So now let's change the code so that we have an error happen. So let's do this.
05:48    We are going to change y to 0.
05:51    So now we are going to 10 divided by 0, and that's going to cause a problem.
05:56    So we are going to get to line 18.
05:57    We are going to try to divide 10 by 0, and an exception is going to happen.
06:01    What that means that the code at line 19, this Console.WriteLine statement, is
06:06    never going to get run.
06:08    What's going to happen is the code is going to be transferred, the program flow
06:12    is going to be interrupted, and we are going to jump down here into this catch
06:15    block where this line of code, the An error occurred!
06:19    Better check the code line, is going to be run.
06:21    So now let's try this.
06:24    You can see that what happened was we tried to divide 10 by 0, which is a math
06:28    error, and you can see the Console. WriteLine inside the catch block is writing
06:33    out An error occurred!
06:34    Better check the code. And also we can see that the code in the finally block
06:39    always runs, because that Console.WriteLine also got executed.
06:44    So that's a quick introduction on how to use exceptions and as we move through
06:47    the rest of this section, we will learn more about how to create our own
06:51    exceptions and work with exceptions in a more advanced fashion.
Collapse this transcript
Introducing the Exception object
00:00    Exceptions are in fact objects, and in fact the exception object is defined and
00:06    derived from System.Exception.
00:09    That is the base class for all the exception objects in .NET. And the .NET
00:14    Framework actually defines a pretty large number of exception classes.
00:19    For proof of that, let's just quickly jump over to the MSDN web site and you can
00:22    see what I am talking about.
00:24    This is the Exception Class definition here on msdn.microsoft.com. And if you do
00:30    a search for System.Exception or if you go to the URL up there in the URL bar,
00:34    you'll see the exception class.
00:35    Now as we scroll down a little bit, you'll see that just like other objects,
00:40    there are constructors.
00:42    In this case, we've got four different constructors and there are some properties.
00:47    So these are the properties that exceptions make available.
00:50    There's Data and HelpLink and Message, and we'll explore some on these later on
00:53    as we through the exceptions, but what I really want to point out is as we
00:56    scroll all the way down, you'll see that System.Exception is the base class for a
01:02    pretty large number of exceptions throughout .NET.
01:05    Look at how large this list is.
01:07    This isn't even a complete list.
01:08    This is a list of a lot of the exceptions that descend directly from
01:12    System.Exception, but the one that we're most interested in is right here,
01:17    System.ApplicationException.
01:19    This is probably one of the most common exceptions that you will come in contact
01:23    with as a C# developer. And in fact, I've opened that window right over here.
01:28    So this is the ApplicationException class, and this class encapsulates all the
01:33    exceptions that are thrown when non-fatal application errors happen.
01:38    So once again, we can scroll down.
01:41    You can see that there is Properties, and there are all kinds of ways you can
01:44    create application exceptions. But once again we get down to the Instance
01:48    Hierarchy or the Inheritance Hierarchy.
01:50    You can see that a lot of other exceptions happen to descend from
01:54    ApplicationException. And this is true throughout .NET.
01:57    You've got exceptions that are descendents of other exceptions. And you might be
02:02    wondering, well, with all these different types of exceptions is it possible to
02:07    write catch handlers that only catch certain kinds of exceptions?
02:12    So to catch specific exceptions, you can put inside parentheses for each one of
02:16    the catch handlers the kind of exception that you're looking for.
02:20    So in the case that you see here, I've got a try block where I'm going to try a
02:25    whole bunch of code and then I have several catch handlers all in a row.
02:29    So I've got a catch handler for an exception that's DivideByZero.
02:32    I've got a catch handler for ArithmeticException.
02:34    I've got a catch handler in case we run OutOfMemory.
02:37    There are all kinds of stuff that I can put here, and I can put a generic catch
02:41    at the bottom of all these too that catches exceptions that don't get caught by these.
02:45    So let's jump over to the code and see how we can handle catching specific
02:50    types of exceptions.
02:51    So here we are in the example.
02:52    This is the ExceptionObject example.
02:54    I've got my program file open, and down in the Snippets I scroll to the
02:57    Exception Object section.
02:59    So let's go ahead and copy the set of code, and we'll paste that it into Main.
03:04    All right, now let's copy the try and catch, all the way down to the finally,
03:10    okay, and we'll paste that in.
03:13    You know what? Since we already know that the finally always runs, I am just
03:17    going to comment this line out.
03:18    We don't really need it for this example.
03:20    So let's comment it out.
03:22    All right, so this is pretty much the same example as I showed previously.
03:26    We've got two numbers.
03:27    We've got x here which is 10.
03:28    We've got y which is 0.
03:30    We have an integer for holding the result. And you can see here that we are
03:33    going to try to divide by zero.
03:35    The only difference from the previous example is that here I am now catching a
03:39    DivideByZeroException, and this is an arithmetic exception. And since I know that
03:46    it's a DivideByZeroException I can say, hey, you tried to divide by zero.
03:52    I can also write out members of the exception object that's passed in.
03:57    So when you catch a specific exception, you get an argument;
04:00    in this case I've named it e, but you can name it whatever you want to.
04:03    This will be passed into your catch handler, and this is the exception object
04:07    that caused the exception.
04:09    So we can do things like introspect that object and see things like what the
04:13    message that goes along with it is and so on and so forth.
04:16    So let's save this and let's build. Build succeeded.
04:20    All right, let's go ahead and run it and try to divide by 0 and see what happens.
04:24    Sure enough, you can see that You try to divide by zero.
04:27    Now that first sentence there, "Whoops!
04:28    You tried to divide by zero!"
04:30    is what I'm writing out, and the "Attempted to divide by zero!"
04:33    string is being written out from the message property of the exception object.
04:38    All right, let's go back to the code, and let's try something else.
04:43    Let's copy this catch handler and paste it down here.
04:47    Now what I am going to do is instead of looking for a
04:51    System.DivideByZeroException, I'm going to look for an ArithmeticException.
04:55    So I am going to hit dot and scroll down here, and I've got an
05:01    ArithmeticException right here.
05:03    So now I'm going to save, and I am going to build, and you can see that the build
05:08    succeeded. And what I am going to do is run this.
05:13    Now because I have the DivideByZero handler already in place, that's the first
05:17    one it's going to jump to.
05:19    The exception is going to jump to the first catch handler that makes the most sense.
05:22    So even though this is an ArithmeticException, it's going to jump to the
05:26    DivideByZero version, because that's more specific to the kind of exception I am seeing.
05:31    Let's try something else.
05:33    Let's take the ArithmeticException and cut it and put it in front of the
05:37    DivideByZeroException.
05:39    Now you'll notice that when I do that I get a little red squiggle on the
05:41    DivideByZeroException.
05:44    Let's see what that error is saying. It says, "Error:
05:48    A previous catch clause already catches all exceptions of this or of a super type."
05:54    What this basically means is because DivideByZeroException is a subclass of the
06:01    ArithmeticException object, this is never going to be called.
06:05    What's going to happen is a DivideByZeroException is going be thrown, but since
06:10    it's a subclass of this guy right here, this catch block is going to catch all
06:15    the math problems that might come up, including DivideByZero. And since it
06:20    occurs first, this code will never get executed.
06:23    So the C# compiler is catching that situation for me and saying, hey, you sure
06:28    you want to do this?
06:29    Why would you put in a catch handler that's never going to be called? So let's do this.
06:33    Let's take that WriteLine out, cut that line.
06:36    Let's put that in there instead. Let's see what the message is for
06:39    ArithmeticException, and let's just take out the DivideByZeroException.
06:43    So now I am catching the more general case.
06:46    I'm catching the ArithmeticException now, not just specifically the
06:49    DivideByZero, although DivideByZero is an ArithmeticException.
06:54    So let's run this, and you can see that we're getting the same message in this case.
06:58    So even though we got an ArithmeticException, it knows specifically what
07:01    happened, and the message in this case is an "Attempted to divide by zero."
07:05    So by using the ExceptionObject, your code can look for and catch specific
07:10    exceptions. And if you don't want to catch a specific exception, you can use the
07:15    catch handler. That just catches any exception that comes its way.
07:19    This is way for your code to be on the lookout for specific kinds of exceptions
07:23    so that it can take corrective action and try to prevent the user from having a
07:26    bad experience while using a program.
Collapse this transcript
Creating your own exceptions
00:00    Now I mentioned earlier that exceptions don't just simply come from .NET;
00:04    you can create your own custom exceptions--and in this movie we are going to
00:08    see how to do that.
00:09    Essentially, by sub-classing the exception object from the system namespace you
00:15    can create your own exceptions.
00:17    And then when you're ready to raise an exception, you use the throw instruction.
00:22    So for example, you can do things like throw a new System.Exception, or you can
00:27    throw a new MyCustomException.
00:28    You have to have the new in there because you've got to create the exception object
00:33    that you are going to throw, and then the throw keyword will cause the exception
00:36    to be thrown, and then the catch mechanism will go into effect.
00:41    So let's go over to some live code to see how we define our own exceptions and
00:45    then throw and catch them.
00:47    So I have my Custom Exceptions example here, and here is my Snippets. I've
00:51    scrolled down so they are creating exceptions section.
00:54    What I am going to first is just scroll down here and I am going to copy some of
00:58    the setup code, copy this, and I am going to paste this in my program. And then
01:05    I'm going to go back and I am going to ignore the catch section for a moment;
01:08    I'm just going to get the finally section, put that in here.
01:12    Now one of the first things you realize is that you don't actually need to have
01:16    a catch section at all.
01:17    You can just have try and finally if you want to.
01:20    So what I've got here is some code. I've got a string variable called the name,
01:24    and then in my try block I've got a function called getName.
01:28    Well, actually, I haven't defined it yet. That's why there is a little squiggle there.
01:31    But the getName function is going to ask the user to input a name, and it's
01:35    going to return it in the form of a string. And then I've got code on line 17
01:40    which simply writes out "Hello" and then whatever the name that you put in. And
01:44    then in the finally block, which remember always runs, we have a string that says, "Have a nice day!"
01:48    So let's go back to the snippets and get that getName function. And what I am
01:53    going to do is get this right here, copy that, and I am going to paste that
01:59    function in right up here. And for the moment I am going to just take this part out of it.
02:05    So what we are going to do in getName is use the Console.ReadLine function to
02:10    read a string, and then we are going to return that string.
02:14    So let's go ahead and run the code that we have and see how well it works.
02:18    So I am going to just build. It ran.
02:21    So now it's waiting for me to enter a name, and I am just going to type in the name scott.
02:26    It says, "Hello scott. Have a nice day!"
02:27    Great, okay everything is working fine.
02:29    Let's suppose we wanted to catch a certain name though and have that cause an exception.
02:35    So let's go back to the getName function, and what we are going to do is we are
02:41    going to say you know, if the string that was entered equals Joe, we're not going
02:45    to allow the word Joe to be put in.
02:47    So we are going to throw an exception called the NoJoesException.
02:50    Now we have to define the NoJoesException, which you see right here on line 14.
02:56    So let's go back to the Snippets and scroll up.
03:00    Here we have our definition for the NoJoesException.
03:03    Let's copy that, and we'll paste it in. And it's a class,
03:07    so I am going to paste it outside my program class.
03:10    So you can see on line 8, I've got a definition here for public class
03:14    NoJoesException, and there's the colon, which means it inherits from the exception
03:19    class, which is contained in the system namespace.
03:22    And remember, since I'm using the system namespace up here, I don't have to write
03:26    out System.Exception.
03:27    I can just use the word exception here.
03:29    So inside my NoJoesException, I've got my constructor, and my constructor is a
03:34    public NoJoesException constructor. And what I'm doing here is I'm calling the
03:40    base exception constructor with a string.
03:44    So before I go any further, let's just jump back over to the MSDN documentation
03:48    to see what the system exception looks like.
03:52    So here we are, in the documentation for the exception class.
03:55    Let's scroll down, and you can see that there are four different ways I can
03:59    construct an exception class.
04:02    There is a constructor that takes no arguments.
04:05    There is a constructor that takes an argument that's a string, and it says
04:08    here, "Initializes a new instance of the exception class where they specified error message."
04:14    Well, that sounds pretty much like the one I want. Let's just make sure.
04:18    Next one is exception with serialization and info and streaming context,
04:22    whatever that is, because it's obviously wrong.
04:24    And there's the exception here with a specified error message and a reference to
04:28    the inner exception. Okay, that's pretty advanced. I am not going to use that one.
04:32    Looks like number two is the one I want.
04:34    So I have to initialize a new instance of the exception class with the
04:37    specified error message.
04:39    Okay, that sounds great. Let's go back to the code.
04:41    Well, the way that I do that in C#--
04:43    well, there is a couple of ways I can do it.
04:45    First, I am just going to call the base-level constructor with the string here.
04:49    Now you might be wondering, why am I not just simply inside my constructor doing
04:53    something like this?
04:54    this.Message = No Joes allowed.
05:00    I am going to save that and I am going to build. Wait, we've got an error.
05:04    It says, "Property or indexer System.Exception. Message cannot be assigned to--it is read only."
05:10    Oh! So I can't actually make an assignment to that.
05:13    Looks like the only way to do it in this case is through the constructor. Okay,
05:17    well, I guess I won't do that then.
05:20    So it looks like this base method is the only way to do that.
05:22    So I'm passing in an error message to initialize the exception with "We don't
05:25    allow No Joes in here!"
05:27    However, I can give the user some help . And there is a field, or a property in
05:33    this case, called HelpLink. Again let's just jump over to the documentation very quick.
05:38    So if we scroll down, you'll see there is a property called HelpLink, and it
05:42    says, "Gets or sets a link to the help file associated with this exception." Oh cool!
05:48    Okay, so I can tell the user what to do in case an exception like this happens.
05:53    Let's go back to the code.
05:55    So what I am going to do is initialize my HelpLink here on line 13 to be a
05:59    link to my web site.
06:01    So back down here in the program--let me close this error window so we have more space--
06:06    you can see that when we get the input from the user, we are going to see if the
06:11    string is equal to Joe and if it is, we are going to throw the NoJoesException.
06:16    Now there's one more thing we have to do:
06:18    we have to implement the catch block for the NoJoesException. So let's go back
06:21    to the code, and down here in the Snippets we've got my catch handler.
06:26    I am going to copy that,
06:28    go back over here, and in between try and the finally, I am going to paste that in.
06:31    So you can see here what I am doing is I'm going to catch specifically a
06:36    NoJoesException, and I've named the variable nje.
06:40    So what I am going to do is write out the message, which is what I initialized
06:44    it with up in the constructor, and then another line I am going to write out "For
06:48    help, visit," and then I am going to write out the HelpLink field that's in my NoJoesException.
06:52    All right, it looks like everything is ready to go.
06:57    Let's hit F6. Okay, the build succeeded.
06:59    Let's hit F5 to run it.
07:01    All right, so I am going to type in "scott," "Hello scott Have a nice day!"
07:06    That seems to work okay.
07:07    Let's try it one more time with Joe. Oh!
07:10    Now, we get an error. It says "We don't allow no Joes in here! For help, visit:"
07:14    and then use the help link that I put into my help message for the user.
07:19    And of course in the finally block it says, "Have a nice day!"
07:22    All right, so this is how you can create your own exceptions, throw your own
07:26    exceptions, and use some of the fields provided by the base system exception
07:31    object to give your users some help and some detailed messages for when
07:34    those errors occur.
Collapse this transcript
Re-throwing exceptions
00:00    The last subject that we're going to examine in the area of exceptions is
00:05    that of rethrowing exceptions. And what that means is when an exception happens
00:10    inside your catch handler, you can do some processing, but if you handle the
00:15    exception, the exception pretty much stops with you.
00:18    You can keep it going by throwing it again, or hence the term 'rethrowing' the exception.
00:24    Now, why would you want to do this?
00:25    Let's take a look at an example, and hopefully that will make it a little bit more clear.
00:29    So here in my RethrowingExceptions example what I am going to do is go to my
00:32    Snippets and I am going to copy some code in over here.
00:37    So first, I am going to start with these lines down here, and I am going to copy
00:41    those and paste them into my Main function.
00:46    So I've got some code that calls a function called DoSomeMath, and it catches an
00:53    ArithmeticException and writes out a message that says hey!
00:56    Look, something went wrong in there.
00:58    You might want to be careful, or something like that. All right!
01:00    Now let's go back to the Snippets.
01:04    Let's copy the DoSomeMath function. All right and that's going to go up here.
01:11    So starting here on line 10 I've got my DoSomeMath function, and this is the
01:16    example that we've been working with up until now.
01:18    So what DoSomeMath is going to do is the same thing we've seen up until now,
01:22    which is try to divide by 0.
01:24    So here I've got my two variables on line 12.
01:26    I've got my result on line 13.
01:27    Here on line 15 I've got my try block, and I am going to try to divide 10 by 0.
01:33    Now, of course, what's going to happen is that's going to cause an exception.
01:37    So the catch handler will execute here, and I will write out something like hey!
01:43    You know, there is an error in DoSomeMath.
01:45    But I don't want the exception to just die here with me;
01:48    I want the exception to continue on and have other exception handlers do their
01:54    thing, because there might be some additional work that needs to be done.
01:58    So inside my catch handler, I am going to throw a new ArithmeticException.
02:04    Now, if I want to just rethrow the same exception, I wouldn't do this.
02:07    What I would do is I would just simply do this;
02:09    I would take out this new and just say throw.
02:12    What that means is, take the same exception that I am currently handling and
02:16    just rethrow it again. And that would be the same exception objects. Things
02:21    would just continue on as they were, and my catch handler would just be one and
02:25    a line of catch handlers.
02:27    But what I am going to do here is--let me put that code back in--I am actually
02:30    going to throw an entirely new exception called an ArithmeticException, because
02:35    remember, what I am catching here is a divide-by-0 exception.
02:38    So let's go ahead and save, and I am going to run this.
02:41    So you can see that what happened here is both catch handlers executed.
02:46    There's the catch handler inside the DoSomeMath function, and then there was the
02:51    catch handler that was in my Main program.
02:54    So let's go back and take a look.
02:57    You can see that this catch handler executed and this catch handler executed.
03:02    If I didn't have this line of code in here--and let me just comment it out, now
03:07    let's try rerunning it again--
03:09    you can see that in that case, only my catch handler executed.
03:12    So the other catch handler doesn't get a chance to run. The exception just gets
03:17    handled and dies in the DoSomeMath function and doesn't get a chance to continue on.
03:22    So by rethrowing the exception, or in this case throwing the new one, we give the
03:27    other exception handler a chance to do its stuff.
03:30    So why would you do this?
03:31    Well, suppose you've got an exception handler whose job is to just log out
03:36    whenever a particular exception happens.
03:39    You don't want that catch handler to be the be-all and the end-all.
03:42    You just want to insert it in the handling process so that that way your log
03:46    file shows that an exception happened. And then once that exception handler is
03:49    done logging out whatever information it needs to log out, it can continue on and
03:54    rethrow that exception so that the other real exception handlers in the process
03:59    somewhere get a chance to do their work.
04:01    So let's take a look at what happens when I take out the new ArithmeticException.
04:07    And I am not going to change the catch section right here.
04:10    I am just going to leave it alone.
04:11    So I am going to run it, and you can see that now both catch handlers are being
04:15    handled again. And because a divide by 0 is an ArithmeticException, the other
04:21    exception handler is being executed.
04:23    So this is a really great way to segment out your catch handlers so that each one
04:28    does its own little piece of work and they don't interfere with each other and
04:32    they are able to pass the exception on down the chain so that all the exception
04:36    handlers have the chance to do whatever it is that they need to do.
04:39    Just make sure that the last exception handler in the line is the last exception
04:43    handler in the line.
04:44    It doesn't pass the error up through to the user.
04:47    At some point, the error needs to be handled and not shown to the user--well, at
04:51    least in most cases.
04:52    So you're going to want to make sure that at least one of your catch handlers is
04:55    where the exception eventually stops.
Collapse this transcript
9. File Management
Introducing streams and files
00:00    We've reached the point now where we've seen enough C# to start doing some real
00:04    stuff, and one of the more common "real stuffs" that you'll probably do when
00:09    working with C# is moving information into and out of files. And the .NET
00:14    Framework provides some really great utilities for working with files and
00:17    information in files, and that's what we're going to cover in this section.
00:21    We're going to start off with an introduction to streams and files.
00:26    So let's start talking about that right off.
00:28    When you want to move the data into or out of a file or across the network or
00:32    over the Internet or some block of memory or some other location, the data has
00:38    to be what's called streamed.
00:40    You can think of a stream as an analogue to its real-world counterpart.
00:44    Think of water moving between two bodies of water in the form of a stream
00:50    or river or whatever.
00:51    In this case, however, the stream data is a bunch of 1s and 0s that represent
00:57    the information of a file, and the body of water is called the backing store.
01:03    Now the backing store can be anything. It can be a file.
01:06    It can be someplace on the network.
01:10    It can be some place out over the Internet;
01:12    it doesn't really matter what it is.
01:13    The point is the backing store is where the information goes to or comes from.
01:19    Streams have certain properties:
01:20    they can be readable, they can be writable, or they can be both.
01:25    Streams can also be what's called seekable.
01:28    In other words, some kinds of streams have this notion where there is a position
01:32    that you can look at and modify.
01:35    Sometimes this is called a random access stream.
01:38    Streams descend from the System.IO.Stream abstract base class.
01:45    Now we're not going to work too deeply with streams themselves in this section;
01:49    we're going to stick to the higher-level classes and utilities for working with files.
01:53    But it's important to have an understanding of what they are, and it's useful to
01:57    have this background so that later on, when you want to go and work a little bit
02:00    more deeply with files, you'll understand what a stream is.
02:03    So at the top, we have the stream class and again, this is an abstract
02:06    base class. And we looked at abstract base classes a little bit earlier in the course;
02:10    if you haven't watched that section, you should go do that now.
02:13    This is a class that forces you to create a subclass in order to provide an implementation.
02:19    So these stream abstract base class provides a whole bunch of abstract, or
02:23    theoretical, things that streams need to be able to do, and then the real stream
02:27    classes you work with descend from streams, such as the FileStream.
02:31    This is a class for working with physical files on the disk.
02:35    There is also the MemoryStream, which is locations located somewhere in
02:39    the computer's memory.
02:40    There is the NetworkStream.
02:42    This is used to move information across the network.
02:45    So actually, let's take a quick look over at MSDN so you can see what the stream
02:49    base class looks like.
02:50    All right, so this is the stream class documentation here on msdn.microsoft.com.
02:55    You can see the URL up there in the browser if you want to go and look at it for yourself.
03:00    The stream class--let's just scroll through this--
03:02    you can see that there's a constructor which makes a new stream, and there
03:06    are some properties, things like CanRead, and CanSeek, CanTimeout, CanWrite,
03:10    that kind of thing.
03:11    And if we scroll down a little bit further, there are methods,
03:14    methods for reading and writing information, for copying information, so on and so forth.
03:18    These are all the base-level functionality features that a stream has to
03:23    provide to its users.
03:24    Now remember, this is an abstract base class, so you won't actually instantiate a stream class;
03:30    what you'll use is one of the subclasses. And if you continue scroll down,
03:34    you'll see that underneath the System IO Stream, there is a whole bunch of other streams.
03:38    There's BufferedStream, there is FileStream, there is MemoryStream, and here is
03:42    the NetworkStream I talked about earlier.
03:43    These are the actual stream classes that you will use.
03:46    But we're not going to cover that right now;
03:48    what I'm going to do is talk about the file and directory higher-level classes
03:52    that we're going to use in this section.
03:55    .NET provides a collection of useful classes for working with files and
04:00    directories, so let's go over those right now.
04:03    One is called the File class, and this provides a very simplified high-level set
04:07    of functions for working with files.
04:09    In fact, this is mostly a static class where you call the methods of this class
04:14    using the file.notation. And if you haven't watched the section on classes, you
04:19    should go do that to understand what a static class is.
04:22    So file is probably the highest level example of working with files.
04:26    The next one down is the FileInfo class.
04:28    This provides more detailed lower-level functions that provide a little bit more
04:32    control over working with files.
04:34    Then there is the FileStream class, which I briefly talked about just a few moments ago.
04:38    This exposes a stream object around a file, which provides very detailed
04:42    control over how information gets written to and read from the file.
04:47    For directories, there is a sirectory class and this is sort of the analogue to
04:51    the file class. It provides very simple high-level functions for working with
04:55    directories, or folders. And then there's the DirectoryInfo class which provides
04:59    some more detailed lower-level functions that provide a bit more control over
05:04    working with directories.
05:05    So we're going to use some of these classes in the rest of the section to work
05:08    with files and directories.
Collapse this transcript
Working with existing files
00:00    Let's begin with something simple.
00:01    We are going to see how to work with existing files.
00:04    Now, the file class provides some features for working with files. And as I
00:08    mentioned earlier, most of the methods in this class are static.
00:11    You call them directly on the file object. And if you're not familiar with
00:15    static classes, you should go back and watch the section on classes to find out
00:19    what a static class is.
00:21    So the file object provides some really simple functions.
00:24    I am going to go over some of them here, not all of them, because it's quite a few.
00:27    But, for example, there is an exists method that checks to see if a file at a
00:31    given path exists or not and if a file does not exist, you can call a method
00:36    called create, which, surprisingly, creates the file at the specified path.
00:40    There are also functions for copying and moving and deleting files.
00:45    There is File.Copy, which copies a file to another location.
00:48    There is a Move function, which as the name indicates, moves a file, and there is a
00:53    delete function which deletes a file at a specified path.
00:57    So let's jump over to the code and exercise some of these functions and see how they work.
01:02    Okay, so I'm here in my existing project with my program file open, and here is
01:09    my Snippets. And I've scrolled down to the Existing Files section.
01:13    So let's begin by just checking to see if a file exists. And what I am going
01:18    to do is use a couple of other utilities to get a path to a special location
01:24    here on my computer.
01:25    So we're going be working with files in the My Documents folder, and I am going
01:29    to copy these first few lines right here.
01:34    So let's take a quick review of these lines of code before we do anything else.
01:38    So the first few lines, I have a Boolean variable called fileExists and I
01:42    initialize it to false because we are going to assume that the file doesn't exist.
01:46    Then we need to build up a file path, and the path just basically specifies where
01:51    on the computer the file exists or not.
01:54    So here I am going to say I have string called the path, and I am going to use a
01:59    special .NET class called the environment class.
02:03    The environment class gives me some utilities for working with the
02:06    Windows environment.
02:08    So I am going to ask the environment to get me a folder path, and the
02:11    GetFolderPath function can take a couple of different arguments.
02:14    I'm going to use the Environment.SpecialFolder.MyDocuments property, and this
02:20    will get me a path to the My Documents folder on this computer.
02:25    Now I could have just hard coded this by typing in C:\users\Joe Marini, so on and so forth.
02:33    That's really not a very good practice.
02:35    You don't want to hard code things into your applications if you can avoid it.
02:39    And windows, and in this case .NET, provides a bunch of utilities for working with
02:43    special document folders. Not just My Documents, but things like the temporary
02:47    directory and the trash or the recycle bin, that kind of thing.
02:51    So I am using this environment class right here to get the path to the My Documents folder.
02:56    So once I have the path to the My Documents folder, I'm then going to add on to
03:03    the end this string right here, which is testfile.txt. And recall I put the @
03:10    sign at the front of the string to prevent this \t here from being treated as a tab character.
03:17    I want the backlash to be treated as a path separator.
03:21    So at the end of all this I'll have a full path to a file named testfile.txt.
03:26    All right, let's go bring up my, My Documents folder, so
03:29    you can see what's in it.
03:31    Okay this is the My Documents folder, and you can see that right now there is
03:34    no file named test file.txt in here, so we're going to create it if it doesn't exist.
03:39    Let's go back to code.
03:41    We start off by using the File.Exists function here on line 17.
03:46    So we call File.Exists. That returns a Boolean result indicating whether the file
03:50    exists. And then I have an if statement and my if statement says if the file
03:55    exists. Then just write out to the console that the file exists.
03:59    Otherwise write out that the file does not exist and we are going to create it.
04:02    Then we call the File.Create function with the path, and this will create the file for us.
04:08    So let's go ahead and see what happens when we build and run this.
04:13    The code compiles and runs, and you can see that we're getting a message out to
04:16    the console that says, "The file does not exist. creating it."
04:19    So let's go back for our My Documents folder, and you can see now that the
04:23    test file has been created. And in this case, I am hiding known file extensions, so
04:29    you don't see that.txt on the end there, but it is there.
04:32    Okay, so test file has now been created. Let's go back and do some more work with it.
04:37    Let's go back to Snippets, and we'll copy this over, copy, and we'll paste this in.
04:52    Okay, so I am going to comment out these last two lines, just for a moment.
04:57    So once we've determined that the file exists, we can then get some
05:00    information about it.
05:01    In this particular section of code here I'm saying if the file exists then let's
05:06    figure out when it was created. And we are going to use the Files.GetCreationTime
05:11    method and the GetLastAccessTime method for the file, and we passed in the file
05:17    path both times to get information about the file.
05:20    And this will tell us when the file was created and when it was last accessed.
05:23    Okay, so now when I run the program again the file already exists,
05:28    so this part of the If statement should execute and we shouldn't have to re-create it.
05:32    So I am going to save, and I am going to run, and sure
05:36    enough, you can see that I am getting the message, "The file exists."
05:39    So we didn't have to re-create it, and you can see it was created on such and
05:42    such a date at such and such a time, and it was last accessed on such and such a
05:46    date and such and such a time.
05:48    Let's finish up our exercise by moving the file to a new location.
05:51    So I am going to hit return and exit on that.
05:53    Now I am going to uncomment these last two lines here, and we are going to move
05:57    the file somewhere else using the File.Move function.
06:01    And what we are going to do is move the file from its existing path--that's the
06:05    first argument--to the path, but we are just going to give it a new name.
06:09    So it's going to stay in the same folder, but it's going to be renamed to newfile.txt.
06:14    So we are going to save, and we are going to run, and you can see that we are
06:20    still getting the original message that it exists and the creation and access times.
06:24    And now we are moving the file.
06:26    So let's go back to the My Documents folder, and you can see, that test file is no longer there.
06:31    It is now called newfile.
06:33    So you can use these functions to operate on files that are existing or create
06:37    new ones on your file system.
06:40    And if you feel like getting a little bit more advanced, go take a look at the
06:42    file class. There is a whole bunch of other useful methods in there that you can
06:46    experiment with for working with existing files.
Collapse this transcript
Working with directory and disk information
00:00    As you might have guessed, just as there are ways for working with existing
00:03    files, there are ways to work with existing directories. And whether you called
00:07    them directories or folders, it doesn't really matter; they're the same thing.
00:11    But in the .NET Framework the class is called a directory.
00:15    Now working with directories is pretty similar to working with files, except that
00:20    directories can also contain other files and directories, whereas files just
00:25    contain information.
00:26    But there are classes for working with directories.
00:28    There is of course the Directory.Exists function which tells you whether a
00:32    directory exist or not.
00:33    You can also create and delete directories the same way you can with files.
00:38    You can figure out what the current directory is for the application.
00:41    This is the directory that the application is currently looking at, what it
00:45    thinks is the current one, where information will be written to or read from.
00:50    And just like in the other directories, they contain other things. You can get the
00:54    files and get the directories that are contained within a directory. And just
00:58    like files, you can move directories around.
01:00    So let's jump over to the code and exercise some of these functions so we
01:04    can see how they work.
01:05    Here I am in my ExistingDir project, and once again I've got my Snippets file open.
01:10    So I've scrolled it down to the Existing Directories part, and I'm going to just
01:15    copy these first few lines right here.
01:21    So this example, so far, isn't too different than the example we saw for the files case.
01:27    Right here at the top, I've got the string variable called the path, which I'm
01:31    using to figure out where the MyDocuments folder is.
01:35    Once again, I'm using the Special Environment class, and I'm calling the
01:40    GetFolderPath, which will tell me where the MyDocuments folder is. And just to
01:46    show you there are lots of features on here, I'm going to just hit little
01:49    dot here on special folder, and you can see there is a whole bunch of special
01:53    folder I can get paths to.
01:54    There is the Admintools.
01:55    There is CommonDocuments.
01:56    There's things like Music and Pictures.
01:59    There's the Startup directory.
02:01    There is the Desktop.
02:02    There is a whole bunch of special paths that you can get access to.
02:06    I'm just going to go ahead and leave it as MyDocuments.
02:08    This will get me the path to the MyDocuments folder.
02:11    Then we're going to call the Directory.Exists function right here on line 1,6 to
02:16    see if that directory actually exists or not.
02:19    Since it's the MyDocuments folder, I'm pretty sure it's going to exist.
02:24    So we have an if clause here that says if the directory exists then write out to
02:29    the console that it does; otherwise write out that it doesn't.
02:32    So this is a pretty good place to start.
02:34    Just go ahead and save and run this in its current form.
02:38    And you can see that the result is that the directory exists. So far so good.
02:42    Let's continue on.
02:44    Let's go back to the Snippets and get some more code.
02:47    What we're going to do now is use the GetFiles function on the directory class
02:53    to write out the names of the files that are in that directory.
02:56    So we are going to copy, and we are going to paste that down here.
03:05    So let's save, and let's take look.
03:07    So the GetFiles function that you see here on line 24 returns a string array,
03:13    which is why I'm declaring this string array variable called files, which will
03:18    hold the results of the GetFiles function. And I pass in the path which is now
03:24    the MyDocuments folder.
03:25    Then below that I'm using our newly discovered foreach loop construct, and so I'm
03:32    going to loop over all the strings in that files array.
03:35    So for each string--and I'm going to call each one of that S--that's in the files array,
03:40    I'm going to write out to the console I found a file plus whatever the file
03:44    name is right here.
03:46    Now I could use the Formatting String function, but I just chose not to
03:49    for simplicity here.
03:50    So let's go ahead and build this, and we can see the build succeeded, and let's run it.
03:54    It looks like we found a couple of files in there.
03:57    We've got a couple of contents of the directory,
04:00    so that seems to be working.
04:02    Let's hit Return and go back to the code. Let's move on.
04:08    Now we are going to do a little bit of extra credit.
04:10    It turns out that there is a class called Drive Info, and I'm going to leave that
04:15    up to you as an exercise to go onto MSDN and look up this class to see what it
04:20    does. But I'm just going to do a really quick simple experiment here. I want
04:23    to copy the code, and then we'll explain what it does.
04:28    So just like you can work with files and directories, you can also work with
04:33    disks or other storage devices that are attached to your computer.
04:38    So what we're going to do here is get information about each one of the disk
04:41    drives on the computer, as long as it is a fixed drive. You'll notice that there are
04:47    different kinds of drives when you look up information about this class.
04:51    There are things like removable drives and so on and so forth.
04:53    So what we're going to do is write out that we're getting the drive information.
04:57    You can see that up here on line 32.
04:58    Then we're going to call here on line 33 the GetDrives function, and as a
05:05    shorthand we're just going to loop this inside a foreach loop.
05:08    So we're going to get each DriveInfo, because the GetDrives function comes back
05:14    with an array of DriveInfo structures.
05:17    So we're going to say for each DriveInfo D which is in the array that comes
05:22    back from GetDrives,
05:24    we're going to execute the code in this loop. And we're going to ask the
05:27    DriveInfo if the DriveType is equal to the DriveType.Fixed.
05:33    Like I said earlier, there are all kinds of examples here.
05:36    If I hit the period, you'll see that there is CDRom and Fixed and Network and
05:39    so on and so forth.
05:40    So we're just going to stick with Fixed, and we're going to write out the
05:43    information about each one of the fixed drives.
05:44    We'll write out its name, how much free space it has, what type it is, and so on.
05:49    So let's go ahead and save. Let's build.
05:51    It works, and now let's run it.
05:55    You can see now that we're writing out some information about not just the
05:58    files, but the drive information.
05:59    So we seem to have too fixed drives: one is called C:, one is called D:.
06:04    They're both fixed and they both have a lot of free space. That's how many bytes
06:08    are free in each one.
06:09    That's a quick example for working with directories and drives.
06:12    Now let's move on and look at some more file information.
Collapse this transcript
Using the Path class
00:00    One of the things that you're going to find yourself doing over and over again
00:03    as you work with files and directories and so on is that there's a lot of
00:07    information contained in paths, and you'll find yourself having to parse out
00:12    paths to extract file names, or just the path portion, or just the directory name,
00:17    or just the file name without the extension. And it turns out that the .NET
00:21    Framework provides a helper class called the path class that makes a lot of
00:25    these operations really simple.
00:27    So if you look at the way a typical path is built, it has a predictable
00:32    structure. And here's a sample path, and this may look different based upon the
00:37    files you work with, but this is just a sample.
00:39    So right at the front, there's the drive name, and it can be a letter followed by
00:44    a colon, followed by a backslash.
00:46    The drive name is the root level of the path, and it's the disk or the
00:51    location where a file is.
00:53    That's followed by the path.
00:55    This is the directory structure that specifies where a file is located. And this
01:00    is usually a nested set of directories, or folders, whatever you want to call, them
01:05    that leads down to the actual file name itself, which is right here,
01:09    somefilename, which is usually followed by an extension.
01:14    Now not all file systems do this, but some do.
01:17    Windows, for example, does, and this also works on the Mac.
01:20    But since we're working here on Windows, we can pretty much be sure that most
01:24    files will have extensions.
01:25    So file extensions are usually a period followed by some amount of characters,
01:30    usually between three and five.
01:32    So let's take a look at the path helper class to see how we can use it to
01:37    help us work with paths.
01:40    In the Path Operations example, I've got my snippets file open, and I've scrolled
01:45    down to the Path Operations section. So let's go ahead and copy over the setup
01:50    code, and we'll paste it over here.
01:55    Now I'm going to be working with a path to the testfile.txt file which we
02:02    created in an earlier example.
02:03    So if you have deleted it, you can go just make a new file called testfile.txt
02:08    in the My Documents folder. And you can see here that I'm using the code I used
02:13    in the earlier examples to get a path to the MyDocument special folder here on my Windows system.
02:19    Let me make this a little bit wider, so you can see that.
02:21    So right here, this is the MyDocuments path, and then we're going to put the
02:25    testfile.txt on the end of it.
02:27    So this is the example file we'll be working with.
02:29    If you don't have that already on your My Documents folder, you should just go make one.
02:33    So what we're going to is save this, and I'm going to go back over to the Snippets and
02:37    start copying over some of the exercises.
02:40    So I'll start with this one, and I'll copy that and paste this over.
02:47    So the first thing we're going to do is extract the directory name from the
02:52    path information, and to do that, we're going to use the Path class. And again
02:56    this is a static class.
02:57    You are going to call most of these methods using the class name followed by
03:01    the function name--in this case it's GetDirectoryName. And you pass in thePath as the argument.
03:07    This will parse out all of the information that's not relative to the directory
03:11    name and then just return the name of the directory that's inside the path.
03:15    So let's save this, and let's hit F5 to run it.
03:21    And you can see here that in this case the directory name is C:\Users\Joe
03:25    Marini\Documents, and it's parsed out the part that is the file name.
03:29    It's giving me just the directory name. And you can see here it is a
03:32    fully qualified path.
03:34    What I mean by fully qualified is it starts at the drive, which is the root, and
03:38    goes all the way down to where the document is.
03:42    So it gives me the entire, full directory structure that leads to that file.
03:46    Okay, let's go back and do some more experiments.
03:50    The next one I'm going to do is get the example that extracts just the file
03:55    name, so this is the opposite of the example we just showed.
03:57    In this case, we're only going to ask for the file name. And in this case, we're
04:00    going to use the GetFileName function on the path class, and this will give me
04:04    the name of the file without the directory information.
04:07    So I'll save that and run it, and you can see here that now I've got the
04:13    directory name, and the file name is testfile.txt.
04:17    So that function parsed out all the information that was not relative to the
04:21    file name and just returned the full file name with the extension.
04:24    Okay, let's go back, and let's do another one.
04:30    We'll copy and paste this one.
04:31    In this case, we're going to get the file name without the extension.
04:36    So let's scroll down here.
04:38    You can see that the path class provides a function called
04:41    GetFileNameWithoutExtension, and again, it takes thePath as an argument.
04:46    So we'll save and we'll run, and in that case, I get just the file name without
04:52    the directory and without the three-letter extension on the end.
04:55    Okay, let's go back.
04:57    It looks like we have one more.
04:59    We're going to copy and we're going to paste and paste this in, okay.
05:07    In this case, the path class is going to give us a random file name.
05:13    Now you might be asking yourself, why would I ever need to get a random file name?
05:17    What this is going to do is ask .NET to generate some random file name for us.
05:22    It's going to consists of a certain number of characters, followed by a period,
05:25    followed by three characters.
05:28    The reason you might want to do this is because sometimes in your applications
05:30    you'll need to save out temporary data and rather than going through the
05:34    exercise of trying to figure out what file name you can come up with that
05:38    doesn't conflict with a file that's already existing in a particular directory,
05:43    you can just call GetRandomFileName.
05:46    .NET will then figure out what file name you can use that doesn't conflict with
05:50    a file that's already in the directory.
05:52    You can then use that file to save out whatever temporary data you have and then
05:56    get rid of the file. And this is the nice little utility to save you all the
05:59    trouble of having to figure out,
06:00    well, can I use this file name or can I use that file name, without conflicting
06:03    with an existing file.
06:05    So let's just go ahead in exercise and see what it does.
06:07    I going to run this, and you can see that the random file name for the current
06:12    path is this sequence of characters right here.
06:16    Now if I exit the program and run it again, you can see that it come up with
06:20    another set of characters here. And it will keep on doing that each time I run this.
06:24    So that's a nice handy little utility for creating random file names that you
06:29    know aren't going to conflict with existing file names in the current directory.
06:34    So that's a quick introduction to the path class.
06:36    I highly recommend you go look it up on MSDN and try some more examples on
06:40    your own.
Collapse this transcript
Reading and writing files
00:00    The last example that we're going to look at in this section is probably the
00:03    one you've been waiting for, and that is actually writing and reading data to and from files.
00:08    Now, there's lots of ways to do this in the .NET Framework.
00:11    The .NET Framework provides a whole bunch of ways for writing data to
00:14    and reading from files.
00:16    There's probably more ways to do this than there are ways to order sushi.
00:19    But we're only going to look at some of the more simple ways of doing this.
00:22    I mentioned earlier that we're not going to get deep into streams;
00:24    you can feel free to go do that as an extra credit exercise.
00:27    What we're going to look at is the higher level order functions for reading and writing data.
00:33    So for writing data, there are some really simple functions.
00:35    There's File.AppendAllText, which simply takes a bunch of text content and
00:40    appends it to the end of an existing file.
00:43    There's the WriteAllBytes and WriteAllLines, which, as their name implies, for
00:49    WriteAllBytes you can just give it an array of bytes; for WriteAllLines, you
00:53    give it an array of strings. They will write out the content to the file.
00:56    And then there's File.WriteAllText.
00:59    Now, unlike AppendAllText, WriteAllText will replace the existing contents of the file.
01:05    So if you want to just replace the content, use WriteAllText.
01:08    If you want to add to the existing content, use AppendAllText.
01:13    Not surprisingly, there are some counterparts for reading data.
01:16    There is ReadAllBytes, and as you might have guessed, this will read all the
01:21    content of a file as a bunch of binary bytes.
01:25    But for the purposes of our exercise, we're going to be working with text, so
01:29    we'll probably use things like ReadLines and ReadAllLines and ReadAllText.
01:33    This will actually read the contents of a file as text content.
01:38    So let's just jump over to the code and actually start exercising some of this,
01:42    so that you can see how it works. Okay.
01:44    In my ReadingWritingData example, I have got my Snippets opened, and I
01:48    have scrolled down to the Reading and Writing Files section.
01:51    So I am going to start off by copying over the setup code, which are these lines right here.
01:57    So I will copy those and paste them in.
02:00    I'll put them in my main function. All right!
02:03    So before we go any further, let's take a look at what's going on here.
02:07    So if you've been following the examples up until now, you're probably familiar
02:10    with the first line here on line 14.
02:12    This is the filePath.
02:14    We're going to be using the environment class to get the path to the
02:18    My Documents folder.
02:20    But we're going to be doing something a little bit different this time.
02:22    If you watched the section on the path helper class, which is previous,
02:26    you will probably notice that they are using a path helper section here.
02:31    Instead of using the backslash character hard coded into my examplefile.txt file
02:37    name, I am using the Path.DirectorySeparatorChar constant, which tells me what
02:44    the separate character for this file system happens to be.
02:47    Now, here on this version of Windows and .NET, it will be a backslash, but it
02:51    might be different based upon what platform you happen to be running on.
02:54    So I am going to just use this constant right here so that I don't have to hard
02:58    code a directory separator into my code, which is never a good idea.
03:04    So I am taking steps here to make my code work cross-platform. All right!
03:07    So now that we've got the path built up, we're going to see if the file exists.
03:13    And if you watched that particular example, you will know that we use the
03:16    File.Exists function do that, here on line 18.
03:20    So we'll see if the file does not exist, so we'll put that little not operator
03:25    right here in front of the File.Exists call.
03:29    So if the file does not exist then we're going to create it by using the
03:33    WriteAllText function.
03:35    So we'll have a string variable here on line 20, which will be the contents of
03:40    the file. And the content is going to be a string called, "This is a text file,"
03:43    And once again, I am using my environment class to figure out what the new line
03:48    character is for this particular platform.
03:50    So once again, rather than hard coding in a /r or /n, or whatever a state
03:55    sequence happens to be the NewLine character on this particular file system, I
04:00    will just use the NewLine constant for this particular environment.
04:04    Then I am going to write out the console that we're creating the file, and then
04:08    I'll use the File.WriteAllText method. And WriteAllText takes two arguments:
04:13    the first is the path to write to, the second is the text content that we are writing out.
04:18    So I am going to build this, and I am going to run it. And you can see that
04:25    the Creating the file... string got written out, because the file did not
04:28    exist in the My Documents folder. So now we've created it, and if you want to
04:33    go ahead and check your My Documents folder to see if it exists, you can go ahead and do that.
04:37    I am just going to keep on moving on here. All right!
04:41    So let's go back to the Snippets.
04:43    Now, let's use the AppendAllText method to add content to the file.
04:49    We'll copy, and we'll paste, and we'll save.
04:54    Okay, so I am going to build this, and now I am going to run it.
05:00    Okay, now you can see that I am adding content to the file.
05:04    Let's go back and look at the code and see what happened here.
05:07    The file already exists, so the if statement here on lines 18 through 23 did
05:12    not need to execute.
05:13    The file's content is getting appended,
05:16    so this line right here, Adding content to the file... got written out, then we
05:21    use the AppendAllText to add the added text string, which I am building up right
05:28    here into the file, and that writes the content out to the file.
05:32    So just to make sure that things are working okay, let's go ahead and open the
05:35    file up so we can look at the contents.
05:37    So here I am in my documents folder.
05:40    Let's open up examplefile, and you can see, here is, "This is a text file" and this
05:44    is "Text added to the file."
05:46    Well, that's great, but I would rather not have to open up Notepad to make sure
05:49    that the content is getting added correctly.
05:51    So let's see if we can read the contents and display the contents into the console.
05:54    All right, so back here in the code, let's scroll down. All right!
06:02    Now, we're going to read the contents of the file. So I am going to copy these
06:06    lines right here and back in my code,
06:11    I am going to paste them in.
06:13    So we're going to write out to the console that we are reading the file, and you
06:17    can see right here we're writing out that The current contents of the file are:,
06:21    and then it will separate a line, to separate the content.
06:23    Then we're going to use the ReadAllText static method on the file class to get
06:27    the current content.
06:28    The current content will come back as a string.
06:30    So we've got a string variable right here on line 35, which will hold the
06:34    results of the ReadAllText function on the filePath.
06:38    Once we have the current content, we will write out the current content to
06:42    the console, and then we'll put a little line separator to increase
06:46    readability right here.
06:47    So I am going to build. Okay, the build succeeds.
06:51    We run it, and you can see that we've now added content to the file and The
06:56    current contents of the file are:.
06:58    And we've got a couple of lines, "This is a text file," and then we've got "Text
07:01    added to the file" twice.
07:03    So I am going to hit Return.
07:04    I am going to run it one more time, because each time we run it, this line right
07:08    here, the "Text added to the file" is going to get added.
07:10    So I am going to run it again, and you can see that now that there are three;
07:14    and then I'll run it again and you can see that now there are four.
07:18    Okay, let's go back to the code.
07:21    One more thing I want to do here.
07:22    I want to show you how to read the contents of the lines of the file using the
07:27    ReadAllLines function.
07:29    I want to copy this, and I am going to paste it in over here.
07:34    This is just another way of reading the contents of the file, so I am going to
07:37    paste that in here. And for now, I am just going to comment out these lines,
07:42    and I am going to uncomment these lines, so that we can actually run the code.
07:52    So whereas the ReadAllText function on the file class will read all the content,
07:58    the ReadAllLines will read the lines and return an array of strings.
08:04    So ReadAllText comes back with one string; ReadAllLines comes back with an array
08:09    of strings, and that's this right here on line 40.
08:12    So I am declaring an array of strings-- that's this contents variable right
08:17    here. Then I call the ReadAllLines function, which will return an array, and
08:21    then here's our old friend the foreach function.
08:24    So I am going to loop over each string that is in the contents array, and I am
08:29    going to call each one of those strings the variable S. And inside my loop, I am
08:34    going to just write out whatever that S string is.
08:38    So let's build, and I am going to run, and you can see that we get the same
08:44    results, only this time, instead of reading the content as one long string, we
08:49    read the contents as an array of strings. All right!
08:54    That bring us to the close of this example and this chapter, so I highly
08:57    encourage you to go explore the file class and do some of your own experiments
09:01    working with reading and writing data to files.
Collapse this transcript
10. Some Advanced C#
Using variable parameter lists
00:00    Up until now we've been working with some of the more basic features of C#, and in
00:05    this section we're going to start looking at some of the more advanced features
00:08    of C# that were added in some of the more recent versions.
00:11    Now most of the stuff that you've seen so far you'll see in C# applications
00:16    all over the place,
00:17    but the ones that we're going to look at now are going to enable you to write
00:20    applications that are more advanced and have more concise code in them.
00:24    And we're going to start off by looking at something called variable parameter lists.
00:27    Variable parameter lists are useful because there's going to be times when you
00:31    want to create functions that take a number of arguments that you don't know in advance.
00:36    The way that you do this is by using the params keyword.
00:40    The params keyword allows you to define a parameter list for function that takes
00:44    a variable number of parameters, and it looks something like this.
00:49    Suppose I have a function that added a bunch of numbers together.
00:51    Now, I could add a whole bunch of numbers, but the problem is, without using
00:55    variable parameter list, I'd have to have a fixed number of parameters.
00:59    So for example, I could supply two integers, in this case, a and b.
01:03    But what if I wanted to add three integers or four integers or some
01:07    unknown number of integers?
01:08    Well, I could go the route of overloading methods, if you watched the movie on
01:13    that section, in which case, I would just define a whole bunch of addNumbers
01:18    functions and define a version of addNumbers that takes two arguments and then
01:22    one that takes three arguments and then one that takes arguments.
01:25    The problem is that gets really tedious really quickly and really bloats the
01:28    code. Or I could just simply use the params keyword and tell my function that it
01:34    takes an array of arguments.
01:36    So, for example, rather than just adding two numbers, I would do something like this.
01:41    And here I've used the params keyword and following the params keyword, I say int
01:47    with square brackets.
01:48    So this tells the C# compiler, hey, compiler, this function is going to take
01:52    an array of arguments.
01:54    And we don't know how long that array is going to be.
01:57    So the params keyword says, just be ready for a whole bunch of arguments.
02:01    Now once I've done that, I can rewrite the body of this function from just adding
02:05    two numbers to adding a whole bunch of numbers. And I'll use the foreach
02:09    construct to loop over each one of the integers in the nums argument that you
02:14    see there in the parameter list, and just keep a running total.
02:18    So let's jump over to the code and actually write this example and see it work.
02:22    Here in my variable params example, I've scrolled down to the Variable
02:26    Parameter Lists sections of my ExampleSnippets, and the first thing we're going to do
02:30    is copy over the function.
02:32    So this is the function that's going to add a whole bunch of numbers.
02:35    So I'll just copy this and go over to the program code, and I'm going to paste it in.
02:40    I'll paste it down here.
02:43    So now I have my addNumbers function, and you can see I'm using the params
02:46    keyword that takes an integer array of arguments.
02:51    So let's exercise this.
02:52    Let's go back up to the code. And I'm going to copy over this code here, which I'm
02:56    going to paste in the Main function.
03:00    So let's paste this in.
03:03    So let's take a look at what's happening here.
03:04    First, you'll notice that we have two different calls to addNumbers.
03:08    There is one here on line 14. There is one here on line 17.
03:11    The one on line 14 is passing in three arguments, 4, 6, and 8, and then the one
03:16    here on 17 is passing in a whole bunch of arguments.
03:18    So what's going to happen is each one of these calls to the addNumbers function
03:22    is going to generate an array of integers, and then inside my addNumbers, I'm
03:26    just going to loop over each one of the integers, add it to my running total,
03:30    and then return the total back to the caller, which will be stored in this
03:34    result variable right here.
03:36    So let's just build this and run it, and you can see that in the first case the
03:42    result is 18, and in the second case the result is 84.
03:45    So I've been able to now define a function that takes a variable number of
03:49    parameters so that I can write my code using this function and not know how many
03:54    arguments I'm going to have in advance.
03:56    Now there are a couple of things you need to keep in mind about the
03:58    parameters function.
03:59    One of the most important ones is that if you're going to use the params keyword,
04:03    that has to be the last argument to the function.
04:05    What I can't do is something like this.
04:09    You'll see that when I try to do that I get some errors, and if I mouse over it,
04:13    you'll see, "A parameter array must be the last parameter in a formal parameter list."
04:19    The reason for this is because since this is variable, the compiler has no way of
04:23    knowing how many arguments are in the array, and therefore, which argument goes
04:28    in the array and which integer is the last one.
04:30    So if I wanted to do something like this, I'd have to make sure that any other
04:36    arguments, whether they be strings or integers or objects, all of those have to
04:45    come before the params array.
04:48    So now we see that there is no error. Well, there is an error up here because I'm
04:51    not passing in the string integer object.
04:54    But anyway, that's how you use variable parameters in your functions.
04:59    So using the params keyword you can define functions that take a variable number
05:03    of parameters which greatly simplifies code that has to work on an unknown
05:08    number of arguments.
Collapse this transcript
Using function parameter modifiers
00:00    Earlier on in the course I talked about the difference between calling functions
00:04    and passing parameters by value and passing parameters by reference.
00:08    So if you haven't watched that movie, now is probably a good time to go watch
00:11    it, so you'll understand what's going on here, because I am going to be talking
00:13    about function parameter modifiers which allow you to change the way that
00:18    parameters are passed to and from functions.
00:22    So let's just take a quick recap to see how things normally work.
00:27    Suppose I had a function that takes an integer parameter, and it looks like
00:31    this, and inside that function, I have a piece of code that adds the number 10
00:36    to whatever that integer parameter was passed.
00:39    Now, if I call it from another function that looks like this, and I have an
00:42    integer named x and I initialize it to the value of 10, and then I call my
00:47    function, the code that's inside my function does not change the value of the x
00:53    variable in the test function down there below.
00:57    However, I can use a keyword in the parameter list for the function called ref.
01:03    This causes a parameter to be passed by reference, instead of having a copy of
01:08    its value passed in, which is what the normal case is in C#.
01:13    Now what I'd do here is I would declare my function as normal.
01:16    I'd have an integer parameter named param1, but I would put the ref keyword in front
01:21    of the type name--in this case integer.
01:24    This causes the param1 parameter to be passed by reference.
01:29    So now here I have my test function, and I've got my integer variable named x.
01:34    Now, when I call the function, I also have to put the ref keyword in front of
01:39    the parameter that I'm passing to the function.
01:42    When I do this param1 is now a reference to the x variable and not a copy of
01:49    its existing value.
01:51    This line of code here, param1 += 10, will in fact change the value of x down in
01:58    the calling function.
01:59    X will now be equal to 20 when this function returns.
02:04    The reason why I need the ref keyword in both places is so that it's really
02:07    clear what's going on in the code.
02:10    So you can deliberately do this when you want to be able to change the value of
02:13    parameters that are passed to functions.
02:16    So let's take a look at one more example.
02:19    There's the out keyword.
02:21    Now, normally functions return values through their return type, but the out
02:27    keyword allows a return value to be passed back via a parameter, and you would
02:33    use this in cases where you wanted a function to be able to pass back more than one result.
02:39    So let's take a look at an admittedly contrived example.
02:43    Suppose I had a function named SqrAndRoot, and SqrAndRoot takes a number as its
02:49    first parameter, and I want it to return both the square of that number and the
02:54    square root of that number.
02:56    I could pass in a parameter named sq, which would be the square, and I put the out
03:01    keyword in front of it.
03:03    I do the same thing for another parameter named sqrt, and I also put the out
03:08    keyword in front of that type named for that parameter.
03:12    Now, inside the body of the function, I would simply assign values to the square
03:17    and square root results.
03:19    So for sq I'd simply multiply num by itself, and that's the square of the number,
03:24    and then for sqrt I'm using the .NET Framework's math library to calculate the
03:29    square root of that number.
03:31    When I call this from a function, say, named test and I pass in the parameters,
03:36    you'll notice that I've to put the out keyword in front of the parameters
03:40    that I'm passing in.
03:41    So when I call SqrAndRoot, I pass in the first parameter, which is x. That's the
03:45    number I want to have the square and square root of.
03:48    Now when this function completes, theSquare and theRoot are going to have the
03:52    values that were calculated by the square and root function.
03:56    You notice I don't have to actually initialize those values, because those values
04:00    are going to be calculated for me by the function.
04:03    So I don't have to assign initial values to them.
04:06    Now, it's one thing to hear me yammer on about it;
04:08    let's actually go over to the code and actually watch it work.
04:10    Okay, so here I'm in my FuncParamModifiers project.
04:13    I've got my Snippets open to the code for this example.
04:17    So first, I'm going to copy this function, which is the SquareAndRoot function,
04:21    copy that and put it over in my code.
04:25    That's the function that we're going to call.
04:27    You can see I'm using the out keyword right here on line 10 to indicate to the
04:32    compiler that sq and sqrt are going to be out parameters.
04:37    I'm going to copy the code, going to call it with, and we'll put that down here
04:44    in the Main function.
04:45    Okay, I am going to put a line there.
04:47    So what we're starting off with here is a number,
04:50    in this case 9.0, and it's a double, and I've got variables named theSquare and
04:56    theRoot which are going to hold the results, and now I just simply call square and root.
05:00    I pass in 9 and I've got my out keyword in front of each one of the parameters
05:04    that are going to hold the output.
05:06    Then I've got Console.WriteLine call that says, hey!
05:09    The square of this number is this, and its square root is this, and I'm just
05:14    passing in those results to the WriteLine function.
05:17    So, everything looks good.
05:19    I hit F6, and it builds just fine.
05:22    Now let's run it, and you can see that the square of 9 is 81 and its square root is 3.
05:30    So it works just as we expected it to, and you can use the out keyword and the
05:34    ref keywords to change the way that parameters are passed to and from functions.
Collapse this transcript
Using optional and named function parameters
00:00    Okay, the next advanced C # feature we are going to take a look at are optional
00:04    and named parameters.
00:05    Now up until now when we've been calling functions with parameters we have been
00:08    supplying values for those parameters, because if we don't, then the C# compiler
00:13    complains that we left a parameter out of the function call.
00:16    Optional parameters allow you to define default values for parameters so that if
00:20    you don't feel like passing in a value for that parameter, you don't have to.
00:24    And the way that you do that looks a little bit like this.
00:27    So I can define a function, and you can see that I define the function normally
00:30    with two integer parameters. But I've got equals and then values after each one
00:35    of those parameters.
00:36    So here for my function, I don't have to supply values for a or for b, because
00:41    if I don't, then a will default to 0 and b will default to 1.
00:45    So, for example, it's just as valid for you call the function like this, where I
00:49    have got a just defaulting to 0 and b to 1, as it is to call it like this, where
00:54    a is now 10, but b retains its default value.
00:58    The other feature is named parameters.
01:00    Now up until the version of C#, I think it was 3.0, you had to call parameters in
01:05    the order in which they were declared in the function declaration; named
01:09    parameters, however, changed that.
01:11    Suppose, for example, that I have a function that looks like this.
01:14    I have got two integer arguments: one named a and one named b.
01:18    I can actually just simply call the function by passing in the name of the
01:22    parameter, a colon, and then the value, and it looks like this.
01:26    So if I wanted to call this function with parameters that are out of order, I
01:29    would simply say b:5 and a:3. And this would call the function normally.
01:35    And you notice I don't have to do anything special to the to the function declaration.
01:38    This just automatically works in C#.
01:40    So I can call the functions with the parameters that are out of order.
01:44    If I wanted to call the function otherwise, I could do it like this.
01:47    I can call the function with just the value 3, which is now a is 3 in that case,
01:52    and I'll put the name of b:7, although in this case I wouldn't have to do that.
01:57    Now notice that if you don't supply a named parameter, then they have to go first.
02:02    So, for example, if I wanted to this b:7 and then 3, that would cause an error,
02:07    because the C# compiler would say well, wait a second. You are not supplying a
02:11    name for a, and therefore I don't know which parameter you are talking about.
02:14    So you have to put the non-named parameters first.
02:18    Let's go over to the code and actually exercise this.
02:21    So here I am in my NamedOptionalParams exercise, and in the Snippets, under the
02:26    Named and Optional Parameters section, I am going to copy over the two functions
02:30    I am going to be using to exercise this.
02:33    So let's just copy these guys first and paste them into the code, and I will
02:38    put them below the Main function here.
02:39    So I have got two functions.
02:41    I have got one called myoptionalParamFunc, and you can see here that I've got a param here
02:48    that's -- param1, this is not optional because it doesn't have a default value.
02:52    This one here is optional because it's being supplied with a default value for
02:57    param2 and then for the third one, which is a string, I've also got a default
03:01    value which is a string value.
03:03    And it's worth pointing out here that you can provide default values for pretty
03:07    much just about any parameter type you can come up with.
03:10    Inside the function all we are doing is writing out what the function was called
03:15    with, and we will write out the values for param0, param1, and param2.
03:20    And you will notice here that I am using some escape sequences.
03:23    I have a \n and \t. That basically means, do a new line and then tab in, which
03:30    will make the results a little bit easier to read. All right!
03:33    Next, I have mynamedParamExample, in which case I'm going to call this function
03:38    with named parameters in the code from the Main function.
03:42    And again, you will notice, I don't have to do anything special to the
03:45    function declaration.
03:46    This just works with normal C# functions.
03:48    So let's go back and copy over the code that actually exercises these.
03:53    Let's start with the named parameters example.
03:56    So I will copy those lines and I will paste them into Main. All right!
03:59    So the first thing we are going to do is call the named parameter example, and
04:05    you can see I have got cityName, stateName, and zipCode.
04:08    I am just going to call them in different orders.
04:10    So the first example is going to call it with state, zip, and then city; the
04:14    second is going to call with city then zip and then state; and then the last one
04:17    is going to do zip, city, and then state.
04:20    So let's go ahead and exercise that.
04:22    We will build it and run it.
04:26    And you can see that in each one of the cases the arguments were passed in
04:30    different orders, but the output is in the right order.
04:33    So each one got its city name correctly, the state name is correct, and the
04:37    zip code is correct.
04:39    Okay, so let's do this.
04:40    Let's go back to the Snippets, and let's pass in the optional parameters example.
04:47    Copy this, paste it over here.
04:50    So now we are going to call the optionalParam function, and in each one of these
04:56    cases we are going to pass in a different set of values.
04:59    This one is going to pass in just one parameter.
05:01    This one will pass in two, and this one will do three, and then we will get to
05:05    this one in just a moment.
05:06    So let's save and build, and now we are going to run it, and you can see that now,
05:13    on the lower part of the output here, I have got Called with.
05:16    In the first case, you can see that the first parameter was 15 and then this two
05:20    second parameters were the default values.
05:22    In the second case, I passed in two parameters, so the first two parameters
05:26    are different, but the placeholder string is still the same. And in third case
05:30    I passed in three parameters which are different values and all of the default ones.
05:34    So let's go back to the code and see what happens when I uncomment this one right here.
05:39    Actually, before I do that, let me comment these guys out to make the output a
05:41    little more readable. All right!
05:42    So I am going to save. And you'll see that I am getting an error here, and the
05:48    reason I am getting an error is because the best overloaded method match for
05:53    blah, blah, blah has some invalid arguments.
05:55    What that basically means is, because I'm using optional parameters here,
06:01    you'll see that there is no version of myoptionalParamFunc that takes an
06:07    integer and then a string.
06:10    So this is a problem here.
06:11    If I'm going to pass in parameters that are being supplied instead of the
06:15    defaults, I have to supply values for all the optional parameters leading up to that point.
06:21    So I can't leave out the middle parameter here, because it thinks I am trying to
06:25    pass in a string value to this double right here, which is not correct.
06:29    So if you are going to use optional parameters and you want to supply values for
06:33    parameters in different orders, you will probably have to use the
06:36    named parameters and optional parameters in the same function call, which is
06:40    what we are going to do right now.
06:41    So let me comment that back out to get rid of the error. Now do both.
06:49    So to fix the error that I had above, what I am going to do pass in the value
06:55    for the first parameter, because it's mandatory.
06:58    There is no default value here, so I have got to supply a value to that, but
07:01    I want to skip over the middle parameter and just provide a string for the last one.
07:05    So to do that, I'm combining the named parameter feature with the optional
07:11    parameter feature. And now the compiler is like, oh, I see, you're trying to
07:14    supply a string for param3, which is over here, and not for param2.
07:21    Okay, well, that's fine with me.
07:23    So let's go ahead and build, and let's run it, and you can see now that all the
07:28    cases work. And this is the most recent case we just added.
07:31    So we have got the mandatory value here,
07:34    the default value is now being passed in for param2, and in the last case we have
07:38    a different string being passed in for param3.
07:41    So optional and named parameters really allow you some great flexibility in how
07:45    you define your functions.
07:46    They allow you to define default values for parameters that you don't want to
07:51    make mandatory for the caller, and named parameters allow you to call functions
07:55    with parameters in different orders.
Collapse this transcript
Using the C# preprocessor
00:00    During your C# coding travels, you're probably going to come across C#
00:04    preprocessor directives, and that's we are going to cover in this particular movie.
00:08    The preprocessor is what its name implies.
00:11    It does some pre-processing of the files before the compiler actually goes and
00:17    looks at all the code and compiles the application.
00:20    The preprocessor directives simply give instructions to the compiler
00:24    which help the compiler do its job before the compilation process actually runs.
00:29    Preprocessor directives are preceded by a hash character, or a pound character, or
00:35    whatever you want to call it.
00:36    So we'll take a look at some of those here.
00:38    The first two are define and undef, and you can see that they have got that
00:42    little--I guess you can call it sharp character, if you want to, whatever is it,
00:45    it has a word preceded by that little character.
00:49    In this case, define and undef allow you to define or undefine a symbol.
00:55    Now, why would you want to do that?
00:56    Well, we will take a look at an example that explains why you would want to
00:59    do that in just a moment, but there are a few other directives we want to look at first.
01:03    Using preprocessor directives, you can also do things like logic.
01:06    You can use #if, #else, #elif, or #andif, and these allow you to use logic to see
01:13    if a certain symbol is defined.
01:15    Now if the light bulb hasn't gone off yet, don't worry; it will in just a moment,
01:18    but there are two more directives we want to take look at.
01:20    They are region and nregion, and these are used for documenting your code, so that
01:27    the C# Express development environment allows you to do things like label
01:31    regions and collapse regions and so on.
01:34    But rather than just talk about them, let's actually see them in action, because
01:37    slides just don't do it justice.
01:39    Let's jump over to the code.
01:40    I have got my preprocessor example open here, and here is my program file.
01:46    The first thing I am going to do is this:
01:48    I am going to do a couple of defines.
01:51    Now, if you're going to define symbols, you need to do it before any other line
01:56    of code in the file.
01:57    So I need to put these defines up here above the using statements; otherwise, this
02:01    will cause problems.
02:02    So if I try to take these out and put them down here and save, you'll see
02:07    that these little red squiggles show up, and that's because the compiler is complaining.
02:11    It says hey, you cannot define or undefine preprocessor symbols after the
02:15    first token in the file. And that's just a fancy way of saying, these got to come first.
02:20    So let's go ahead and cut those and put them back up there.
02:25    So now I have defined some symbols, but what exactly does that mean. Why am I
02:28    defining symbols in the first place?
02:30    Well, the reason for doing this will become clearer when we paste in the rest of
02:34    the example. And I am going to go ahead and paste these guys in down here, copy,
02:39    and I'll put these in the Main part of my program.
02:43    So what you'll do here is you will notice that when I've got these #if and #else
02:48    and #endif, they are checking to see if a particular symbol has been defined.
02:53    So let's imagine that you're building a version of your application where you
02:56    only want to include some code if it, say, in a debug configuration, or if
03:03    it's in a demo mode.
03:04    Suppose I wanted to have this code right here only included in my application
03:10    if I'm shipping a demo version of my application, versus a fully released, fully
03:15    functional version.
03:16    Well, in that case I can simply change this from the DEBUGCODE to DEMOMODE or
03:21    whatever it is that I want.
03:22    You can see I have also defined a JOE symbol here.
03:26    I can make up whatever symbol I name I want.
03:27    Now, what's going to happen is the compiler is going to come across this logic
03:30    and say #if DEBUGCODE. Okay, well, if there's a symbol name DEBUGCODE then the
03:36    code that's in between this #if and #else is going to be included in the
03:42    compilation process and code that does not meet that logic test is not going to be included.
03:47    You can see here on line 18 that this code is in gray.
03:51    That's because the compiler is going to ignore it.
03:53    I can just write things that's not even code in here. Watch!
03:56    No red squiggles, right? Why?
03:58    Because the compiler is completely ignoring this code; it's not meeting the
04:02    logical test to see if the DEBUGCODE symbol is present.
04:05    Let me go ahead and delete that.
04:08    So now if we build and run--let's just do that really quickly, build and run;
04:12    we will hit F5--you'll see that the lines of code that met the logical tests of
04:18    those preprocessors was included in the application and they are executing.
04:22    So let me hit Return and get out of here.
04:24    Now let's go back up to the top.
04:26    What I am going to do is I am going to take out this #define for JOE, and we'll save.
04:31    Now watch, notice how the line of code that's inside this #if, #endif section
04:37    for the JOE symbol went and turned gray.
04:40    That's because I've gotten rid of the JOE symbol and this line of code is no
04:44    longer relevant, because this logical test on line 20 no longer evaluates to true.
04:49    Similarly, I can get rid of the #define DEBUGCODE, and you'll notice that the
04:54    line of code that used to be included in the compilation process when DEBUGCODE
04:59    was defined is now gray and the else condition is now being included.
05:03    So this bright line right here, it says:
05:06    "This only gets written out in non- debug code" is going to execute.
05:09    So if I run this now, you will see that that line of code is getting executed
05:13    where the other lines of code are not getting executed.
05:15    In fact, they are not even included in the program.
05:17    If you were to disassemble this code using a disassembler, you'd notice that
05:21    those lines of code aren't even present in the final application. Okay.
05:25    So let's take a look at one more preprocessor directive, and that is the region directive.
05:30    What I am going to do is copy this right here, #region.
05:33    I am going to put that in front of the Main, and then I am going to copy the
05:40    endregion. And I am going to put that below the Main function right here.
05:48    Now when I save, what that does is it tells the C# compiler that this is a region of code.
05:53    Now, this doesn't affect compilation.
05:55    It's really just for documentation, because watch what I can do now.
05:58    Over here in the C# Express IDE, I can click on this little collapse button and
06:04    you can see that it collapses down, and the text that I've included after the
06:07    region declaration here on line 10 is what gets included in that little label.
06:12    So I can collapse that down and you can see now that all that code is hidden.
06:16    So if I wanted to just collapse my code down to make it easier to read, I can
06:20    separate my code into different regions and then expand and then collapse them as I see fit.
06:25    Now if you're coming from other languages, such as C or C++ or Objective-C,
06:31    you'll probably see sometimes these preprocessor directives used to define
06:36    constants, and you'll see the #define directive used to define numbers and so on.
06:43    That's not the way things are done in C#.
06:46    In C# we have the const keyword, which we discussed earlier in the course
06:50    for defining constants.
06:52    So 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:00    You can use the const keyword instead.
07:02    Here, we are going to use the #define and #undef and so on, just to affect the
07:07    way that compilation happens.
Collapse this transcript
Working with delegates
00:00    Next couple of subjects that we are going to take a look at are fairly advanced,
00:04    and they are delegates and events.
00:07    I am going to start off by taking a look at C# delegates.
00:10    C# delegates are sort of like callbacks that you may have seen in other languages.
00:14    If you're familiar with programming languages such as JavaScript or Java or C or
00:20    C++, then you're probably familiar with the notion of a callback function.
00:25    A callback function is assigned at runtime and you can change callback functions
00:29    while the program is running. And the callback function is simply a way for you
00:33    to provide a piece of functionality that can be switched in and out as it is
00:37    needed. And delegates provide that functionality in C#.
00:40    Essentially, a C# delegate decouples the caller of a function from the call
00:46    function, which is essentially the same thing that callbacks do.
00:49    So to declare a delegate use the delegate keyword, and you're essentially
00:53    defining a type of function that is going to be called.
00:57    So I use the delegate function. Then I provide the type that the delegate
01:02    is going to return.
01:03    So in this case I'm declaring a delegate that returns an integer. Then I need to
01:08    provide a name for the delegate, and I can make it up as much as I want to.
01:12    I can use whatever a legal function name would be.
01:15    In this case I am just using the generic term delegateName, but you can use
01:18    whatever name you want. And then you have to provide any parameters that the
01:22    delegate is going to handle.
01:23    In this case I'm declaring a delegate that returns an integer and takes two parameters:
01:27    there is an integer and a string.
01:30    Then when I want to use the delegate, I use it like any other kind of type name.
01:34    So in this case I'm declaring a variable named func, which is of type
01:40    delegateName, and I'm assigning it to be someFunction.
01:43    So as long as I declare someFunction to be the same format as the delegate that
01:48    I have declared above, I can switch that function in and out as much as I like.
01:52    Then I just call the function like I would any other function.
01:55    In this case I've got an integer result which is being assigned
01:59    to the result that comes back from the func variable, which is now pointing at
02:03    the someFunction function, and it takes the integer argument 3 and the string argument "hello."
02:09    Then all we have to do is actually write the someFunction callback. And you can
02:14    see here that I've got a function named someFunction, which returns an integer
02:18    and takes two parameters--an integer and a string--and it has the same format as
02:23    the delegate that I declared at the top of the slide there.
02:27    So let's jump over to the C# code and actually implement this and see how it works.
02:32    Okay, so I am here in my delegate example, and I've got the UsingDelegates
02:37    project open, and I have also got the ExampleSnippets file open, and I've scrolled
02:42    down to the section on using delegates.
02:45    So the first thing I am going to do is copy my delegate declaration.
02:49    That's this line right here, so I will copy that and I will paste it into
02:52    the Main program here.
02:55    Now I am going to paste this inside the namespace but outside of my program class.
03:00    So I will just put it up here. And this basically says to the C# compiler, hey
03:04    compiler, there's going to be this thing called a function that has the format
03:08    of returning an integer and taking an integer argument, so be on the lookout for it.
03:14    So I am going to save that, go back to the snippets.
03:17    Now I am going to scroll down here and copy these two functions,
03:21    the functions Square and Cube.
03:24    So let's copy these guys, and we'll put them in the code outside of the Main function.
03:31    Now notice how each one of these functions returns an integer and takes an
03:36    integer argument, just like the delegate is declared up here.
03:41    So this delegate returns an integer and takes an integer argument. All right!
03:45    Now we can write the code that actually uses the delegate.
03:48    Here is what we are going to do. To do that, we are going to go back over to
03:52    Snippets and we are going to copy this piece of code right here.
03:57    Let's put this in our Main function.
04:00    Let me explain what's going on here.
04:02    Now that I've defined my delegate as a NumberFunction--that's this guy right
04:07    here--I can now declare that as a variable.
04:10    So on line 15 I am creating a variable named f which is of type NumberFunction,
04:16    and remember, that's a delegate.
04:17    So I can assign to f the name of a function that matches the same description as the delegate.
04:24    In this case, it's the Square function.
04:27    So down here is the Square function.
04:29    It takes an integer argument, and it just simply returns the square of that number.
04:32    It takes that number and multiplies it by itself.
04:36    So, on the next line, on line 16, I am doing a Console.WriteLine that says. the
04:41    result of the delegate is. and then the result number is going to go in here, and
04:45    then I simply call the function f with the number 5.
04:48    So f is now pointing at the Square function, because I assigned it to that up here on line 15.
04:52    So, I am going to call the function f with 5, and that's going to square the number.
04:58    That's going to write out the number 25.
05:01    So let's go ahead and run that. But before we run, that let's comment out these
05:04    two lines, so we can isolate the results for the moment. All right!
05:07    So we will save and we will run, and you can see that the string that's being
05:12    written out is the "result of the delegate is 25," just as we expected.
05:16    Okay, so far so good.
05:17    Now what we're going to do is uncomment these lines. And notice I'm changing
05:21    the delegate on the fly.
05:23    So now, instead of the f variable pointing at the Square function, it's going to
05:28    point at the Cube function.
05:30    So, while the program is running, I'm changing what the function that's going to
05:34    be called is, by changing the value of the f variable from Square to Cube.
05:39    So now this f variable right here on line 19 is going to be pointing at this
05:44    function down here to Cube.
05:45    And Cube takes the number and multiplies it by itself three times, which is how
05:50    you arrive at the cube of a number.
05:53    So on line 20, I am going to write out the result of the delegate is, and then the result.
05:58    I am going to call the function the same way.
06:00    I am going to call the function f with the value of 5, but in this case the
06:04    result is going to be very different.
06:06    So we should see two things written out.
06:08    We should see this line written out here, when f is pointing at the Square
06:12    function, and then we should see a different value written out here, when f is
06:17    pointing at the Cube function.
06:19    So let's build, and we can see the Build succeeded.
06:21    Okay, let's run it.
06:24    And you can see that the result of the delegate is 25, and then the result of
06:29    the delegate is 125, which is what we would expect, because we changed the
06:34    delegate to point from Square function to the Cube function.
06:38    Delegates are a really powerful and flexible programming construct in C#.
06:43    They do the same thing as callback functions, but they do it in a more modular way.
06:48    If your code calls for such flexibility, such that you need to be able
06:51    to provide callback functions, the way that you accomplish that in C# is by
06:55    using delegates.
Collapse this transcript
Handling events
00:00    In this example we're going to see how to use C# events, and specifically we're
00:04    going to create our own events and our own event handler.
00:08    Now the work in this particular movie is based on the delegates movie.
00:12    So if you haven't watched that one, you go back and watch it now because events
00:16    need delegates to work, and it's important that you understand delegates before
00:20    you attempt this movie.
00:21    So there are four steps involved in declaring and triggering C# events.
00:27    The first is that we have to create a delegate which is the event handler.
00:30    And just like we did in the previous section, we do that by using the delegate
00:34    keyword and then we declare the delegate named. In this case have got an
00:39    EventHandler which returns a void value.
00:42    So there's no return value from this function.
00:44    And then I declare the parameter list.
00:47    In this case, there is an integer parameter and a string parameter.
00:51    Now inside the class that's going to implement this event, I need to use the event keyword.
00:55    So what I do is I define a my class, and I do that normally with my class
01:00    definition. And then somewhere in my class I do something like this.
01:03    I say public and then the word event in front of the EventHandler delegate name,
01:10    and then I give it a name which is going to be used by the consumer of this
01:14    class to hook onto my event.
01:17    So somewhere else in the code someone who is using this class is going to write
01:21    something like this.
01:22    They'll write myClass and then some variable name, in this case object
01:25    equals new my class.
01:27    So now they've created an instance of this class.
01:30    Now what they want to do is listen for, or sometimes the word subscribe is
01:34    used, to this event.
01:36    To do that, they'll use the myEvent property which I've declared up there in myClass.
01:42    They'll use the += operator to specify a handler function that will be used
01:49    to handle that event.
01:51    This is called subscribing to an event, and it adds the handler function to the
01:55    list of functions that the myEvent is going to broadcast to.
01:58    Then what all I have to do is declare that function.
02:01    Here I've got a handler function, and notice that it matches the same format as
02:05    the delegate that I declared in the first line up there.
02:08    It say void function, and it takes two parameters, an integer and a string, and
02:13    then it implements whatever code there is.
02:15    Now this is the function that's going to be called whenever that event happens.
02:20    And you can see that there's the += operator. That subscribes to the event.
02:24    If you wanted to have your code to stop listening to an event, you would simply
02:28    use the -= operator and the same name of the function that you used to subscribe with.
02:34    So let's take a look at this in action in real code.
02:37    All right, so I've got my UsingEvents example open, and here is the
02:42    program code, and over in my snippets I've scrolled down to the using the events section.
02:46    So let's just take this one step at a time.
02:48    I'm going to first copy over the delegate declaration for myEventHandler.
02:52    So I am going to copy that and paste it inside my namespace here, outside my
02:57    program class. And this basically tells the C# compiler, hey there's going to be
03:02    this thing called a delegate which is an event handler and it takes a string
03:05    argument, and I'll supply that later. Don't you worry about it, but it's going
03:08    to be coming along.
03:09    Okay, now let's go ahead and declare a class, and this as an example class that's
03:15    just going to raise an event that other people can listen to. And I'll put that
03:20    class declaration up here above my program.
03:22    So let's take a look at the class declaration, and then we'll go further.
03:26    Here in my class I've got a member variable for this class on line 13, and
03:30    it's called theValue.
03:31    I've also got an event handler for valueChanged here on line 14.
03:37    So whenever this string value here called the value changes I'm going to
03:42    raise an event so that people who are using this class can listen for it and
03:46    say, oh, the value changed.
03:48    Then I've got a property right here starting on line 16. And if you are not
03:53    familiar with properties, you can go back and watch the section of this course on properties.
03:58    But I am exposing a public string property named val, and you'll notice that I am
04:02    only supplying a setter which starts here on line 18.
04:06    So the setter does two things.
04:07    First, it sets the value of theValue member variable to whatever the value
04:13    supplied to the property was.
04:15    And then it calls the value change event here on line 21.
04:20    So anyone who is subscribed to listening to this event is going to get notified
04:25    that the value has changed.
04:27    And it passes in the value of this private--the value member right here as
04:33    the first argument.
04:35    All right, so all that's left to do now is go back over to the Snippets and copy
04:41    over the code here that listens for the event, and I will put that in my Main.
04:50    So let's go through this line by line.
04:53    Here on line 30 I am creating a new instance of my event example class, and
04:59    that's this class right here-- the one that implements the event.
05:02    And I have got a variable called myEvt.
05:06    Then on line 32 I say myEvt.valueChanged, which is the name of the event.
05:11    All right scroll back up.
05:13    You can see there on line 14, that's the value changed event, +=new
05:19    myEventHandler, which is the name of the delegate. And then I need to supply the
05:25    name of the function that's going to handle that event. And the reason there is
05:28    a red squiggle there right now is because I haven't declared the my Evt_value changed function.
05:34    So let's go do that right now. Back over in the snippets I'm going to copy this
05:39    function right here.
05:40    This is my Evt value changed, and I am going to copy that and paste it, and I am
05:46    going to paste it below the Main function.
05:49    So now you can see the little red squiggle error has gone away, because now I
05:52    have a function which is going to handle the event.
05:55    And let's just take a quick look at the event handler.
05:57    So here on line 46, you can see that in the function all we do is just write out
06:02    the value of that argument that was passed to us.
06:06    And if we scroll back up to the class, remember that when we call this event
06:10    we are going to pass in the string that is represented by the private, the value
06:15    member of my class here.
06:17    So now we're pretty much about done; all we need to do is take a look at
06:21    what lines 34 through 41 are doing.
06:23    What I've got here is a string variable, and then I have a dowhile loop. And what's
06:29    going to happen is I'm going to read a line of text from the console, and if that
06:34    string is not equal to the value of exit, I'm going to set the public property of
06:40    the myEvt object to that string.
06:43    Let's scroll back up.
06:45    That's going to cause the setter of this property to trigger.
06:48    It's going to set the value of the theValue member variable to that string, and
06:54    then it's going to trigger the event.
06:56    And so this loop is going to just keep right on executing until I type in the word exit.
07:02    And when the word exit gets entered, the program will terminate, because there's
07:05    no more code after this in the Main function.
07:07    All right, so let's actually run this.
07:10    Okay, so now the program is waiting for me to put in the string, and I am
07:14    going to put in the word Joe. And you can see that when I set the value of that
07:19    string, the event handler gets triggered.
07:22    My event handler gets called.
07:24    The string gets passed in as the argument and we are just writing out that string.
07:28    I can type in anotherstring.
07:32    And once again, the event handler gets called. I can yet another string, and I can
07:37    go on and on like this, but now I am just going to change the value to exit, and
07:43    then the program terminates.
07:45    So that's how you declare an event handler and an event in C# using
07:50    delegates and the event keyword.
Collapse this transcript
11. Garbage Collection
How garbage collection works
00:00    Earlier in the course, you may have heard me refer to C# and .NET as a
00:04    managed-code environment.
00:05    What that basically means is that the .NET Framework provides automatic
00:09    memory management for you.
00:10    You as the programmer are not responsible for freeing up the memory that your
00:15    program's objects use during the course of the running of your program.
00:20    Now, this is not like other languages.
00:22    In languages like C and C++ and Objective-C, you as the programmer, when you
00:28    create objects that take up memory, you are responsible for making sure that
00:31    that memory gets returned to the system at some point.
00:35    But languages like .NET and other language like JavaScript in Java and so on,
00:39    those are managed-code environments.
00:41    There are ways that the system figures out that memory is no longer being used
00:45    by your program and reclaims it automatically.
00:48    Now, to take a simple example, when you do something like this in your C#
00:52    program, you have some object type definition, maybe you've made a new class,
00:56    and you use the new operator to create a new instance of that object,
01:00    that allocates memory somewhere in the system. That tells .NET, hey, you've got
01:05    to go find some memory to hold my object.
01:08    And the Framework will take care of figuring out when this object is no longer being used.
01:12    You don't have to do anything special. .NET will just figure out that you're
01:16    done using this object, and it will put the memory back in the system for you.
01:20    So let's take a look at conceptually how this works.
01:23    There is a big pool of memory available to the system, and we can think of it as
01:27    this big purple box you see right here.
01:30    Now, your program is going to use this memory during the course of its
01:34    operation. And as your program runs, it's going to allocate blocks of memory and
01:39    when it does that those blocks of memory are going to be taken out of the system
01:43    memory pool and assigned to your program. And then in your program will do
01:46    whatever it does with that memory and all these objects.
01:49    At some point there is a special class in the .NET Framework called the
01:53    Garbage Collector, and garbage collection is the process by which .NET figures
01:58    out that memory is no longer being used by your program and can take it back into the system.
02:04    So the Garbage Collector has a way of keeping track of the objects that you have
02:07    allocated, and when it figures out that these objects are no longer being used,
02:11    it simply puts them back in the system memory pool.
02:14    This process is completely invisible to your program.
02:17    You don't have to worry about doing this at all.
02:18    It all just happens for you.
02:20    So let's take a look at how garbage collection works.
02:23    Suppose we have a function, looks like this.
02:26    It's called myFunction. And inside myFunction I've got this new MyObject.
02:32    Well, out in the system memory pool when I do that, a block of memory is going
02:35    to be allocated that holds MyObject.
02:37    That creates what's called a reference.
02:40    That myObj variable that you created inside your function is now going to hold a
02:44    reference to that memory location.
02:47    Now, you can go and do a bunch of things:
02:49    you can call a method, you can set a property, you can call SomeOtherMethod.
02:54    But when that function ends, that myObj variable is going to go out of scope.
02:59    And at that point there are no more references to MyObject. Because that
03:03    variable is gone now, that little reference line disappears. And the Garbage
03:07    Collector comes along and says, hey, no one is using that thing anymore.
03:10    I can just return that object back to the memory pool.
03:14    So what are some important things to know about garbage collection?
03:17    First, your program does not need to initiate this process; the Garbage
03:21    Collector figures out when it needs to run and reclaim memory.
03:25    Now, there is a way for your program to initiate garbage collection, and we'll
03:28    actually take a look at that in an example in just a bit.
03:31    The Garbage Collector balances between performance and app memory usage, and the
03:38    objects are not necessarily reclaimed right away.
03:41    So these two things mean that you, A, don't know when Garbage Collection
03:47    is going to happen.
03:48    The Garbage Collector tries to figure out how your program is doing its work and
03:52    how much memory is being used, and it tries to strike a balance between making
03:57    sure that your application doesn't take a performance hit while figuring out how
04:02    much memory is being used and trying to say, okay, well, memory use is getting
04:05    kind high, maybe I should go take some of that memory back.
04:08    The other thing you need to realize that when you're finished with an object,
04:11    it might stick around for a while until the Garbage Collector figures out that it needs to run.
04:15    Now, objects can detect that they are about to be released from memory, so
04:20    when you create an object in a class, you can actually write a method called the finalizer.
04:25    Now, this is rather advanced.
04:27    I'm not going to cover it in this course. But you can just be aware that there
04:31    are ways for your objects to figure out that they're about to be released back
04:35    into the system memory pool.
Collapse this transcript
The Garbage Collector object
00:00    Let's take a look at a real example to see how garbage collection actually works.
00:04    So I've got my Garbagecollection project open up here, and in my Snippets file I
00:09    have scrolled down to the Garbage Collection section.
00:11    So let's go ahead and take a look at some of the garbage-collection routines
00:16    that are available to us.
00:18    So first I'm going to copy these three lines and paste them into my application.
00:24    Now there is a global object in .NET called GC.
00:29    You can see I'm using that right here on line 12.
00:32    The GC object is the Garbage Collector, and I'm going to call a function on the
00:38    GC object which is a static function here called GetTotalMemory. And it takes a
00:43    parameter--I'm not going too deeply into this. Don't worry about what this does.
00:46    Basically I'm saying to Garbage Collector, hey, tell me how much total memory is
00:50    currently allocated to my application.
00:52    So this is a pretty simple place to start.
00:54    Let's just build this and run it and see what happens.
00:56    So I'm going to run it, and the console is going to write out how much allocated
01:00    memory there is to my app. And you can see that when I run this the amount of
01:05    memory that's allocated to my application right now is 186,836 bytes.
01:10    Now don't worry if this number looks different for you and your example. This is
01:14    going to different for everyone's system.
01:16    This is basically how much memory is currently allocated to my app.
01:20    So let me hit Return, and we'll exit the app.
01:23    Okay, let's go back to the snippets and paste in some more information.
01:26    So the next few lines I am going to copy right here, and I'm going to paste
01:29    those below these lines.
01:32    So starting on line 16, I'm going to allocate 100,000 bytes in an array that holds bytes.
01:40    So this is 100K of memory that I'm going to allocate, and then I'm going to
01:44    basically do the same thing here on lines 18 through 20 that I do at the
01:49    beginning of program. And we'll see if this makes a difference in how much memory
01:52    that Garbage Collector thinks is allocated to my programs.
01:55    So let's run, and you'll see that we start off with 186,000 bytes.
01:59    Now let me hit Return, and this is going to cause the allocation to happen.
02:03    And now you can see that the amount of memory allocated to my app is 295,060 bytes.
02:09    Now notice it's not exactly 100,000 bytes more than the original size. Again,
02:15    don't worry too much about that, and don't worry too much if this number looks
02:19    different for you on your system.
02:21    The .NET Framework keeps track of a whole bunch of overhead internally, so when
02:26    I allocated those 100,000 bytes, a lot of other things happened under the hood.
02:31    So it looks like more memory got allocated then I asked for, but that's just the
02:35    .NET Framework doing its work.
02:36    So let's go back to the application.
02:40    Now what we're going to do is actually trigger the garbage-collection process,
02:44    so I am going to copy these lines here, and I'm going to paste them in here.
02:49    And you'll notice that on line 22 I'm calling the Garbage Collector's collect method.
02:54    This will actually trigger the garbage-collection process.
02:58    So we're going to start off by seeing how much memory my application gets when
03:02    it starts. Then we're going to allocate a whole bunch of memory and see how much
03:06    that changes things.
03:07    Then we're going to call the Garbage Collector's collect function which will
03:11    cause the Garbage Collector to go out and look at memory and say, hey, how much
03:14    memory isn't being used and how much can I reclaim? And that's going to be this
03:19    line right out here. We're going to write out what the results of that are, so
03:22    let's save this and run it.
03:25    Okay so we start with 186k. It goes up to 295k. Now let's watch what happens
03:32    when the Garbage Collector runs and we call that collect function.
03:34    Okay, it looks like the allocated memory dropped back down to about 210,000,
03:40    almost 211,000 bytes.
03:42    Again, I didn't get all hundred thousand bytes back, and that's because, as I said,
03:48    earlier the .NET Framework has some overhead that it's working on. So it did
03:52    figure out, however, that those bytes actually aren't being used by anybody.
03:56    So I was able to reclaim those bytes by running the garbage-collection process.
04:01    Now again, I want to emphasize that this is just an academic exercise here and
04:05    shows you how the Garbage Collector works.
04:07    There are going to be very few instances in your C# career when you're going to
04:11    have to actually care about running the Garbage Collector, if ever.
04:15    I've been working with C# for a long time.
04:17    I've never actually had to do this. But it interesting to see how the Garbage
04:20    Collector works and what you can do with the Garbage Collector to figure out how
04:24    much memory your application is consuming.
Collapse this transcript
12. Debugging
Common compilation issues
00:00    In the long, and no doubt illustrious, C# coding career that lies before you, you
00:06    are going to have to deal with compiler issues and bugs, and that's what we're
00:10    going to talk about in this section, debugging, and we're going to start off with
00:14    dealing with common compilation issues.
00:17    Now, many of these are fairly common, and they tend to trip up new C# developers.
00:22    Don't feel bad if this happens to you.
00:24    I personally assure you that I myself have committed every single one of the
00:28    issues I am about to show you.
00:30    So I've got my CompileIssues sample project opened, and what I am going to do is
00:33    walk through each one of these issues and show you why each one is a problem.
00:38    So I am going to start with issue number one.
00:40    Let me uncomment this line of code, and we'll save. And we've got a problem.
00:45    In fact, let me hit the F6 button to try to build, so we can see what the
00:48    problem exactly is, and I will scroll that code into view.
00:52    We can see here down in the error list it, says, ah!
00:54    There is a semicolon expected.
00:57    Well, a semicolon is expected at the end of every line of C# code.
01:02    If you're coming from a language like JavaScript where semicolons are optional,
01:06    you need to realize that in C#, that's not the case.
01:08    You do have to have a semicolon that terminates every single one of your statements.
01:13    Double-click on the error, and it takes us right to that point in the code.
01:17    We can put in our semicolon, and save, and then we can build, and now everything
01:21    is all right again.
01:22    Now we're getting a bit of a warning here that says that the myString variable
01:26    is assigned, but it's never used, but let's just ignore that for the moment.
01:30    Go down to issue number two.
01:32    So issue number two, I am going to uncomment this line of code, and once again we
01:35    get a whole bunch of errors.
01:38    Sometimes it's tempting to try to look for the error that's the simplest to fix
01:42    and try to fix it that way.
01:43    In fact, if you look in the error list, you'll see that there's a bunch of errors.
01:46    One of them says "; expected," One of them says ") expected."
01:50    So you might be tempted to just jump to that line and try to like put a
01:53    semicolon in to fix things;
01:55    that's actually the wrong thing to do here.
01:57    What I suggest you do is start with the topmost error, because sometimes when
02:01    you fix the topmost error, that will fix all the errors below it. And if you
02:06    look really closely at this line, you'll notice that the problem is that I
02:10    didn't close off the string using double quotes. And sure enough, once I do that,
02:16    all the other errors go away.
02:18    Before you try to figure out which is the easiest problem to solve, try to
02:22    figure out what the actual error is, because now you can see that the compiler
02:25    is saying, oh yeah, there is a semicolon, and oh yeah, there's the parentheses.
02:29    It just couldn't see them before, because it thought they were part of the
02:32    string, Hello World.
02:35    In the next issue, I'm going to use an ArrayList.
02:37    If you watched the section on collections, you know what ArrayLists are.
02:41    They are a type of collection that works like an array.
02:44    I am going to uncomment this line, and sure enough, we've got problems.
02:48    If we look in the error list, it says, "The type or namespace name
02:53    ArrayList could not be found (are you missing a using directive or an
02:57    assembly reference?)."
02:58    That's just a very long-winded way of the C# compiler saying, I don't know what that is.
03:03    And there's also a visual cue.
03:05    You'll notice that objects that are recognized by the C# compiler are
03:09    highlighted in a certain color, like the console object right here.
03:13    Now ordinarily, ArrayList would be highlighted as well, and it's not, and that's
03:17    your first clue that something is wrong, along with this giant red squiggle
03:20    underneath it that gives you the error.
03:23    It turns out that the problem is I have not included the right namespace in
03:27    order to use ArrayLists.
03:29    So I have to scroll to the top of the file, and sure enough, I'm using the
03:34    System.Collections.Generic namespace, but ArrayLists are contained in the
03:39    System.Collections namespace.
03:42    So I have to say using System.Collections. And when I put that using statement
03:49    in, you can see that the problem goes away.
03:53    Let's scroll back down to where that code is, and you'll see now that the
03:57    ArrayList object is highlighted in light blue the same way that the console is,
04:02    which means that the C# compiler is recognizing it. All right!
04:06    Let's move on down to the next issue.
04:08    I am going to uncomment these lines of code right here.
04:12    I am going to save, and you see that we're getting a complaint that a
04:22    curly brace is expected.
04:24    The curly brace is actually expected way down at the end of the program. Well,
04:28    clearly something is pretty wrong here.
04:31    And if we scroll back up to where the error actually is, you'll notice that
04:36    I've got my open curly brace here and a closing curly brace here, and those seem to match up.
04:42    You can see that when I put the cursor next to the curly brace, the IDE
04:46    highlights the two braces to show me they match.
04:48    But the problem is that I have actually got an extra one all the way over
04:51    here on the end of the for statement, and that's causing the compiler to
04:56    think that all the rest of the code following that line is contained in an
05:01    unclosed curly brace block.
05:03    Once I get rid of that extra curly brace and I save and I hit F6, you can see
05:09    that that error goes away.
05:11    So the lesson here is, indentation does not necessarily mean what blocks are.
05:17    You have to put braces so they match each other.
05:20    Just because you put one brace up here and another brace in another line down
05:23    there, does not mean that those make a block.
05:26    You have to make sure that you have the same number of closing braces as you
05:30    have opening braces; otherwise, you're going to get weird errors like that.
05:35    Let's move on to issue number five.
05:37    I am going to uncomment this string right here, I am going to save, and I am
05:41    going to get a nice big red squiggle.
05:43    It says down here in the error list:
05:45    "Too many characters in character literal" and "Cannot implicitly convert
05:50    type 'char' to 'string'."
05:53    What's going on here?
05:54    I've got my quotes.
05:55    I've got the string defined. The problem here is that you can't use single
06:00    quotes to define a string in C#;
06:03    you must use double quotes.
06:05    The single quotes are for individual characters. And so you see that when I put
06:12    the single quotes into double quotes, the error goes away.
06:16    Now, I am getting another warning that says that that string is not used, but
06:18    don't worry about that for now.
06:20    Scroll down to the next issue.
06:21    I'm going to uncomment these two lines.
06:29    So I have an integer array of values and it's called myarray = 0, 1, 2, 3, 4,
06:36    so we've got 5 items in the array, and then I am trying to set the array item at
06:41    index 2 to be 10, and I am getting an error.
06:44    It says "'myarray' is a 'variable', but it is used like a 'method'" and the
06:49    problem here is that you don't use parentheses to index into arrays; you
06:54    use square brackets.
06:58    Parentheses are used for calling function; brackets are used to index into arrays.
07:05    You can see that once I change the brackets, everything is fine. All right!
07:08    Let's go on to the next issue.
07:10    I am going to uncomment this call to Console.WriteLine, and then I get an error.
07:15    It says, "'System.Console' does not contain definition for 'Writeline'."
07:19    What are you talking about? Sure it does.
07:20    I've been using Writeline throughout this course.
07:23    There's a function there called Writeline.
07:24    I know that there is. In fact, I used it probably up here earlier. See, there it is!
07:28    And then I realized, oh, wait a minute!
07:29    No, there is a capitalization problem in there.
07:33    That actually has to be a capital L. That's because C# is a case-sensitive
07:39    language; case matters.
07:41    This is something you'll run into probably at least once when you're
07:44    writing your C# code.
07:45    You need to make sure that the cases match. That's true of variables.
07:49    It's true of function names.
07:50    It's true of almost any type of declaration that you make in C#.
07:55    Let's move on to issue number 8.
07:58    In issue number 8 I have got three lines of code.
08:01    I've got an integer variable that's set to 2,500,
08:04    I've got a floating-point variable that's set to 35.895, and then I'm trying
08:12    to set the value of f into the value of i. Now, I've got two different
08:18    problems going on here.
08:19    First, "A local variable named 'i' cannot be declared in this scope, because it
08:23    would give a different meaning to 'i', which is already used in a 'child' scope
08:26    to denote something else."
08:28    That's a very, very long-winded way of saying, you know what, I've already used
08:32    i somewhere else in this code block.
08:34    So if I scroll back up, there it is.
08:37    I've already used the i variable in this for loop.
08:41    So it's not going to let me use it again down here.
08:44    No problem. I will just simply call this i1, and I will call that one i1.
08:51    I've got another problem. The problem here is-- let's look at the error list--"Cannot
08:55    implicitly convert type 'float' to 'int'.
08:58    An explicit conversion exists (are you missing a cast?)." Yes, I am.
09:04    Remember, you can't implicitly cast a variable that is of a larger size into a smaller size.
09:11    You have to explicitly tell the compiler that you're doing that.
09:14    So what I need to do to convert a float into an int, I have to put the word int
09:19    in parentheses. And what this tells the compiler is, hey compiler!
09:23    Treat that floating-point number as if it were an integer, which will let me
09:27    assign it to another variable that is of that same type--in this case integer.
09:32    And you can see when I put that cast in front of the F, everything goes away, and we're fine.
09:37    Next issue, issue number 9, I am going to uncomment these lines.
09:41    I've got two integer variables: one named a, one named b. And then I've got an
09:45    if statement, if (a = b) then we're going to write out, yup!
09:49    They're equal numbers, and no sooner do I do that, then oops!
09:52    I get an error, and it says, "Cannot implicitly convert type 'int' to 'bool'."
09:57    What's the problem here?
09:58    I am not trying to convert anything to anything.
10:01    Well, remember that inside if statements what you're checking for is a Boolean condition.
10:06    That's how the if statement knows to execute. And the problem here is that I'm
10:10    not using double equals signs.
10:12    I'm using the assignment operator, not the equality check operator.
10:16    So once I change this to the equality check operator, the error goes away,
10:20    and everything is fine.
10:22    One more issue that I want to show you, and you'll run into this, and sometimes
10:27    it can be pretty confusing as to what's going on.
10:29    I am going to uncomment this entire function.
10:31    I've got a function here called func, and it takes an integer variable and if
10:38    that integer parameter is greater than 0, then it returns 0.
10:43    If that parameter is less than 0, it returns -1.
10:46    But I'm getting an error.
10:48    It says, "CompileIssues.Program.func: not all code paths return a value."
10:55    The problem here is that I've declared this function to return an integer value,
11:00    and I am returning an integer value here and returning an integer value here.
11:05    But what happens if the parameter a is equal to 0?
11:08    Well, there's no path in here that returns a number.
11:12    I have to make sure that if my function is going to return a value, then all of
11:16    the possible code paths that it can take have a return statement in there.
11:20    There's a couple of ways I can fix this.
11:22    I could put in an if case for a is double equal to 0, but since that's
11:27    the only case left, and the function would have returned by now if any other
11:31    case have been encountered, I can just simply say return whatever else.
11:35    I can say return 100, or I can return 1,000, or I can return whatever I want as
11:40    long as it is a valid return type.
11:44    Those are 10 of the most common compilation issues that you'll probably run
11:48    across in your C# coding.
11:50    Next, we're going to take a look at how to use the debugger to look at
11:53    code while it's running.
Collapse this transcript
Setting breakpoints and examining code
00:00    As useful as it is to be using the console and the Console.WriteLine methods to
00:06    see what's going on inside our application while it's running,
00:09    there's really no good substitute for using a good debugger which you can use to
00:14    examine the code while it's actually running. And the debugger allows you to do
00:18    things like place breakpoints in your code, examine the code, examine variables,
00:23    change things while it's running, and so on.
00:26    If you've done any kind of programming in other environments, like, say,
00:29    JavaScript using either Firebug or the WebKit Developer tools or coding
00:34    environments like C++ or Java, you might be familiar with using a debugger.
00:39    If not, don't worry about it.
00:40    I am going to show you how to use the debugger that's contained here in the free
00:44    version of Visual C# Express.
00:47    I am just going to use the existing example that we've already got from the
00:51    section that we did on reading and writing file data, so I've got that example
00:57    back open in my editor here.
01:00    Take a quick look. Under the Debug menu,
01:03    you'll see that there are a couple of options related to debugging.
01:07    There's the Start Debugging option, which is this option right here on F5,
01:10    and that's actually how I've been running our examples each time we've tried them out.
01:14    I just hit F5 and that starts the debugging process.
01:18    You can also start an application without debugging by doing the Ctrl+F5. But if
01:22    you want to actually have debugging information, you'd use the F5 version.
01:25    There are also things like Step Into and Step Over, and things like Toggle
01:30    Breakpoint, and we are going to see how each one of these works.
01:33    So let me close this menu. And the first thing I am going to do is show you how
01:38    to place a breakpoint.
01:40    Here we have our Main function, and the Main function is going to be the entry
01:45    point into our application from the .NET Framework.
01:48    The .NET Framework is going to find this function and then call it to start our program up.
01:51    So the first thing I am going to do is find the first place where I can put a
01:56    breakpoint. And it looks like this line right here, line 14 is where our program
02:00    actually does something.
02:02    So way over here in the left-hand side of the gutter, next to the line numbers, I
02:06    am going to click, and you see that when I click, a couple of things happen.
02:10    First, this little red circle shows up.
02:13    That little red circle indicates that it is a breakpoint, and you'll notice that
02:17    when I place that breakpoint, all the executable code that gets associated with
02:22    that line--in this case, it's line 14 and 15, because I have one statement
02:27    that's spanning multiple lines--gets outlined in red. And it indicates to me
02:32    that that is a breakpoint.
02:34    A breakpoint is a point in the program where when you're running the
02:37    application, the debugger will stop execution right before it's about to
02:42    execute that statement.
02:44    So let's go ahead and start debugging the program.
02:47    Open the Debug menu. I am going to choose Start Debugging, or you can just press F5.
02:54    Now when I do that, you saw the Console window kind of momentarily come up there
02:58    and then disappear behind the IDE. And now you can see this little yellow arrow
03:03    inside that little breakpoint there, and it shows me where the current statement is.
03:08    The breakpoint that was red is now outlined in yellow, and you can see that
03:13    we've got a couple of other windows that have shown up.
03:15    Down here in the bottom, on the left- hand side, we have the Locals window.
03:21    We also have something called the Watch window.
03:24    The Locals window shows me all of the local variables that are currently
03:29    within the current scope.
03:31    So inside the Main function, I can see all the local variables that I can
03:35    currently have access to.
03:37    Over here in the Call Stack, this shows me all of the functions that have been
03:41    called leading up to this point.
03:43    Now right now we are in the main function.
03:46    I have only got two items on the Call Stack.
03:48    I have got External Code which is the .NET Framework's execution engine, and
03:52    then I've got the ReadingWritingData. exe!ReadingWritingData.Program.Main, so
03:58    that's the function that I'm in.
04:00    so ReadingWritingData.exe! that's my program.
04:03    ReadingWritingData is my namespace. Program is the class.
04:06    That's this program right up here.
04:08    Main is the function, and it says I am on line 14. And sure enough, if I look
04:13    over at the little arrow, yes, I am on line 14.
04:17    The other thing that happens is that this little Debug toolbar showed up in my
04:21    toolbars up here. And I have got buttons for Continuing, so if I hit F5 right
04:25    now, the program will just continue to run until it reaches the next breakpoint.
04:29    Or I can stop debugging which will stop the application, or I can restart.
04:34    I can have the program go back to the beginning.
04:36    I can click on this little yellow arrow here to show me what the next statement
04:39    is going to be, and that's where the yellow arrow right over here is.
04:42    I've also got these three icons for Step Into, Step Over, and Step Out, and we'll
04:49    take a look at what each one of these is.
04:51    To step over this code, I can simply choose the Step Over function.
04:56    That will cause the current statement, the one that's highlighted right here, to
04:59    execute. And if you look down here in the Locals window, you will notice the
05:03    filePath variable right now is null.
05:07    There is no value assigned to it.
05:09    Watch what happens when we step over that line.
05:13    First, the little yellow arrow goes to line 18, because that's where the next
05:18    line of executable code is.
05:20    The second thing that happens is, if you look down in the Locals window, the
05:24    filePath variable now has this string in it, and it has a path to the example
05:30    file.txt. And you notice also it's red, and the reason it's red is because the C#
05:36    debugger is highlighting the local variable that changed.
05:41    After I step again, it's going to stop being red, because it's not going to
05:45    change after that point.
05:46    I can scroll down a little bit here.
05:49    Now if I wanted to, I actually could just simply change the value that's in
05:53    this local variable.
05:54    I can just double-click on it and say, you know what?
05:56    I don't want it to be called examplefile.txt; I want it to be
05:59    called joesfile.txt.
06:05    I just changed the contents of that variable while the application is still running.
06:10    So now this line of code right here is going to check to see if the file exists,
06:14    and it does not. So when I step over that statement, we'll see that the brace
06:20    gets highlighted, and I step again, and now we step into the if statement.
06:25    So now we are going to create that file and set its contents.
06:30    And once again, I can step over this, and you can see now that this content
06:34    variable has changed.
06:36    So I can also do things like hover over using the mouse.
06:40    I can hover over things that are in the code.
06:42    For example, if I hover over the Environment.NewLine statement right here, you
06:46    will see I get this little pop-up window that says what the new line's value is.
06:50    And you can see that it's \r\n. Or I can hover over this local variable, and it
06:55    shows me what the contents of that local variable is.
06:58    I can also hover over things that are built into the .NET Framework.
07:01    I can hover over the file class, for example.
07:03    When I hover over the file class it shows me that it's of type System.I/O.File,
07:09    and I can click on this little expander here, and it shows me all the things
07:13    that are inside that file class.
07:16    Now, it's a built-in class, so it's not going to show me very much, because
07:19    it's in native code.
07:20    But I can now just use my debugger to step through this code, and I can watch
07:25    the application as it runs.
07:27    You will see that variables are changing.
07:30    I can change the value of variables and so on.
07:33    If I've gotten tired of just stepping through this, I can just go ahead and hit
07:37    the little green arrow, which will cause the application to run, and we can see
07:42    that the application is now running.
07:43    And if I go ahead and hit the Return button, the application will stop, the
07:48    debugger stops, and I am dumped back into my text editor.
07:51    Let's make a slight modification to this application.
07:54    What I'm going to do is make a function, and I am going to make a function down
07:59    here called static void ReadAndListContents(). And it's going to read and list
08:13    all the contents of the file. So basically, I am going to copy these lines of
08:17    code right here, take them out of the Main function, and put them into a
08:22    function And I am doing this because I want to show you how the Step Into
08:26    functionality works.
08:27    I'll just get rid of that comment right there.
08:30    I need to pass in the filePath, and I also need to call that function,
08:37    so we'll call ReadAndListContents with the filePath. And just to isolate this,
08:47    we'll take out this code right here, so that we only have one piece of code,
08:52    that's ReadingAndListingTheFileContents.
08:55    What I am going to do is run the application again, and it's going to stop at
09:00    this breakpoint right away.
09:02    This time I am going to start at using this little green arrow right here.
09:06    You can see that the breakpoint got hit.
09:08    What I am going to do now is scroll down and I am going to place a breakpoint
09:12    on this function call.
09:13    So I just click there to place another breakpoint, and now I'm going to hit the
09:18    little green arrow again, which is going to continue on to the next breakpoint.
09:22    The application ran until it got to this breakpoint.
09:25    Now I can use the Step Into function, and that's this icon right here.
09:31    If I wanted to just simply execute this function without stepping into it, I
09:34    could use the Step Over.
09:35    That doesn't mean skip over the function;
09:38    it means execute it but don't go inside. Just do whatever the work it does, and
09:43    then go on to the statement at the level where I currently am.
09:46    So if I stepped right now, the next statement would be this Console.ReadLine.
09:49    But if I do a Step In, I will actually step into that function.
09:55    And now I can do Step Over and Step Over again, and you can see now that the
10:00    current line, as indicated with this little yellow arrow right here, is inside the
10:04    ReadAndListContents.
10:06    I could just simply keep on stepping and stepping and stepping and
10:09    going through these foreach statements and so on, or I could use the Step Out function.
10:15    If I click on Step Out, the execution is going to continue to the end of this
10:19    function and it's going to put me back into where the calling context was.
10:23    If I click Step Out, now I'm back out here where ReadAndListContents was called,
10:30    but now the function has finished executing and if I step again, I'll go on to
10:34    the next statement, which is the Console.ReadLine.
10:38    That's a pretty quick introduction to using the debugger.
10:41    The nice thing about the debugger is that it allows you to slow down the
10:44    program's execution so that you can see things as they are happening.
10:47    And as you saw, we were able to place breakpoints and examine variables.
10:51    We were able to change the contents of variables.
10:54    We were able to step into and out of functions.
10:56    The debugger really will become your best friend as you're writing your code
11:00    because it makes debugging of your applications so much easier.
Collapse this transcript
Using the Debug class
00:00    Throughout this course I've been using the console window to write out
00:03    debugging and other diagnostic information so that we can see what's going on
00:08    inside the application.
00:09    For examples like this, that's all well and good, but when you write your real
00:12    applications, if you're writing a console application, you probably don't want
00:15    to have it littered with debugging information that your users are going to see.
00:19    Or if you're writing an application that doesn't use the console window at all,
00:22    you're going to need to have some other way to get that output visible to you
00:26    while you're debugging your app.
00:28    The way that we are going to do this in this particular example is by using
00:31    the System.Diagnostics namespace, which gives us access to something called the debug class.
00:38    The debug class gives us a way for logging debugging information in a way that
00:42    we can see it which doesn't interfere with the actual output of the program.
00:48    To use the debug class, I am going to do a couple of things.
00:51    See, on line 16 the System. Diagnostics namespace. This gives me access to
00:57    something called the debug class, which gives us a bunch of features that are
01:00    similar to what we've been using the console window for--
01:03    WriteLine statement and a few other things that we'll take a closer look at.
01:07    The debug class is going to log all this information to a place called the
01:11    output window, and the output window is going to show up here in the IDE
01:15    when we make it visible.
01:17    To use the output window, there is a couple of things you are going to have to do.
01:20    First, under the Tools menu, go down to the Settings submenu and make sure that
01:25    the Expert Settings option is checked.
01:27    Once you've done that, under the View menu, there will be an option for Output,
01:32    and when you choose Output this little output window will show up here in your IDE.
01:37    Don't worry about the Show output from option just yet. Tight now it's empty,
01:40    but that will be filled in for us.
01:43    If you are a sharp-eyed reader, you'll notice that I'm using pretty much the
01:46    same code that we used in the Reading and Writing Data Files example, although
01:51    I've re-organized it a little bit to use functions and so on.
01:55    What we are going to do now is first build the application, so hit F6.
02:01    And you'll see that down in the output window, a whole bunch of information was
02:05    logged for us by the IDE.
02:07    It says that the build was started, and then there is a line that says,
02:09    hey, Build 1 succeeded.
02:11    So everything looks pretty good.
02:13    Our code can also use this same output window to log debugging information, and
02:18    the way that we are going to do that is by using the debug class.
02:21    Go ahead and scroll down and see how the debug class works.
02:25    This code probably looks familiar to you if you watched the earlier example on using files.
02:30    I'm not going to focus too much on that.
02:32    What I am going to focus on instead is the information that I've put into the
02:35    file to help with debugging.
02:37    Here's a debug class call. And you will notice that the debug object has a
02:42    function called WriteLine, which works pretty much the same way that the
02:47    console's WriteLine object works as well.
02:50    Only instead of sending output to the Console window, this is going to write
02:54    information out into this output window down here.
02:58    Here I am write-lining out some piece of information that the file was created,
03:02    and so on and so forth, and we do the same thing down here.
03:06    A couple of other features, though.
03:07    There is a assert function call, and assert basically makes sure that the
03:13    Boolean condition supplied in here is true.
03:17    If it ever evaluates to false, the debugger is going to pop up and say, hey,
03:21    something went horribly wrong in your program.
03:23    You might want to take a look at it. And we'll see an example of that in a little bit.
03:26    We also have this here, Debug Indent and Debug Unindent, and that will help us
03:32    make our debug log output more visible in the output window below, which we'll
03:37    see in just a moment.
03:39    Let's go ahead and run this program, and we'll see what happens.
03:43    Let's just take a quick refresher of the code.
03:46    You can see that when the code starts
03:47    we have a string variable that holds a filePath, and we are going to create a data file.
03:52    We are going to write some information out to it,
03:54    and then I am going to read the contents back in. And all that's going to be
03:58    happening in these functions down here.
04:00    We have a function for creating the file, we have a function for writing the
04:03    file content out, and then we have a function for reading the content back in.
04:09    So the last thing I want to point out before we run this is that unlike the
04:12    console window, the debug object has a special version of WriteLine.
04:17    It's called WriteLineIf.
04:19    What you do here is you supply a Boolean expression. If this expression
04:24    evaluates to true, then the WriteLine happens; otherwise the WriteLine doesn't happen.
04:29    In this particular case, we are saying Debug.WriteLineIf the contents array
04:34    length is greater than 2.
04:37    Well, if that length of that array is more than 2, then this particular
04:41    WriteLine will happen; otherwise it won't. So let's go ahead and run this example.
04:49    We ran the file, and we added a whole bunch of content to the file, so let's
04:53    go ahead and hit Return to exit, and let's go examine the output in the output window.
05:00    The first thing you will notice is there is a whole bunch of output messages
05:03    that were put here by the .NET Framework.
05:06    You don't really need to pay attention to any of these.
05:08    These are messages that the debug version of .NET Framework is sending out for
05:13    you to look at as a programmer, but for now, we are just going to ignore that.
05:16    What we are going to do is look for our first examples of debug output, and
05:20    they are right here.
05:21    For example, we have Writing File Data, File Data Written,
05:26    The file has more than two lines.
05:28    Well, where did those come from?
05:29    Well, if we scroll down in our content, we can see right here, this did not
05:35    execute, because the file already exists, but if the file hadn't existed,
05:39    we would have called the WriteLine function for creating the file with content whatever.
05:43    However, when we write the file data out, you'll notice that the WritingFile
05:48    Data string got written out, and because it's indented, right here you can see
05:53    that there is a little bit of a tab space in here, which makes the debug
05:56    information a little bit easier to read.
05:59    Down here we do the same thing. After the file's data has been written, we have
06:03    a debug output statement that says the file data has been written, and that's
06:07    also indented. And because the contents of that file had more than two lines,
06:13    you can see that this WriteLineIf statement executed.
06:17    Let's do one more example.
06:20    Let's see if we can get this assert to trigger right here.
06:26    What we are going to do is pass in an empty string content to write to the file.
06:32    I've decided that here in my application that anyone who calls this function has
06:37    to provide string content that's not empty.
06:41    If I pass in an empty string, I want my program to raise a warning message and
06:46    say that someone has tried to do something that I don't approve of. And the
06:50    great thing about these debug messages is that when you build the release
06:54    version of your code, none of this stuff gets included;
06:57    only the debug version of your application will contain these debug calls.
07:04    So let's go back up into the code here.
07:05    I'm going to uncomment this call to WriteFileData, and I am going to pass in an
07:13    empty string. And that's going to cause that assert to pop up.
07:18    Let's see what happens when I try this.
07:20    I am going to run this.
07:22    When I ran this, the Assertion Failed dialog message comes up.
07:27    So here the title says Assertion Failed, and then I have some options. Do I want
07:30    to abort or retry or ignore?
07:33    Now this is a non-fatal assert, so I can just go ahead and ignore it if I want to.
07:38    But for now what I am going to do is click Abort, which will cause the
07:42    application to stop.
07:43    I can see where that assert was. It's down in here.
07:47    You notice that there wasn't a whole lot of helpful information that came up in
07:51    that Assert box, just a big stack of messages that says, hey, here's the
07:55    function where things went wrong.
07:57    So I can include a message in this assert.
08:01    I can say, "Tried to call WriteFileData with an empty string."
08:10    This version of the Assert function will not only pop up the dialog;
08:15    it will give me a nice easy-to-understand message, so I can see what's going wrong.
08:19    Let's try that one more time. And you can see that this time, next to that
08:24    little red error message that says, Tried to call WriteFileData with an empty string,
08:28    that's the message that I put into my Assert box, and it shows me all the
08:32    functions that got me to the current place.
08:35    So right here at the top it says, at Program.WriteFileData.
08:38    That's where the assertion happened. And you can see that we got there by
08:42    calling through Main, and then we came in via the .NET Framework.
08:46    These are all the .NET Framework functions right here. Bt it shows me how we
08:49    got to where the assert is.
08:51    So I am going to click Abort. And then at this point I would go back and I would
08:56    try to figure out, okay, who is calling WriteFileData, who is doing it with an
09:00    empty string, and so on?
09:02    This is how you can use the debug class to add some extra debugging information
09:08    right into the IDE while you are debugging your application.
Collapse this transcript
Conclusion
Goodbye
00:00    Well, that brings us to the end of C# Essential Training, and I want to thank
00:04    you for joining me as we explored the basic concepts of the C# language.
00:08    You are probably wondering where you should go next, and I have a few
00:11    recommendations for you.
00:12    Spend some time exploring the online documentation for the C# language and .NET
00:17    Framework on the Microsoft Development Network web site at msdn.microsoft.com.
00:23    This is a very good reference resource for learning more about many of
00:26    the objects, classes, and language features that we were introduced to in this course.
00:31    Since C# is the foundational language for other Microsoft frameworks, such as
00:36    Silverlight, Windows Phone, and ASP.NET,
00:39    take a look at some of the other programming resources in the lynda.com Online
00:44    Training Library, such as Objective-C or JavaScript Essential Training.
00:48    Seeing how other languages approach similar problems and situations can
00:53    significantly increase your understanding of how each language has its own
00:56    benefits and drawbacks, and will broaden your understanding of the discipline of programming.
01:01    Finally, go back to some of the examples in this course and try some experiments.
01:05    The more practice you have with the language, the better a C# programmer you will be.
01:09    Good luck with your C# coding!
Collapse this transcript

No comments:

Post a Comment