C# Object Oriented Programming with Hands-on Practices | Kerem Aydin | Skillshare

C# Object Oriented Programming with Hands-on Practices

Kerem Aydin, Software Developer, Unity Developer, Gam

Play Speed
  • 0.5x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 2x
65 Lessons (6h 56m)
    • 1. What We Will Learn?

      3:02
    • 2. What is Object Oriented Programming

      1:59
    • 3. Intro to Objects and Classes

      5:48
    • 4. Class Structure – Banking Application

      3:50
    • 5. Actions in a Class

      9:41
    • 6. Instantiation – Testing Our Application

      9:55
    • 7. Access Modifiers

      2:56
    • 8. Static Class

      2:29
    • 9. Partial Class

      2:25
    • 10. Nested Class

      4:04
    • 11. Homework 1

      1:47
    • 12. Answer

      2:22
    • 13. Introduction to Fields and Properties

      4:48
    • 14. Code Organization With Regions

      2:39
    • 15. Demonstration - Field and Properties

      7:19
    • 16. Intro To Methods

      2:35
    • 17. Utility Methods

      7:44
    • 18. Passing by Variable

      4:12
    • 19. Methods in Our Application

      9:04
    • 20. Intro to Construction

      4:45
    • 21. Demonstration - Constructors

      8:52
    • 22. Homework 2

      2:24
    • 23. Answer for Homework 2

      9:34
    • 24. Intro to Windows Forms Applications

      7:00
    • 25. Create Windows From Application

      11:25
    • 26. Intro to Windows Forms Events

      2:14
    • 27. Demonstration - Windows Forms Events

      12:38
    • 28. Input Validations

      5:37
    • 29. User Controls

      9:41
    • 30. User Controls 2

      10:20
    • 31. Homework 3

      3:51
    • 32. Answer for Homework 3

      7:18
    • 33. Intro to Data Logic

      3:13
    • 34. Refactoring - Logically Organizing Elements

      13:23
    • 35. Intro to System IO Library

      4:08
    • 36. Conclusion

      0:52
    • 37. File System as Data Storage Unit

      8:50
    • 38. File System as Data Storage Unit 2

      8:41
    • 39. File System as Data Storage Unit 3

      13:54
    • 40. File System as Data Storage Unit 4

      5:16
    • 41. File System as Data Storage Unit 5

      8:40
    • 42. Intro to Inheritance

      10:09
    • 43. Intro to Inheritance 2

      6:30
    • 44. Non - Inheritable Member

      5:39
    • 45. Sealed and Abstract Modifiers

      3:27
    • 46. Sealed and Abstract Modifiers 2

      12:49
    • 47. Acces Modifiers Revisited

      10:54
    • 48. Polymorphism

      8:42
    • 49. Interfaces

      10:15
    • 50. Interfaces Part 2

      11:41
    • 51. Homework 4

      3:18
    • 52. Intro to Event Driven Programming

      8:06
    • 53. Events and Delegates

      13:28
    • 54. Intro to Exception Handling

      7:27
    • 55. Demonstration - Exception Handling

      8:19
    • 56. Demonstration - Exception Handling Part 2

      10:54
    • 57. Homework 5

      1:00
    • 58. Answer for Homework 5

      6:08
    • 59. Tips and Tricks - Keyboard Shortcut

      9:38
    • 60. Tips and Tricks - Code Styling

      5:00
    • 61. Tips and Tricks - Code Snippets

      1:43
    • 62. Tips and Tricks - Documentation Comments

      2:08
    • 63. Tips and Tricks - Overriding To String Method

      2:27
    • 64. Tips and Tricks - Handle Exceptions Globally

      4:00
    • 65. What We Have Learned

      1:11
14 students are watching this class

About This Class

Hello there,

Welcome to C#: Object-Oriented Programming in C# with Hands-on Practices course.

Object-oriented programming is the foundation of many current application development approaches. Interfaces and principles of object-oriented programming are crucial. It does not important whether you want to use C# to build web apps, mobile apps,  games or understanding C# classes if you want to succeed with clean coding, agile and design patterns, you have to master OOP.

In this course, we use interactive programming techniques; which means we will be building applications together and furthermore there will be lots of home-works to be done, of course, followed by answers. There will be lots of tips and tricks regarding beautiful and efficient coding techniques.

That`s why you are at a great place to start with OOP with C#

All my students will have a chance to learn not only the whats but also learn the whys and hows.

What you will learn?

  • Introduction to Object-Oriented Programming

  • Class Structure in Detail

  • Windows Forms Applications

  • System Input Output

  • Class Hierarchies

  • Event-Driven Programming

  • Exception Handling

  • Tips and Tricks

Why would you want to take this course? 

Our answer is simple: The quality of teaching.

When you enroll, you will feel the OAK Academy`s seasoned instructors' expertise. 

No prior knowledge is needed! 

It doesn't need any prior knowledge to learn OOP.

This course starts with very basics. First, you will learn some terminology. Then the show will start and you will learn everything with hands-on practices.  I'll also teach you the best practices and shortcuts.

Step-by-Step Way, Simple and Easy With Exercises

By the end of the course, you’ll have a firm understanding of the OOP with C# and hungry to learn more.

Video and Audio Production Quality

All our videos are created/produced as high-quality video and audio to provide you the best learning experience.

You will be,

  • Seeing clearly

  • Hearing clearly

  • Moving through the course without distractions

  • Dive in now!

    We offer full support, answering any questions.

    See you in the course!

Transcripts

1. What We Will Learn?: Hello, everyone. Welcome to the cores Object oriented programming in C sharp. So in this course, you are going to be familiar with what object oriented programming and class structure is, how the class hierarchies work and why it is so important to develop object oriented applications. So we will use interactive programming techniques, so there will be lots of projects and a lot of homework to be done. There's gonna be lots of tips and tricks regarding beautiful coding techniques and as a bonus, And in order to visualize what we have learned, we will be covering two important dot net libraries, windows, forms and system io. Now, to be able to do projects and the homework, you will need only visual studio installed in your computer with standard C sharp libraries . Now I use Visual Studio 2017 in my computer, but which version you will use. It's not very important at all, whichever one you have now, before we start, let me give you a brief outline of what we're going to learn in each chapter. One introduction to object oriented programming introduction to object as well as many different types of classes to the glass structure properties of class structure and an introduction to different class types. Three Windows Form applications, rial world form based applications and introduction to events. As we mentioned earlier. Throughout this course, we're going to create this type of form based applications. Four System input output library. Basic file operations such as reading, writing, updating the file content end deleting five glass hierarchies, everything about inheritance, such a Z interface structures, encapsulation and polymorphism. Six event driven programming delegation and events structures in detail. Seven exception. Handling bug free programming and fail safe mechanisms. Now I know that sounds like a lot, so let's begin. 2. What is Object Oriented Programming: what is 00 P. So object oriented programming is an approach to software development in which the structure of the software is based on objects interacting with each other. This interaction takes the form of messages passing between objects in response to a message. An object or several objects together can perform an action. Our world is, in fact, an object oriented platform. For example, if you want to go to the store, you interact with a car object. It physically takes you there after you initialize the process by getting into the car and starting the engine. If you want to open a door to your house, for example, you put the key, which is an object into the lock and turn. It is, in fact, sends your request into a mechanical system, and as a result, you can either open the door or not. You did not need to know how the mechanical system works. You just create a request and wait for a response, a message of success or one of failure. Similarly, users of software based applications air isolated from the complex structure of the programs. For example, when you want toe log into a website. You initiate the action by simply clicking a button. You're isolated from the process of how your home page is prepared. In the software program, the button object in Iraq's with a controller object, and it interacts with the actual server to accomplish the task of accessing a single Web page. 3. Intro to Objects and Classes: objects and classes as we talked about earlier. Everything is an object. In a software programming world. An object is defined as a structure accompanied by some set of data that has some methods to interact with that data. For example, if you wanted to make a clock, you would create an object that has a pair of containers to represent our and minutes. Also, you would need a method to set the time at least once and tell the time whenever you want. So these sets of specifications defined the class of a certain object type. In short, a class defines object properties, including a valid range of values and a default value. An object is just a product or an instance of a class, as in this watch is an object of a clock class. Now they're several properties of objects to be considered before creating classes. Abstraction. You only need certain basic properties of an object in your class. Definition Watch, for example, may carry lots of different technologies in it, but its main purpose is to show the time, plain and simple inheritance. Although we need our classes as abstract as possible, we also need them to be suitable for extensions, you may need a more precise watch with additional attributes like seconds and milliseconds or additional functions like GPS tracking encapsulation. Now let's think about, ah, GPS tracking functionality for a second. You know you want this kind of function in your watch. You would not want every other watch to be designed exactly like this. Some property should be hidden unless they become necessary. Polymorphism polymorphism is the ability of two different objects to respond to the same message in their own way. For example, functionality to tell time has two different displays, one for analog and one for digital watches. Now we're going to go into detail of each of these properties later, but I just want you to look into the basic class structure. So in order to demonstrate, we're going to look into banking systems. But first, open up your visual studio editor, Go to file, select new and select Project. A new project window will open. And as you can see here, it s is what kind of project we want to create. Since I chose who when Saul Visual studio for dot net development and set up it brought us the C sharp projects by default. No, if you did not select the dot net development at installation, you confined a visual C sharp tab under the other languages section. Okay, good. Now select class library .net standard as the project from the list. Now, the class library is a simple project that holds collection of classes. There is, ah minor difference between the dot net standard and the dot net framework glass libraries Since the dot net standard project would be more comprehensive. That's why we're going to select it for our project here. Let's give a name for the project here. Now, this will be a class library for banking systems. So what? We name it about bank class library. We have to be very clear. Click. OK, so now you can see in the solution Explorer here. Our project has been loaded with only one script in it. And that's named class one dot CS. Now this script we can see one class definition which is also named class one. Of course, we don't really like this name and we're going to change it by right clicking in Solution Explorer and select rename from the menu end. Let's rename it to account and a message box pops up even though it's not always necessary is a good habit to keep in mind. The name of the main class is the same as the name of the script. So in fact, it is expected to see Onley one class definition in a script with the same name, right? So let's click. OK, and we created our first class. For now, it just has a name and really no purpose associated with it. 4. Class Structure – Banking Application: class structure. So before we go into the details of our application, let's think about the watch example again. In class definitions, there are three main parts to be considered. One fields the parts of the object where data is stored inside in ah, clock class. These would be hour and minute containers to methods. Methods are the actions of the object is supposed to perform when requested. So the action set time and show our two methods of the CLA Class three initialization. Once the object has created, the default values of the objects should be initialized. Additionally, there can be some sets of actions that need to be performed. Constructor is the part where these initial actions are performed in a class. Now let's hope in our class. So is in the clock example. We need to understand the use cases in our banking application. The main objective in our application is to design a page that shows someone's account information. In this information, there should be one an account number, which is a unique account. I d to a customer's name, the name of the account holder. Three date of birth for credentials know that even though commenting is a good thing. You should not comment for everything so obvious. Since it is clear that the date of birth is the customers, we don't necessarily need to provide further explanation. Four. Phone number five Address. Six Current balance The final amount in the account. Seven List of transactions. The list of all in and out money transfers. Positive input for deposits. Negative input for withdrawals. Did you see that? There seems to be an error here. Let's have a look. We should add the collections library to the class. We had that and yes, now we're done. All right, So these are all the fields of our class since they all contain some data related to the account structure. Of course, we can think of many other possibilities to put into an account structure, but let's keep it simple for now. 5. Actions in a Class: So now let's think about the actions an account object ought to perform. The main purpose of the account is to show the actual amount of money. Of course, they're also deposits and withdrawals of money and an update of the final balance. Accordingly and and then finally, but not necessarily the address and phone number of the owner can change, so we can then create a method to do that as well. So in order to define these actions will need to create methods. Now a method structure is composed of a return type, a name of the method and parameters or arguments. The return type is a type of data that we expect after completion of the method. It is a message signifying the end of the action or simply the final result of the action. Yeah, it could be a string and imager or any other type of object. If there is nothing expected at the end, simply the void type should be written now. Parameters, on the other hand, is what has been given or fed into the action and a simple action operation. Two numbers of energy time should be given to the function and As a result. Again, an energy type is expected. Now let's get back to our class. So first we need to create a method to display the current balance, and it should be something like this. Now is a good practice. We should use informative names for our method. Instead of names, I do something, display things or just spit. We'll use a name like display balance. Additionally, in method names will capitalize the first letter of each word in the method name so that we can read each word properly. This type of naming convention is named camel notation. Yeah, you've heard of that before and it's used in a variety of places. We will now try to show you whenever we encounter an example. So since this method has no return value, we specify the return type is void. At the end of this action, we'll expect to see the balance on the output window or whatever user interface we've created. Also, we have no parameter to give, so we simply we'll leave it blank. So this place inside the curly bracket is called the body of our method, and we're going to fill it in after we're done writing all of our method descriptions and now for the deposit and withdraw money method in these type of request, everything can go wrong. You didn't expect you hear that for me, But you've got to be prepared so the bank can be closed, the server may malfunction. Or simply there could just be no money in the account, right? That's what I mean. So we would like to have a validation if our process is completed successfully. So for that we'll use a bullion type as a return type. So first will create a deposit money method. Just put it down as ah method ing deposit money method should have only one parameter the amount of money deposited. Yeah, and since we specified the current balance as double type, the deposited money type should be a double type is well, yes, Good. Another naming convention is here putting a letter a before the parameter and also using a camel notation. Now, if we do this, we can separate the parameters from field and variables defined in the method. Now, in methods with return types, you should return the value with the return key word is success variable as the name suggests keeps the information about if request is successfully processed, and if that makes sense to you, that is it. So now we'll do the same thing with the withdraw money method and will create an update, phone and an update address methods with the void, return type and string parameters. And now we'll need to create a method for initialization. Now, as I mentioned earlier, the initialization method is a in a class, it has a special form, and that's called a constructor. So here we can create it just by typing the name as in the method structure without a return time. Eso the constructor in a class is actually optional default. Constructor like this is automatically created in a class, but here we have essential parameters to be specified at initialization and for each account, we definitely need customer name and the birth date of the customer, so we'll just write them as parameters. We don't need the account number to be passed down as a parameter because it should actually be a computer generated. I d to ensure uniqueness and the phone number and the address are optional parameters, so we'll give them a chance to be left Blanca's well, by assigning default values to them. The parameters which have default values should be written in the end, in the parameter list just like this. And if no argument is given, these parameters will have the arguments given in the constructor, in this case, just some empty values. It would be zero for imager and no for string etcetera. Okay, good. So now that we've finished with definitions, we will need to initialize fields with the given arguments. So just fill customer name, date of birth, phone number and address parameters. Aziz, you are given here. That way we'll be consistent now for the account number we're going to use the G u I D structure globally unique. Identify. IRS class ensures the resulting imager will be unique. So assigned g y d new g Y d get hash code as account number. Great. Now about current balance and transaction list fields. So initially our balance should be zero, so we'll assign it the zero. Normally, we don't need to assign zero because, well, primitive data type variables such as energy floating doubles are initialized with zero at description automatically. But I'm just pointing that out for you. And even though we don't have transaction list since the list structure is a reference type , we do need to initialize it with new as our keyword lists. Raise structures and other classes are are some examples of reference types, and they need to be given space in the storage with the new keyword. 6. Instantiation – Testing Our Application: testing our class. So now that we're done with the initialization to test our newly created class, we need to have some output screen. So for that, we're going to use a console application. So go to the solution. Explorer. Right. Click on the solution and from the menu select add. Then new project and New project menu appears. And select the console lap from the list. Its name it Demo Click. OK, okay. So now we have the demo application in the solution Explorer. Since our solution now has two projects in it, we'll need to define which projects should be the start up. And for that will just right click the Demo Project and Solution Explorer and set as start a project. Excellent. So now when the program stars, this main method will work first. Now, here you should notice that in the console application the main method belongs to a different class, and the class is name program, and the main method is is just a static method with the void return type and an array of string as a parameter. So when we start the program by clicking the start button here, we'll just see a console window for a while, and then the program terminates itself. Now to keep the console from terminating immediately, we will right here console. Read the key. Now click start again on and hopefully you noticed and your counsel to is no longer closing itself because now it expects to read a single keyboard input from the Consul. So now when we press any key, the program terminates again, right? That's just is expected. So now let's get back to our application Now, for starters, will just want to see some info about an account that we will create the console. And for that reason we'll need to have this information, which is given by the user right now. Remember the parameters that we specified at the constructor of the Count class. These parameters need to be given one by one. And to get input from the console, we're going to use console Reed Lyon method and create a customer name variable and a sign that given input like this now, before expecting the input, we will need to inform the user about what it is that we are expecting. So before they read line method, we're going to push the console output saying, Please enter your name. Mm. And let's just it. So you see, we need to write our name here, So when you press enter, it accepts the output and assigns the customer name. Then the program is back to expecting any key to be pressed now for birthdate. We're going to need day, month and a year. So for each where we're expecting different lines of inputs and signing the associated variables, right, And as you can see, we have an error. But that's as expected, since we are giving input a string data types and expecting imagers as a result. That's why we have this air. So how do you resolve? We'll need to convert the string input to an imager using the convert class. That's just type convert to end 32 here. Now the number 32 that signifies how many bites right? Stand in energy type is 32 bytes, so we'll use that and do the same for the month and year. Please note that this type of programming is error prone, so if a user does not give manager input, the program would give a runtime error and crash right now, we'll just ignore that now. We also need ah, phone number and address. So just please enter the phone number and an address as before. We can just cast them to the variables. Have phone and address. Great. So now we have all the necessary parameters to create our account class. And, as mentioned, earlier classes are referenced types, right? So what does that mean before? We do need to initialize or object with a new key word. Create my account with account class type. Oh, we haven't ever. Here. Account class cannot be found to in our application. There are two projects, right? One is class library that holds all the necessary classes inside, and the other one is the main project. So to use the classes inside the class library first, we need to make sure our demo projects sees the class library. So for that, we will need to create a reference to it. So in the solution Explorer, click the references tab under the demo project. And as you can see here, there are many libraries. Well, none of which happens to be the class library. It's a right click. References add reference reference manager window opens, then under projects. Just check the box of the bank class library. Click. OK, now the demo project can see and use the classes inside the class library. Hey, wait a minute. The error stills there because we've only saw part of it. So you see, at the beginning of the demo program, our class belongs to a demo name Space. On the other hand, account class belongs to a bank class library name space. So one way to solve this problem is to add the bank class library to our demo like this war . Just change both name spaces to the same name so they belong to the same hierarchy and each class in that name space can we'll be able to find each other. So is easier, I think. Teoh, just add one library to another, so we'll go the first option. But I just wanted to point out that you do have an alternative. Now let's create a new account using the constructor first parameter his customer name Second parameter is date of birth to create new daytime object will simply use new date time, year, month, day. And as you can see, visual Studio brings as the most suitable constructor of the daytime class with three manager parameters. Now, note also that we can actively create new objects in the parameter area like this very easily. The remaining parameters, Airfone and address. So just enter them as well. Okay. Yeah. As you can see, we've got another error. So it says this constructor is inaccessible due to its protection level. So that means we need to arrange it excess modifiers. 7. Access Modifiers: access modifiers. So all types and type members have an accessibility level, which controls whether they can be used from other code and your assembly or other assembly , and just to remind you, an assembly is a compiled output of any dot net application. Typically ah de L l or E X C five. So you can use the following access modifiers to specify the accessibility of a type. Remember, when you declare it public hypo, Remember, can be accessed by any other code in the same assembly or another assembly that references it. Private type or member can be accessed only by code in the same class or struck, protected type or member can be accessed Onley by code in the same class war in a class that is derived from that class, and we will learn how some classes can be derived from another. In the next chapters, Internal Tiger member can be accessed by any code in the same assembly, but not from another assembly. There are also intermediate access levels, such as private, protected and protected internal. But for now, let's get back to the application to go to the constructor of the account class Access modifiers should be placed at the beginning of the description. Then here We did not specify any access modifier, so it is private by default. So we want to access his constructor from another project in the same assembly. So what should it be, either internal or public? Now? It would probably be logical to make public on. That would be more suitable, don't you think? So? Public it is. So let's check back in the demo project and look at that. It worked. Now let's consider the fields of the class. Each field of the account is private by default because we did not specify anything. When we try to access them like this, we cannot see them in the list. So that's Ah, just go back to class definition and make the customer name and the current balance fields public. Great. So let's go back to the demo project. Bingo. We can access those two as well 8. Static Class: class types now there many class types we can consider. But before we move on to the derivation of one class from another and all of that advanced stuff, it's really good to know the basic one. So if you already know it, that's review. If you don't, this is good stuff. So first of all, the static class is the same as any other class, right, except a static class cannot be in Stan Shih ated. In other words, she cannot use the new keyword to create a variable of the class type. Because there's no instance variable. You access the fields of a static class by using the class name itself. For example, if you have a static class that is named utility class, that has, AH, public static method named Method A. You call the method like this. It's very simple. A static class can be used as a convenient container for sets of methods that just operate on input parameters and don't have to get or set any internal instance. Fields, for example, in the dot Net Framework Class library, the static system math class contains methods that perform mathematical operations without any requirement to store or retrieve data. Another example is system console class that performs consul input output operations. So why don't we check out the council library in our application? And we used the console output method here. So right click on the console class. So, like go to definition from the menu or you can press F 12 and this is the class definition of console. And perhaps you can see there are lots of method definitions. But know that naturally, all these methods are also static or hate, since static classes cannot have non static methods airfields. Also, as you can see, we can define the same method with the same return type, but different parameters set. 9. Partial Class: partial class, so it's possible to split the definition of a class or method over to orm or source files. Each source file contains a section of type or method definition, and all parts are combined when the application is compiled. This is desirable when working on large projects, enabling several programmers to work on the same coat were when working with automatically generated source. The code can be added to the class without having to recreate this source file To split the class definition just used the partial keyword when partial student classes with study and sleep methods combined, it makes a whole student, but right now let's go back to our project. So in the account class, we actually have two types of information. One is customer information and the other one is account activity. So let's split this class into two where these two categories are separated. First, make this class partial by putting partial as the key word copy and paste this line since the two class definitions should be exactly the same, right? So now we carry the customer related fields one by one, and when we're done with the fields, we carry the two methods named update, phone and update address. I guess we're done. Build solution and there's no compile area. Just to be sure, let's run the demo. Want bingo, see how it works with no problems. So normally I would separate the files as well, but I guess this is enough for demonstration purposes. 10. Nested Class: nested class, so type defined within a class or ah, struck is called a nested type. For example, here, the nested classes in the container class, regardless of whether the elder type is a class or restructure nested types default to private, they're accessible on Lee from their containing type. Right. So you can also specify an access modifier to define the accessibility of a nested type. So without any further ado, let's have a look at our account class again. Now, here, take a look at our transaction list. What do you see in this list? Were planning to hold the amount of transactions done by the user. Right. Tally up the transactions keep tracking. So that means that if money is deposited, there will be a positive amount of transactions. And if money is withdrawn, there will be a negative amount of transactions and those should be added into the list. However, in banking applications, there is more information such as the date of transaction, the time of transaction location, where the transaction is done just to name a few. So for all of this information, and in order to store it, we would need more than just a single double type in the list, and for this reason, we're going to create a nested transaction class. So let's go to the end of the account class and create a new class named transaction and create the fields one by one. First amount of transaction, we'll need some public data types. Since we want to access these field transaction date date time format is usually sufficient for both time and date. It is for now, anyway. And location Location ought to be self explanatory. Okay, so that does it for the deposit type of transactions. But we're also going to need some negative values as well. So to do that, we're going to define the enumeration type, which is abbreviated in it. Short form, as in, um so let's create the Denham transaction type here, and this in, um will be nested in the account class as well. And for this we only have two types deposit and with drawer all so now in the transaction class and transaction type field, and it will go back to the list and change the double data Type two transaction and we'll do the same in the constructor, and that is it. So then we can compile the project. It works great. So we have successfully created the nested transaction class. 11. Homework 1: what we learned. So let me just run down. Ah, for us both. Here what we've learned in this chapter, we've learned what object oriented programming is the difference between object and classes , the structure of a class, accessibility of elements and the basic type of classes. Now it's time to assign you some homework. So open up your editor again. First, get rid of the partial classes. Since our application is not developed by multiple developers. Now we're gonna create a customer class here instead. Right? Click on the bank class library project and at a new class and the and new item window opens. Name the class customer and click. OK, Now the customer class has been created. So first of all this, make it public. So we'll go back to the account class, create a customer field named account customer. Okay, so now your job is to carry all these fields and methods to the customer class and create one functional constructor that we can initialize. I need for you. Good luck 12. Answer : Okay, so now you're ready for the answer for your homework. So our job is halfway done. Since we've already group customer related fields together, we can simply cut and paste all this area inside of a customer class. And now we just need to create a constructor. So it's a good habit to keep constructors between fields and methods. So now parameters are customer name, date of birth, phone number and address. Pair the parameters with fields, initializing all of them one by one. Now go back to the account class. And since we carrying some of the fields, we have errors. So we'll just do it years here and initialized the account customer with new because it's object tigers class. And the parameters are similar to the constructor of the count class. And now we're gonna add them one by one. And that's it. We successfully separated the customer class from the account class. Build it. Bingo. It works. Good job 13. Introduction to Fields and Properties: So in this chapter, we're going to focus on elements of class structure in detail. So as we mentioned in the previous lessons, the class structure can be considered in three parts field methods and constructors. So let's start with fields now. To put it formally, A field is a variable of any type that is declared directly in a class. Fields are members of their containing type. For example, balance variable below. Here is a member of a double type A class. May have instance, fields or static field or both instance Field are specific to an instance of a type. So if you have ah, car class with an instance field, let's say tire. You can create two car objects and then change the tires in each car object without affecting the other tire. Yeah, no. On the contrary, a static field belongs to the class itself and is shared among all the instances of that class changes made from one car. Let's say changing gas prices, for example, will be visibly immediately. Two instances off all the cars, if they have access to the field fields, are declared in the class block by specifying the access level of the field, followed by the type of the field, followed by the name of the field. A field can be given an initial value by using the assignment operator. When the field is declared, the field will be overridden by the constructor if it is initialized there as well. Now, generally you should use field only for variables that have private or protected accessibility. That makes sense, right? Data that your class exposes to other codes should be provided through methods and properties, so we'll talk about properties. A property is a member that provides a flexible mechanism to read, write or compute the value of a private field. Properties can be used as if they are public data members, but they actually use special methods called excess er's to. This enables data to be accessed easily, and it still helps promote the safety and flexibility of methods. So get is a property excess ER and that is used to return the property value. And then set is the property excess ER, which is used to assign a new value. The value keyword is used to define the value being assigned by the set excess er, so these excesses could have different access levels. For example, here we've defined the seconds field and prepared a property our to access it. So to get how many hours is within a given seconds, we use the get excess er to return seconds divided by 3600. And when the hour is assigned, we took the assigned value with the value keyword and then updated the seconds field. So conversion in between fields and the assignment of fields is only one use of properties in the property. Said excess er, we can look to see if the assigned value is a valid one. So this example we only assign whatever the given our value s seconds. However, if we're talking about a clock class, the our value cannot be bigger than 24 or less than zero. Right. So we can check these ranges inside the set excess er like this. You know what? Well, understand this better when we get to error handling. So constants are unchangeable values which are known at compile time, and they do not change for the life of the program. They're declared with the const modifier and must be initialized after declaration. They're very much like static data types. In fact, they can be considered as unchangeable static fields 14. Code Organization With Regions: So now let's go back to our banking application and exercise what we've learned so far. So this is our account class and these are instance Fields. We have one constructor here, and we have declared several methods. The transaction class is in nested type that we define inside the account class. And these are the instance field of the transaction class. So now let's tidy up the coat a bit. First will align the comments. The tab key is quite useful here and here. We need to update this comment since we created this transaction class down there. Okay, so now let's introduce you to region keyword. So with the region keyword, we can group are code in sections, so just type in region, field and properties feel declaration ends up here so well, right end region. You don't have to write the whole thing, but it is good to know what region ends where. So now when we click the minus symbol right here, the region collapses. That's pretty meat, isn't it? Okay, so click the plus button and the region comes back now do the same for the constructor section. It's pretty easy if we just copy the whole line and paste it in the end of the region. And then we just have to write end here and the same process goes for methods. And we are done. So now, when we collapsed them all, we can easily see what is left behind. These are nested types, so let's create a region for them as well. We have, ah nested class and nested enumeration here and region, and we're done. 15. Demonstration - Field and Properties: so we tidied up the code for enough for now. First of all, let's create a static field sort of banking application. We might need to exchange money to, you know, other currencies. For that, we can create a public static exchange rate. So if we have more than one account, the exchange rate should remain the same for all. Even if its value has changed from one particular account. Object, right? So that means that we should declare it as static. And for now, let's just initialize it as 1.1, and now we will define the property. So let's think about the customer structure. You don't want to make the entire customer file public. That would not be advisable. So we just want the customer name to be accessible and create a property for that and the mighty get excess er will return account customer customer name now current balance. Let's change its access level to private the leading the public. Hayward First will create a regular balance property. Second, we want to be able to check the amount of money in a foreign currency, so that will return the current balance multiplied by the exchange rate and list of transaction field, and we would like to access the last transaction. Then we simply return the last element in the list like this. Oh, be careful here because we may have no element in the list, which would indeed cause an error. So we'll check if the number of elements is greater than zero else. Just returned. No. Okay, now back to the customer. And we may also need to access or set the customer phone in address field. It will create a string customer phone here and simply return customer customer phone. And as you can see, hey, don't have a phone field in our list. So go back to the customer class and here, make the phone and address field public, and now we can access the phone number. Now, we also want to be able to update the phone number s o in the set excess er assign value to the phone number, and we'll do the same for the address field. Okay, good. So now that we've created methods to get and set the phone and address field, we no longer need the update, phone and address methods below. So simply comment out these methods with this comment button here already. So we're done now creating properties for the phone and address. So you should notice, however, that these fields may not be given in some database structures. Ah, leaving ah data field blank is not permitted. And here we want to display some type of text of these fields are empty. So in order to do that, we are just going to create to constant fields. And the first is for address named Empty Address. And we want to put unknown into the address field. If it's empty and the 2nd 1 is for phone named Empathy, phone and just four number signs will be sufficient here. I think so. Now, if the phone is no are empty, which means it is not given or it's just blank. Just push the constant value above else assigned the given phone number, and we'll do the same for the address field. Just copy the if statement and paste it here. Ellis part is similar as well, and that's it. We successfully arranged our fields and gave them access with various properties 16. Intro To Methods: methods. A method is a code block. The contains a series of statements. The main method is the entry point for every C sharp application, and it is called by the common language runtime when the program is started. So Methods air declared in a class by specifying the access level optional modifiers static or one of the ones which I'll show you later, such as abstract or sealed. The return value the name of the method and parameters if there are any passing parameters . So by default, when a value types such as imager float, double straying etcetera is passed to a method, a copy is passed instead of the object itself. So therefore, changes to the argument have no effect on the original copy. In the calling code. If you really want, you can pass a value typed by reference using the ref keyword. When an object of a reference types such as classes and list, is passed to a method, a reference to the object is past, and that is if you change a member of the object by using this reference that changes implemented on the original copy that makes it. On the other hand, the attempt to re initialize all variables with the new keyword inside. The method would have no effect on the original value overloading methods. So two methods can have the same name, even the same return type Onley. If their signatures are different, that is, they need to contain a different parameter list. So this is called method overloading. It's on the same class, for example. Here, the ad method can be created with different number of parameters, type of parameters or border of parameters. So these examples, the last one would given error, since its signature is the same as the 1st 1 even if their return types or different right . 17. Utility Methods: So now let's get back to our application. So we're going to focus on our methods now. So open up the main method, which is a member of the program class. In here. We have three right line methods to push our console messages, and many read line methods as well to read the input from the user. So we will collect all of these with extended functionalities in a single static class Now , so right click on the demo class and the Solutions Explorer Select Ed, then select Class and the new White Emmanuel Open. So let's give it a name of utility methods. We'll call that our class and click add. So the utility methods class has been created. Now we got to make ecstatic. In fact, we don't need to make this class static as long as the method defined here are steady but is only logical to collect static methods in a single static class. Yeah, so now I go back to the program, and here we have a pair of statements. One is to inform user about expected input, and the other one is to actually get this input so we'll want a method that merges these two functions to create public static and read text input. We'll create those methods with only one parameter, which is a message to show we will return the given input at the end of this method. Now, in order to show the past message, we'll use console the right line method and to get the input from the user console Read line. That's the method that I mentioned earlier and the return value is assigned. Okay, good. So now to summarize, we should show a given message to the user and expect an output and then return whatever input is given. Makes sense. Okay, so now go back to Main Method and comment out the replaced lines. Call read Text input method from static utility methods class. The past argument is Please enter your name message here, and the return value of this method should be assigned to the customer name Variable and that's it. So let's test the code and it works. So now here we will do the same for the birth date of the customer. For the birthdate. We need to request new American puts from the user, so create a public static read numeric input method in the return values energy. This time again, we'll push the past message to the console and then a sign that given input to the return value. And here we have an error that we encountered before. So we need to convert the given string input to an energy value. So just copy it from here and paste it in here and now one by one, we will call this method first day of birthdate, and we simply call our static method of this static class. Our console message is here, and of course, we need to change it a little bit for day. And I will just copy this statement and paste and then adjusted for month and year. And now we can comment out the now obsolete code segment and we'll test it again. And I think you can see that our methods air working perfectly. So now, for phone and address, we don't necessarily need any additional methods will simply call read text input for both of them. - Oh , you know, I just had an idea for the read key method here. Wouldn't be cool if we wrote a method to show the famous press any key to continue message . So for this, let's create a static void method. And first push the message with the right line. Second, just call, read key and here comment out this line and call our new press any key to continue method. 18. Passing by Variable: and here we're done writing the requested functionality. So here we used a traditional approach, which is writing a method to return a certain response. Now, of course, there can always be another approach in the utility methods class. Create another void read text input method. Now here we have an error. It says that we've already defined a method with the same parameter types above. So even though we created the method with the void return type, it's still can create confusion at the assignment. So in this we will have to pass the variable by reference type and assign it inside the methods body. So for that, we'll add ref string parameter. So the statements are easy. Simply disk all the previous read text input and assign the variable that is passed. And in order to test that, lets go back to the main and change the line for the dress input. And first we'll need to create an address variable, so to separate. These then passed this address as a reference parameter with the ref keyword. Now, for a string variable to be passed down into a method will first need to initialize it, so just initialize the address with an empty strength and look that that's it. There's no air. So now we need to see if the address has really changed when we pass it down like that. So to do that will put a break point here after the statement and debug the application. So this brake point will pause the application after this method is called. Now to see what happens just before execution will put another break point here, and then we can start the application. So just write 12 until the program hits the break point. And there it is. When we move the cursor onto the address variable, we can see its current value, which is empty. Just make the application continue. And right. Some address were address, and now the program hits the second break point. So when we check the address again, we see that our input has been successfully past year in this variable. Now stop the application and remove the break point. We can do the same for an American. Put simply create the method with the void, return time and follow the same procedures before we're not gonna have to test this for now . Since it's not that necessary. We just wanted our class to contain this method then because it might be needed in the future. 19. Methods in Our Application: No, our application needs a little left. Great, don't you think so? Here we create a single account and our application terminates. We want to be able to create one and then perform several actions with it. Yeah, so for that we can use the while loop. So first, let's define the loop condition to be true at the beginning and put it into the wild statement. Now, we could just right true in here and exit with a break statement. But it's simply bad programming. We're not gonna do that. Well, so far, we wrote a procedure for creating an account. We need to put these in a single method called create account, create a private static method with account return type and put everything inside return. Value is a new account. So change the name of the account to be new account and return it and lead the unnecessary comment block since we will not be needing them. And here call the method so that my account is created now for the demo will want to make a deposit and withdrawal and display the remaining balance in a loop. So, first private deposit money, second private withdraw money and third private display money. So all three methods get the account as an argument. Simply put these methods under the Associated Comment lines, and we're done with the definitions. So now we can fill in the body parts. So in deposit money, we want to call the deposit money method of the account. But as you can see, we did not have such a method in the list. Of course, that's because these methods are not accessible from outside the class due to the private accessibility level, so we can change your access modifiers and make them public. Now we can see the method in the list, so the deposit money method inside the account class expects an amount of money to be deposited. So for that we need to change the definition of this class here to be able to pass the amount as an argument. So for now, let's just say that we want a deposit 1000 and then withdraw 500 of it and the money parameter to the definition of the deposit amount and pass it down and then do the same for withdraw money. Now, here it seems that we made a grammatical error in the name, so to change it just right click and rename. So click to include comments. If you want this name to be changed in the comments as well, right? Withdraw money and click. Apply, then have a look. The name's changed, and in the comment above, it seems that we already use the correct name since renaming and the comments works on Lee , if detect is exactly the same as the method A. So now what did we do? Re created an account and then deposited some money and then withdrew some of the deposited money and displayed the balance at the end. Now we do need to pause after we display the final amount. So we move this method inside the loop to ensure that deposit money and withdraw money methods are now complete, says finish writing. The display balance method is well, and then we'll be done on the surface. So let's go to the definition of the deposit method and all his empty. So we'll start with display balance. It's easy. We'll just push the current balance with console right line as our method in the deposit money method. Normally we would want to fill transaction list is we make a deposit or a withdrawal. But for simplicity, let's just increase the balance by this given amount. No, you do a similar thing and decrease the balance for the withdrawal method. And that's it. We're done. So now let's test it just past the account creation part, putting acceptable arguments after we passed the address. We are inside the loop and it says current balance is 500. Now. You remember. Why is because we first deposited 1000 then withdrew 500 of it. Now, if you restart the loop pressing any key, it will simply continue making these transactions repeatedly. 20. Intro to Construction: constructors, so whenever classes created its constructor is called class may have multiple constructors . Take different argument. Constructors. Enable the programmer do set default values limit in stance, see ation and write code that is flexible and easy to read. A constructor is a method whose name is the same as the name of its type. It is declared in a class by specifying Onley the access level, class, name and parameters. If there are any default constructors. There are many different types of constructors. For example, if you don't provide a constructor for your class for your objects to be in. Stan Shih, ated with something C sharp creates one by default and sets member variables to the system default values. The default constructor is a constructor which has a public access and no parameters and no statements in its body Static constructors to initialize a static class or static variables In a non static class, you must define a static constructor, so static constructor is used to initialize any static data or to perform a particular action that needs to be performed only once. A static constructor does not take access modifiers or parameters, so it is called automatically initializing the class before the first instance is created or any static members are referenced. It cannot be called directly, so that means that the user has no control on when the static instructor is executed in the program. Private Constructors, a private constructor, is a special instance constructor. It is generally used in classes. It contained static members only. The declaration of the private constructor with no parameters prevents the automatic generation of a default constructor. So that is it. A class has only private constructors and no public constructors. Other classes except nested classes. It cannot create instances of this class. Copy constructors, a copy constructor, is a constructor that is used to initialize an object from another object of the same class . It has only one parameter, and it is the object that is wanted to be copied. Each statement in the class is an assignment operation from the fields of the original object to the new object overloading constructors. Constructor overloading is quite similar to method overloading. That is, we can create more than one constructor if their signatures are different. So in the account class, for example, we can create default private and public constructors together as long as they're parameter lists are different. As we mentioned earlier, Static constructors take no parameters, which makes its signature with the default constructor. So it's OK, since static constructors cannot be called by the user. Optional parameters the definition of a method or constructor can specify that its parameters are required or that they're optional. Any call must provide arguments for all required parameters but can omit arguments for optional parameters. Each optional parameter has a default value as part of its definition, in fact, of no argument is sent for that parameter, the default value in the definition is used. Optional parameters are defined at the end of the parameter list after any required parameters. So here in this example, first we define the required parameters, and then we define the optional parameters at the end of the signature. Just get back to our application. Shall we 21. Demonstration - Constructors: open the account class and enlarge the constructor region. So here we created Onley one constructor, and it is pretty much everything that we're trying to accomplish with a constructor. We've also seen how we can use default parameters. But now, above this, let's create the default constructor ourselves. So what? This? We can make sure that the fields are initialized in the proper way. Everything's pretty much the same with the constructor below. So will copy and paste it here. As you can see the parameters to create a customer object or missing, we'll need to replace these with the default values. First, put admin for customer name and we can leave it empty. But having ah customer with no name would, I don't know, make me crazy and the same goes for the birthday, so we'll need to put some acceptable date for it. Let's choose 2000 January 1st phone and address. Not very important, so just put no values for them. Okay, so that's it. Now we have two constructors in our account class, so let's test the default one. So here just initialize the account with the default constructor put break point and afterwards, and start the application. So when we move the cursor on the account object, we can see what's inside. And you can see the owner of the account is ad men and the rest of the fields are successfully initialized with their default values, So we'll stop the application and remove the break point. Now let's go back to the account class and here we will create a copy constructor Copy constructor. Will Onley take another account object as an argument. Then inside, we'll just need to copy the fields. Ah, given object to our instance. So first directly copy the account number and the current balance. I hear you should notice both of these fields or private, but how can I access him like that? Well, to put it simply, it's because you count class knows the fields of another account class. So if we were toe put another object of a different type, the private fields would still be inaccessible. This situation this is very convenient for the copying of constructors. So after these private feels, let's copy the members of transaction list and first in Stan. She ate the list with the new keyword, then add each member of the transaction list of ah, given account class to this list of transactions one by one. Of course, you might be thinking, sometimes there are shortcuts to what we do. Yes, for example, if we instead she ate new list, giving the originalist like this it in stance e eights and simply copies each element into the new list, You may notice this is basically what copy constructor does to the class. Yeah. So for now, let's comment out this part. And finally, we need a copy customer. And to do this will first in Stan. She ate the customer with the new keyword. And we use the copy constructor of the customer class at this instance. Aviation to copy the original customer of the given account. No, no, no, no. We have an error, of course, because we didn't find any copy constructor in the customer class. If you recall. So in the quick fix window, it asks if we want to create it, and simply by clicking on it will do the job now, right? Click the constructor and go to implementation. So here we are, inside the customer class and here the definition of the copy constructor has been created , but there is no implementation. So, as we did before, will need to copy the field into this object one by one First customer name, date of birth. Oh, number end undress and that's it. The copy constructor for the customer class and therefore copy constructor for the account class has been implemented. Now go back to the program. First, let's create an account with the create account method and then create another account and initialize it with a default constructor. Finally re initialize the 2nd 1 with copy constructor passing the first object as argument put two break points here and here and start the console will enter some acceptable input on the account Object is created, it hits the brake point. When we look inside the my account object, we we can see the values we entered in the console window. Customer name is Jack. You know that. It's now let's execute the next line and create a copy constructor object with default constructor. And as you can see here it has some random account number and customer name is admin. So go to the next line Now copy account object is re initialized with the original account object, and we can see here that the account number has been changed and it is the same as my account object. And that's how we know that our copy constructor works perfectly. 22. Homework 2 : So what have we learned in this chapter? We investigated what our fields and how properties air used different types of methods, structures and how parameters can be passed and different constructor types such as default static and copy. So now what does that mean? That's right. We're gonna give you a small job to do open your editor and first delete any unnecessary instance e ation go to the account class and below Inside nested types region. You will find the transaction class so first organizes class with regions, eliminating the public fields and replacing them with properties if necessary. Second, create a method to display the information about a transaction. Third, implement regular default and copy constructors. And after that, then go to deposit money as a method of the account class, created transaction, object and add it to the transaction list, and finally do the same with the withdraw money method. Good luck to you 23. Answer for Homework 2: alrighty, then first of all, the organization of the members. So let's create a region for fields here and carry everything inside. Since we do not have anything else as a member, and after that, just get rid of all the public access modifier so that we have only one private feel. No, typically. Well, normally I I cannot think of any scenario that I would need to access these fields from the outside, So I do not need any property. Ah, just for an example, let's create a property for money amount. Okay. Public double money amount is the definition. Now in the get excess er return the original value of the field and in the said excess er simply assigned the given value to the amount of the transaction. Okay, that's it. We're done with the field now. The second objective is to create a method to display a summary. So first create a region for methods, Then write the definition of the method and to display the value we will use the console right line method and his push The total amount to the console we can give the date when the transaction takes place is well no. Then the two string method can be used directly, or we can show the date in a formatted way, which is specific to date time types. Also, we would like to see that type of transaction, and for that the type of transaction field should be enough. And if the type is deposit display deposit, otherwise display withdrawal on the console and this is pretty long code, but it is quite straightforward. So now for the constructors, let's start with the default one. First, we'll create the region definition of default. Constructor. There's a simple is this Now? If we make it public, we could be able to create it without amount or anything. But you know what? Let's just make this private because we don't want to allow default transactions in our application, So at least the amount of money should be specified. Yeah, now, since we will not be using this constructor, no need for an implementation. Now let's create a regular constructor. The constructor that we would need so in this constructor will need to initialize fields above one by one. The first parameter is the amount of money, and the second on is the type of that we call transaction and that it So we do not need any other argument, a sign amount of money to the given value and do the same for the transaction type Date of transaction can be assigned when the constructors called. You see date time now would give the current time. So just a sign. Normally the location can be taken from some other service, like a geo locator or something. But since we do not have that sort of function in our application, let's just put ah constant value. So now we're done implementing the regular constructor Copy constructors. Easy. Create the definition with only one parameter, which is a transaction object to copy and one by one assigned each field with the values in this transaction object. - This is our copy constructor. And now let's go to the deposit money method. First we need to. Instead, she ate a deposit transaction and put the amount of money and the type of transaction which is deposit. Now, add this transaction object to the list of transactions and this finishes our fourth objective. Now the fifth objective is more or less the same, so you can just coffee in pace below and just change the type of transaction here and now recall that we have a property named last transaction, which refers to the transaction in the end of the list. So go to program. And here we want to display the previous transaction. So for that, go to my account last transaction and call display transaction method, and we'll do the same after the withdraw. So copy and paste it there and started the application console window opens right. Some default information for each prompt. And when you come to the deposit and withdraw operations, the summary of each transaction is displayed properly. Different types of transactions with different amounts are done. And at the end, that current balances shown. That's all we're done here. Good job. 24. Intro to Windows Forms Applications: Windows form applications. So this chapter, we're going to learn one layered architecture pattern. So it'll be an investigation of fundamentals of layered software architectures through very basic architecture prototypes. Two Windows Form applications Introduction to that you I and the Controller Logic, which Windows forms provide three event handling will be an introduction to event types and request management. Four. User controls. Custom control creation. So let's begin so layered architecture is probably the most common architecture pattern. It's widely known by most architects, designers and developers is otherwise known as an in tier architecture. Pattern components within the layered application are organized in the horizontal layers, so each layer performs a specific role within the application. For example, presentation Layer would be responsible for handling all the user interface and the browser Communication logic. Where is a business layer would be responsible for executing specific business rules associated with her request. So each layer in the architecture forms and abstraction around the work that needs to be done in order to satisfy a particular request, for example, think about the banking application the presentation layer doesn't need to know about or worry about, how to get account data for instance, it only needs to request input in a particular format. And similarly, the business layer doesn't need to be concerned about how to format account data for display on a screen or even where the account date is coming from. It only needs to get the data from the data layer and then passed that information up to the presentation layer. In this chapter, we're going to look into the top two layers now. We do not intend to go into detail of a full ties application with all of the well, perhaps tedious aspects. Ah, a prototype with only two layers will be constructed presentation or you I layer and the U I controller layer, where everything that involves business logic is embedded inside. So let's begin. The presentation layer is a layer in which user can interact with the application. It often contains additional business logic as well. It can also be called the user interface, or you I layer Um, because it contains the visual components in other words, controls. So in general terms, it is only responsible for input. Transfer to application. No input validation and rule processing is done in this layer, although controls can be used to request input in a very specific format, leaving no necessity for validation. Introduction to Windows Form so Windows Forms is a smart client technology for the dot net framework. When you use a development environment like visual studio, you can create Windows forms, smart client applications that display information, request input from users. And it handles these inputs with a special type of method called events and Windows forms. Form is a visual surface on which you display information to the youth you ordinarily build . Windows forms applications by adding controls two forms and developing responses to use her actions, such as mouse clicks or key presses. A control is a discrete user interface element that displays data or accept data input. The Windows forms contains a variety of controls that you can add into these forms controls . It displayed text boxes, check boxes, buttons, drop down boxes, radio buttons and even Web pages. Even existing control does not meet your needs when those forms also supports creating your own custom controls using the user control class. When Windows form is created, a group of files are created alongside, for example, when you create a form named Log in form designer file. A controller file and a resource file is generated by the system as well. It basically follows a layered pattern with all the fundamental components which are presentation business and data later. Okay, so this resource file on Lee contains some constant data and has no storage functionality. But it's still a bidding example. I think you get it right now. The designer file is a place where the form elements in the user interface are initialized . If any element is dragged and dropped into the form window, that element will be automatically initialized in. This class. User can change the contents of this file in the editor, but it is not recommended for beginner. Now. The controller part is code behind the file of the Windows form. It contains the main class structure of the form with fields, methods, constructors and event. The business logic related to the use of the form or user control is implemented here. The resource file is an XML file that contains resources such Aziz images, paths and constant variables that you can use in the control. A resource file is created by default alongside the form although that's unnecessary because it doesn't really contain any resource, is at the very beginning. So let's get back to and continue our application and create a Windows Form application. 25. Create Windows From Application: So here is our application. Go to Solution Explorer. And at the top we have ah class library where we put our classes and a console application , which is currently the startup project of our application. And inside we have a program class, and inside of that, there is a main method. So this is the entry point of our application. Statements are executed one by one, starting from here. So in the beginning we start with creating an account. And to do that, we request lots of input from the user. Windows forms provides a nice interface for all of these inputs and which is one click, it'll let us create our account. Now we're not going to change the previous projects too much. We we'll just create a new Windows Form project for a start up. So go to solution right click ad new project and the new project window opens and select Windows forms app from the list. And the name of our application is That's just right. Demo form. Okay, so the new project has been created and there's one automatically generated form. Item inside. Now go to the program class of the Demo form project and as you can see, it is the same with program class of the console application with main entry point. So in the main method, there are extra statements for initialization of controls and at the end, the form control is started. Now the form has all the necessary component, so we can rename it. But let's just delete the default form with the delete key and create a new form of our own right click project from the menu. Add windows form and the ad new item window opens, and the name of the new form is create account form. Click add, and the new form is created now in the main change, the starting form to be the create account form. And now we have our main user interface Now in Solution Explorer. As you can see, there are two projects of this form. One is designer and the other one is the code behind so over the code and see it just as the class structure derived from the form based class. There are class name and ah default constructor and inside components are initialized. Also, you may notice that this is a partial class where the other part is in designer code, and when we open up the designer file, we can see that it has the other part. Indeed. Now, at the bottom of designer, we have system generated codes to start controls in the form, and at first there is only the one empty form control. Let's go back to the main, the designer window and let's edit it a little so right click on it. Jews, Properties and the Properties panel opens, and we have lots of properties, beginning with the name of the form. So we want to change the caption of the form. So go to the text element and right, create account panel and press center. So the caption is updated. And then we can change the locks setting as well, because we don't want it to be resized. And look that we have successfully created our first form. So go to solution Explorer. And as you can see, after we changed some settings and properties, the resource file has been automatically generated toe open that, and then exhale like interface opens so we can define additional properties here. Now, we're not actually going to be using this part anywhere I just wanted to show it to you. So let's go back to our designer Now. Here there's a toolbox panel, which you can access from the View menu in case you need to. There are lots of controls you can end to the form window, and the most common are listed here under the common controls tab. So in our application, we're going to need controls for inputs, select text box from the list and drag and drop it into the form and properties. Change name to customer name text box. And this will be used for our customer name announcer like the label from the list and at it. So this is the show. What? The text boxes? Four. So we'll write in customer name label as our name. Now go to text property and right customer name inside that, and our label is updated. Okay, so the second control is a date time picker. Drag and drop from the list and the name is birth date picker. So each control has different sets of properties. We can choose maximum possible date for the birthday here. That's that's right. 31. 12 2000 as a max date and minimum date can be something from, Oh, let's go way back toe 1980 and the label for birthday. So the name of the label is birth date label on, and the text is birth date. After the phone number, we'll choose a masked text box, so arrange the size control so that it doesn't look weird. So the name of this control is phone masked text box. No mass text boxes have masked properties that you can edit for. Ah, typical us A phone number format. We'll need to use this mask. This ensures that user can only enter the required numbers and add LaBella's well. Name is phone label and for the tax. Just phone is enough. Hank. Now for the address, we'll add a rich text box. Control the name of the text boxes address rich text box, and a rich text box can take text inputs on more than one line. So address information probably contained three or four lines, so, typically is to regular text box is not enough and add label. The phone label seems a little bit off to me. Okay, so the name is address label, and the caption should be address. Alrighty. So now we're done with our first form. So now we need Teoh. Make it. Ah, a little more compact. So? So, like the form and change the locked property toe false. You can drag at these points to resize the form. Ah, yeah, I guess that's okay. And then change the lock Property back to true. So now we can add a button and the name of the button should be create account, but And the caption of the button is create. And now to test it Ah, the console application is opened. We didn't update the startup project. So close it up and go to the demo form, right? Click and set it as started project. It's now it's tested again. Bingo! It worked. So our main form with different controls has now opened who will fill it in with different inputs. And now we can click create. Okay, so it doesn't work. Why? Because we didn't implement anything underneath of this button. So it doesn't know what it's supposed to do. Basically. So that means we need events in order to do that. And coincidentally, that is a neighbor. Our next lesson 26. Intro to Windows Forms Events: Windows form events, an event is in action, which you can respond to or handle. In code. Events can be generated by a user action, such as clicking the mouse or pressing a key by program code or by the system. Most events have a strict formats of definitions and can be created by the designer in the visual studio. By default, events are to find with private accessibility levels avoid return type, and the method name is a control name, followed by the event type and a set of parameters. Other formats or possible is well, and we'll go into those details in the final chapters. I think now the same event can be triggered by several objects, so it's a good idea to keep track of which object triggered the event. The sender parameter and the parameter list contains the reference to this trigger object. If an argument is the parameter, on the other hand, that keeps some event specific arguments inside, so event driven applications execute code in response to an event. Each form and control exposes a pre defined set of events that you can program against. If one of these events occurs and there is code in the Associated event handler. That code is invoked the types of events raised by each object very, but many types are common to most controls. For example, most projects will handle a click event. If a user clicks of form the code in the forms, Click event Handler is executed. On the other hand, Onley check boxes or controls, which have the check box within handle the checked changed events, and it's raised when the check box is checked or unchecked. 27. Demonstration - Windows Forms Events: so back to coding. First, click the button object and go into the properties panel. Now here there is an events tab that you see all the event types that the button object can trigger. Click Event is the default one. If you double click and empty area here, the editor creates a button click event in the controller automatically. Or you could just write the name of the event yourself, which I don't really recommend. So the statements in the body of the event will be executed. So let's right. Anything just to test if it really does work. So right Message box show Create button has been clicked. Start the application, create account window opens, so click the button and our pop up message comes up great. So close the application. Now we want the phone and address inputs to be optional inputs, and the user needs to be able to leave them blank. So let's open up some room here for two check boxes. If the form is not re sizable, just changed the lock property of the form. So add check box from the toolbox panel and just drag it into place. Now we need to change its properties. So click on properties. That's the icon here on the properties panel. Now the name of the check boxes phone check box. And we don't really need any caption for this control. So just delete the text property and then will be the same for the address input. First added check box, then changed the name of it to be address check box and to lead the caption. Great! So now let's examine the events of our check box control. As you can see, there are lots of different events and the default event is indeed checked, changed event and less time. We created it just by double clicking here. If we double click the control itself, the default event will be created. So now we want this check box to control the availability of the phone text box so we will bind the enabled property of the phone masked text box to the checked property of the phone check box to go back to designer. Initially, the check property of the check boxes falls since the phone area should be available by default. Make it true. I noticed that the Czech state also changed to be checked and in designer, the check box seems checked as well. Okay, so now let's do the same for the address check box. Assigning ones checked property to the other ones, enabled property and change the checked to be true and properties. Okay, good. So let's tested again. Great. So as you can see when we click the check boxes, the phone and address areas, changes to be disabled or enabled. Now let's find out what we should be implementing. Next. Let's go back to the old program class of the console application project. Now, after we collected the input, we will create an account object here, so copy it and go back to the click event of the create button. I will comment out the previous test code segment and just paste it right. Belong now. As you can see, our project does not recognize the account class. So for that first we need the class library to be added to references. Right click references of the demo form end a solution Explorer click and references the Reference manager window opens and then check bank class library from the list. Leave the demo blank and click OK, now go to the line where the error is. Click the link bone and it shows us some potential fixes. So click the top suggestion, which is to add using bank class library. Great. So now the account class is recognized, and now just one by one will need to collect inputs from the interface. First customer name is stored in the customer name text box, text property. Assign the birth date too. The birth date picker value phone to text of the phone, masked text box and the address to the text of the rich text box. Now we no longer need to request year, month and day separately since we have it all together in the birthdate variable. So now we can display a message about the status of the account for that well, right message box show account of customer customer name has been created. All right, let's test it. Just enter some random values for each area and click the button. Our message appears. As you know, the phone and address areas might not be enabled, so therefore, we may not be able to reach its text property now because we do need to make sure it collects inputs without any error. So for that we will create private properties that we can control the availability of inputs and access Er's. So let's create private string phone text input as it property and in the getter, Just check the phone text boxes enabled, If it is enabled. Return text property otherwise return. No. Now below. Replace the tech segment with this. Okay, good. So now we will do the same for the address text input and get her check for availability. Otherwise, return no value and replace address text code. Segment. Okay, so now we want to display the created account in another panel for that. Well, first comment out the message. Go to the demo form project. Right. Click ad windows form and the new item menu opens. Okay, so the name of our form is display account form, so click add, and the new form is created, so no right click properties. And now we can change the title of the form to be account in formation. All right, now go to the controller file. The default constructor has been created. So to display the account information first we need an account so and account parameter toothy parameter list and class library to the code. And since we will always need an account for this to work, there is no need for a default constructor, so we can just disable it by making it private. Right now. Go back to create account form and we create a new display account form object with the same name with new account as the only argument and after that right display account, show dialogue, and this will stop the flow of the program here and show the form until it closes again. Now, in the meantime, we don't want the old form to be seen. So call the hide method like we did before. And then after that dialogue is closed, we can show this form again. Okay, so let's test it. When we click the button, the new form opens successfully, and when we close it, the old form resurfaces again. 28. Input Validations: great. So now is a good time to implement input, validations, phone and address or optional and not much validation could be done about them. So here will need to put validations for customer name and birth date first the customer name validation So define bull Validate customer name. That's our method with Onley. A string argument which is the input text to validate Now typical name must have more than two letters and must have I don't know if you were then 25 letters So if these conditions are valid for a given name will return true otherwise return False Of course, We also need to check if there really is any input. So if given text is no, we cannot access its length property. Okay, so I should probably mention that you may have noticed Ah, we always make the check with the methods String is no or empty. It is not know are empty and its length is valid. It returns True, right? All right, so now let's do the second validation Boule validate birth date with only one argument a date input to validate. So here we will use a date time compare method to find out if the given date is earlier or not. So it takes two arguments, one of which is the given input. Now we're trying to find out if the customer is older than 18 years old, So to find out what time that is will need to subtract. 18 years from now, the daytime compare methods returned one of three possible outputs. Negative 10 or one. It is one. It means that the given time is later, then 18 years before. Therefore, customer is not applicable, so it returns. Fault otherwise return. True. Now that our validation methods are ready, we can use them. So first validate customer name. If it is invalid, we return a message in a box that says customer name is invalid. We'll do the same for the birth date and return. Birthdate is invalid message If the validation fails. Of course, we can't let the program flow to continue if any of these validations fail, so we'll just return if any of them hits. Okay, so that's yet. So let's start the application first. We'll try it with empty customer name, and it quickly shows us the message. So now let's write something for the customer name. And let's try to find some unacceptable birthdate. Okay, So as you can see, we cannot find anything since we picked a minimum date for this control. So we simply cannot choose anything later, then The year 2000 right? But this is not a very good implementation, because if we let this be our user interface every year, we need to update the minimum so that anybody who's 19 years old can open an account. Right? So our business side implementation is necessary, but right now we're gonna leave that. 29. User Controls: user controls. The user control gives you the ability to create controls that can be used in multiple places within an application. You could include all of the code needed for validation of common data that you ask the user to input. And some examples of this are email addresses, telephone numbers and, you know, postal codes. Now, another efficient use of the user control is to simply preloaded combo box or a list box with static items that you commonly use in almost every application. Some examples of this are countries and regions, city states, office locations, that kind of thing. So, for example, think about a form that the user has to fill in several similar boxes like this. Normally, we would need to create four text boxes and four labels, and then additionally, we would need to organize the positions of each control one by one. So instead of dealing with all these design issues separately, weaken simply create a single user control with two elements and two properties, referencing the text elements of the label and text box, a sense of the user control to our classes. In principle, we can utilize this object everywhere in the application makes sense. So now let's go back to the application Open display account form. So here we want to display the list of transactions in list form so that we can see all of them at once. So let's use the list. Box control from common control. Resize it right. Click Select properties and the name should be transaction list box. So here items. This is the items property. You can define items to be displayed in the list from here, line by line. Now, as you can see, the two items that we put our displayed in the list right now, of course, we're not going to use these values in our application. Our transactions should come from the controller. So now at a text box and a label under the form, and we'll use these to display properties of the account so additionally, Now, add a panel from the container tab in the toolbox Jews text box and label and just drag and drop them onto the panel. We can use this panel toe carry these individual controls together as a group. So normally, if we plan to use this kind of control group for each property of account. This is what we dio, um, because it is a lot of work. Instead of dealing with all of them individually, we will create a user control. So right click the demo form. So, like ad user control and new item window opens. So the name of the user control can be custom text box control, and the new user control has been created. Now go back to the display account for him and right, Click and cut the previously added panel. Go back to use control, right, click and paste. Or, you know you can just use the shortcuts Control X and control V. Now position the controls somewhere around the top and we can reduce the size of the user control. And then in the Properties panel, you can find the doc property also like the middle one so that the panel fills the user control, select text box control and find the anchor property, and we'll select the top and right edges so that the distance to them remains the same. Even if we resize a control now we can change the name of the text box to be no custom text box and the name of label to be custom label. All right, so now Bill the application so that our control can be used. We'll go to designer and have a look here, and you can see that our newly created user control is listed in the toolbox under demo form components. So now we can just drag and drop one of them onto the form. Now we need to access the label and the text box. So go back to user control, right click select view code from the menu, and the controller file opens. So here we will define the string the label tax property and get excess er return text property of custom level and in the center assigned the value to this property. Now do the same for the custom text box. So just create a property named text input and get her return the text property and in the center, a sign it. And that's also we created our property successfully. So now let's see how we can access them. So go back to the designer of display account form. So like to use the Control Jack Properties panel Now we should have seen them, but it seems that we cannot. Sometimes the designer update can take some time. So let's just delete the control and we can build and add a new one. You know, the famous saying right, went in down reboot. So now add the control from the toolbox again. Bingo. Now we see the label text property. So change it to be customer name, find the text input property and to test it, let's write something in it so we can see it's changes in the control. Okay, so just delete it. We don't want anything to be seen. They're about to fall now. Just change the name of the user control to be customer name, panel and new control. Change its name to be transaction type panel and change the label text to transaction type and now for the transaction amount. So the label text should be the same, and we'll keep adding these controls until we have enough to show all of the necessary properties of a transaction. Now, as you can see here, we need to be very careful about naming them in these types of interfaces. Things can. We don't get too complicated pretty quickly in the coding. If you cannot recognize you controls easily, and then we just select these transaction controls and weaken position 30. User Controls 2: now in this area. We want to show the details of selected transactions in the list. So for that, we'll first need to assign some data source to the list box, which is empty of the moment. So we'll go back to the controller of the display account form. And in the constructor, we get the account. But we don't assign it to anything. Create a private account field and name it my account. So a sign my account to be the given account now assigned the data source of the transaction list box to the transaction list of the account. And it seems that we can't access transactions from here because of its accessibility level . So go to the count class, find the transaction list among the fields and properties. There it is. So is private field by default. Create public list of transactions with the name transaction list. Now in the getter return the list of transaction and we don't need a center because we don't want it to be set from outside of a class like that, right? So now go back to the display account form and a sign transaction list as a data source and Of course, just a signing does not do the entire job. We will also need to specify which property of a transaction we should be displaying. So set display member to be summary. And right now, we don't have such a property in a transaction class. So we'll go to account right click on the transaction class and go to definition here in the fields and properties will create a string summary property and it's getter. We will need some information. So luckily, we created a display transaction method before and that contains this summary that we need So we can just copy and paste the first line. And that shows what kind of transaction it is. Can captain ate the amount of money and the transaction date one by one, leaving space in between. Great. So this time we want to show the time of the transaction as well. So in the two string method, use this format. Ah, it seems like we did make a mistake earlier for the month. We need a capital M, not small m, but it's just like this for now because the small m is for minute. Right? Okay, good. So now we're done so go back to display account form and we finished how we would display the transactions. But we don't have anything to show you, right? So go way back to create account form. And after the account is created, let's just make some transactions. So first will deposit some money and then withdraw some money. Okay, so that's it. Start the application and we'll write some name to get past creation. So now, as you can see, the two transactions that we just made are listed in the list box, so we still have some jobs to do here. Since neither customer name nor selected transaction information can be seen in these user controls, so and the application Select List box and we need to find out which transaction is selected in the box and when this selected item changes, so go to properties and under event list. Find the selected index changed event and double click. Create a new index variable transaction list, box selected index. So that's the property that keeps the index off the active list items and now create transaction variable. Ah, there's an error. So let's see what the quick fixed menu says. Add necessary elements to the code. Good. A sign selected transaction to be the transaction of the account with same index. Good. So now we have our transaction. So one by one, we will assign them to the controls in the form first, customer name. Now, the customer name has nothing to do with a transaction. So for the transaction type panel, it seems that in transaction, we do not keep any string properties that that shows that type of the transaction. So that means we need a string property. Because the text input property is string type. We will need to add it. So go to transaction class, create string transaction type strength. So now, in this summary, we already have this information we can just cut and paste. Now we cut it because we don't want the same thing to be coated twice, right? It's just one of the golden rules of coding. Just put transaction type string variable to summary in its place. Create location, string, variable, return location and finally create date string Variable. We did this before, uh, in the summer here, So just cut and paste this too. Okay. Great. Now that we're done, we can go back to display account form. So first we'll assign transaction type string. Second transaction date. Panel input should be assigned to be date. String a sign money amount. It is double variable, so converted to string now finally assigned location and we aren't done. So let's start the application and test it. And bingo, it works. That's great. So, as you can see, um, the transaction information can be seen in these boxes, so we'll change this election and look at that. They are updated accordingly. That's terrific. We are done. 31. Homework 3: what have we learned in this Chapter? One. We introduced layered architectures, especially presentation and business layers, and we investigated them in detail. Two. We introduced Windows forms as well as controller structures. Three. We talked about event structures and explained different event types and four besides forms . We gave some detail about custom user control structures and what fun they are. So now let's talk about your homework. We prepared a challenging and, well, some not so challenging jobs for you, so if you're ready to tackle it, let's go. So we'll start with an easy one. Here we have a customer name, and now we need a control to show the current balance. Now, please note that it should change dynamically with newly added transactions. The 2nd 1 is about the transactions themselves. Now here we displace, um, default transactions. But it's not enough. We also need to be able to make new transactions. Right? So, Jack, let's add the controls together right now. First we'll make a text box and then a button control. The name of the text box is deposit amount text box, and that's put some default value for this control. I think 1000 should be sufficient. Okay, Now for the button. The name is deposit button. And the caption is deposit. Of course, as the name suggest, when we click this button, it should make a deposit with the amount specified in the text box. Okay, Now, for the with draw. First, add text box and change name to withdraw amount text box and make the text. Ah, let's make it 500. Add button and its name is withdraw but and set the caption to withdraw. So now when we click these buttons, it should first make the associated transaction, and then the list should be updated here. Okay, So here's the tricky part. Just updating the data source of the list is not enough for the list to be updated. You're going to need to change something in our code to make sure that we see the change in this list. So what do you search the internet and try to find the solution yourself? Okay. I'll give you a hint. Binding lists. All right. Good luck. 32. Answer for Homework 3: Alrighty, then. Now, for the first assignment, let's add our custom user control onto the form and just place it under the customer name panel here Goto Properties and will change its name to be balance control handle and update the label text to be current balance. Okay, so now we're done with the design. Let's now go to the controller script. So the customer name is assigned here. However, this place is under selected index changed event and the customers not dependent on any transaction. So it should not be called every time like this. So let's remove it from here. And but it didn't sign the constructor. And the same thing is valid for current balance. We need to initialize it here. So assigned text input, Property of balance control panel to be current balance in the account. Okay, so that's done. So let's test it. All right. So, as you can see, the current balance is displayed properly so we can move on to the second assignment. Now, notice that these deposit and withdrawal buttons do not work yet, so we'll go to designer double click. The button is one by one. So that the click events were created and in the deposit of end first, collect how much money should be deposited and deposit amount is equal to text property of deposit amount, text box. But the text property is string. Therefore, we will need to convert it to double with convert to double as our method. Then after that, we simply call deposit money method of the account object with the selected amount as the argument. So the withdraw function is more or less the same. So we can just copy and paste it below and will change the deposit amount Variable name to withdraw mount and change the name of the control as well. All right, so now below, we will need to call the withdraw money method. And the argument, of course, is withdraw amount. Now we're almost done with the implementation of these events. But as you may have noticed, when we make a transaction, the current balance changes and that needs to be updated as well. So go to the constructor and find the previous code segment from the first assignment. Then just copy and paste it to the end of the events. Now it's tested. Okay, so when we use these buttons. Now the current balance is updated accordingly. So now let's change the transaction amounts for both. They still work the same. So perhaps you can see here, Even though the current balance is updated, there is still on Lee to transactions in the list box. New transactions were not shown in the list. So here the data source of the transaction list box was assigned to be the transaction list of the account. That means that the data source is affected by the changes made in the transaction list. However, even if the data sources updated the transaction list, box is not aware of those changes. So we need a type of list when there is a change in it that it forces all the objects that the list is assigned to asses. Well, now, if you have search a little bit on the World Wide Web, uh, you should have been able to see the binding list solution. Did you find it defined Binding list of transaction type as a field and I'll name it data assigned data source to be data now just above a sign data to be transaction list of account. Since both of the list types are the transaction class. It's allowed. So now when there is a change in the transaction list, the data will be changed to. And when the data changes, it will force the owner list box of the data source to update itself. Now, sometimes thes update processes ah, aren't triggered properly. So therefore, when we really needed to be updated, we will need to reset bindings of data like this. So let's put it under the withdrawal event as well. Okay, so we're done. We'll start the application and just click the buttons randomly. Man looks good to me. It works perfectly. You did it. So we successfully updated our list box and current balance controls well done. 33. Intro to Data Logic: introduction. All right, So far, we have successfully created our user interface and controller structures with several forms and user controlled. Now, besides a user interface, there are other fundamental layers that you need to get acquainted with. So in this chapter, we're going to investigate the lowest part of any layered architecture, and that's called the data layer. So to do that, we will introduce another important .net library system, Io. So in summary, we are planning to use the file system as a data storage unit for our application. But first, let's have a look and learn into what is a data layer. The data layer is responsible Onley for storing the data or retrieving the requested data from a storage unit such as a data base Database technology can be one of so many options, as long as it provides storage functionality between databases and the business layer. There is usually some other layer called data access or, in another word, the persistence layer, and that provides the means for excess ing raw data in the database. Conveniently now we're not going to dwell on these intermediary layers at the moment. We're going to just focus on the data layer as a whole. Now, in lots of ways, the data layer is different from the business layer. The business layer is the grouping of business functionality. It is the center of any application. To put it simply, the business logic is what to do, and the business layer is where you want to do it. Okay. On the other hand, the data layer just involves the means to access the data, and it does not change too much, really, depending on the business rules in the application. So in our application we have designers and controllers of forms and user controls, which constitute presentation and the business levels of our application. And the rest of the application is inside the bank class library, which is supposed to contain Onley basic classes called models. Now, if we're talking about data models, they should not contain any business logic inside it. All right, that makes sense. So what we need to do is move the business logic from this library. If there is any into our application with controller classes, the remaining models in the class library or needed by all the layers of the application, therefore it becomes a common layer, so the common layer should contain Onley, common models and some utility functions that may be required by all layers. 34. Refactoring - Logically Organizing Elements: So let's get back into the application and organize our solution so we'll open up Solution Explorer. And as we mentioned before, if any of these panels somehow gets closed, you can find them in the view menu. So first will go to account class and open a nested types region. Yeah, Here we have our transaction class, Although it is nested under account, we use this class several times without using the account class. If you remember, so it should not be nested dependent to account class anymore. So select transaction class with transaction types in new Marais Shin and cut it with control X and right click bank class library project. So, like Dad, class add new item window opens and the name should be transaction. And the transaction class file has been created. So now pays the previous code here and this comment segment here that's unnecessary, so you can just go ahead and to lead it. Now the members of the transaction class, our fields and several properties a t least one property right for each field. And it also has only one method which is to display information about the transaction on the console that seems really that there's not that much business logic inside. So we'll go back to account class, open methods region. And we have three methods, and it seems that there's not much business logic inside here either. So let's create account controller class in the demo form project, right Click Project and class and add new Item window Opens. So the name of the new class is account controller and the account controllers created. We'll make it public, create a field of the account object end, quote it model at bank less, library to the library list to fix the error. Okay, so define constructor with only one argument and assigned this argument to the model. Okay, so now go back to the account class. And among these methods, only display balance has some business logic inside. Since our application is now Windows forms application, this method needs access to forms and controls. So, in other words, the presentation layer in order to display the balance and this implementation is just to display the balance in a console. Therefore, it is console application specific implementation, so it cannot stay here. So we'll move this code into the account controller class and now we've gotten other error . So in this type of implementation, we may need to access each field through properties, since we're using a model to access them. So let's go back to the account class and at the top, you see how there's some a static field and the private fields are account, customer account number, current balance and list of transactions. So let's start with the account number. Now. You may have noticed we have a problem with naming of the properties. Since Field and property have the same purpose, it's only logical that their names are the same. Yeah, so here we avoided the problem naming transaction list, a property of list of transactions. But I would say, and hopefully you'll agree. It's not a very efficient naming system, so the solution is using underscore prefix in the name of fields. So let's right. Click the account number, select rename and put underscore at the beginning of the name and click Apply. Now, the account number name is available for the property, and we'll make get excess er to return the field, and there should be no setter, since we don't want it to be set outside of the class, and we'll do the same for current balance. And since we're going to change a lot of names, using a shortcut would be way more efficient. Don't you think so? Here the shortcut is double control. Are change name putting underscore a za prefix Change the name of the balance property to current balance. Now let's change the name of balance in foreign currency as well and the prefix to the list of transactions. And then we'll change the transaction. List property, too. All right, we're almost done. Change the account. Customer name. Okay, Now go to the transaction class. And here we already created the necessary properties. So just put prefixes into the names of the field. And one more thing, we will need a property for transaction date. So let's had it. And we're now done. So, as you can see here, that transaction class also has a display transaction method. So let's create a transaction controller class in the demo form project. Add model object. Define our constructor like we did before, and we will move display transaction method from the transaction class into here. We'll fix the errors by replacing them with the models properties done good, So the display transaction method has been implemented in the transaction controller. So go to the account controller and we'll do the same for current balance. For now, these methods keep using the console. That's let's keep in that way. For now, we can implement the user interface for them later. Go to account class deposit money and withdraw money are the methods that Onley contain the necessary implementations, such as insertion to list and the assignment operations. Therefore, there's really no need to carry them. Build a solution to see if we're missing something, which is always a case in organization jobs and the build failed. So will open the error list here. And it seems that the errors air from the console application. Why? Because we carried the methods it was using. I just wanted you to see how that works, Okay, so since this is the old startup project, there's really no need to bother with it. I just wanted to point it out, right? So let's just discontinue this project by unloading it and build again. See, so now it succeeds. And now let's prepare our demo form for data logic implementation will right. Click the demo form project Add class and you want a menu opens. And now we are planning to keep our storage operations in a single static class. So we'll name it. Storage utility functions and the storage utility functions. Classes created. Remember to make it public static. Okay, good. So now this class will keep the methods and the properties to use the file system as database. And then now, in the next chapter, we will see how we can read and write from the files and use it for our needs. 35. Intro to System IO Library: system input output. In other words, system io name space and dot net library contains types that allow reading and writing to files and data streams and types that provide basic file and directory support. The name space contains many classes for these operations. The file and directory classes provide static methods for the creation, copying delish in moving, renaming and opening of a single file or directory. All methods in the file class require the path to the file that you were manipulating, and many of these methods return other Io types when you CREATOR open files. So info classes air pretty much the same as file and directory classes in terms of functionality. Anyway, they provide properties and instance methods for typical file operations. Because all file methods air static, it might be more efficient to use a file method rather than a corresponding file info. Instance. Method. If you want to perform on Lee one Action Path class. So a path is a strength that provides the location of a file or directory methods of this class or used to perform operations on string instances that contain file or directory path information. A path can contain absolute or relative location. Information. Absolute bath. Fully specify location. Violet directory can be uniquely identified regardless of the current location. Relative bads specify a partial location. The current location is used as the starting point when locating a file specified with a relative path. The file Stream class provides a stream for a file supporting continuous read and write operations. The final class can assist the creation of file stream objects, or you can use its own syntax. But once it started, you can use it to read from right to open and close files on a file system, as well as to manipulate other file related operating system handles. The general syntax of the constructor of a file stream class takes several parameters to understand the purpose of the stream Object file path, absolute or relative path of the Target file file mode specifies how the file should be open should it be created a new or are we trying to access an existing file file access mode defines Constance for read, write or read. Write access to a file. If the file is not given right permission and it's tried to be written to the system does not allow that and file share mode. So this attribute specifies how two different file streams would access the same file. For example, if a file is opened and ah, file share method mode is specified as read, other stream users can open the file for reading, but not for writing. Yeah, Now, as we mentioned before, we intend to create a file system, directories and files to keep track of the active account. The main objective here is to handle the file operations in a way that can be accessed outside the data layer. So we have only two simple instructions to access one store account to retrieve account. 36. Conclusion: Yeah. OK, so you might be scratching your head going. What have we learned? One. The properties of the data layer have been explained. Making all the necessary changes in our application in order to separate data logic from business to system Io library. We've investigated that in detail, including all the fundamental classes. Three. So, finally, we successfully created basic operational file system storage. Now, it has been a long road, Um, especially with all the organization and the Iot implementation, but it really is worth it, right? So good job. Your perseverance pays off. Well done. 37. File System as Data Storage Unit: So let's begin. Let's start by specifying the path of the main directory that we're going to keep our files in. Define constant String Main Storage directory. A directory named Tim in the Root Directory should suffice Now a backslash inside the path string is a problem here since the backslash Um, well, it's a character as well in string terminology. So to avoid that, either put to back slashes or simply put the at prefix before the path at is the easier way to go, I think. Okay, so now we will check if this main directory exists. Since we will try to access the file this under it, we need to add system io library to the code, of course. And if the directory exists in this path, it returns true, otherwise returned false. It's a simple Is that so? What about the place where that we do this kind of check so I could only hope that you guessed it correctly. We're going to use this static constructor since it's called automatically in the beginning . It's a perfect place to check the database connection and prepare everything for the application and in our case, to prepare the file system. So if the directory does not exist, we'll just use Create directory as a method of creating the directory class. And the path is the one we've checked. Good. So now, as we mentioned before, we need Onley. Two methods to be access from outside one is to get the last created account, and the 2nd 1 is to saving account. So let's start with the save functionality. But first we'll need to specify how we're going to keep our files. That's a file can be filed with any extension. Let's say dot that the 80 file with account I D. As the same as the same name will use account I d in the name, since it is unique. So the first line of the file can store underscore separated account I D and customer name in this format. Since the number of transactions in the account is not known for each transaction, we will need to keep information line by line like this so that each next line represents a new transaction. Okay, so now first, Ah, let's create the file. As we specified. The file create method is a static, straightforward method to create a standard file. If the file is created before it over right, and since we will keep the information line by line, it would probably be better for us to use the create text method. Instead, it's format is typically easier to implement. So now to write our file, let's use the using statement. The using statement is used when we want everything written inside to be flushed successfully and flush just means everything to be closed properly when we're done with the files. So just simply cut and paste the code segment inside and then assigned the output of this to a stream writer object. So a stream writer is special stream object to read and write from text files. Now for the header line stream writer object right line account number. Underscore customer name over each transaction in the transaction list. We're going to add one more line, so let's first create the contents of the lines string. First, the transaction type, then transaction amount. Transaction date is a little tricky as always, so we will use this format for our file. That's easy, understand? Right? And finally a location straying stream writer object Right line transaction line. Okay, So now it's important that we know in which format to keep our dates. So let's cut the format that we used and paste it inside a constant variable called date string format. Now go back to the empty area and put this variable inside the to string method. Excellent. It's looking good. We're about halfway done. 38. File System as Data Storage Unit 2: As you may have noticed, we also need to keep track of customer information. So for that we'll need to create another directory where we will keep our customer data. Now there's no need to really get creative with a file. Names will keep them under the temp to directory now inside the check directory method. Let's check for this directory as well and inside the static instructor. Create this directory in case it's not there. It's now in the second part of our save account method, we will need to specify the format of customer data. File name only contains the name of the customer, and we assume that everyone is named uniquely in the world. It is strange world, but let's keep it simple for now. So the first line of the file can contain almost all of the necessary information about the customer. But there is an address lot, so the address string can contain several lines. Now, since we'll be keeping our data line by line, we cannot expect it to just fit on a single line. So each of the following lines keeps part of the address information. Backslash in is a special character for new line. Keep that in mind now. Previously, we used file class, and for this job, we're going to use file info class now in this class will first need to create a file info instance with the selected path. - So again, we use the using statement. And once we created the file info instance, the rest of the code is exactly the same as before. Stream writer. Right line. First customer name, then birth date. Ah, right. You caught me. We don't have a property for the customers birth date, so let's go to the account class. And here we created a date time, property customer, birth date and the getter return the birth date of the customer. Mm. You see what's happening here? We can't access the birth date from here as well. So it's like a waterfall. It kind of just keeps on going. So we're going to handle it. Despair with me. This is part of the fun of learning. So here you see this select customer class from here and go to the definition just by pressing the F 12. And now it seems that we missed the customer class when we were correcting the other models , so we can do it now. So first, put an underscore as the prefix to each field, Then get rid of the public fields. Okay, so now create customer name property in the getter return customer name, field, and then we can do the same for the date of birth. Now, I have to be honest with you for a second. If I mean, you know, I'm always honest with you, but for right now, let me just tell you that if you choose, this path is a profession. You will be doing lots of re factoring like this. It's just it's just ah, you know, part of the game. But I'll assure you, it's never too late to reconsider your life choices. I'm just playing this. This is great, isn't it? I mean, it keeps you alive. Anyway, we're done. So we'll go back to the account class now, here, return date of birth property, and then we can finally go back to the utility class. Now we can add customer birth date to the line, and the string format is the one that we used here right now. Add customer phone. Great. So now we're done with a header line. Now for the address lines, we'll need to separate address information with the split method. This method splits the given string into sub strings that are based on the characters in an array. The characters will be the ones that represent the end of the line so that each sub string is one line of address. Now the characters we should use for that are back, slash are and back slash n So for each address line in sub strings, well, right, new line into the file. So that's it, and we're done saving our account. 39. File System as Data Storage Unit 3: So now it's handle how we retrieve our created account back. So first we will create an account just to return directory. Get files is the method that we used to get all the file names from a given directory path , and we'll get them into a string array so that we can find the path of the last account file. So let's just assume that the last entry on the list would be the last added file. Of course, before this, we will need to check if there is any file inside the directory. So if the length of the array is zero, men return. No. Now I really wish this was the correct way to go, but they get files. Method of the director class does not guarantee that the file order is according to the time of their creation or update. For that, we will need to use the directory info class, so we'll create an instance of directory info. Use the get files method of this instance, and then you'll see that this method returns an array of file info objects, which contains a lot of information about the files, and then we need to check the right time for each item in the file Info array. Sorry I was falling asleep on you there. Well, I mean, I don't know, you feel the same way as I do, but this is just too much coding, Teoh, just to get a single object from a list, don't you think? Or am I reading your mind Where you always already thinking that? Um well, luckily, it's way easier with link or language. Integrated queries. So all you gotta do is just instance he ate last file info object from the array call order by descending as our method and or the elements of the array according to their last write time. After that, just returned. The first element, which is guaranteed to be the newest isn't link well, beautiful. I almost shed a tear, but really, when you're dealing with complex database, it is beautiful. All right, I'm recovered down. So now we will need the same control. Ah, but with the file info array. And we'll comment out the obsolete code segments. We can get the file path from the file info array with full name property, and then we also need to extract the file name from the path. In order to do that, we will use the past class. And what do you see here inside the path class? There are lots of methods to manipulate the path string. So right now, we'll just need the file name without the extension park. And as you can see in the save method, this filing course bonds to the account I d. So let's just keep this information inside the account. I d variable before we move on. Okay, so now to start reading the file, we need the using statement again. Call stream reader file open text. Then they give him file path. So we'll read the first line of the file with the read line method. Now, to extract the customer name, we will use this split method of this drink class with underscore as a separator character . So customer name is the second element. So return it into the customer name variable. So here we're gonna live on the edge. It's the beauty and the danger of the using statement. So, outside these curly brackets, nothing survives, including the customer name. See what I mean? So defined the customer name outside the scope and a sign it inside and now, my friends for the transactions. So first read a line into the next line string here and create a while loop, which checks if there is still a lying to read, it's the same is checking if the next line is empty, so if it enters the loop, it means that it is a transaction line. Unless not forget at the end of the loop, we will need to read the next line so that it doesn't just go toe loop infinitely. And let's greet a transaction line variable and be done with it. Now again, we will need to use thespian function. So for that we create a parts array and split the transaction line from underscore character locations. And now let's check and see how we have saved transactions below on. Copy the information and paste it here well, so if you pace it nearby, then we can cheat, right? So transaction type is the first element. The 2nd 1 is transaction amount. 3rd 1 is transaction date string and then finally the location. So now let's convert them into the proper formats. First transaction amount. Convert the string to double and now the transaction date Convert from string to date time . You know what we're going to need to use the date Time parse exact method. So, in other words, to parse Exactly, we need to know which format we used in the string. Luckily, bump a bum. We are prepared. Date string format is our format. There is a transaction type, but I don't want to deal with it here. Um will handle it at the constructor of a transaction. Okay, so now we're done extracting all the necessary arguments from a file and we need to create our transaction object, Go to transaction class. And as you can see, we do not have a constructor that takes all the arguments for all of the fields. So what we do is we'll create a new with all the necessary parameters. First double amount of transaction, then transaction type, string, date, time, transaction date and transaction location. Okay, so this is an instance constructor for all fields. So just one by one, we will initialize them. Money, amount, transaction, date, location. Fields are initialized. And for the transaction type, we need to find out which string corresponds to which transaction type. If the transaction string is deposit, the transaction type is deposit. Otherwise it will be withdrawal. Okay, so here it seems we forgot to put the prefix in the transaction type field. So we'll go to the field definition devil Press control are and update the name piece of cake. Now go back to the utility class, create a new transaction object with these argument. Transaction amount, transaction type, transaction date and transaction Location, Then after that, yes. What? We've successfully extracted transaction from the file. 40. File System as Data Storage Unit 4: So we need to add these transactions to our account. Right? We've created an account with a default constructor here, but first of all, we need to extract customer information to create an account object. As you can see, the customer name has already been extracted, so we know the name of the file. So let's start nested using statement here, create stream reader for customer call file open text and the path of the file is storage directory customer name dot That now read the next line in the stream. We used next line variable here, too, but now it has been declared twice. Let's just declare it once above and now its scope does not reach below. Now let's see what the first line of the customer file is, and it's here. So copy and paste it close to our code in order. Teoh reference. It will use a big word just to make sure that it's legit and we'll use this split function again, just like we did before. For the header line, be count file For the sub strings, we can use the header parts array above, so we already have the customer name extract, birth date with date time parse exact method. The second sub string should be date parts exact Method needs the format of the date, so copy and paste it from below. The third argument is no, and that's it. Phone number is the third sub string, and we'll need to carry these variables outside the scope of the using statement Now for the address part. So it's the same routine as with the transaction lines. Yeah, First read the next line in the customer stream. Copy and paste the wild loop statement from the low and copy the 1st 2 statements as well. And James the variable name to address line. Okay, good. So now we need a variable for the address, like birthdate and the phone number here in order to collect all the address parts, you know. So here we only sign the first dress line to the address variable and then in each loop. When we read the next line, we will just add that to the address, putting a new line character first, and that way we'll keep the line breaks as well. We will need to add new address lines into the address variable with the plus equal sign. Now, if we just used the equal sign on Lee, the last line would be assigned as the address. Ah, I made a mistake. So we have to use this dream reader object created for the customer file. But instead we use the one for the account. Okay, so that's it. We do not need any additional coding for the address. Thus, we have successfully extracted the customer information. Good job, folks. 41. File System as Data Storage Unit 5: and now back to our objective. What was our objective? Do you remember? We need to return the last account. We already created the last account object here. Now we want to re initialize it with all of these extracted fields. So instead she ated with new account. And as you can see here, even if we used the constructor with four parameters here, we would not be able to fully return the last account. Because the account i d is not assigned in any of them. So goto account class in the regular constructor here. As you can see, the account number is assigned to some unique I. D. So if we just copy and paste this constructor and then and account number as a parameter, wouldn't our problem be solved? Yeah. So a sign the account number field to be the given argument, and that's it. Now let's go back to this storage utility class, initialize it with a new constructor here. First account I d. Then customer name, birthdate, phone number, and finally, the address. Okay, so now that we're set and done, we will need to add the extracted transactions to the account object. So here Let's just see if we have defined such method. Okay, so it seems that we did not. And when I say we I mean I. So let's go to the account class and add void. Add transaction as a method with the new transaction parameter. So inside the method, we'll just add this transaction to the list of transactions. But hold on. We're not done here yet. We need to update the current balance according to the amount and type of the new transaction. For that, I want to introduce you to our big friend. This switch statement. So if a transaction type is deposit, then add the amount to the current balance. Otherwise it is withdraw. So we subtract the amount, right? That does the job go back to our code. Add transaction. Now, after we've collected all the extracted transactions from the file Weaken return our last account in peace and solitude. That's it. We're done. So now let's collapse thes two methods into definitions. So from the storage utility class on Lee, these two methods can be accessed, right? This is what the data layer is supposed to be doing. It separates us from all the complex storage logic. So now we just need to test it. So let's go to create account form after the account object is created here and transactions, they're done. Let's just save our account, using the storage utility functions. Then let's get the last account and assign it to our last account object. But a break point here so that we can observe the changes. All right, start the application. Now. Of course, there are going to be summarily. Errors are okay, Okay. We can't control everything in our code, especially with all the re factoring going on. The first customer name is an accessible That's natural, right? Since we made a private, if you remember and the phone and address fields give the same error, probably do the same reason. So just write the name without an underscore so that it can access it through property and we'll just fix them quickly Now. There's also some errors in the assignment of phone and address, so we can set these excess er's they're no longer used. So let's just comment. Amount. Build the solution this time. Good. It successfully build start the application again. That's right. Something for the name for example, Jack Animal and a random phone number and put some long address information into the dress box. So now when we click the button, it hits the brake point. Step over the code from this button here and now, our account should have been saved in the directories under route. So let's go check him and file Explorer, go to the local disc C, and here we can see two directories over the 1st 1 Inside. There's our account file with its account number as file name, right Click, and it opens with a note pad. Now we can see the header and two transactions. So make sure you close up this file and go back and we'll open of the other directory. And here is the customer save file firs. Line is we're name, date and phone number. The rest is the address. Okay, so now go back to the code. It's time to test if I can retrieve from the files back into our object. Well, step over the code again. Here, the last account object is assigned. Now, if you look inside, we can see the customer information, and it seems there is no where there Now, if you open the list of transactions here, you can You can actually see that two transactions listed and they have been retrieved from the code as well. So I don't know about you, but I do believe that our storage operations seem to be working perfectly excellent. Then they feel good. 42. Intro to Inheritance: class hierarchies. So in this chapter, you're going to learn what inheritances, how to create base and derived classes and maki modifications such as abstract, sealed and virtual. How to override members, how access modifiers work in the hierarchy, what polymorphism is and how to implement interface. It's so let's begin. Are you ready in dot Net. You can create a parent class. It contains, in other words, encapsulate its common functionality. Additionally, you can create hierarchies defining a child class that uses, extends or modifies the functionality of apparent class. So this process is called inheritance. Right? Makes sense. The class whose members air inherited is called the base class, and the class that inherits the members of the base class is called the derived class, So inheritance is one of the most powerful and fundamental features of any object oriented programming language. First of all, all types in the dot net framework implicitly inherit from the object class or a type derived from it. So does that mean well, it means that the common functionality of the object classes available for any type. For example, if you want to initiate an account object, even if you count classes no implementation. In the beginning, you would still have access to the four methods that are inherited from the object class. Cool. So another example is windows forms objects which are used in our application. In previous chapters, all forms are descendant of the form class, which means that numerous properties, events and methods of the form class base is accessible to all form types, and a second fundamental object oriented feature is polymorphism. Polymorphism just means defining methods that must be implemented by any derived classes, which results in unique implementations for each different classes that they're in. So the method defined in the base class must also be included in the derived classes. But the implementation of the method is left up to the derived class. So even though the implementation is different, it ensures that the inputs and outputs of the methods are the same. Thus the basic functionality is maintained. So this type of implementation has seen a lot in what we call the interface structures, and you're gonna be familiar with the concept once we start coding Now, the purpose of the inheritance class is to create base classes that encapsulate properties and the methods which can then be used by the drive classes of the same type. So consider our account class, which is the display balance method, which is defined inside. Then you can derive to several classes, savings account and a checking account. Because these classes use the same logic to display balance information, they inherit the display balance method from the base account class, so this enables you to create one common code base that's easier to maintain and manage. So after you to find the classes, objects of these types can then be called and then use the methods of that account class. So here the client code does not know anything about the account class or which method belongs to a base or drive class. So in C sharp and dot Net, A class can only inherit from one single class, however, inheritances transitive, which means that you can define an inheritance hierarchy for a chain of types. In other words, tight D can inherit from Type C, which inherits from tight be, which inherits from the base class type A, and the members of Taipei are still available to Type B. C and D right makes sense. Okay, So now let's go back to our application and see just how base and Dr Classes work. So in the solution, Explorer, let's find any Windows form object that we created before. Okay, So create account form is one of them, and that's holding up the code file just by double clicking now, here is you can see this form has been derived from the form class, which already belongs to some class hierarchy itself. And just right, click the form class and go to definition. Members of the form class can be seen here. Now, look, as you can see here, many properties, events and lots of different method definitions exist in the form class. Now go to beginning the file. And here it seems that the form classes derived from another class named container Control . So now let's put a pin in here and look into how the class hierarchy in the user controls work. Okay, So go to solution Explorer. And there we have custom text box control. So let's over the code, though. Yikes. I apologize. I opened the designer by mistake. Okay, so there we go. Um, now, here we can see that our custom control is derived from the user control class. Yeah. Now go to the definition of user control. And it seems that container control is the base class of the user control classes. Well, so what does that mean? It means that every method, property and event available toe a form class is available for a user control class too. I know, I know it sounds like I'm making a big deal about it, but it's true. It's huge. You'll see what I mean as we go on. So now let's go a little bit further and we can see what container control is based on. And we can see two different pace types here, one of which is an interface. Ignore the interface and go to the definition of the base scroll Herbal control class. And we found another class which has, I mean is like, archaeology isn't it has four different base types this time and again, only one of the base types is a class. Okay, which is named control. Okay, now let's stop right here. And I want to go to the account class that we created. Now we want to derive a new class from account And to do that, just go to project name, right click and new Class and new item and a window opens. So let's name the derive class like, um, checking account. Okay, so first, make it public, remember? And let's define its base type, which is account. So this is our first derived class. Yeah. Okay, so let's save the solution. Just by pressing Control s now, let's go to the create account form, and we'll try to instance e eight, a checking account. So create an object named New Checking Account. And yeah, we'll just use the default constructor here. Since we didn't define any other constructor, that's fine. Now, to see the available members of this object, just put a dot in the end of it, and the list of accessible members is displayed. Now, as you may have noticed already, these were all members of the account based class. Right now, we don't have any elements in the derived checking account class, and still we can access these members. See, now we're talking, right? So if you look really closely in the definition of each member, it specifically says that they belong to the account based class and that's it. So let's just delete this code segment before we move on and we'll dig a little deeper. 43. Intro to Inheritance 2: alrighty then. So not all methods of a base class are inherited buying derived classes. There is an obvious exception. Have you thought of it? Yeah. I'll give you a hint. Each class has to define their own constructors, including static ones. However, you must be careful here because a constructor for every class in the inheritance Jane must be called as well. Now, you're gonna understand that concept better when we start coding again. But hang in there, stay with me because I need to explain a couple of more things. Finalize er those are very much like constructors. They're used for cleanup. Such a smell ary management and releasing any additional resource is after an object is destroyed so they cannot be inherited. And they follow the same pattern as constructors when they're called by the garbage collector in base as well as derived classes. Now this syntax of a final izer looks like a negation of a constructor Done there. A final Isar does not take any modifiers or have parameters, and they cannot be called. They're invoked automatically to do any remaining job. So in General, C sharp does not require so much memory management. The reason is that dot net framework garbage collectors implicitly manages the allocation and the release of memory for your objects. On the other hand, when your application uses unmanaged resource is such a Z controls files, database and network connections, you should use the finalizes to free up those resources. So you might want to think about it as the final Isar structure is more about program flow , so we're not gonna pay any more attention to it in this course. But just think about it that way. Sealed class No. By default, any C sharp class can be inherited. However, there are cases that you may want a class not to be inherited, in other words, to be sealed. So let's say, for example, suppose that you have an account class and you want to create a derived checking account class. Based on this class, Another programmer can come along and create a drive class based on the checking account and then use it in ways that let's just say you really didn't intend. So, frankly, it happens a lot, especially in large applications with multiple developers. So by using the sealed modifier, you can create classes that cannot be used as a derivative. In other words, you cannot make a derive class from. So that's why this type of classes often referred to as a final or sealed class abstract class. So nothing about Ah, slightly different scenario. Let's say that we have in account class but do not want anyone to. Instead, she ate this class that is, client code cannot create an object of this type. So this class is rather in an abstract structure, kind of like art, forming a model for classes to be derived from. By using the abstract modifier, you ensure that no one can create an instance of a class. Therefore, access to the methods and properties of the class must be through a derived class. So let's say, for example, here. In order for clients to gain access to the display balance method, they must create an instance of one of the derived checking account or savings account classes, right. So the account class Onley exists. Here is a blueprint to show what's expected of a certain account type. Now, to actually influence the members is left up to the derived classes, so the abstract method is a method that has only a definition and a signature, but no implementation, as I'm sure that you can see right here. It's just a method name of return type and the parameters these air. Just basic information regarding how the method should be implemented now. Abstract properties can also be defined in a similar way here. Let's consider a name property, and this property has only one access. Er the getter specified inside, and there is no implementation for that. And this means that the derived classes must Onley implement the get excess er for a name property of the base class. Now you can declare non abstract members in abstract classes, but you cannot declare an abstract member in non abstract classes because if certain class has an abstract method or a property in it, it means that that class is incomplete. All right, so therefore it should be abstract as well. How's that for being abstract overriding methods and properties? So we've established that abstract members must be implemented by derived classes now, in some cases, we should also let non abstract members be implemented again, in other words, overridden by derived classes. So, in order to be able to override a member. The member in the class must be marked with the virtual keyword now by default members of the base class or not marked as virtual so therefore they cannot be overridden. 44. Non - Inheritable Member: all right. So the last time that we were in our project here we created a derived checking account class. So let's start the coating again. First, let's create a checking account object. Initialize it with a default constructor. Now, as you can see right now, this glass is empty. So therefore, we don't have another choice for a constructor, but the default one. So let's put a break point right here and let's see what happens. Create form ovens and just fill the inputs in with some random things and click the button . So, of course, first, a new account object is created. Now, if you look inside this object, we can see that it's just unordinary account object created with the given parameters. Now, if we run the program for another line, the checking account object should be created. But when we look inside this object, we see something strange. Do you see it? Yeah. This is just like any other account object created with a customer name admin and somehow the members of this object. Soon it's just automatically initialized. However, we don't have any constructor in the checking account class, right? None. So what's going on the default constructor that the system provides is something that it just works like this. Um, if we were to allow it to be created. However, because of the inheritance process that's going on here, the constructor of the base account class is involved. Okay, so go to definition of account class by pressing the F 12. Keep now open the default constructor there. And as you can see, the customer named Admin is created alongside with other initialization process ease. So the constructor of the drive class actually works that way. Okay, so I wanted you to see that. So when it's called, it calls the constructor of the base account class specified here just like that. Now, since we did not specify anything before, the system automatically called the default constructor. So now let's specifically requested to do so. So here the first base constructor does its job, and then we can do additional initialization is here or you know what's ever necessary right now. Just go back to the create account form and observed that the account object that we created in the process uses a constructor that has a lot of parameters, and we probably will need the same type of thing for the checking account. So let's go to account class here. Just let's just copy the signature of the biggest constructor. And now create the check any crown constructor, and then paste the parameters here now to see it better. Let's move some of the parameters down to the next line. Okay, There you go. So now let's let's create which constructor to call from the base class. You with me? Okay. Right base, first account I D. Customer name, date of birth, phone. Ah, address. Now, have a look at this. Just notice that these are the exact parameter names that we used in the checking account constructor. So it simply takes the parameter from the client code, and then it transfers it to the base constructor one by one. Okay, so now let's assume that we forgot to specify which base constructor to use here, since it doesn't know what to call it would simply go for the default constructor. Yeah, So go back to create, account and initialized the check and count. Object with the parameters that we collected before. Now, since we are one parameter short, let's just put minus one for that parameter, and it just happens. Be for account i d. But the break point in and start the program. So now fill the boxes in with some random stuff and click the button and the checking account object is created. Customer name and phone. Everything seems to be in place. Perfect. So stop the program. 45. Sealed and Abstract Modifiers: Now we're going to derive another class from the account. Go to class. Library. Right. Click. Bad new class. So right, savings account for its name and click Add. So the savings account classes created Now. First, let's just try and make it a derived one from the checking account class. Since we created the necessary constructors, the system does not prevent us from doing this right. But it is not the purpose of the savings account. So we were planning to create to derive classes first the checking account, which is derived from the account class and then second, the savings account, which is also derived from it. So to ensure that this type of mistake does not happen again, we've got to go to the checking account and make it sealed. Does that make sense? So the sealed modifier forbids the checking account to be used as a base class. Great. So now we can change the base of the savings account back to account class. Okay, good. So now let's make this savings account sealed as well, so that it will not be derived from. Okay, so go back to the checking account and just simply copy everything there now paste them inside the new class. But the only change here is the name of the class. So just replace them with a new name and that's it. Now go to account class and let's make this class an abstract model. And why don't we see what happens next? So go to the create account form. Now here we should not be able to instance she ate this account class right there it is. Now they let's just let's just assume for a moment that that were on Lee used the derived classes and we will not need an account object anywhere. So we'll comment out this line and just replace the name of the checking account object and build the solution. Okay, so, as expected, we have two errors. I mean, I expected it. I hope that you did. If he didn't, that's okay. Stay tuned. In storage utility functions, we used the account object to retrieve the last account from a file. So now let's go to the account class and check the methods there. We have three non abstract methods defined. Therefore, it's probably not the best idea to make this classed abstract right. We're going to come up with another solution to keep our model safe 46. Sealed and Abstract Modifiers 2: okay so far, we created the account class. We then derived two different account classes from it, which are the checking account and the savings account. Now, since we also need account objects for storage operations that we can use for any drive classes that are going to come from it as well, we cannot make this class abstract. So for this reason, we're going to add one more level and keep our abstract account model in the account based class. Just follow me along to Solution Explorer right click bank class library. So like add class and the name of the new class is account base click add and the account based classes created. So first, let's change it to public abstract. There we go. Now go to the account class and change it back to non abstract and make it derived from account base. Now what should a basic account model half? Check the methods, so let's begin with them First. Public cool deposit money method with Onley the amount of money as a parameter. So if we define it like this, it's your given air, so we're going to create an abstract version of it and the 2nd 1 is abstract again. Bull withdraw money method, and we also need some properties. First, create abstract string customer name and let's define, get and set access er's for it. The 2nd 1 is double current balance now, since we require it to be changed through ah deposit and withdraw methods only. All we need is a getter for this property. Okay, so now go to account class and we have a current balance here. Inside the get excess er is defined, so let's go to method definitions. As you can see, there are air roars. So since we implement the abstract methods from the base class, we need to override them. Thus, there's a need for the override modifier. I think that's the name of this chapter. At least that's what we're gonna focus on now. Um, so let's put it here. Ah, just to see what happens. Oh, now you see, there seems to be another error, so observe here that the order of these modifiers is important. Ding ding ding all flagged that up for you. Okay, so we should put abstract sealed virtual or override as the keywords after the access modifiers and before any return times. Boom! There we go now. Do the same for the withdraw money method done, and we have properties that need to be updated as well and customer name. The signature of the current balance property fits, but the customer name property is different from the one that we specified in the abstract based class. It has both access Er's so defined the center here and assigned the value to the customer name. What's this? There appears to be a different error, so go to the definition by pressing after wealth. Okay, so it seems that the customer name property inside the customer class also needs this kind of arrangement. So let's check the base class. All right now, it seems like we're done. So let's build the solution. Yes, it's exceeds, but you knew it would. Now let's go to the create account form, right? See, now we're able to create the account object again, since it is not abstract, so we're going to modify the base class a bit for a checking account. But before we do that, let's remember how our application works that started up. First the account is created, then the display account form opens, and that shows two transactions in the account. Let's close it up for now. Now we go on to account base and add abstract double commission property. So this is a property that holds the commission rate that the bank is going to collect from each transaction. So go to the account class and implement overridden commission property. Oh, great. A little too much. So let's delete that and created ourselves. So first, let's create a private field for commission property. Then in the Getter returned this field. Now, after we assigned the value in the set excess er yeah, that's it. We're done now in the account class, we have two methods that we override. We want the derived classes afterwards to override these methods as well. So go to the checking and count class and right public override, and it will display the list of methods that are suitable to be overridden now select deposit money method, and it automatically generates everything. So in this particular implementation, it just calls the method of the base class. Thus, nothing is different for this method. Um, you know, in the in the checking account, so we'll do the same for withdraw money. Okay, so we're done. So for now, let's leave these as they are, and we can go to the account class. Now we're going to create a method to display some info about the account, and we will use the console to show a message to the client. Console right line method can be used here on the message. Contains account i d current balance and the type of account class were in, which is just, ah, regular class. In this case, the right line method can be used like this. So we can We can also add the parameters after the message. Right. So here we passed the message as a regular account. But we do want this method to show the class type in derived classes as well. So what do we use? We're going to use the virtual modifier. That way we can override this method in the derive classes. So go to the checking account class and start typing override. And as you can see, display account info method is available. Telesis, delete the default implementation, right. Console right line. And the first message is the balance of the checking account. Then we want the client to know the commission rate, and that's it. Now go to the create account form and we can remove the comment at the instance. See ation of the checking account object. Change name to new checking account. Now, first, call display account info as our method of the new account object. Then do the same for the new checking account object. But a break point right here. And are you ready? Start the application. And again, we could just puts, um, random entry info into the boxes and click on the button. The break point is hit. Now step over this line and the first method is executed. I know. I know. You're gonna ask me toot. It's a Windows forms application. Where's the console? Well, you're not wrong, but you're not right either. Uh, let me show you in the view menu. There is an output window for developers to monitor the application process and to see messages like this. So, as you can see, our message has been pushed here. And if you step over one more line, the method in the checking account object should be called as well. Okay, So observe here that even though they're the same method of the same base class through the virtual modifier and the override property, we have two totally different results. Cool. All right, well, we're done. So right here, you can stop the application in peace. 47. Acces Modifiers Revisited: access modifiers revisited. So even though almost every member of a base class are inherited by derived classes, whether or not they're visible depends on their accessibility. The effects of access modifiers on A members visibility for derived classes are right here and as follows and I quote, private members are visible on Lee. If the derived class is nested in its base class, Otherwise, they are not to make them available to any derive class, you should make them protected. Protected members are visible, and they have protected accessibility in those derived classes. Public members are visible in derived classes. Makes sense. Public inherited members can be called just is there, defined in the derived class. Internal members are visible. Onley in derived classes that are located in the same assembly is the base class. They're not visible in the derived class, is located in a different assembly. So let's not give internal accessibility levels so much thought and focus on private and protected in public modifier. So consider just the three fields A, B and C in a base class. Ah, so in this next example that protected and public Field A and B are accessible through a drive class, even though private field see is not okay. So now let's see how access modifiers work in our application. Go to the account based class and by default. Of course, a member has internal accessibility if it is not specified. And as you can see here, we only defined public members so far. So that means that each member is accessible to everyone. Now let's add one more method here with ah, different accessibility level. And to do that first, go to account class and the last method here is add transaction, and we're gonna add this to the base class to go back to account based. Now, let's first try to make it private. Create abstract avoid. Add transaction is the method with Onley one parameter, which is a new transaction. Now what did I tell you? As expected, there is an error. So says here that virtual or abstract members cannot be private because private members cannot be access from derived classes. Therefore, they cannot be overridden, but virtual and abstract members are meant to be overridden. In fact, they're begging for it. So let's make it protected and see how it works. Okay, now go to account class and check the implementation of the ad transaction method. There's an error, of course, since we did not use the override modifier here, add the override keyword before return type and there's still an error. Was that expected by me anyway? So this time the errors caused by incompatibility of access modifiers between the signatures of the abstract method and the implementation here. So basically the rule is that you cannot change the accessibility of any methods in derived classes. So if we change this to be protected, the error would be resolved. Good. So now let's go to where this method is used. So we use this method in the storage utility functions. That's to add the transactions that we extracted from a file. And since the method is protected, it cannot be accessed from outside Now. Normally, we're not really supposed to use this kind of special method for the job, which, for which fundamental methods are you supposed to be doing that already, But I want to show you what happens so simply to add a positive transaction. We should use the deposit money and to add a negative transaction or withdraw, we should just use the withdraw money method. So let's fix this issue here. So first, open up some space for our code and go toe account class and copy the switch code segment there and paste it in here. Now, according to transaction type, we're going to call either deposit war that withdraw money method. But first, carry all the codes where we extracted information about a single transaction, which are amount, date and the location of the transaction. If the transaction type is deposit, then call deposit money method. And, as you can see here and the list, we don't have a method that can take all three arguments inside. So let's define a new deposit money method so we write the parameters transaction amount, transaction date and transaction location one by one Copy and paste this line into the withdraw part and just change the method name, too. Withdraw money. So now if you drag the mouse cursor on the error or any other of the pops up, it will give you a quick fix, which is to generate a method within these given parameters. So now we can do the same for their withdraw money method to and There you go. The errors are resolved, and the rest of the code is now, obviously. So we'll just comment them out, save the changes and go to the account class. Now we have to find automatically generated methods somewhere. Okay, Here they are, inside the constructor region. Let's move them to where they belong, which is at the end of the methods region. So the methods are automatically implemented with an error condition. Right? So just erase it. Now we need to create and add withdraw transaction inside. And luckily, if I remember correctly, we just commented such code segment earlier. So in stored utility functions, just copy the code and paste it inside, then new withdraw transaction method and uncommon them. Almost everything is in place except the transaction type. So here, just right, withdraw. And let's do the same for the deposit money method as well. So after we created the new transaction object with the given parameters, the only thing left to do is to call the ad transaction method, so we'll add them to. All right, that's it. All right. So you get what we're doing here, right? The main purpose of creating protected methods is to make sure that we can access the methods both inside this class and also from the derived classes. So we're gonna test if we can do that, go to the checking account class inside the deposit money method here, let's try to access add transaction. And as you can see, it is in the list of a member of the account class. So let's delete this and now try to override a method at the end of this class. And since the method is in the abstract based class, we are allowed to do that. However, we really don't need such functionality here, since the unique functionality of adding a transaction to the account is already implemented within the account class. So therefore, we are going to add the sealed as a modifier here, just like we did in the class definitions of the checking account and savings account. Right? So when we had that modifier add, transaction can no longer be overridden. Thus, the functionality of this method is now and here to four preserved Good job 48. Polymorphism: interfaces and polymorphism. I know it sounds like a mouthful, and no, it's not an exo planet of some other multi verse. But I want to remind you that in the beginning of this chapter, we talked about how important Polymorphism is to object. Organic program. So we gotta cover here. Polymorphism is the ability of derived classes inheriting from the same base class to respond to the same method. Call in their own unique way, that's all. So what does that do? It simplifies client code because the client code does not need to worry about which class type it's referencing or whatever, as long as a class types implement, this same method interfaces. So let's say, for example, that you want to I don't know. You want all the account classes in a banking application to contain a get account info method with the same interface definition but different implementations based on the account type. Since the savings and the checking accounts air for holding the money for different periods of time, you'd get results after calculating the balance for each of them individually. So let's leave the account class for a minute and go to the account base class. Now here we have to base abstract methods, deposit money and withdraw money in the account class. We implement them with the override modifier, and they have a common functionality that can be accessed from any derived glass. Now, on the other hand, in the checking account class, we override them again, giving them a specific functionality according to the business requirements of a checking account class. Of course, we're now we we only call the methods existing within the base class rendering override operation useless. Um, so why don't we implement their unique functionality now? So the first is the deposit money method, so we want to calculate a new amount of money after the bank takes its commission. So to do that, we simply subtract deposited money amount multiplied by the commission rate. Then we just deposit the remaining amount using the base method. Now, please observe here that we deposit less than what is given into the checking account. Now we can use the same approach in the withdraw money method as well. Just copy the code line in the deposit money method and paste it into withdraw money. But this time new amount is the sum of the given amount and the commission, so we simply reduce the balance. By this much. The bank gets its commission, and the customer on Lee gets the amount of money that they requested. So, of course, for this toe make a difference. We will need to determine the commission rate. So you know what? Let's not get greedy. If if that's what you're thinking and let's just call it 1% I'm sure that's enough. Of course, we're going to assign the commission in the other DR Class, which is the savings account. Copy the code segment here for, uh, for the assignment. Now, first paste it into the constructor here, and then we could do the same thing in the savings account class. So in the savings account, it is logical that we have a lower commission rate, assuming the bank will be keeping a lot of money in savings for ah, well for a longer period of time. And it will benefit from interest, as we all do. Right? Um, so it's very specific business logic right here. So now we just need to implement the deposit money and the withdraw money method here as well, so we're going to change the methods here a little bit. So let's say that in the savings account in order to encourage saving more. Um, let's just say that there's no commission all and thusly. You can see this method works the same as the base implementation. All right, so now let's test how these accounts are going to work. Go to the create account form and we need to prepare the code to display to derive accounts together. First comment out the obsolete code segments and we'll comment out the old account object as well. All right, now let's copy the checking account instance E ation code and use it to create the savings account object. Just changing the name should to fight and now down below. We want to display checking, account and savings account together so we just create another display account form. Now the first form is going to take the check in counter object, and the 2nd 1 will have this savings account object and to display them both. We'll just need to get rid of the show dialogue, and instead we should call the show method and we'll do the same for the second form as well. So to distinguish them, we also need to give the forms different titles. To do that. Let's first copy these two above, then change the text property of the first form to checking account and the 2nd 1 to savings account. And that's it. We are done hit the start button, and the created count form opens. So let's just write any name and click on the button. Both display forms open together, so let's first deposit some money into the savings account. Now, Since we did not cut any commission from the deposit, the exact amount is seen right here in the balance. Now, on the other hand, when we do the same thing in the checking account, here's the effect of the 1% commission. You can easily see that occurring. So now when we use the withdraw money method, this time the commission affects both of them, but in different amounts. Excellent. So that's using the same methods in different derived classes and how those result in different outcomes. And that, my friends, is pretty much how Polymorphism works 49. Interfaces: so as we've seen so far, you can create an abstract based class. It does not contain any implementation, but just defines the members that must be used by any derived class. When you use this kind of abstract class classes that derive from, it must implement all of its inherited members. Since all of them are defined as abstract, you could use another technique to accomplish a similar result. You want to know what it is cool interfaces. So in this case, instead of defining an abstract class, you need to define an interface that defines the method signatures as in abstract methods. So classes that implement an interface are contractually required to implement the interface signature definition and cannot alter it. This technique is also useful to ensure that will client code using the classes know which methods air available, how they should be called and the return values to expect. So notice that I used the letter I before the name of the interface. It's an obligatory naming convention to separate interfaces from other classes. Now you know. So now, since implementing an interface and inheriting from an abstract base class are similar, why do we need an interface structure. Well, the advantage of using interfaces is that a class can implement multiple interfaces. As we mentioned before, the DOT net framework does not support inheritance from more than one class. So as a work around to multiple inheritance, the ability to implement multiple interfaces is included. Interfaces air also useful to enforce a common functionality across the different types of classes. For example, think about the calculator example from before. Supposing that you want to, um, have this calculator be able to do, I don't know triggered a metric calculations. So if you want to create a scientific calculator that's based on these two, the resulting class would be required to implement all of these methods. So in our application first, we created an account class derived from an abstract account base. Additionally, from an account class we derived and other two classes, which are the checking account and the savings account. In our account based class, we have only abstract methods. It means that all methods of this class must be overridden by any derived class that inherited. It's pretty much the same rule with the interfaces, so it's assumed then for a minute that we want to turn the account base into in interface. First of all, we'll need to get rid of abstract class. That's this part of the name and make it interfaith. Oh, and as expected by me, there are many errors. So first will go to the name of the interface that says here that there is a naming rule violation and you must put the letter I before the name. All interfaces must begin with I. By the way. I know it's pretty selfish, don't you think? I I now the first property and they're just two errors. So it says that abstract in public are not valid modifiers for this member. Mm. The abstract modifier is not necessary because everything is already logically abstract here. Right? So the only difference is that you do not override these members, you implement them. Normally, public modification is not necessary because all interface members are public by default and they should be accessible from anywhere. So why don't we try and get rid of them all at once? If you hold the old key and selected with a cursor, you can select text in a rectangle just like this. Now delete them all so that we get rid of most of the errors. And here let's also delete toe protected modifier. Hey, that's it. Our first interface has been created. Now let's see how the derived class should be altered in order to be able to use this interface in the derived account class. There are many errors involving inherited members, of course. So it's expected. So this one, It says deposit money method is not suitable to use override modifier. Okay, so the reason is that the class that implements and interface is contractually required to contain these methods. There is no override process in place. You remember that from before, right? The same is valid for the sealed modifier. Since you do not override anything, sealing them is not logical. Okay, Now let's Ah, let's undo all those changes that we did. And we'll start to create an other interface that ah, I want to introduce you to will go to the solution Explorer, right. Click the project and add new class. And the new item window opens now select interface from the list and will just name the interface. I account valid day table, validate table, validate table the name validate table may seem to you incorrect, but it's just a common naming convention for interfaces that contain validation methods. So, as intended in this interface, we are planning to define the methods for validating a given account class specifically, at instance, e ation. Now the return type is always bullying here, and they will return if a certain input is valid or not. First method is to validate, given customer name, and it expects that the customer name is from the client. 2nd 1 is birthdate. Now. You may have already recognize that we actually implemented these two methods in previous chapters. Additionally, we want to know if given amount of money is acceptable for deposit and withdraw. So first, let's create is deposit money valid as a method and then is withdraw money Valent and that is now defined. And we're done. So let's change it by adding is request valid to the names to make it more clear? Okay, now go to the account class. In the name of class, we see that it is already derived from the account based class, and then we add the new validate table interface as well, and as you can see here there are four errors with a common point. We did not implement anything in the interface. Oh, no. Before you throw up your hands in disgust, let's see here that all the members of the interface very similar to abstract structures except some syntactical differences. So let's just implement them here. And since we're going to implement methods exactly as in their signatures, we can just go to the interface and copy them all, just exactly as they are defined. And now we need to put their access modifier sent, which our public by design. So just write them at the beginning, one by one. Then we need the body part of the methods for our implementation, and that's it. 50. Interfaces Part 2: now, As I mentioned before, we already implemented these two methods, right? So let's go to the create account form. And at the end of the code, there are to validate methods for customer name and birth date. So let's just copy and paste them into the account class one by one. First, we'll copy the validation code for customer name. Now, this code takes customer name and it looks as if the length of a customer name is in a specified range. All right, then, copy the validation code segment for the birth date. Okay, so this is good. It's dynamic code which controls if the person with a given birth date is at least 18 years old Now, the implementation of the money request methods. So we'll assume that we have no common logic for validation of a given amount of money. Um, in other words, for each account type that can be derived from this particular account class, we will have a different set of rules. So let's just return true for these methods and let Dr Class take care of them. That's what it's for. Now, in order for the derived classes to implement these method we have to make these two members virtual. So go to the checking account class and start implementation, and this is a suitable place for them. Let's just copy and paste the virtual methods here and change the virtual modifier to override. Now, this time we need to make him override because we no longer implement the interface. Right. The base class here is the non abstract account class. And of course, we're not gonna leave him like this. So we'll put in some rules for validation. Ah, go to beginning the class and defined two new constant variables. The 1st 1 is the minimum possible amount of money to deposit. Let's just call it to 50. That ought to be enough. And another one is the maximum possible amount to withdraw. Ah, just put 1000 here now in the deposit money validation. Just Jack. If the given value is more than the minimum amount and if so, it returns fallings. Otherwise it returns true, and it's pretty much the same code for the withdraw money validation already then. So with this finished, we're done with the checking account class and we're going to need this code for the savings account as well. So let's just copy it and paste it after the last method in the class. All right, So in the savings account, we may not need an extra validation for deposited money because the bank would like a customer to save it in the account whenever they whatever they want. Right? So putting a validation may not necessarily be a good business rule, but we're not. Bankers were coders, so therefore, it will just you know what, delete the validation. It's OK. Since the method is already to find his virtual overriding, it is not an obligation already. Now we Onley need to define one constant here, which is the maximum amount to withdraw money. Let's call it 500. Um, that's gonna suffices a limit since as a bank, we also don't want the customer to withdraw so much money at once. And then there's a run on the markets. And never mind we're not bankers or coders. Okay, now we're done with the implementation of the methods in the interface, so let's use them the way they should be used. Let's go to the deposit money method and call the validation method for the money. If they given amount does not pass validation, it returns, falls. Otherwise, initiate the base deposit money process and do the same for the withdraw money method. Pretty much straightforward at this point. Now observe here that we call the deposit and withdraw money methods and return some Boolean value representing. If the process has been successful or not, eso go to definition of deposit money just by pressing the F 12. And as you can see here, we had fixed this excess response to false. So let's return true for deposit and withdraw money. Actually, for the withdraw money, we need an additional check here. So basically, if there is no money in the account, we'll just simply not let the client get any money because, hey, you're broke, pal. So let's check if the requested money is more than the current balance of the account. If not returned false. Otherwise, we can let the system create a transaction, and then it reduces the given amount from the balance. And please note here that this is a common check to see if it's valid for any drive classes . So the implementation is in the base class, and that's it. We're not done with the savings account, so let's go to the checking account and do the same. And it's always easier to copy and paste and writing your own code. In fact, 90% of a programmer's job is pretty much copying and pasting. So better get used to it early as possible. Right? But always double check. So let's build the solution. You may ask, since we used exactly the same code in both a checking account and a savings account, why not just implement them all in the account class? I say that's a very good question. It's not always about, though, what you are coating right now. It's about what will be required later. So in large projects, if there is a logical difference between two functionalities two classes, you must separate them in the very beginning. Sometimes, of course, you do repeat the code, but in the long run, if their purposes air different, then they should be different at some point in the development. So the most important thing here is to be organized and object oriented. Approach is all about the organization, and in the meantime, the application build successfully. Now go to that create account form. And in the create account event, we first create two accounts and display them on separate forms. So why don't we go ahead and display the account form just by hitting the F 12? No, there are two button click events inside that calls deposit and withdraw money methods. So let's check if these requests are successful. And if not, then it displays a message to the user. If deposit money failed. Show a method in the message box. It says deposit request is not valid and return do the same for the withdraw money method. - Okay , now, that's it. Now we are done. So start up the application to test everything. Uh, I just wanted a level with you. I got a confession to make. Jack is not really my name. But you know what? It's got a nice ring to it, don't you think? And two forms are displayed and click the buttons in the display form of the checking account. And since the ranges of valid it works. So let's increase that withdrawn money amount. If you recall 1000 I think was the range and it works again. So now let's try to withdraw more. Then the account has. There you go get we get an error. Now it doesn't matter how small is the amount. So we have a similar result in the savings account. Since this is a common functionality. And, of course, in the savings account, there is no limit on how much you can deposit. But if we try to withdraw even 1000 it gives an error. Alrighty, then. Hey, I don't know. I'm stoked. That's it. Our application works well, As intended, I was gonna say flawlessly, but there's always more to learn. 51. Homework 4: So what have we learnt in this chapter? We introduced you to what inheritance as well as polymorphism what those guys are. We learned about how base and derived classes work, implementing several account type classes. And we also demonstrated how to use abstract sealed virtual and override modifiers and how access modifiers work. Then, finally, we explained the importance of interfaces. Now they work and how they differ from other elements in inheritance. And now it's the moment you've all been waiting for. It's time for your homework. So in your homework, we want you to create simple calculator classes with basic arithmetic functionalities. First Open Visual studio editor. To create a new project, go to the file menu, select new then select Project New project when it opens. So like console app from the list. And the name of our project is, um, calculator, app and click OK, so we're creating a console application just for some clean space. Now, don't worry. We are not going to deal with the console input output operations right now or even this time at all. In the main method, let's create to variable Assign X to be 23 and let's just say why is too now create the abstract calculator based class with add, subtract, multiply and divide functionalities and used to energy input. The return types of these methods should be in the exact format of a calculator class that we already gave you in this slide. Create derived simple calculator class from the calculator base and Stan. She ate this new class and make four of the calculations with X and Y here to test your methods, then create the advanced calculator interface that can take a square root square and a cube of a given energy input and then finally create a drived advanced calculator class, which is derived from both the calculator based class and the advanced calculator interface . Good luck. 52. Intro to Event Driven Programming: event driven programming and exception handling. Now in this chapter, we're gonna introduce you to delegates and events, which are crucial, incredibly crucial in object oriented programming. And then after that, we're going to demonstrate to you how programming is prone to errors. In other words, exceptions. And then how to a handle them with special coating structures. Call. Try catch blocks. So why don't we begin No. In object oriented applications, messaging between the object are a result of direct requests that initiate the interactions methods and Properties airway to send your request and get some return value as a result of that request. Although this is not always a case, why don't we consider how you interact with objects in real life? So suppose in real life you receive typical messages in responds to an event that's occurred. Let's say, for example, if is raining and there's Ah, traffic snarled everywhere and your professor cancels a class as a result. So let's say she would send out an email to all the students at the university or wherever you are in order to, you know, make sure everybody knows that I'm canceling class. I'm stuck in traffic or whatever. So this is the type of messaging that we refer to as broadcast messaging. So the message is sent, and then the students decide whether to ignore or to respond to the message, preferably in the form of inaction. Now, on the other hand, wouldn't it be better if the mail is just sent directly to the students who take that particular course? In that case, the students would be subscribed to the course, you know, at registration time, in order for the emails to be sent. This type of messaging is often referred to as subscription based messaging. Makes sense means that the means of interaction is specified, and the client just needs to subscribe to the service. Now. Applications built with the dot net framework are object oriented, event driven programs. There, he traced the processing chain in the call stack. You can identify the event that started the process in the very beginning. So in this call stack, we see that first, the main method of the program class has been called, and then the click of end of the deposit button has been triggered by the user in a Windows Forms application like the one we have been building here to four. There is a user interface that a user can use to interact. In order to initiate this event, for example, the user might start the process of a log into a Web application by clicking a button so classes can also initiate event. A static storage class, for example, can broadcast an event message that no user with given credentials is detected so you can also subscribe to external events. A Web service may notify you when your team is going to play in your city, let's say, or you subscribe to a newspaper that tells you when it's going to rain, and then you would create an account watcher service that would issue an event when the account is depleted and it takes action. Whenever that happens, and before we go into the details of event driven programming and C sharp, we must go through what delegation is. So delegation basically means to decide how an outside request will be handled by the application Now. To do that, you first create your request and then use them in your class in a certain format, however you like. Then the program decides which method will handle your request, their quest is examined, and a method that fits the request is assigned to perform. Say, for example, if a project manager receives a request from a customer, it's delegated to a suitable member of the team with a sufficient knowledge on the issue. So a delegate is a type that represents references to methods with same parameter list and return type. The signature of the delegated method is composed of access modifier, delegate, keyword, return type, method, name and parameters. When you in Stan, she ate a delicate You can assign its instance, too. Any method with a compatible signature and return time. The method can be called in other words, invoke through the delicate instance. So here, for example, we created our delegate instance with the object name. My Del Instant. So this instance is the ad delegate type, and the implementation is an other method. My addition in any available class with the same return type and parameter list. And then at the end, I can use this instance to make my calculations sin. Tactically, events are not very different from delegates. Events enabled a class to notify other classes when something of interest occurs. It's a type of subscription based messaging. The class that raises the event is called the publisher, so it determines when an event should be raised. The classes that handle the published event or called the subscribers so their job is just to perform in action, which has taken in response to the event. Now an event can have multiple subscribers, which means that more than one type of response can be given to the same event through different event handlers. So if an event has multiple subscribers, the event handlers are invoked simultaneously when it is raised. And, on the other hand, the same subscriber can handle different events from multiple publishers. And, of course, naturally, if an event has no subscriber, it just won't ever be raised. Now in the dot Net Framework class library events are based on the event handler delegate and the event are eggs based class. In a very basic way, event handlers air nothing more than methods that are invoked through delegates. Normally, to bind this delegate to a method, we have two instance, she ate the event like any other delegate. So in Windows applications, event handlers are assigned by using the plus equal operator, and they're typically used to signal user action such a zoo button clicks or selections from AH list in a user interface. 53. Events and Delegates: So why don't we go ahead and open up our calculator application from the previous homework to demonstrate what we've learned so far. So here we used to calculator classes to make some simple calculations, and we're going to make use of them now. So to understand events better, let's create a user interface. So it would be pointless to make you design a form for at this particular moment. So we're we're going to just use one that I prepared for you, uh, before you were watching me, and you'll be able to find the attached that file in the lecture so downloaded, if you haven't already. Now, in order to add the form to our application, go to the solution Explorer, right Click project and select. Add existing item from the menu. Find the downloaded zip file in the browser, uh, extracted somewhere. Now there should be two files inside one code and one designer class. Make sure that you only select the cold file. The designer file will come along with it and just click add. And with that, the new calculator form is added. Now, if you open the designer class, you can see that there are many user control elements in this form. Now open the designer by double clicking, and you should see the user interface on. And it's a simple interface that lets the user enter two numbers and push a button to see the result of the associated calculation that uses these two numbers. So right click and select view code. As you can see, we did not have any coding here, so this is just an empty form with a finished user interface. Now, if you may remember, in order to add events to this application, we can simply double click the control in the designer just like this. Yeah, the button click event is now subscribed. So here, this is actually the event handler of the click event. So to see the actual event just right, click and find all references and then go to the second reference and what we have here in the part of the designer about Add Button, the publisher Click Event has been assigned to an instance of an event handler and button click with plus equal sign, and the subtract button click event is not assigned to anything yet, So why don't we in stance. She ate an event handler for this is well for now. Just skip the division and multiplication functionalities and double click the square button. Then finally, the square root click event has been subscribed. Now we need to implement these four event handlers so that we have a proper response to the button clicks. However, we're not planning to write their functionality from the very beginning. We already have a simple calculator and advanced calculator classes. We simply need to Why're the functionality of these two to the calculator form using delegates? Ah, you knew there was a point to all this. So if you go back to the main program class, you can see that we instance e ated two objects of these classes here, and we'll be able to use those for our purpose. So let's hadn't Stan. She ate a calculator form named my calculator form. Now call the show Dialogue Method of it. Now let's go back to the code of the form to prepare the delegates. First, we need to create the signatures right delegate in, add with two inputs and do the same for the subtract delegate now in creation of the double square root method. We only need one parameter. And of course, finally the long square method. Okay, so these are the delegate definitions. So now we need to create delicate instances. So first, create and delegate, subtract delegate, square root delegate and finally square Delicate. Now, in fact, this is still not an instance e ation. We simply created fields toe hold the instances of these delegates. Once we do in Stan, she ate them. Now we can use these in our events, even without instance. See, ation, we can do the instance Asian whenever we want dynamically. So before that, though, we're going to need two variables for the operations. So let's create properties for them so that we don't call the user control all the time. From the X property, we can access the value of the numeric up down control which we named X input box. Since the value is in the decimal type, we will need to type cast it to in teacher and we do the same for the UAE property and that we're ready to handle the events. The result text box displays the result of the selected operation. So we will just assign it to be the result, and we can call the ad delegate field as if it is a member method like this. Of course, we do need to convert it to a string format, and we'll do the same for the subtract of end and for the square and square root events. We only need one variable, and we'll use X input for these and that's it. We're done with that. Now let's go to the main before doing anything else. Let's just test the application first. We'll put in some random values for X and Y and click the add button. As you can see, we have an exception that says the object reference is not set up to an instance of an object. We created the delegates, but we did not assign anything for them. They are empty, so let's assign something for the job description. Here. Let's get rid of the obsolete code blocks commenting them out. These two calculator objects have this efficient implementations in a form. First, a sign and delegate to something use the type of the delicate like constructor to instance unit. The addition operation is implemented in a simple calculator, so that's a sign it add method for this job. And here we just created a bridge between the delegate inside the calculate form and the method that is defined and used inside the simple calculator object Right now, if we're subtract delegate, simply copy and paste this line. Change names from ad to subtract. No, observe here that we did not change the ad method, but still we have no error. Okay, that's because we can assign any method Aziz long as a parameter list, and the return type is the same as the delegates. So let's just change it to actual method now for the square Root delegate. We cannot use the simple coffee later object, right, since it does not have any method that takes the square root. So instead we just need to use our advanced calculator instance here, and it's like signing some other person with or, I don't know, appropriate qualifications for the particular job, which is the very definition of delegation. And then, finally, the square delegate should be assigned to the associated method in the advanced calculator object done. So now we contest it. So let's assign 15 for X and 10 for the Why click on add? The result is 25. Some track. It's five square of 15 is to 25 so that's also correct. You can check me on that and finally the square root. And I'm pretty sure that's correct, too. Okay, so we successfully used delegates from outside the form the handle these events Perfect, Amando. 54. Intro to Exception Handling: exception handling. So in every code, no matter how small it is, things can always go wrong. Exceptions are special types of events we can say that occur when something does not go according to plan. So think about storage operations. So when you try to save data to a database, the connection may fail. Access could be denied the database. Maybe full or even there can be no disk in the computer, so your applications should also be able to handle any of these exceptional scenarios that might occur during processing. So the dot net framework provides an extensive number of exception classes that can handle and that can be used to handle any of these common areas and more. For example, let's consider the file not found exception, certainly one of the most popular. Now it's an exception class that is thrown when there is an attempt to access a file that actually does not exist. So this class contains information, searches, the file name error message explaining why the exception happened and the source of the error, which is an object or an application that try to access the file, the air message and the source information can be found in pretty much all exception classes. Whereas the file name information is pretty specific for each of the file operations now, you can always create application specific exception classes with additional information. You know that just makes it easier for users to understand what went wrong. Try, catch, block. Okay, so now suppose that you want to write a certain fine, and in order to handle a code like this in which airs may happen, that's when you should use the try catch block or a bunch of them. Try cash blocks. So if the file is not in the given path, for example, the program will surely raise a file not found exception. Now, any exception that occurs in a code that is inside a try block can be caught, and the code processing is transferred to the catch block, and you can handle the exceptions there. For example, here it would skip a success message so that the user would be informed with a failure message, and you can define multiple, even different catch blocks for a single try block. And when the try block is executed and a random exception is thrown, the program will evaluate each catch block until the suitable catch condition is found. So if the exception type does not match any of the exceptions in the CAT statements, the program flow would continue without entering inside of any of the catch Block makes sense. So let's say, um, I don't know supposed the exception is the file not found exception. And you know, we'll just continue from the previous example. If you put three catch blocks in like this, the program would skip the first catch block for end of stream exception and execute the 2nd 1 The 3rd 1 is the base exception class of all the input output exception types. Thus, if we forget to put the file not found exception in implementation, um, this one would be caught anyway. Right. But also note that these two exceptions come from the same base class, the I o exception. And you could simply just use this exception type in your catch block alone. Since you know both of them Earth, same type. And we'd be able to, you know, catch these two exceptions in a single block, but you can go further, so why not? So if you use the exception based class, which all exceptions air based on and catch them all. You can catch him only easily. I advise you not to do that because just being able to catch them means absolutely nothing . Each exception class has a different type of handling mechanism, so you should fix their damage in the associated Catch block. Does that make sense? It's after try and catch blocks. You can use one additional block called the Finally Block. So once ah, that's included, it is entered, even if the exception is thrown or not. So what Is that me? Well, the purpose of the finally block is to release system resource. So if we follow from the previous example, you just used the finally block to close the files that might be left open after storage operations or enter into log. That says that you're leaving the current process very useful. I know it sounds like it ought to be an Olympic event, but in your code you can always throw an appropriate exception if you somehow detect that things did go wrong. Now, in order to do that, you should use the throw statement, and instead she ate an exception object. So with this, you can put your own message and a year code and then that informs the user about exactly what went wrong. It's always better Teoh well, not let any exception occur at all. But like I said, if it is going to be inevitable, you should just not let the system do your job. So, for an example, before trying to right into the file, if we check that the file is there or not, we can immediately take control of the situation. And that way we can terminate the program flow on our own terms. On the other hand, sometimes it's not a bad idea. Toe use exceptions to control your development, for example, not implemented exception. That's a good way to find out what is missing in your application. This exception could be thrown and functions that are well not implemented yet, and you would get a notification by the system pretty quickly after some testing. So once you get rid of the exceptions, then you would be pretty sure that your applications complete 55. Demonstration - Exception Handling: now before the bump it a bomb demonstration. Let's do some cleaning up so we don't need these code blocks anymore and a calculator application. It's gonna be expected that there might not be many exceptions at all. So instead, let's assume that we want to read a text stored in some file. Now, with these kind of operations, you will require some resource elements. Obviously, you're going to need some careful error management, so we'll begin with a try block. Now. Supposing that the path variable keeps the absolute or relative path of the file, and we're going to read all text inside this file with the help of the file class. Naturally, we will need the system, Io Library added, And that's it. So that's all the coating that were. We'll need to read a file now. Every try block should be followed by a catch block. So first, let's start with the most basic base exception class, and if we catch any exception, we should definitely catch them here, and then we will inform the user in a message box about him. Now we can't say anything specific with an exception like this, so we just you know, say something is wrong and we show the message that comes with the exception. So now let's start the application. Okay, that was fast. So it says that an empty path name is not legal. So this error stems from leaving the path string empty. So this kind of input related exceptions. These air named argument exceptions, so we need to catch them instead. So just copy and paste the message box here and update the message to be something more informative. For example, path is invalid. Okay, so now let's change the path to something different that will definitely throw an argument exception again. Okay, that ought to do it. Start the application. As you can see, the error message says that there are illegal characters in the bath name, so the exception is the same, but the message is distinct and much more informative. Now let's use a legal path name this time, so we'll assume that there is a file named some file directly under. See Dr and we want to read it. So I assure you, I do not have such a file. Okay? So again, we call the exception inside the general catch block This time, though, it says that it could not find the file. This is the typical message of the file, not found exception. So let's stop the test and add a catch block for this particular exception. Type. So again, we'll just copy the message box code line below and chains message to be file not found. Yeah, let's begin again. Here it is. So the message. We can even see the path of the file that we're trying to read, since we use the correct exception type to catch it. Okay, so now let's assume that the file is under some directory that does not exist. Started up again. Something's wrong and out says that part of the path could not be found, which translates into directory does not exist. So this is the message of directory, not found exception. So lets include that in the catch blocks. So the message this time should say, Directory not found. And let's go back and begin the test. Now, as you can see, our custom message shows up, which means that we caught the appropriate exception again. So now I guess you know that's enough. You get it now. But before I let you go. Let's assume for a moment that we actually expect the reading to be successful, so we show a message after the operation. So let's insert a break point here. Now we're still not done, because even if we included lots of different exception types, we still might have some unhand Aled exception specific to a read operation. So before or instead of the general exception, let's look for a base exception type that is Onley for file operations. And it's named Io Exception. So all exceptions that we have seen so far are derived from this. So we can say that if we forget to include something, it will definitely be caught here. And then after these catch blocks, we will add the finally block as well. Now, if we used file info instead of file class, we would need to release the file after reading it. But since we used a resource, why safe method? We will. We'll just use the finally block to log some info that signifies the end of the reading operation. All right, so let's go ahead and start the application one more time and the break point hits before the reading attempt. So when we execute the read command, it directly goes to the second catch block. Since the argument exception isn't there anymore? Now please observe that we could not see any success message since you just skip the rest of the code right inside the block. But if we continue now, it'll display the message about a missing directory. So just click OK and just go one more line. So again, it's kept the rest of the catch blocks since we already caught one, and now we are in the finally block. Now, if you open the console, you can see that our log is there. Finally, block is entered no matter what happened in the try catch blocks and we can go on with the execution. But there is no point, so let's just stop here. 56. Demonstration - Exception Handling Part 2: so we made, I think, a big enough point about storage operations. So now let's consider our calculator application. We initially argued that the calculator application would not need a lot of exception handling. Yeah, let's reexamine that from the start. Now, at the beginning of the class, we just have the field declaration so there can't be any fault with them. And in the property declarations, we can do some management. So in the get access er, we Onley have some conversion operations from decimal value Metric up, down, controlled to the energy type data. Um, we cannot expect anything to happen there by itself. Eso let's carry on now Here we have implementations of events. Now, As you may remember, we already had one error regarding the instance she ation of delegates. So let's surround this part with try catch blocks to catch associate ID null reference exceptions. So when we catch this exception, we can inform the user about that. Of course, since we took very close care about errors last time, we were not gonna be able to catch anything right now, So let's go back and let's recreate an air conditioned by the leading the instance, see ation of the ad delegate object. So start of the application and we do not need different inputs. So just click, add, and then, as you can see, our custom message pops up. Now, since we handle the exception, the result is not assigned to anything, and we can use any other feature uninterrupted. Now, apart from displaying an error message, we could also block the addition functionality and the user interface, blocking the faulty area so no one will ever fall again. That makes sense, right? So start the application again, and when we click the add button, as you can see, it becomes disabled. So here it seems that we do not need any other error message. Now. Some text value is assigned to be the result of some delegate function. So when we go back and fix the exception again, don't worry. There's not much to fear. Not much. On the other hand, if we take this code out and this form is used in some other context, well, they might forget to. Instead, she ate the delegate again. So we do need to think about future exceptions as well. Ah, we've come back to it. So now, before changing the other event handlers. Let's think about another scenario, So let's assume that we have ah, range of acceptable values for X and Y. Since we use numeric up down control, we can arrange the maximum possible value in the properties panel. Now it says that a maximum is 100 here. What's a sign? Some larger value for it and handle the range programmatically So Zain the same maximum number for why as well. Okay, so now go back to the code again. In the get excess er of X, we get the input from the user control. Here we can check whether the current value is larger than, let's say, 1000 or not. It is. We will throw the argument out of range exception. This exception takes the parameter name as the first argument, and the second argument is the message that we would like the user to see. Okay, so since we thrown exception here, the value of the input box would not be returned. Let's go ahead and do the same for why, as well copy and paste this block and we just need to change from X to y everywhere. Okay, that's it. Now it's time to catch this exception whenever we use these inputs. The catch argument out of range exception. So let's just display the default message in a message box. Start testing. So if we put 100 here, we can make the calculations without a problem. Right now, if X is larger than 1000 when we click the button, we get an exception that says X is out of range. Okay, so click OK and put a large number for why this time. And we have the same error for the UAE input now, before ending our test. Let's use the subtract button. Ah, As you can see, we have an unhand Aled exception on our hands and the program terminated as a result. So this is the only thing that we're trying to avoid in the first place. Let's manage the exceptions for all click event handlers. So first copy the code here, and then we can paste it under the subtract button click method and then replace every ad with the word some track. Alrighty. So now we can do the same for the square button as well. Now in the square delegate. We need to reduce the number of parameters also, and finally, we'll do the same for the square root method. Okay, so now we're done. So now let's go to the designer and create the multiplication and vision events. Double click the divide button and the divide button click event handler is created and go ahead and do the same for the multiply button. Now these two event handlers have been created without any implementation. Now, I don't know about you, but we just can't leave him like this. So we should make sure that the people know this is not intentional. So we can simply leave a comment, of course, but it's better practice to throw a not implemented exception and places like this, so that lets users as well as testers know that it is still in development. You get it cool. So why don't we start up the application again? And when we try to use the divide button, it throws an unhand Aled exception and it works. Justus. We intended it to do all right 57. Homework 5: what have we learned? So in this chapter, we introduce you to the concept of event driven programming. So we demonstrated how events and delegates work and implemented some of our own. Furthermore, we learned what exceptions are and how we can handle them in our advocation with the try and catch blocks. And, of course, this is what you've been really waiting for. Your homework is pretty self explanatory. Um, we want you to implement these two unimplemented event handlers now, as we did with the others. You should use delegates and handle exceptions. Now, the only thing you need to keep in mind is in the divide button click event. You should check for divide by zero exception. All right, keep that in mind and good luck to you. 58. Answer for Homework 5: alrighty, then that means that you are ready for some answers. Now you got it right. I'll start the implementation by creating the delegate methods. So we need a delegate that takes two integer inputs just like add and subtract delegates that we created before. So that means we can just copy and paste them here, changed name from add to multiply from subtract to divide and the return type of the multiplication is long imager and division his folks. That's it. The delegate definitions air done. Now we need to create delegate instances for them as well. First multiply, multiply delegate and second divide. If I delegate now, we can use these delegates. The implementations are more or less the same as the implementation of pretty much any other event handler here. So let's just go ahead and copy the implementation of the subtract button click event and then paste it under the multiply buttons. Change the delegate instance to multiply, delegate and update the message. Now disable multiply button in case there is a no reference exception. So now let's copy this and paste it above change. Multiple. I delegate to divide delegate, update the message and change the button name to Divide Button. Now in division, we will also need to look for um, what would happen if the divisor that's given a zero. So we catch divide by zero exception here and then when we catch it will just simply display the error message to the user. Okay, so that's it. Now we're done with the forms coding. Now we just need to. Instead, she ate the delegates outside the form in the main method. That's just copy the code for add and subtract delegate instance. See ation change the and they'll get to multiply. Delegate, Since the delegate types are really not suitable, we have an error. So we'll change that type to multiply as well. And finally call the multiply method of the county later object and do the same for the division delegate in stance. See Asian as well. Now we can start the application enter under No. 15 for X and 10 4 Why, no if we click the Multiplied, but the result is 150. If we use the divide button, it is 1.5. So let's test the exception handling because we know that it's working so far enter a very big number for why and quick multiply argument out of rains. Exception is thrown. So let's see what happens when we try to divide by zero. Well, then it didn't throw any exception at all. The result box has an infinity symbol in it. Well, this is obviously wrong. We certainly wouldn't want to encourage generation to think that dividing by zero means infinity. Um, so let's go back to the event handler of the divide button here inside the try block. We're going to throw the exception ourselves. So if why is equal to zero throw new divide by zero exception. Okay, so let's test that again. Click divide. Bingo. It works well, technically, it doesn't work, but I think you get the point. So we successfully developed a calculator that has numerous functionalities and no unhand Aled errors. So thanks for playing along and goodbye 59. Tips and Tricks - Keyboard Shortcut: tips and tricks. So this is the chapter that we're going to introduce you to some tips and tricks that we've prepared for you. Hold on to your hats, gentlemen and ladies. Buckle that seat belt. Well, no. Everybody should buckle their seatbelt and don't text and drive, but never mind. I just want to let you know that you can use these to enhance your programming skills and make a difference, especially if you're gonna be working with a team of developers, which is the goal? All right. Tip number one Shortcuts in visual Studio Visual Studio offers extensive numbers of functionalities to make development easier for you and for everybody else who develops. Most of these functionalities can be accessed easily and efficiently by using shortcuts. So think about Solution Explorer and the Properties panel in Visual Studio Solution Explorer is a panel that we used to access the items in our projects and we can add, remove and rename them. And then later on, we can change the properties of any of them in another panel named properties. However, most of the time, we don't even use thes panels and keeping them open all the time. Can really be a pain in the well bothersome anyway, especially if you're dealing with smaller screen real estate. So what we always should do is get in the habit of closing this panel and make it active well, whenever you think it's necessary. How do you do that with a control? Ault l Shortcut. You can display the solution Explorer, and when you're done, you can simply hide it again with a single click. It was very important to be able to see your code as much as possible, especially when you're trying to find a bug. So you should know these two shortcuts, which are frequently used among the other panels. You should frequently save and build your project to see if there's any unhand Aled compiler error or to prevent any loss of work, just in case a problem rises with your computer. To save your work, you can always go to file and click this button to build a solution. On the other hand, there is a special menu, which you can use so when you change something, it's a life saving habit to keep your project saved with control shift s and the log and left side of your screen immediately informs you with the items saved text who? I love to see that now if you press control shift B, you can get notified with build. Succeeded as a wonderful message immediately or immediately after a considerable amount of time, depending on the size of your solution. Of course. Now, if you frequently need this, the time tends to be shorter. Since Onley, the changes you made should be compiled again, right? If you want to find out where a certain class or object is defying, you can select one of the go to definition and go to implementation items right here in the right click menu, find all references item. On the other hand, this could be used to see the complete list of the locations that are used. Now, if you press F 12 after selecting something, it directs you to the first location immediately. When you press shift F 12 the reference list open so that you can select which reference you would like to go to manually. And it's a very detailed list indeed. Okay, now, of course, you can always use the control key to go to the location of definition just left click the object or the class pressing this key, and it navigates for you easily. So these shortcuts really come in handy, Especially when you're trying to find out what the heck is wrong with your code. I mean, where exactly you might possibly have a particular ever in your code? I just can't stress enough. How much of your time is gonna be wasted trying to use the right click menu all the time. So the location of the buttons to comment and uncommon to the code is up here. You can use the associated key bindings available to use these functions easily. Just select the text and press control K, then control you. Too uncommon. If you press control, see after control K. You can comment the text again. You can also select just ah part of the code and use this function there as well. Select the part of the text and press control K and control. See, And as you can see, the comments arounds the text with the special characters making it disabled. Now indentation is very important to your coding style. If you don't keep proper indentation, you can lose track of which code is inside which block and believe me, that can get complicated and you wake up in the middle of a nightmare. Fortunately, you can easily turn it back to normal, using the shortcut control K then controlled D to format document. So let's assume for a moment that you just started coding and you forgot to include any library in your code, you would not be able to use any classes at all. Normally, you can wait for visual studio to give you a quick fix about you know which library should be added. Or you can just press control dot to display the import list. That way, when you select the right option, which is the 1st 1 most of the time, it would immediately add the library to your code. That's really easy, right? I mean, right, right. Shift in all keys. Have special properties when editing text. So if you press shift and use the arrow keys or mouse, you console ECT lines in between the start and end points of the text cursor. Yoki, when used with the arrow up and down, can also move the selected line. Additionally, you can select rectangular area with the mouse, and this comes in really handy when you want to change the lines of the same code together , you can also use it to put or delete indentation of the code. Now, of course, you do not need to memorize all of these default key combinations. I mean, you'll get used to them, believe me, but you can change any shortcut. They're customizable. Let me show you how a real quickly go to the tools menu. So, like the options. But let me just show you that from the list under the environment Select keyboard. Now, if you write the function in the search bar, it will navigate you to the related results. So under this list, you'll find shortcut or shortcuts listed for the selected function. You can enter the key bindings to an input box here, and it will tell you for which function this particular key were. Key combinations are used now to change any key bindings. First, you will just have to find the function from the list above. Then, if you want to write a new shortcut and you're OK with not using the shortcut for the other function for which it's designed for. You can just assign it here. Now, if you want to go back to the default shortcuts, the reset button right here can be used personally. I just find formatting the document to be very important. So I always keep the shortcut keys where I can easily use them. Now, let me just advise you to use control shift plus key, um, for your combinations instead of control, keep rest after some other control. Key kind because sometimes the first control key combination can be used as a shortcut for some other function. Keep your function separate. 60. Tips and Tricks - Code Styling: tip number two, code Stylin and beautification. So you heard me mention before code indentation, but also formatting. These are both good ways to express yourself as a programmer, especially developers working with a team. You've gotta have clean programming skills. It makes for easier debugging, better time management and while self confidence because you are inefficient programmer. Now, additionally, some other developers who will have to understand manager code they should not have any problem at all and trying to decipher what the heck you were trying to do. Visual Studio offers a range of formatting options that you can use in your code. Go to the Tools Menu, Select Option and under Text Editor Select C Sharp, then select code style, and you can find the formatting tab right there. Now, in this tab, you confined pretty much everything related to your styling, indentation, placement of brackets and spacing and expressions, or just some of them. And then, after you're done with your settings, you can use a shortcut to format your documents Pretty straightforward right now. There are also alternative external tools that you can you can use to help you with this. If you're looking for some open source free tool. Let me point you over to a style code. Beautify their So let's see how you can find and use such a tool. Open your favorite browser search for a style, then it navigates you to the website of the tool. And, as you can see here, it is licensed under the General Public License and the Code and execute a bles you confined here is for advanced users. Eso We will need something more practical, so go back in search for a style extension for visual studio. You can now find a link to the visual studio marketplace for the extension that we are looking for. Ah ha! Go ahead and open it. When you're searching for an extension for your editor, you should always Jack to see if it's compatible. As you can see here, this version of the extension is not suitable for Visual Studio 2017 so I have to specifically look for it. Don't there it is. So when you download and install this, you can use it in the editor easily. But first you need to select your preferences to go to the tools menu, select options and you can find a style listed here. Now, as you can see this four matter, it can be used received, plus plus a swell but pronounce Elect C Sharp settings tab here can be used to arrange your preferences, and you can find everything inside even more than what the default document for matter can offer. For example, here in this tab their different styles listed for just how bracket should be placed. How cool is that? So to use this setting, you must first go to the environment and then keyboard and the options window and a sign a short cut for this tool. And then, once you've arranged everything, you simply click the button and let it do its job. Of course, there are many, many more paid and and and even more free code beautification and styling tools on the Internet. It's only one of them, but you get the idea. I just want you to know it's important. Um, you got to be able to reach them when you need something for your development environment, right? 61. Tips and Tricks - Code Snippets: number three code snippets. Code snippets are small blocks of code that can be inserted in a code file, using some specific short word called snippets. So and the editor go to the Tools menu. So, like code snippets, Manager open the language list. Observe that the code snippets can be used for a variety of programming languages. For now, we'll use C sharp. So under visual C sharp tab, you can see the default list. Now. Each of these snippets can be used to create many different code blocks, so let's look into the four each, for example, and to use a code snippet, you must first begin typing, and a small window should help you to find the correct word. Here, it says Tab twice to insert for each snippet, and we'll do that and it brings you the whole for each code block. See tour, sniff It, for example, creates a constructor for you. Class snippet can bring a whole other class ready for you to change the name on If blocks switch statements, property definitions, whole methods, whatever you need can be found in this list of snippets. And if you care to continue, can create your own snippets for your own code blocks as well. Good luck with that 62. Tips and Tricks - Documentation Comments: number four documentation comments so commenting is good and all, but it should be neither too much nor too little, but just right. So where to comment? And the file is another problem, and it should be a standard that is, You should always look for necessary explanations at pre defined locations, but it's not that way. So depends upon everybody style. That's why I'm gonna tell you what to do. If you look at any structure to find in the dot net framework, for example, this class, you can always see a summary under the name of the structure. Now, if you go to the definition of it, you can see that this is actually a special form of comment called documentation. Common. As you can see, the same style is seen on method definitions as well. Now, if you select one of the classes defined by you and go to the definition, you can create the summary of it using three slashes, and it automatically creates the formatted comment block for you to write whatever explanation this particular class needs. Of course, it's always better to be concise and precise about it. You can use the same comment style for, well any member, including constructors methods and properties. So then, after you're done with your summaries, you can see them when you just put the mouse cursor over it hover, whatever. But that's really kind of neat, isn't it? Of course, this does not mean that you should only use document comments. However, this comment style really comes in handy whenever you're developing. I mean, whenever you're in development. 63. Tips and Tricks - Overriding To String Method: number five overriding to string method. So in the dot net framework, any derived class can use the members of its base class. Since all classes are implicitly inherited by the object, these methods are available to everyone. One of them is the to string method, and it has a very unique application. So let's say supposing you've got a customer class that has, ah name, surname and age of a customer, and you give this object to any method that requires a string so it would accept it because the two string method automatically gives the string representation of the object. So let's start up the project and see the console output. Of course, as expected on Lee, the name of the class is displayed. This is probably the default implementation of this particular method. So why don't we mosey on over to the customer class and override the to string method Now? We wanted to show the name, the surname and the age of a customer as a summary. So when we start the application again this time, we can see exactly what we would like to be informed about this particular object. So let me tell you It's especially useful when you are trying to display the object in a control like text and list box. Just giving them toss control would work with this simple trick, and you would not need to handle it inside the client code. 64. Tips and Tricks - Handle Exceptions Globally: number six handle exceptions globally. The DOT net for anymore provides a couple of events that can be used to catch. Unhand Aled exceptions. You only need to subscribe to these events once in your code when your application starts up. But first, first chance exceptions. So by subscribing to this event, you can catch almost every exception. Well, you can actually not catch all of them, but you can just come up with some logging mechanism that helps you identify which exceptions are encountered in the process. The threat exception event is used to handle the you. I related exceptions. If your application uses Windows forms, for example, this is the type of exception you need to catch. Unhand Aled exceptions. On the other hand, unhand Aled exception is used to catch all non u I. Threat exceptions. And of course, both of them are equally vital to your process if you want to log every problem in your application, which I would highly recommend. So now, at the starting point, which is the main method of the program class for both console and Windows forms applications, you should register these three events now. I did save you some time here and wrote that myself and in fact on the Internet searching how to catch all unhand Aled. Exceptions should eventually lead you to find these codes. But please observe here that the first chance exception and unhand Aled exceptions belong to the APP domain class and subscribed by associated methods here. Now all of these methods have been implemented so that we could log what is going on in the program flow, for example and unhand Aled Exception class also returned if the application will be terminated or not as a result of an unmanaged air. So we just log these errors even if the application will close Now we cannot save that session to be terminated. But with this information, we can certainly restart the application from the beginning. Okay, so in our program, we simply trying to read some of file. And since there is no file at this best buy location, one of these exceptions should be thrown. And after that we'll try to do the same thing without the try catch block. So let's start the application and just see what we're going to catch. So, as you can see, the directory cannot be found exception has been caught by first chance exception Handler, even before the catch block could act now. Since we are already handling this exception, there's really no need to do anything else in this event handler. So when we come up to the UN handled code is you can see here the unhand Aled exception has been quant and the program waits for our console command, and after that it just terminates. So normally it's not advisable to use the console output to inform the user for logging. The debug methods are more suitable, which Onley works in the development phase so that you can take care of the problems before the release ever gets to the user. 65. What We Have Learned: So with this chapter are object oriented programming course has come to a close. Now, I really hope that you've enjoyed it as much as I did. And as much as you've learned from this course now, I'm gonna be waiting for your comments and questions. So if if you'd like to have an extra explanation about, Well, pretty much anything. Um, of course, I will be the judge of that. Now, software programming is very cool once you get used to coding relentlessly. Um, no problem is new. So please don't hesitate to search anything on the Internet for an answer. And just copy your code and paste it into the search engine and you'll see you can't believe what you're going to come across. So until we see each other again, have a great day. I certainly hope that we meet again in some forum. May be discussing software related problems. Um, but have a great time coding. Please practice and stay cool. Keep your gold clear and good luck on your next endeavor.