C# in Depth: Puzzles, Gotchas, Questions at Interviews | Elias Spock | Skillshare

Playback Speed


  • 0.5x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 2x

C# in Depth: Puzzles, Gotchas, Questions at Interviews

teacher avatar Elias Spock, Chance favors the prepared mind.

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Lessons in This Class

53 Lessons (4h 39m)
    • 1. 00 Promo

      5:17
    • 2. 01 Outline

      2:05
    • 3. 02 Mutating Through Readonly Fields

      4:01
    • 4. 03 Mutating Through Arrays

      3:58
    • 5. 04 Mutating Within Using

      6:21
    • 6. 05 Conclusion

      0:48
    • 7. 01 Outline

      2:05
    • 8. 02 Specialization

      4:15
    • 9. 03 Constraints

      7:17
    • 10. 04 Variance and Generics

      8:22
    • 11. 05 LSP

      5:09
    • 12. 06 LSP Demo

      8:01
    • 13. 07 More on Variance and Contravariance

      5:38
    • 14. 08 Conclusion

      2:59
    • 15. 01 Outline

      2:05
    • 16. 02 Floating Point Numbers

      17:13
    • 17. 03 Arithmetic Overflow

      9:07
    • 18. 04 Check for Arithmetic Overflow

      5:58
    • 19. 05 Rounding

      6:22
    • 20. 06 Decimal and Money

      9:36
    • 21. 07 Conclusion

      6:00
    • 22. 01 Outline

      2:05
    • 23. 02 Altering List

      7:17
    • 24. 03 LINQ Deferred Execution

      2:59
    • 25. 04 LINQ Closures

      5:00
    • 26. 05 Generics Conversion

      5:09
    • 27. 06 Conclusion

      1:49
    • 28. 01 Outline

      2:05
    • 29. 02 Overloading Base Method

      4:14
    • 30. 03 Method Hiding

      4:33
    • 31. 04 Property vs Method

      6:41
    • 32. 05 Impl Abstract Classes

      7:29
    • 33. 06 Conclusion

      1:49
    • 34. 01 Outline

      2:05
    • 35. 02 Concepts

      9:16
    • 36. 03 General Puzzles

      6:46
    • 37. 04 DateTime Roundtrip Puzzle

      6:14
    • 38. 05 Arithemic on Dates

      4:06
    • 39. 06 Calculating the Age

      6:33
    • 40. 07 Conclusion

      6:00
    • 41. 01 Outline

      2:05
    • 42. 02 Abstract Class vs Interface

      5:11
    • 43. 03 Implementing Dispose Pattern

      12:04
    • 44. 04 Encapsulation and Information Hiding

      9:57
    • 45. 05 Encapsulation in Practice

      9:18
    • 46. 06 Interning

      6:09
    • 47. 07 Const vs Readonly

      3:14
    • 48. 08 Lock vs Monitor

      3:23
    • 49. 09 Rethrowing Exceptions

      2:52
    • 50. 10 StringBuilder vs String

      2:19
    • 51. 11 Conclusion

      1:22
    • 52. 01 Weirdness of Nullable Comparisons

      4:25
    • 53. 02 Out Arguments

      1:36
  • --
  • Beginner level
  • Intermediate level
  • Advanced level
  • All levels
  • Beg/Int level
  • Int/Adv level

Community Generated

The level is determined by a majority opinion of students who have reviewed this class. The teacher's recommendation is shown until at least 5 student responses are collected.

43

Students

--

Projects

About This Class

This is an advanced C# course.

Build a solid foundation in C# learning odd cases related to how the language is designed

This course contains mostly practical puzzles learning which you get a better C# developer. You can find out on the Internet tons of impractical puzzles which don’t make you a better C# developer. This is not about this course. Yes, of course, even impractical puzzles sometimes are helpful especially if you’re preparing for a C# interview. However, I bet on puzzles which teach you the thing you absolutely need to understand. Indeed, this course deepens your understanding of C#. Apart from that, you’ll learn some very important things like the problem of types substitution. You’ll learn about the fundamental problems related to processing date and time values. Believe me, you’ll be astonished!

This course is built in a manner of a game. I’ll show you code examples in Visual Studio and ask to answer the question related to that code example. You’ll have some time to come up with your own answer and after that we continue. Puzzles, gotchas and cautionary tales are presented here to frighten and inspire you! Regardless of your current skills, you’ll remember things you’ve forgotten, learn things you didn’t know and become a more robust programmer.

So, this course is "must see" for anyone who wants to improve his knowledge of C#.

Here is my Teaching Approach

No fluff, no ranting, no beating the air. I esteem your time. The course material is succinct, yet comprehensive. All important concepts are covered. Particularly important topics are covered in-depth. For absolute beginners, I offer my help on Skype absolutely free, if requested.

Take this course, and you will be satisfied.

Content and Overview

This course is aimed at all kind of developers. It provides solid theoretical base reinforced by the practical material.    

In short, this advanced C# course covers the following topics:

  • The evilness of the mutable structures. You’ll see several examples when mutable structures demonstrate the unexpected behavior.
  • Generics and arrays including specializations, constraints on generics, variance and covariance, Liskov substitution principle and more
  • The pitfalls in arithmetic: how floating-point numbers are implemented, how to compare them, how arithmetic overflow behaves with different types, how rounding works, the difference between decimal and money
  • Collections and LINQ: how to alter an existing list, the deferred execution of LINQ expressions, the peculiarities of closures within for and foreach loops, list conversion
  • Methods and Overloading: overloading base methods, method hiding, when to prefer property over method; the reasons on why to avoid optional parameters, implementing abstract classes
  • Date and Time puzzles: concepts related to dates and times including how a computer stores time, UTC and GMT, time zones, global and local perspectives; time-zone related puzzles, roundtrips, arithmetic on dates, how to calculate the age.
  • FAQ at C# Interviews: abstract classes versus interfaces, how to implement the Dispose pattern, what is the difference between encapsulation and information hiding, encapsulation in practice, strings interning, constant versus read-only fields, lock versus monitor, how to rethrow exceptions, when to use StringBuilder instead of string
  • And yet a short section of miscellaneous puzzles Enroll and start an exciting journey learning C# puzzles!

Meet Your Teacher

Teacher Profile Image

Elias Spock

Chance favors the prepared mind.

Teacher

I'm thankful enough for that I love what I do.
I began my career as a postgraduate student participating in Microsoft ImagineCup contest.
I've been working with .NET platform since 2003. I've been professionally architecting and implementing software for nearly 7 years, primarily based on the .NET platform. I'm passionate about building rich and powerful applications using modern technologies. 
I'm a certified specialist in Windows Applications and Service Communication Applications by Microsoft.
I'm one of the coordinators of the MSK.NET User Group in Moscow.

"If it's work, we try to do less. If it's art, we try to do more." - Seth Godin.

What I can say is that software is my art.

See full profile

Class Ratings

Expectations Met?
  • Exceeded!
    0%
  • Yes
    0%
  • Somewhat
    0%
  • Not really
    0%
Reviews Archive

In October 2018, we updated our review system to improve the way we collect feedback. Below are the reviews written before that update.

Why Join Skillshare?

Take award-winning Skillshare Original Classes

Each class has short lessons, hands-on projects

Your membership supports Skillshare teachers

Learn From Anywhere

Take classes on the go with the Skillshare app. Stream or download to watch on the plane, the subway, or wherever you learn best.

Transcripts

1. 00 Promo: Hi. Welcome to the course. See Shop in depth. Basel's gouaches and questions at interviews. I am the last for a engineer Spark from engineers bob dot com, and I'll be leading you through the course. I began my career as it was. Grated Student Participating in Microsoft Imagine Cup Contest I've been working with Dr Platform since 2003. I've bean professionally architect and implementing software for nearly seven years, primarily based on the dot net. Glad for I am passionate about building reach and powerful applications using modern technologies. I am a certified specialist in Windows applications and service communication applications by Microsoft. And here is my teaching approach. No fluff, no ranting, no beating the air iced in your time. Of course, material is succeed, yet comprehensive. All important constants are covered, particularly important. Topics are covered in depth for absolute beginners. I offer my help on Skype absolutely free requested. Take this course and you'll be satisfied. The scores contains mostly practical puzzles, learning which you get a better see shop developer. You can find out on the Internet thons off impractical puzzles, which don't make you a Battersea shop development. That's not about this course. Yes, off course. Even the practical puzzle sometimes are helpful, especially if you're preparing for a C shop into you. However, I bet on puzzles, which teach you the things you absolutely need to understand. Indeed, the scores deepens your understanding off SEASIA. Apart from that, you learn some very important things, like the problem off times substitution. You'll learn about fundamental problems related to processing data. Time values. Believe you'll be astonished. This course is built in a manner of a game. I'll show you code examples in visual studio and ask to answer the question related to that gold example. You have some time to come up with your own answer, and after that will continue. Basel's conscious and cautionary tales are presented here to frighten and inspire you. Regardless of your current skills, you'll remember things you for gotten learn things you didn't know and become a more Boston programmer. So the scores is must see. For anyone who wants to improve his knowledge shop, the scores is aimed at all kind of developers. It provides solar theoretical base bring forth by the practical material. In short, the scores covers the following topics. The evilness off the mutable structures. You'll see several examples when mutable structures demonstrate the unexpected behavior. Generics and the race, including specializations constrained, some generics, variance and co variance, risk of substitution principle and more. The Biffle's in arithmetic. How floating point numbers are implemented. How to compare them. How Earth Magic Overflow Behaves with different times. How rounding works the difference between decimal and money collections. Ellen Que How to Poulter and existing list. Differed. Execution off Linke expressions. Peculiarities of closures within four and four inch loops. Least conversion in other topic. Concerns methods and over looting over losing based methods. Method Hiding went to prefer property over method. The reasons why. To avoid optional parameters and how to implement abstract glasses. Date and time puzzles, including concepts related to dates and times, including how a computer stores Time You to see and G m T time zones. Global and Local perspectives. Time Zone related. Basel's Ground Trips Earth Magic on dates. How to calculate the Age F. A Q. At sea shop interviews, abstract glasses of us is into faces. How to implement the disposed better? What is the difference between encapsulation and information? Hiding encapsulation in practice strings in turning constant versus read only fields locker verses monitor how to re throw exceptions and went to you String builder instead of stream and yet a short section of miscellaneous puzzles in the role and start an exciting journey learning See Shop Basel's I'll be waiting for you inside the course. 2. 01 Outline: Hi. This is Engineer Spark from engineers bag dot com, and the section is going to be somewhat unique. Yes, you'll see some puzzles in this section, however, it is not full of them, and the main goal here is to teach you some very important facts and concepts about which many questions are asked at Sea Shop Interviews. Iran A survey for some time ago about topics in which my students are interested in the 1st 2 winners are the following topics. Advanced. See shop puzzles and see shop. Interview. I decided to combine these two topics since they're similar in some points. By the way puzzles are very popular at interviews. I'm not sure if I'm going to create a separate course dedicated to see shop interviews. You'll see the most popular questions asked at interviews related to she shop here in this section. So we're going to cover the following topics. Abstract glasses versus interfaces. How to properly implement I disposable. What is encapsulation and what is the difference between encapsulation and information hiding? You'll see a simple example of proper encapsulation what is in turning and how strings are stored constant versus a read only lock versus Monitor. How to properly re throw exceptions and string builder votes a string. And it's possible that the section is going to be updated from time to time. Okay, let's get straight to business and learn the difference between Absar classes and into faces in the next lecture. 3. 02 Mutating Through Readonly Fields: one of the most popular questions on interviews for C shop developers is. What's the difference between class and structure? Most interviewers expect that you'll answer that glasses are referenced types allocated on the heap, whereas structures are value types allocated on the stack. Most of the candidates answer exactly that. While this is mostly correct, the deeper answer is different. The main difference between structures and classes is that structures implement the semantic off copping by value were asked glasses, implement of the semantic off, copping by reference. This is the most important aspect, especially from the A P I. Designing perspective. The only case when allocation method matters is the case of performance problems. If profiling data shows you're really named problems than you might be interested in converting reference types into value types, let's consider a good and bad examples off using structures. Let's switch to a visual student and look at an example. Here is a structure named Mutable, which contains an integer value. It also has a public method, which increments that integer value by one and returns the result. This is a very bad I D, and you'll see why very soon. Consider also the following client code. We have a glass named a here, which contains three members of type mutable. The 1st 1 is a property with getter. The 2nd 1 is a public Redon left field, and the 3rd 1 is a regular field without any additional modifiers. In the main method, we make three call players to the increments X method for each case. What do you think will be printed out to the console both in the first and second cases, 11 will be printed out, while in the third case it will be 12 Let's explain why this is so. In the first case, we work with a property which has a somatic off returning a value. It leads to copping a new valley on each call. So each call to the property mutable returns a brand new copy off the mutable structure. That's why incriminating doesn't work. The second case is the interesting one. Seems like we have a direct access to a variable here. But the thing is that compiler generates temporal variable for calls to redundant feels so in the reality it will look like in the following code snippet in the third case. We have a direct access to the structure instance. So in both goals we work with the same instance. Do you feel how bad the design of the structure is? It's a pure evil. This is because that structure, which implements the copy by value semantic by the language design, is implemented. A sim you double reference type in the code. Let's look at a good example of a structure. Here. You can see the point structure, which contains two values of type in. It exposes the increments operation, which always return in your instance off a structure so we don't modify the internal state of the instance. We just always create a new one. This is true in mutability. It's impossible to misuse the type which is designed in this way. Mutability logically implies referential identity. Values do not have a referential identity. That's why they're called value types, not reference types. If you need to mutate something, make it a reference type 4. 03 Mutating Through Arrays: This is the second part of evil Struck's. One would think that we're already seeing pretty everything. In the previous lecture, however, epicure behavior is waiting for us once again, and this time that behavior is related to least and the race structure objects, let's dive into the code without rambling. In this case, we have the same mutable structure off customer type. However, this time we add instances of customer type in the first case to the generic least and to the regular array. In the second case, the test method implements exactly that. So the question is, Will the age being commanded in one off these cases or not? Or maybe it will be incriminated in both cases. Stop the video and take your time to think a little bit and write down your guests. - And here's the answer. In the first case, we deal with a regular indexer implemented as a property in the least type. If you're not familiar with indexers, then Google for it. Insured indexers allow us to provide access for clients to the elements through the syntax with square brackets. In this case, we access the first element using square brackets and the behavior here is equal to the behavior with a regular property from the example in the previous lecture, so the initial value will not be incriminated. We work with a copy. Off the initial instance, it seems like the second case is the same as the 1st 1 seems success ing Instances through indexer will result in copping off those instances. See Shop doesn't support managed pointers and cannot to return a reference to a field off a class, for example. So what can go different in this case? And surprisingly, these cases really different. A compiler applies a special optimization for accessing elements in an array. There is a special I'll instruction called L. D L M A. That allows to get a reference instead of copy. That's why, in the second case, we're really modify the elements off the rain, not their carpets. Let's round the code and check if everything works as we discussed. Indeed, everything works. As I said, Let's look at the third case off. Civil Struck's in the next lecture 5. 04 Mutating Within Using: Let's look at another interesting example when it instructs could incur much harm. Let's dive into the cold right away. It's usually imagine that someone implemented his own structure that represents some kind off safe handle. Wrapping low level in pointer. This structure accepts in Pointer in It's constructor and pull the argument to the corresponding property. And here is a very important detail the structure diplomat's the I disposable interface in the dispose method, that guy who implement of this structure decided to avoid double closing off the same handle in case of multiple calls. For that, he checks if the handle is not equal to end point, her zero and on. In that case, he really closes the handle. Finally, he a science in point or zero to the handle in order to avoid excessive calls to the close handle method. In case the client makes multiple calls to the dispose method. It may sound reasonable, however, the Bombay sticking already consider three different clients. All of them are very similar. All of them create an instance of the my handle, do something with handle and call the dispose method in the finally block. The slight difference is that the second client casts that handle to the eye disposable interface before calling the dispose method. In this example, this seems extremely synthetic aled, but in the real world, developers often rely on some slick ways off dealing with the lifetime of objects, and they easily can call the dispose method exactly on my disposable interface. So there is nothing impossible or strange in this scenario. In all the cases of the last line off, Gold asserts that the handle equals two point or zero, since this is what we expect. So the question is, will one of thes asserts, fail or not? Take your time, think a little bit and come back after writing down your answer. - And here is the right answer. With the first case, everything is pretty simple. The dispose method is being called on the my handle directly, and everything works. As expected, the handle will be zero, so they assert, will not fire. The second case is different. When we cast the handle instance, toe I disposable the handle instance will be boxed. Boxing makes a copy, so apparently the dispose method is called on a completely other instance. As a result of handle will not be is eared and the assertion will fire. The third case is the trickiest one. Before answering the question, you need to understand how using statement get expanded. Here is a code snippet that shows how, actually the resulting code looks like when the using statement is applied to an expression which represents an unknowable value type. Look at this, knowing this fact, you off course may expect that the initial instance off my handle will not be zero it. Since this looks like the second case, however, there is another and in this case, more prioritized back can be applied. The trick here is that the compiler has an optimization that detects that the dispose method is exposed directly on the value type. Then it effectively generates a call in the finally block without boxing. Knowing this fact, would you change the answer? It happens that there is a more relevant beat off spec regarding our case. Here it is a using statement of the form using resource type resource equals expression Statement corresponds to one of three possible expansions. A using statement of the form using expression statement has the same three possible expansions, but In this case, resource type is implicitly the compile time type off the expression and their source variable is an accessible in and visible to the embedded statement. That's to say our program fragment is equivalent to the following code. Yes, you can see an invisible instance will be generated and off course. Second sequence. The initial instance will not busy eared, so the conclusion is that you should strive to avoid mutable Struck's as much as you can. This is another horrible story that shows how much evil can be brought by mutable Struck's . 6. 05 Conclusion: mutable structures are pure evil. There is too much unpredictability related to mutable structures. The compiler generates a temporal variable for accessing read only field. The compiler generates the special instruction for accessing elements in an array, and the compiler generates a temporal variable, expanding using expressions. All these facts lead to unpredictable behavior off mutable structures. This is only a part of madness. There are more strange things. I hope this section is enough daunting that you'll do everything you can to avoid implementing mutable structures. 7. 01 Outline: Hi. This is Engineer Spark from engineers bag dot com, and the section is going to be somewhat unique. Yes, you'll see some puzzles in this section, however, it is not full of them, and the main goal here is to teach you some very important facts and concepts about which many questions are asked at Sea Shop Interviews. Iran A survey for some time ago about topics in which my students are interested in the 1st 2 winners are the following topics. Advanced. See shop puzzles and see shop. Interview. I decided to combine these two topics since they're similar in some points. By the way puzzles are very popular at interviews. I'm not sure if I'm going to create a separate course dedicated to see shop interviews. You'll see the most popular questions asked at interviews related to she shop here in this section. So we're going to cover the following topics. Abstract glasses versus interfaces. How to properly implement I disposable. What is encapsulation and what is the difference between encapsulation and information hiding? You'll see a simple example of proper encapsulation what is in turning and how strings are stored constant versus a read only lock versus Monitor. How to properly re throw exceptions and string builder votes a string. And it's possible that the section is going to be updated from time to time. Okay, let's get straight to business and learn the difference between Absar classes and into faces in the next lecture. 8. 02 Specialization: these puzzle is extremely simple and more experienced. Developers know the answer, however. We need to cover some basics. So let's look at the code. We have three classes to off them are called A and B Be dress from A, and they both override to string method to didn't know to the type, so to speak. The third glasses called Engine and it declares two methods. One is generic and another one takes an argument of Type A. Everything is extremely simple. The clients code creates an instance off the engine type and then called the run method passing A in the first case and be in the second case. Actually, we have four cases here in other two cases are the same as the 1st 2 cases. The only difference is that we declare the returning values from their own method s dynamic . The question is what will be bring to doubt? Take your time, think a little bit right down your answer, and then get back and check if you were right. - So let's get the answer from the compiler directly around the code. And here is the out book. First of all, notice that the output in the 1st 2 cases equals the last two. It means that the story in the last two cases is pretty the same as in the 1st 2 So in the first case, a compiler calls a specialized run method that takes the perimeter off type A. What compiler does is that it looks for the most better match. The compiler sees that there is a method that text specifically an argument of the eight type. Thus it calls it in the second case, when an argument of the B type it's past the compiler sees that there are no any methods that taken argument off the top. It replaces, be using T and looks for any generics. That's why generic version gets called. This example teaches you how the compiler actually resolve such calls. Generally speaking, it looks for a better match. Why one would need to roll out overloaded generic method and a method takes a specific type within the same class. The only reason is to gain some performance benefits in high performance scenarios. Generally, the compiler resolve specialized methods faster than generic ones. Besides, you need to understand that both implementations have to do the same things. The client should not be punished in any case, either. He calls a generic version all the specialized one. So pay attention to this fact. The only difference between such methods have to be the type of arguments. There are no exceptions from this rule. 9. 03 Constraints: the spousal is the continuation off the previous one. They could be crammed into a single one lecture, though I decided that they're worth enough to be separated. So as you may know, generics allow constraints to be applied to them. We use constraints to specialize. The types that can be passed as a generic parameter here is a quite synthetic example. At first, we declared to interfaces here called I Fu and I bar each of them declare one method. We have a class that implements both I fool and I barring two faces. So the implementer class has two separate methods you can see on the screen where they send to the console being called. And finally we have to extension methods, which recite in the extension methods glass. The 1st 1 is generic with a constraint that says that T has to implement. The eye bar interface for the 2nd 1 is non generic, and it explicitly takes an instance that implements the I food interface. Now we can look in the client's code. We have three cases here. In the first case, we create an instance of the implementer type and call the extend method in the other two cases. We create instances off the implementer type and implicitly cost them to the interfaces it implements. So the question is, what will be. Bring it out to the console. Take your time. Don't hurry, think a bit, Write down your answer and then get back to check. If you were right, - let's run the go to look at the actual results. So here are the results. They're quite interesting, and I bet many of students wrote wrong answers. Let's uncover what other reasons. Offsides, the output. The first case is pretty simple, and actually, the answer could be inferred from the knowledge you got in the previous lecture. Indeed, this is the same case a compiler tries to resolve the extent method, and it sees that there are no methods that taken argument off a specific type. I mean implementer time. As a result, it makes a conclusion that the best match is the generic method, so it's a result of the bar things method gets called. By the way. How can we force the compiler to call the non generic version off the extent method? Let's check if the non generic method will be called in case we command out the eye bar interface implementation. Let's do this. Wow! The compiler is upset. What does it say? Surprise! It says There is no implicit conversion between implementer and I bar. Despite we commanded out the eye bar, the compiler Steel wants to call the generic method. We can try to commend out the eye bar constrained. In this case, the compiler is upset because it can't resolve the call to the bar things methods we have to return back the constrained. Here are some interesting scenarios. In addition, if we just remove the generic method, then we lose all the profits of generics. And the last goal to extend through the eye bar will not work. Whom we could try to add. Another extent method with a specific argument off high bar type. Let's do this. Oops. Now the compiler cannot resolve the first call, since there is ambiguity caused by the fact that the implementer implements both into faces simultaneously, we could try to roll out both extension methods as generics. With constrains. Let's dry. Unfortunately, that also will not work. Since the ambiguities still there, the compiler cannot decide which method to call Let's get to the first implementation, we can force the call off a method we want and the client's side. The first way is to perform the explicit conversion off the I food when we need to call the specialized version. Another option is to rely on an implicit conversion instead of using bar. Relying on the compilers type inferring mechanism, we tell the compiler that we want to work through the Eiffel Interface and in this case of the specialized method will be called the last case. Well, we rely on an implicit conversion toe. I bar results in the call off the generic method since it's the best match, so constraints do not have any influence on resolving off method calls. They're checked on Lee after the best matches determined and remember that overloading on constraints can introduce ambiguity and non generic specialization is only a better method . If the type is an exact match 10. 04 Variance and Generics: don't pay attention to the variants term yet. We will have a more detailed talk on the topic in the next lecture in the selector. What I want is to puzzle you. I encourage you to pay close attention to this and the following lecture. Seems they're highly practical, so let's look at the code. In this case again, we have a deal with hierarchy off glasses. Our hierarchy is not deep, though We have two classes here, Point to D and 20.0.3 D that inherits from the 0.2 d. What these glasses represent is obvious from their names. Treat this example as a synthetic one, because in the real world that kind of inheritance would not be appropriate. This is another topic. I just want to mention that this kind of inheritance is called utility inheritance. I've heard this term from a colleague off mile of lad Horcoff in shirt. The fact that two objects have the same data properties doesn't make them similar. What mags the object similar is their behavior, So there is no need to couple objects which have different semantic. This example demonstrates exactly that evil technique. If you want to learn more concerning such things, including solid and meta principles off object oriented programming. Consider taking my course called Software Architectures Matter and Solid Principles in C. Sharp. Okay, then let's continue except two classes. We have some kind of a plotter that has a scaling function, which takes an array of 20.2 D type and transforms it into a new one, multiplying the coordinates by the scaling factor. Look at this gold. They're alone. Traps this cold is absolutely valid, and nothing wrong can be found from the first sight. However, there is danger. Let's look at the client's code. Our client wants to call the scaling method. Passing in array of 0.3 devalues What not compiler allows to do this? A client sees their scaling method and wants to transformation. Saray of 0.3 devalues. The client knows that these glasses have the inheritance relationships, so the client writes absolutely legal code and expects that nothing wrong will happen. So you see the code, and I'll ask you to answer the question. What will happen when we make a call that you see here my badger scared you and everything will be fine. Or maybe an exceptional the throne. Take your time. Think a little bit. Don't forget to write down your answer, then get back and very fire. Answer. - To get the answer directly from the runtime, let's just run the program and woops air a type mismatch exception is thrown. The exception was thrown at the first attempt to initialize in array. Element off 0.3 d type. We try to initialize it asked the 0.2 d time off course. This is not possible, since parent Type cannot be converted to a child type implicitly. At the same time, we can change the scale method in a way that it would perform an explicit conversion since it expects 0.2 D and actually works with 0.2 D. All this very unfortunate situation is possible due to the fact that raise in C shop arc ovarian. Historically, in the next lecture, we will talk in more details about co variance and cultural variance. In short, NC shop were able to cast in array of Type B to an array of Type A. If B is a subtype off a, how can we fix the problem to fix the problem? It would be better to return in you area. Let's rewrite our function. In fact, I'll just add another function. - Now if we try to assign the result back to the storage variable that the compiler will say that it's a bad idea. It sees that the returning array is off base type and can't be cast to an array of subtype . And we can't fix the situation changing the storage type to the least off 0.3 d, the compilers still upset. To fix the problem here, we need to get the result into a separate variable. The best thing we can do here is to roll out a new scaling method that takes innumerable off 0.3 D and returns scaled innumerable of 0.3 d. - The conclusion is that erase, allow co variance and contra variance, but not safely. I want you to learn one. The very important topic in the next lecture. Let's talk about the list of substitution principle, or L S P. In short, 11. 05 LSP: before girl further, I want to spend a little bit of time covering a very important principle that belongs to the solid acronym. Solid stands for S r a P o C, p, L S B and D I P, each of which is an acronym on its own and represents a separate, object oriented design principle. If you want to learn more about solid principles, I would recommend you taking my course called Software Architectures Matter and solid principles. In this lecture I want to cover. Only one of these principles will talk about the L S P or least of substitution principle. This lecture and the next one are not related to see sharp puzzles directly. They cover an adjustment very close, yet important topic. Since this course in the end covers see shop interviewing questions. It's a good idea. Never speak is one off the advanced topics that can be touched at an interview. This lecture is titled Problem Statement. The official definition from Barbara Liska off the list of substitution principal sounds like this if S is a subtype off team than objects off type T may be replaced with objects off type s without breaking the program. It's not very hard to grasp what this definition means, but I'll quote the definition off. L S P from the book off Uncle Bob. Agile principles, Patterns and Practices in C shop just in case we find there the following definition off the list of substitution principle, the list of substitution principle states that subtypes must be substituted ble for their base types. By the way, Barbara Lisk off is a scientist who described this principle in 1988. The original paper was written in Greece, and it was very hard to understand and apply toe object oriented programming in practice. Let's try to clarify what it was B means for developers in practice. What does it mean to be substituted ble for a class? Let's pretend that we have a client which uses the FBI off interface. Be there are two. It is implemented by classes A and C. Class C can be considered substitute hable for Class A. If the client doesn't observe any difference using the Class C instead of A from the client's perspective, a client shouldn't experience different behavior using different inheritors of the same base class or an interface. Actually the L S P is strongly related to her object oriented languages. Allow us to use inheritance. If Glenn's be inherits from a, then we can use B S A. But we can to use a SB. Thus, clients off a can use both A and B even if they know nothing about be. This is basics off polymorphism. Despite this is basics developers all the time. I violate the logic off such a relationship, by the way, as a remark, I want to remind you that it's not necessary to have such a mechanism as the inheritance to model such relationships between objects in dynamically typed languages, we use the so called dark typing. If a bird's wings like duck, it quacks like a duck. Then I called at birth a duck. That's why the term duck typing appeared dynamically. Typed languages don't know if we're allowed to call a certain method or not. The runtime checks if an object can respond to a message by saying a message. I mean a call to the method, since in dynamically type languages, it's better to say send a message rather than call a method. Let's get back to the main topic. There are two ways of breaking the substitute ability. Violating contract and violating co variance or control variance. For a significant number of developers, it's unclear what does it mean? So it requires the further clarification. Without understanding, these fundamental concepts will not be able to design types which don't violate their speed . Sooner or later, you'll bump into the horrible problems caused by oh speed violation. The topic of contracts is covered in the course dedicated to solid principles I mentioned before. So here we will touch the topic off variants and Contra variants only. Let's look at an example of Phyllis P violation related to variance co variance in the next lecture. 12. 06 LSP Demo: this lecture is titled l SB Violation Demo. Let's consider a classic example of Phyllis Be Violation. I love this example because of two reasons. The 1st 1 is that it actually demonstrates the L S P violation, and this reason is obvious. And the second reason is that it shows that object oriented programming often can't directly map the relationships between objects in the real world into the same model off relationships between them in code. A great number of developers think that writing code in Hopi language, they're modeling aerial world domain problems. And partly this is true. But the real world relationships between objects sometimes can be motile directly in Opie language. Here's one of the Neave Opie statements child glasses. Implement is a relationship with based classes. For example, dog is an animal cat is an animal, so we can create three classes. Animal is the base class, and the other two are inheritors. Unfortunately, sometimes this kind of design doesn't work as expected, and you'll see this in a minute. So let's reflect the relationships between two riel world notions and code. We want to implement a rectangle and square being able to calculate their areas. I'm sure you'll agree with me that in the real World Square is a special case off rectangle . It's others because square is a rectangle with equal sides. Okay, let's switch to visual studio. Let's create a rectangle and square. I created the rectangle class, which has two properties with and height, and the square, which inherits from their tango class. Separately, I'll create the class, which is responsible for calculating areas of that shapes. Looks fine. From the first side. I'll pretend that I'm a client and I want to create two shapes and calculate their areas. For that, I'll implement the main method where all the things will happen that first, I'll just create a rectangle with with equals two and hide equals five. After that, I'll call the ST IC Cal correct angle method and get the result, and I also send the result to the console. Now I want to create a square. Wait a minute. What the hell is this? How a square can contain sides of different length. I'm not even going to run the program, since it's obvious that something is wrong here with a pile of square square allows to set different length to width and height. This design clearly violates the list of substitution. Principal square is not substitute hable for rectangle rectangle implements the in variant , which states that width and height could be off different length. Square has to implement another in variant which states that width and height have to be equal. I intentionally or meet that. Actually they also have to be greater or equal to zero. There is another problem is hiding here. Most likely, you would need to create methods which take rectangle as a parameter and implement some business logic. In case of calculating the era, such a method could look like this. This method checks the type of the accepted parameter and run the appropriate calculation algorithm. What do you think? Is it a good way to define methods all over the code base which have to work with rectangles? Doesn't it resemble you something we've seen previously? Yes, indeed, this is a violation of the open close principle. This method is open for modification. What will happen if we introduce a new shape? Correct. We'll have to modify that switch statement. This example of Phil SP violation is a hidden violation off OCP. So how can we fix such a poor design? Let's look at a simple, possible fix. Obviously, we need to make impossible, setting different length offsides for a square to fix the problem. For now, the expectations of the squares clients are broken. The air, a calculator class now demonstrate that there is a problem off separated data and behavior . The calculation algorithms are separated from the rectangle and square classes, which own the data required for calculations. The area calculator can't exist without rectangle and square. So why the behavior was moved away from rectangle and square rectangle and square for now, obviously lack cohesion to cure the disease, where always should construct proper abstractions. What we want to obstruct away is the business logic of calculating the area. Each shape has its own algorithm off calculation. The area. It is much better to make behavior shared rather than data. Let's obstruct away the calculate area method by introducing the I shaped interface. I want the rectangle and square to inherit from the eye shape. Implementing their own algorithms, Square now defines its own property named side length. Now a client can't misuse. It's a P. I Here's an example of a client in case of rectangle calling to calculate area, A client will give the area off a rectangle, while in case of square, a client will get the area of a square. The client can set different length, off width and height to a square. 13. 07 More on Variance and Contravariance: variance is the notion that describes the types compliance. It branches out to two notions. Coherence and contra variance. Assuming the type A canned the cast to Type B Type X is co variant in case X off take and the cast two x off b, for example, I borrow stream can because to my bar off object, this gold snippet shows that s is called Aaron too. Oh, here's a simple example which demonstrated the problem off casting as human would have the following clause hierarchy the base glass animal and the inheritors dog and get and a nave generic implementation off stack. The following code will not compile in C shop c Sharp d proc eights this to prevent the possibility off writing the following code we're trying here to add cats to dogs. A raise in C shop are co variant because of historical reasons. So the following code will compile and the violation off the SP will be detected Onley in the run time. There will be an exception. Starting from C shop for generic interfaces. Allow variants through special keywords in and out generic classes. At the same time, don't allow variants. The out keyword guarantees that inside the implementation off that interface, a generic parameter can only be used in the return statements. It solves the problem we've seen with adding a cat to a stack of dogs. This can be expressed as in the following snippet. Even the stack class from the previous example implement this interface than the following code will compile and be absolutely correct. On the contrary, we can use the in keyword to ensure that the generic parameter is only used as the input. Here's the code snippet, which demonstrated the idea if the stack glass implements this interface than the following code will compile and be absolutely correct. Another example I want to show you comes from the Basile off the dot net framework. It is also well known example of the SP violation. There is a generic interface named I Collection Off T defined in the BCL. The stop derives from the innumerable of tea, and it defines the following methods. Ed clear contains copy, too. Remove. There's old sir generic class named read only collection off team, which derives from the I collection of team. Yes, you can guess from the name off the read only collection off T. It implements a collection which cannot be changed after initialization at the same time, read only collection Off T derives from the I collection of tea. What means that it should support all the operations defined in that parent, a generic interface. A second sequence, the read only collection has to implement, add clear and remove methods somehow but how it is supposed to implement them, taking into account that these operations are dip located to perform on a read only collection off course, there is no meaningful way to solve this problem. So there it only collection just throws. They're not supported. Exception from that modification methods. It clearly violates the list of substitution principle, since clients that work with my collection of tea don't expect such behavior. And this is logical because other implementations off I collection off T, such as least off t don't throw is not supported. Exception. They just work is expected from a class which exposes modification methods. Throwing, not supported. Exception is a strong smell off l s P violation. Another smell, which indicates the L S P violation demonstrates itself by appearing off too many down casts in the code base. If a client is constantly checking the actual types of based classes or interfaces, it automatically means that a client is concerned about different implementer. Zobaie. Some reason it means that a clan knows some internal details about the objects hierarchy construction. This smell is a consequence off the SP violation an example of such a smell you've seen in the lecture where we discussed the relationships between square and rectangle. The code snippet on the slide demonstrates this problem as well. Down costs are not always the indication off SP violations. It is allowed to downcast a type. If you're absolutely sure about the type, you need to downcast too. Consider the following example. For example, if we're absolutely sure that this function is called only with an I d off a privileged customer, then we can freely downcast the object returned from the repository and perform an operation. This kind of downcast, just so to speak, reminds the compiler that the rial type is privileged customer 14. 08 Conclusion: Let's sum up quickly what you've learned in this section. First of all, you've seen that the compiler resolving method calls is looking for a better match. The only reason to roll out an overloaded generic method and the math of the text a specific type within the same class is to gain some performance benefits in high performance in Paris. Besides, you need to understand that both implementations have to do the same things, and known generic specialization is only a better choice for the compiler ive. The types of arguments match exactly constraints on generics do not have an influence on resolving off method calls. They're checked on Lee after the best matches. Determined overloading on constraints can introduce ambiguity. You also learned that arrays allow co variance and contra variance, but not safely a simple definition off the SP sounds like this. The list of substitution principle states that subtypes must be substituted ble for their base types. It means that a clan should not experience different behavior using different inheritors off the same base class or an interface. So the code, which is compliant to the L S P, enables proper use off polymorphism and such code becomes more maintainable. There are two general rules. You should adhere to keep your code compliant to the L S P. First, do not violate a contract by either strengthening preconditions or weakening past conditions. And second, do not violate co variance and contra very INTs explicitly mark the generic parameters by in or out keyword if possible in practice, The L S P violation also demonstrate itself in the following race. First, implementer throws not supported exception from a method which is inherited either from a base glass or an interface. Second implementer has empty implementations or stops instead of meaningful implementation . And third, so each case statements appear here and there with checks off the actual type. Often argument down costs is a similar smell. Congratulations. You reach then of the section That was quite an interesting journey. Let's talk about methods and over looting in the next section 15. 01 Outline: Hi. This is Engineer Spark from engineers bag dot com, and the section is going to be somewhat unique. Yes, you'll see some puzzles in this section, however, it is not full of them, and the main goal here is to teach you some very important facts and concepts about which many questions are asked at Sea Shop Interviews. Iran A survey for some time ago about topics in which my students are interested in the 1st 2 winners are the following topics. Advanced. See shop puzzles and see shop. Interview. I decided to combine these two topics since they're similar in some points. By the way puzzles are very popular at interviews. I'm not sure if I'm going to create a separate course dedicated to see shop interviews. You'll see the most popular questions asked at interviews related to she shop here in this section. So we're going to cover the following topics. Abstract glasses versus interfaces. How to properly implement I disposable. What is encapsulation and what is the difference between encapsulation and information hiding? You'll see a simple example of proper encapsulation what is in turning and how strings are stored constant versus a read only lock versus Monitor. How to properly re throw exceptions and string builder votes a string. And it's possible that the section is going to be updated from time to time. Okay, let's get straight to business and learn the difference between Absar classes and into faces in the next lecture. 16. 02 Floating Point Numbers: for First of all, what is a floating point number? It is a number with a decimal point. B equals 3.14. For example, you were constant equals 0.58. At the same time, you have to understand that internally, BC doesn't operate with floating points. It just doesn't know what it is. BC can store and operate with such a value like 1/3 for example, with us. Any floating point number has to be represented by once, and Sears, with some precision precision, defines how many digits are stored. Let's start with a basic example. Look at this creeping method. I'm scared already off course, absolutely trivial. However, before laughing at this code, try to answer the question. What output will be produced? True, False, false, True, true, true or maybe false? False. Take your time. Think a little bit I'll be waiting for you. Welcome back. Let's run the code and look at the results. Wow, The first case gave us true in the second case gave us false. How the hell is this possible? Both cases are absolutely the same, except two numbers. But the meanings, so to speak, is the same. How How the hell is this possible? Well, the correct answer would sound like decimal math. How we know it from the human's perspective cannot help us predict the result off operations performed on binary values. Let's try to reveal what happens here in the first attempt is to write the internal values to the console. I want to call to string all these double values, passing the precision I want to see. Let's run the program and look at the results. Food seems like the numbers are the same. However They're not to string is very sleek and shows us what we want to see, not what is really inside. Okay, then at the next step is more low level one. I'm going to give the binary presentation for that, either allowed a function that will transform a floating point number into its spinal representation and return back the result as a string. Now we need to call this method to get the out for the initial values 0.10 point two and 0.3 and the resulting values from the adding operations. Let's finally around the program and see why we see such strange results. Yes, you can see 0.2 in binary really equals the resulting off, adding 0.1 to 0.1. However, 0.3 Devers from the result off adding 0.1 to 0.2. Somewhere in the end, we see that 0.1 plus is your 0.2 is a little bit greater than just 0.3. Don't rack your brain. Just remember that float and double types are based to representations, and you can't predict values resulting from binaries relying on decimal math before looking how to cure the disease. Let's play around with floating point numbers a little bit more. Here is the second case. What I do here is that I divide 1.0 by temple in zero, and after that I multiply the result by 10. Assigning the result to be logically be has to be equal one. The next line of code does the same as in the previous one, just using the adding operation. The result again has to be equal one. After that, we have three cases. In the first case, I compare be to one, and they have to be equal from the mathematical point of view. The other two cases check, See, so the question is what will be printed out to the console. Take your time to give the answer. I'll be waiting for you here. - Let's run the code to see the answer. Wow, What the hell b equals one, while see does not. Also we see that si is not greater than one. What means that it is actually less than one? Why? How is that possible? At first you need to understand that 0.1 cannot be represented exactly in base to there is always a small rounding error. It may sound extremely strange, but multiplication mitigates the small difference that appears as a result, off working with floating point numbers at the same time, repeated addition or subtraction increases the difference. Let's look at a real value of being seen. We're not going to look at them in binary. We have another way off looking at the real value. Using the power off for matting dot net provides the AR format where R stands for round trip. It shows all the digits. Let's run the code and look at the result. Yes, you can see the C value is really a little bit lower than one. Thies is how the binary math works. Okay, great. Let's look at another example. This method is almost the same as the previous one. Look carefully. We declared two variables A and B and after that we got one. Variable is the result of division and the last one is the result off a backward operation . So apparently a one has to be cool. One, especially since we use the multiplication operation. So you see here three checks. The question is the same. What will be printed out to the console? - Come back. Don't be shy. Let's around the code. Who False? True. True. How's that possible? It seemed like the first case had to be true. However, the first case differs from the case in the test precision. There are two peoples related to the behavior we observe. The 1st 1 is that I didn't say about the Target compilation platform off the current project. The current project is set toe x 86 CPU architectures. The results of mathematical calculations can be different on x 86 x 64. This is exactly this case, however, compiling to a certain platform cannot be considered a bog. Look more carefully. Here we declare the A one variable is double, whereas A, B and C are float. The thing is that changing the floating point numbers type increases a rounding errors. This case demonstrates exactly this. In the end, a one is less than 1.0. Only a rounding to seven digits makes a one equal to 1.0. Another option is to change the type off, a one to float. Let's do this and no, let's run the test. Good. Now we see that a one equals 1.0. Even without rounding. However, I want to demonstrate also that the behaviour is different when we target the X 64 platform . For that, I'll change float back to double here and change the target platform in the Projects properties. Now let's around the code and check the behavior. Indeed, a one equals 1.0 on X 64 even with a one declared as double. But in any case, avoid changing or floating point number types within calculation blocks. Consider these advice as the best practice. There is something inherently wrong with all these examples and the wrong thing here. Is that how we compare floating point numbers in the first place? We check the strict equality, so to speak. However, we rarely need to compare floating point numbers with precision more than three or four digits after the decimal point. The street comparison compares numbers with a super precision that we don't actually need. The last method contains a code snippet, which suggests the way we need to compare floating point numbers. However, more often we compare floating point numbers without rounding them. So let's take the last example and fix the problem without rounding. I'll write a function that correctly compares to floating point numbers. - So here we take the absolute difference between 20 prince applying the standard function math , APS and check of the result doesn't exceed the precision we want to achieve. So in this case, even changing flow to double amplifying the rounding error, we managed to correctly detect that. Actually, the difference between the result and 1.0 is so small that we understand we can actually treat them as equal. Always use a small tolerance comparing floating point numbers. It doesn't mean you should mix floats with doubles during calculations taken to count. The facts we encountered in this lecture 17. 03 Arithmetic Overflow: arithmetic overflow is another interesting topic we're going to address. Overflow is a very important topic from the mathematical point of view. If you deal with complex aromatic, especially on the verge of maximum values, then this topic is for you. The other students will also benefit from this lecture. Getting deeper knowledge regarding aromatic and primitive types. Let's start with a puzzle right away. I wrote here three functions that emulate the overflow conditions with three different types, including int decimal and double. Let's start with the simplest one. I declare the max variable, which equals the maximum possible value Ellen to jerk and hold max. Value is a static property that belongs to the in 32 structure. In the next line, I declare another variable, assigning to it max value plus one. So the question is, what will happen or what will be printed out to the console? Here are the answers. I suggest next is greater than Max. They're equal. Next is greater than zero or equal to zero and the last possible and sarees and exceptional the throne. You can take her time to come out with. Answer A Soloway's. I will be waiting for you here. - Let's run the coat to check how this works in reality. So when the overflow on integer types happen, the value rolls over to the minimum value. So every assertion here will be false. The next value is less than zero. The same will happen if overflow happens on you. In short, you sure? Long you long answer on What about decimals? The following method does the same. It declares the maximum value that can be hold by decimal and then adds one to it is signing the results to the variable called next. The assertions here are also the same. So think a little bit right down your expectations and get back to check your answer. Let's around the code. So, Louise Oops. The overflow exception is thrown decimal doesn't like overflows. Decimals boundaries are in variance off the decimal type. And it doesn't like when someone tries to break its in variance to protect its in variance . It throws the overflow exception. Decimal thinks that you don't understand what happens in your program if you allow the overflow, so go and fix it. The third case is also an interesting one. Overflow double does the same experience methods. The assertions are also the same again. Think a little bit. Maybe try to remember math fundamentals. They can help you to give the right answer. So write down what you expect from this function and get back. - Okay , let's continue. I'll around the code. Wow, I bet for many students these results were unexpected. So it happens that next equals Max and the second sequence. It is, of course, greater than zero. The thing is that floating point numbers are implemented in a way that adding one is effectively adding zero at the range off one multiply. Tell to the power off 308. That kind of behavior is actually meaningful, since adding one to an extremely big number doesn't change anything. If you add one E 32 to the maximum value off type float, you'll get infinity. Here is an example. - Let's run this method. Indeed, the result is infinity. Okay, let's look a little bit closer at how to enable checks for overflow explicitly 18. 04 Check for Arithmetic Overflow: as you have seen in the first example into just allow overflow, the value rolls over to the minimal value. This is the behavior by default, however, see Sharp allows to force the check for overflow. Generally, we have two options to first exceptions in case of integer or flows. The 1st 1 is to enable overflow checks at the level of a project so it will check all the arithmetic operations within the resulting assembly. For that, go to projects properties, then go to build and click on Advanced. Here we have the following option. Check for automatic overflow under flow. Let's take the box and click OK, now we can round overflow into and see if the overflow exceptional the throat. Indeed, overflow exception is thrown. Checking for overflow slows down the performance. It's a rare practice to turn on, checking for entire semblance instead. In places Well, we need to be sure that there is no overflow, and especially when we know how to recover from the overflow, we can apply checks for overflow more gradually. Before doing that, I'll turn off global checking, so see Shop has special seen tax for overflow checks to first the check. I'll use a special keyword checked. The syntax allows to apply. Check on a single aromatic expression. However, you can use the checked section. We can write more than one aromatic expression within the checked section, and all of them will be checked for overflow explicitly. Let's run the code and check if it works as expected. Yes, the exception is thrown. Checked expressions run slowly than unchecked, so checked expressions, which run in the long loop can significantly degrade performance. When you apply checking globally, you can use the unchecked keyword to explicitly remove checking from certain aromatic expressions. Syntex is the same as in the case of the Czech keyword, so I'm not going to demonstrate you there. Unchecked syntax. Now I want to tell you a short story about bad and good practices related to primitive times and checking for overflow. Long ago, I worked for a company where many developers moved to see Sharp from Delfay and other old languages. They burn their traditions to use unsigned types in every case where negative values have to be duplicated. For example, they declared counters or integrators, as you means they were sure that you in somehow protect them from having invalid values in the corresponding variables. However, as you learned in this lecture, this is not how things work in the real world. This is because you eats are not protected from being overflown so anyone could pass negative values into their methods, which required a you in value to be passed and overflow will a cure in such a case, and no one will detect it at run time until bug reports will come. Another, much less important concern is that only a subset off dotnet languages understand on science types. So if you write a public AP I where you require unsigned primitive types to be passed, you prevent using your library within languages, which are unaware of unsigned primitive types. However, in the real world, I never faced this problem, though. The problem. Israel Just remember that there is an agreement between C shop developers to use unsigned, primitive types Onley in private AP I were a property, for example. It's where convenient to represent an I P V four address internally. As for unsigned bytes, you also will face the necessity to rely on signed primitive types when you work with low level unmanaged code for the purpose off inter operation. So in the end, I would say that generally you should stick with the Intertype wherever possible to represent integers if you need to duplicate some range of values than right validation methods. In rare cases, rap arithmetic operations by the checked sections use unsigned types only in inter operation scenarios and in rare cases where unsigned types are very convenient. 19. 05 Rounding: surrounding is a separate, pretty interesting topic. Let's start with a puzzle right away. Here is the method, which defines five variables of type double in all the five cases we call the round method from the math glass. In the last two cases, we also passed the precision to which we want around. Don't pay attention to the fact that we compare double values without relying on some kind of tolerance. Yes, we discussed talking about best practices off floating point numbers comparison. This puzzle is not affected by the fact that we compare here double values with liberals directly. The possible concerns how they're rounding works and invent. As always, we have some assertions they will result either in true or false. Try to guess the results. Take your time, think a little bit right down your answer and get back. I will be waiting for you here. - So the first assertion that a equals six returns true while the second assertion turns falls. How is this possible? Sounds like this is not logical. However, there is logic. The default mode off rounding is called to even so by default, midpoint rounding rounds to the closest even number in case off 5.5 that will be six. And in case off 6.5, that will be six since seven is odd. If I try to add another argument in Tele sells the devices that we can pass one off the two enumeration values that in admiration is called Meat Point rounding. And it has to values away from zero ender to even The default mode is to even how away from zero works when a number is health way between two others. It's rounded toward the nearest number that is away from zero. How to even works. When a number is halfway between two others, it's round it over the nearest even number. I'll expand the region down here to show you the difference. These short table shows the difference between these two rounding modes. When we're around 3.5 in away from zero mode, the result will before as well as in case off to even well, we around 2.5. The result will be three in away from zero mode, while in two, even though the result will be too, three is further from zero than to. That's why we have different results in this case. Okay, then the third assertion returns. True, since 7.35 will be rounded to seven Sound 0.35 is not half way between two others sold around. Method will just round to the closest one, the last calls to round past the precision off rounding. In both cases, we want to round 21 digit after the floating point rounding 7.32 will result in 7.3 and rounding 7.35 will result in 7.4 since for is the closest even number. Actually, they're rounding away from zero is more commonly taught in school. So most people are not familiar with rounding to, even as the alternative to even rounding is also known as banker surrounding .net defaults to rounding to even as it is statically superior because it doesn't share the tendency off rounding away from zero to round up slightly more often than it rounds down. Assuming the numbers being around a tend to be positive depending on the data set, Symmetric arithmetic rounding I'm talking about away from zero mode can introduce a major bias since it always rounds midpoint values upward to take a simple example. Suppose that we want to determine the mean off three values 1.52 point five and 3.5. But before that, we want to first round them to the nearest integer before calculating their mean. It's quite a regular task for calculations within the bank system. Note that the true mean off these values is 2.5. Using symmetric arithmetic rounding these values changed to 23 and four, and they're mean will be three. Using banker surrounding these values changed 2 to 2 and four and they're mean is 2.67. Because the latter rounding method is much closer to the true mean off the three values, it provides the least loss off data. That's why I don't let relies on the two, even or bankers surrounding by default. Okay, in the next lecture, we're going to talk about the important difference between decimal and the concept off money 20. 06 Decimal and Money: I want to discuss the difference between decimal type and the notion off money in this lecture, However, traditionally let's start with a simple puzzle. Here is the method, which declares two decimal variables. The 1st 1 is initialized by 1.0 and the 2nd 1 by 1.0 of the M. Sapphic says that this is a literal, off a decimal type. In the end, we have to assertions. The 1st 1 directly compares X and Y, and the 2nd 1 compares their string representation. So the question is what will be printed out to the console? Take your time. Don't hurry up and write down your answer. Let's run the code to check the rial behavior. The direct comparison returns true, while string comparison returns false. As I said, the puzzle is pretty simple. However, many developers get confused for some reason, X and Y are equal from the mathematical point of view, and decimal reflects exactly that fact to string takes the exact value stored in the decimal variable, and it doesn't cut excessive zeros. As a result, it compares 1.0 and 1.0 off course. These strings are not equal since their length is different. Okay, let's get to the topic I want to discuss here. There is a widespread opinion that decimal type is money, by the way, we even at the famous ah, fix two decimal values. However, there is a tiny but extremely important difference between being my and being a tool for representing money. So decimal is not money decimal was invented for representing them. Let me explain in more depth the problem off representing money in the rest of this lecture . I'm going to talk about monotype us an obstruction instead of using decimal type for presenting money. Values in the last project I have been participating mean we relied on the decimal and integer types for a long time. From the beginning, we knew that using primitive types for values off that kind is an anti pattern, but we stubbornly have been using them. This will loan anti pattern is called primitive obsession, representing I P address as a string or representing zip code. There's a string are quite good examples off this anti pattern. In short, zip code email i p address are in love complex concepts which have to be represented by high level classes that encapsulate rules protecting in variants, which belonged to the implementation off a complex concept. If you represent emails using strings, then anyone can pass any string they want. It's an email. Many rules can be encapsulated inside the class. Such a zip code, for example. It can contain the mapping between codes and regions or something else representing ZIP codes by strings. You'll eventually see that all the logic related to ZIP codes is spread over the code base . So let's get back to the problem of representing money values in the US There are scents and dollars in the Russian Federation, Rubles and Coptics. One ruble equals 100 coptics. So our System Inter operated with an external system which performed all its calculations in Coptics represented as integers. It required topics as the input and return Coptics as the output. If we wanted to pass in two rubles and 50 topics than we passed in the following variable and we haven't seen any problems up to a certain time. But those Coptics represented in in 32 started to spread throughout the whole system. In many cases, we've had to convert them into decimal type to correctly display the value on the screen. You definitely don't want to show users 250 car picks. You want to show two rubles 50 car picks. In other cases when we handled users input off money values, we've had to convert them into complex in order to pass a bill into that external system. Eventually we found ourselves in writing the following function These function except toe arguments and have to answer other any mismatches between counters dispensing event arcs contained for integers that represent money values expressed in complex. As you can see, this go is very smelly. This is actually a ball of mud everywhere you have to elicit. What are you working with right now with topics or rubles? Then you have to convert them in tow either Coptics or rubles, depending on the case and only after that you can compare them from converting topics to rubles and vice versa. We wrote to extension methods called cop to rube and group to cop. Grating extension methods on primitive types is the first sign of the disease. So we ended up converting money values everywhere in our code base. Even if you manage to avoid conversions in your domain logic. Such conversions, with last extension methods, will stand the boundaries off your application. You always have to be sure that you work with in a property type with an appropriate value stored in the type without riel protection. In the end, we decided to solve the problem by introducing money structure. It's a form of value object design pattern. Let's look at the money struck. This particular structure is made specifically for Russian currency. Imagine what will happen if you need to work with different currencies. How the hell Willy Hello? Different currencies with different exchange rates, which, by the way, change frequently Decimal is not enough. In such cases, you'd need something like this money structure or maybe a class just more sophisticated. The idea is that you need some kind of abstract entity to represent a complex concept. This is the only way to go. So these money structure implements I quit to compare, and I comparable to simplify comparisons on the client side. It defines the private constructor that takes decimal. The only way to get the money instance is to use either from Coptics or from rubles maths passing either Coptics as long or rubles as decimal. In case your money is suited for a specific currency, that's a good idea. And here's why. Imagine that we made a construct republic but then declined Can ride the following code. What is that? $200 or 200 cents? This is also the reason why it is bad to allow implicit casts. It is bad in both cases, either. It's allowed to implicitly convert longer decimal into money. Really? Will you be sure that the expression money M equals 200 m does mean that it's $200? Maybe someone just put AM in order to compile it, but actually wanted to initialize it by $2. Consider the following to perform, add and subtract operations. I override the corresponding operators. The conclusion is that decimal is a good time. However, you should not examine the anti pattern called primitive obsession. Rely on an abstraction instead. Otherwise, you will spend hours to effect er, the mass you brought to a project. It's also extremely easy to introduce box relying on primitive types. Remember, primitive types cannot reflect conceptions. Money is the concept. Decimal is close, but very often not enough 21. 07 Conclusion: what problems related to standard daytime tops do exist. First, along the section, we found out that the local perspective is highly deceptive. Local implies the local time off a certain machine without involving any time zones. The local time zone is used, but without keeping all the time zone related information along. Second, the local perspective silently gets dropped after crossing any bound er's. You passed date time to the third party, and they will be completely unaware of where from this time value came. If that third party passes you back the time value, you also lose any possibility to determine the source of that value. Third, daytime hides rotten eggs in the form off. Seek implementation off. Tracking the perspective. You saw the problem on the example when we performed a round trip conversion off a value which is on the verge of a transition. We used UTC and local perspectives and figured out that daytime hides another secret option called ambiguous DST, which allows to demonstrate some magic. Fourth comparison off to date time values completely ignores the perspective and offset few . The major drawback off the daytime offset is that this time doesn't present a certain time zone. In reality, the instance of daytime offset can be created from a certain time zone. However, the instance itself doesn't carry any time zone related information except the offset. As you remember at time Zone is not an office it and this is the problem. Despite that problem, the advantage of the daytime offset is that it presents an unambiguous moment on the timeline you to keeping the offset. That's why these type is not so bad for arithmetic operations on date and time valuers and conversions between time zones with help off the time zone in FA type. Now a couple of words concerning the time zoning for class the most significant disadvantage off the time zone in for it's not the fault off the times. Only in for type is that it is based on the Microsoft Time Zones database. In cases when your application has to massively work with time zones, tracking events in the past scheduling events in the future, you'll face old times on naming, resulting in the necessity to map of those old names two names in i n a database and possibly you'll face the problem off a shallow history of changes in time zones. In fact, the database from Microsoft stores some incorrect and incomplete information about transitions between standard and daylight saving time in certain time zones. I'm not going to demonstrate you those box. I'll just attach the link to a block post where John Skit show such box. Taking into account all the things you learned in the section, it becomes apparent that B cell lacks a top that can unambiguously defined a moment on the timeline, keeping all the information about the time zone simultaneously. It is apparent, as well, that BCL lacks types that can represent date and time values separately, using daytime values. Ignoring one part or another is not the Samos using special types for presenting dates and times separately. In general, a P I off date and time related types in BCL is very subtle and hides many people so you can easily stumble upon AP I off Basile. Daytime related types allow you to work with date and time valuers without an understanding off what is going on under the hood. It might seem that it's a good thing when an a p I hides internal details. However, this is really good when it's done without fooling the user. A user for Nipah has to understand the behavior semantics, off objects he's working with. While those AP eyes are hard to understand, in many cases, thanks Roberts in the majority off cases. If you understand the internals of BCL daytime early, the types you can write reliable code that works with date and time values. However, if your application works with date and time values massively, if it should implement scheduling events in the future. If it digs historical dates, then I would stronger command you to stick with no time library or quartz enterprise scheduler dot net Depending on the requirements. No, the time replaces older standard types with a much more reliable FBI. Quartz is more suited for scheduling. Both projects are open source. It is not sufficient to know about problems and pitfalls. Off date. Time related tops, toe work with date and time. Baylor's properly. Don't forget that arithmetic on dates is very tricky. It's very hard to implement your own arithmetic on dates and use accurate formulas to calculate age. Strive to take into account a time zone, and don't forget about the 29th of February. Pate fall 22. 01 Outline: Hi. This is Engineer Spark from engineers bag dot com, and the section is going to be somewhat unique. Yes, you'll see some puzzles in this section, however, it is not full of them, and the main goal here is to teach you some very important facts and concepts about which many questions are asked at Sea Shop Interviews. Iran A survey for some time ago about topics in which my students are interested in the 1st 2 winners are the following topics. Advanced. See shop puzzles and see shop. Interview. I decided to combine these two topics since they're similar in some points. By the way puzzles are very popular at interviews. I'm not sure if I'm going to create a separate course dedicated to see shop interviews. You'll see the most popular questions asked at interviews related to she shop here in this section. So we're going to cover the following topics. Abstract glasses versus interfaces. How to properly implement I disposable. What is encapsulation and what is the difference between encapsulation and information hiding? You'll see a simple example of proper encapsulation what is in turning and how strings are stored constant versus a read only lock versus Monitor. How to properly re throw exceptions and string builder votes a string. And it's possible that the section is going to be updated from time to time. Okay, let's get straight to business and learn the difference between Absar classes and into faces in the next lecture. 23. 02 Altering List: to find. Very often we face the case when we need to change an existing list of fighters. Look at the following examples Here we have a regular released off integer values we to rate over the leased using a forage loop. We try to remove all the even numbers from the least within that loop. In the end, we have an assertion in the form off console right line. So the question is the same as always. What will be printed out to the console? Okay, let's run the gold to look at what will happen at around time. Whoops. An exception has been thrown. Why does this go throw an exception? This happens due to the fact collections used in the for each loop are treated as immutable . Have you ever thought what it is for? Each loop for loop is clear and straightforward. It is based on the operator, you explicitly setting the force statement. But what about the forage loop? It seems that there is no way to Reiter from the first sight. However there is. Please remember that the for each loop is a short version off the following code. The compiler expensive for rich loop into something like this. We get an in numerator here which has a method moved next to move the car. Sir. Within the collection, we get current values by calling the current property. This is done in a while loop to reiterate over the whole collection. If you look inside the move next method, you'll see that there is a hidden check which ensures that the collection was not modified . If it sees that the collection was modified, it will throw an exception. So how toe alter an existing list? There are three major ways to achieve what we want. The 1st 1 is to use a for loop. Look at this coat. Here we have a regular for loop which starts from zero and goes up to the count off list. The list is modified within the loop. I am not going to run this girl. Believe me, it works. Eso is It works as we expect. Looks like this is a pretty easy way to alter. Released However, let me introduce one change to these peace off code. Seems like this change is not related to how the look works. But now I want to ask you what will be printed out here now you could think that everything should be fine and the resulting least will contain only four and five. Let's run the code and set a break point inside the loop. I'll go through the loop step by step. Do you see this? We removed the first item. One is not at the zero index, but the iterated equals one. As a result, we skipped the step off comparing the item at zero index. After the first item is being removed, I'll drop this break point. I'll drop this. I'll remove this break point and set another one at the end of the method. Let's see what the list contains now. 13454 items instead of two. To fix the problem, we also need toe alter the it aerator along the way. Let's around the code. Everything works fine. In theory, this method off altering at least should work fine. However, we can still rely on the for loop, avoiding changes off the traitor variable. Let's expend another method. Look at the for loop. They sloped, goes backward. It starts from the last item and goes to the 1st 1 The trick is that removing items within such a loop incur changes off. Only those indexes were already not interested in because we passed them. I'm not going to run the code. I'm sure you see that it will work. Indeed. Unfortunately, unfortunately, both ways are not always applicable. When we have some sort of complex rules, we have some hidden into connection between items. Then we may need another, more robust way in case of a simple condition. The most robust way is too reliant on is to rely on the special link method called Remove All which accepts a lambert the which accept a lambda expression. The remove all implementation takes all the responsibility off, altering the least itself the most robust weight alter the list is not toe altering it all . Yes, sounds funny, but this is how things work. So the most robust ways to create a separate least and filter the initial one Here's an example of how to do this with help off link. Here we have an initial least and then we declare the 2nd 1 We filter all the odd numbers and add all the remaining items to the newly grated list in this case, I call the greedy operator to least to immediately return you filtered collection This way does have a problem with excessive memory consumption. In certain cases where we're processing millions off items in simple cases, this is a pretty good way to go. In short, there are the following race off, altering an existing list. Alter within a for loop going backward, older within a for loop, modifying the generator. Alter calling the removal method and alter by introducing an additional least, this is not about altering at all, but actually it's often sufficient to achieve what we really want. 24. 03 LINQ Deferred Execution: develop. Let's start with the easiest puzzle related to link expressions. Many developers forget how link actually work, so we need to stay this example. Let's get to the code without rambling too much. Here we have a list of integers. It contains three values. After that, we're all the way RL ng method, which accepts alarmed expression. In this case, we filter all the numbers which are greater or equal to then a gram of three from the initial list, and then we just bring out the number of items in the quay released. So what do you expect? It will be printed out. - If you answered one, then you're right. Link methods can be divided into two groups. The 1st 1 is deferred methods and the 2nd 1 is greedy. Methods. Differed methods are the following select select many take skip where and others the greedy one sort of the following count average mean max some first last two least two array and many others so greedy operators, when called, forced to run all the previously constructed link expressions In our case, there were expression will only be executed as a result of calling the count greedy method But before calling count, the third item will be removed explicitly via the removed method, so the end result will be one scenes. There is only one element which is greater or equal to two. Be careful with this stack. Overflow is full of questions related to the specific behaviour. Offline cooperators, the full list of operators and their classifications can be found inside the link I attached to this lecture. 25. 04 LINQ Closures: There is an old, quite strange behavior related to link expressions and the so called closures. Closure is a code construct. When an external variable is captured by limbed expression, it's always easier to look at code rather than talking about it. So look at this method we have to closures here, in both cases were trying to feel her. The initial string, which is a B C D E f. We're filtering by vowels. The first filter is written by a four loop, and the 2nd 1 is written by a forage loop. After each loop, we're forcing link expressions to run. So the question is what will be printed out in both cases. It's a very tricky question. Think a little beaten right down your answer. Then get back and check your answer. I will be waiting for you here. - Let's run the go to check what will happen. Wow, The first part causes an exception. A raise out of the boundary. We even haven't to reach the second loop. Okay, then why this happens? The thing is that land expressions get compiled into the code which represents delegates in a separate class and in a for loop that will be the same delegator written several times until I reaches value equal to five. Here's how it looks like in reality. C. Sharp compiler creates a separate class like the display class, which contains alarmed expression and the variable to hold the two Reiter As soon as we work with the same despite class, we work with the same delegates. Well, we forced the link expression to run. We end up with that exception. We can fix it by introducing a temporal variable writing a closure. This way, we guarantee that each iteration will work with a separate delegate, which represents the code in the land expression. Here's how this code gets compiled in this case. The display glass instance is created in each iteration, and as a result, we work with different delegates. Let's around the fixed gold and check if it works. Great works fine. By the way, the second part works finest well. However, the second loop will print a B, C D. E f, excluding only the last vowel. In case off older compilers, my C sharp code is compiled by the rustling compiler take into account that compiler versions existed before dot net 4.5 expanded forage loops with closures in a way which we faced running our program for the first time. The only one difference is that it wouldn't throw an exception. It would just pick the latest vowel and filter their initial string using only that last vowel. Be careful with that. So the right answer to the question what will bring it out in the second case would be the answer. It depends on the compiler version. 26. 05 Generics Conversion: in this lecture, you'll see some old things that happened to conversions between types using link old at the first sight. Indeed, there is always a correct explanation. Since we're a tech guys, we're not talking about philosophy or economics. Okay, then let's look at an example. We have a function here which defines the list of integers. Then we have for expressions, which try to convert the least off integers to the list of doubles. The first expression relies on extension method you can see below. The second expression uses the standard cast method, the other to rely on the sequel like syntax to perform the conversion. The question is, which of these expressions work fine and waged a lot? Write your answer and get back to look at the reality. - Before running the code, I'll wrap expressions into try cage blocks. Now I'll run the code, and the first expression fails. Why? The thing is, that runtime item is of type object, and we can't cast it to double the invalid cast exceptional the throne. The second expression fails because of the same reason. Cast method works exactly the same as the previously called Convert Method. They're roughly the same. The first sequel like expression is the same as the previous cast method. So with throws, the last expression deliberately casts each item to double explicitly. What allows all the items to be converted properly cast in a query always solves the problem. In such circumstances, remember that generics can't see conversion operators, boxing reference and malleable conversions. The first way to avoid the problem, as you have already seen, is to cast in a query. However, there is another way. Actually, we can fix our first expression for that we should change the convert method. What do you think we can do here to solve the problem? - Object is a pretty stupid type. It is the source off our problems here. We can leverage the power off dynamic typing. Starting from the dot net for Dynamic allows compiler to see the underlying type at run time so we can change the object. Type two dynamic and everything will work fine. If you are not aware of dynamic typing Google for it and read about the dlr in dot net 27. 06 Conclusion: congratulations. You reach the end of the section. You learned a lot, so let's briefly wrap up what he learned in this section. You learned that it is better to avoid over loads through inheritance. You also learn that it is better to avoid method hiding. Be careful with this feature. It can lead to an unexpected behavior. Sometimes it is better to turn methods. Arguments into properties from the A. P I perspectives. Optional parameters are almost never used in public AP eyes. Be careful with virtual calls from constructors. Avoid them when you can. Here is the sequence of constructing an instance of a type which participates in inheritance relationships. Remember that field initialize er's execute first. After that constructors get from the most derived type up to the top class in the hierarchy . Constructors start to execute one after another until the most derived glasses reached and executed at last, and finally the construction is finished. Remember, avoid calls. A virtual members from the base glasses you can to use this feature in order to impose calls on the derived type. Consider to redesign your FBI in such cases in the next section, we're going to learn a lot of very interesting facts about working with date and time values. I hope to see you soon 28. 01 Outline: Hi. This is Engineer Spark from engineers bag dot com, and the section is going to be somewhat unique. Yes, you'll see some puzzles in this section, however, it is not full of them, and the main goal here is to teach you some very important facts and concepts about which many questions are asked at Sea Shop Interviews. Iran A survey for some time ago about topics in which my students are interested in the 1st 2 winners are the following topics. Advanced. See shop puzzles and see shop. Interview. I decided to combine these two topics since they're similar in some points. By the way puzzles are very popular at interviews. I'm not sure if I'm going to create a separate course dedicated to see shop interviews. You'll see the most popular questions asked at interviews related to she shop here in this section. So we're going to cover the following topics. Abstract glasses versus interfaces. How to properly implement I disposable. What is encapsulation and what is the difference between encapsulation and information hiding? You'll see a simple example of proper encapsulation what is in turning and how strings are stored constant versus a read only lock versus Monitor. How to properly re throw exceptions and string builder votes a string. And it's possible that the section is going to be updated from time to time. Okay, let's get straight to business and learn the difference between Absar classes and into faces in the next lecture. 29. 02 Overloading Base Method: these lecture will teach you that there is no such a notion as to the bast match for a compiler. The compiler can only determine a batter method. So to get the first insight about how the compiler resolves methods, let's look at the following code. Example. Insured. We have two classes here. Juan is derived from another. The base class defines a method called Do, which takes an inter church s an argument. The derived glass defines an overload of that method, which takes an argument off type long the clients. Gold creates a new instance off the B type and passes an argument of top end. The question remains the same. What will be printed out to the console? - Taking into account what we learned concerning matching of generics, it would be logical to say that the do method will be called which belongs to Class A. However, that's not the case. Let's run the code to see what will be printed out in reality. Yes, I said, be sprinted out. Why this is so seems like do, which takes into he's a better match. However, resolving method overloads. The compiler uses the following rule. It searches for the match in the most derived time, and if there is any match, even not the best one, it will call it. The compiler even will not analyze the base class. This is done so because of the behavior of the derived class is preferred by default. Otherwise, changes in signature of that method in the parent class can lead to a situation when the compiler will call based classmethod instead off and overloaded in the derived class. That would be nonsensical from the client's point of view. The client, which inherited the base class and overloaded that method, will be unaware of such things. That would be quite strange. So once again, if we change the type of the base class methods argument to double and passing argument of type double, then of course the base glass method will be called Let's check it. This is because there are no mattress in the derived class. All in all, try to avoid overloads when we talk about inheritance. This is not the same as to override a method. Try to use different names instead of overloading. To avoid such collisions, 30. 03 Method Hiding: in this lecture, we're going to look at a practical case. I stumbled upon this case several times. Have you ever heard that you can apply the new keyword? Two methods? Declarations. If not, then you should definitely learn this lecture. If not, then you should definitely learn this lecture. Inheritance is not so commonly used as beginner, and developers often think inheritance is often used when building complex frameworks such as WP F or win firms. Small frameworks and the regular code rarely used inheritance. However, sometimes we really need to harness the power of inheritance. In such cases, you have to be familiar with some peculiarities. Let's look at the code I prepared. We have two glasses here. One is based glass and another one is a derived glass. The 1st 1 defines two methods. The 1st 1 is a regular one, and the 2nd 1 is virtual. The draft Glass overrides the virtual method and applies the new keyword to the first method. Look at the client's code. First, we create the base class instance directly. Second, we create the draft glass instance as the inheritor of the base class, and third, we create derived glass. Instance directly. After that, we have several calls. The question is what will be printed out to the console. - Overriding is the classic, a way in which your derived glass can have more specific behaviour than the base class. When a virtual method is called on an object, then the most derived version off the method is called. Hence, even though we're dealing with, is really derived as a base class, then functionality defined in direct glasses used hiding means that we have a completely different method. When we call right now on is really derived, then there is no way of knowing that there is a different right now. I'm on derive class, so it's not called. It can only be called when we're dealing with the object. As the draft class. You know, hiding is sometimes an accessory infrequently useful but generally bad. So be very wary off it of the writing is when you provide a new of a right implementation off a method in a disk ended class, when that method is defined in the best class as virtual at the same time. Hiding is when you provide a new implementation off a method in a disk and in class. When that method is not defined in the base class as virtual or when you're a new implementation does not specify override. Hiding is very often bad. You should generally try and not to do it if you can avoid it at all. Hiding can cause unexpected things to happen because hidden methods are only used. One called on a variable of the actual tap you defined. Not if using a base class reference. On the other hand, virtual methods which are overridden. We'll end up with the proper method version being called even when cold, using the base class reference on the child class. 31. 04 Property vs Method: Sometimes we face the dilemma to implement a certain member. Either it's a property or a method. The problem may seem obvious, but it's not even experienced. Programmers make mistakes when choosing between property and method. So what's the difference between them? Let's consider the first case. Sometimes methods may require more than three parameters. In such a case, you generally have three options. All the parameters, which can be set to a meaningful default state convert to properties, create a bunch of overloaded methods and create a method with a long list off optional parameters. Let's take a look at how this examples look in the code. All the three options have their own advantages and disadvantages. Let's consider them in turn. The first option of converting parameters to properties is not the worst one. It can make your A P I cleaner. The more parameters required by a method, the preferable this approach becomes. If a method takes four parameters where only the 1st 1 is always required, then you'll end up with eight method over loose to cover all the cases. There's another peculiar difference between the 1st 2 approaches. If you convert on required parameters to properties. And there are other properties with public centers which are relevant for other methods than how a client should suggest which properties are used by which methods. So if you stick with the first approach, then be sure that your class is highly cohesive. What means that all the methods used all the properties? You can extract glasses to achieve this level of granularity. The second approach with over lutes does not have this problems because the client always sees the available options directly through Intel incense. When calling to a method, though your code in this case tends to become a mass is, you can see the third option is the most beautiful, but the most inappropriate for public 80 IES. The thing is that it does not allow to at parameters without breaking existing clients and compile time. Let's look at an example here we have three optional perimeters, but what will happen if you want to add a new optional parameter? You can't just at a new parameter to the existing method, since it will break all the existent clients in the run time, it means that all the clients have to bear compiled in order to use your new version. I'll not demonstrate the runtime crash, but you can check it on your own. You also can't easily add an overload, adding a new parameter to the end of that overload. Why the things that after that, all the clients which called the first method version, will be broken? A compiler on the client side will say that it cannot resolve the difference between these two methods. Signatures. Let's look at it. You can see here that the compiler says that it sees ambiguous signatures. The last problem you should be aware of when using optional parameters is that the default values get backed into the COLLI into code. Thus changing the default value will have no effect on existing clients without Rick compiling their code. That was the first concern regarding methods and properties. Now let's look at the semantic difference between properties and methods. I remember you should great properties as simple as you can. They should not throw exceptions in getters. They should not connect to database, and they should not be a synchronous the most notorious fail of creating a property inside the BCL in dot net instead of a method is the date time now property. In my opinion, this particular case is not the worst in history, though it's an embarrassing one. So what's wrong with that? The daytime now is implemented as a property rather than a method. This is not wrong. From the point of the actual implementation. It is implemented correctly. The point is that this is semantically wrong from the A P. I design perspective. If every time the getter of a property returns different values, then this is a method, not a property white. Because the property is a natural, beautiful entity. For example, year is an attribute off a date, so it would be correct to get the year as it follows. Yes, that's it. That's how it should look like. Not like a chain wreck, By the way, similar to the case, Green, you greed member is implemented a PSA method. In this case, there were new dictates that this should be a method, but for example, they could have named it greed next, And even in this case, it should be a method as well as the daytime. Now I'll show you the example off misusing a property from my own practice. So there was a simple window which was implemented without MVV m and all this stuff in the Zamel CS file was a string property which in its centre, said the text in a text block and for some reason it did it a synchronously using application Current dispatcher begin invoke method 10 minutes. I couldn't understand why the following code didn't work as expected. Don't think about the secret meaning of this code. The point is that the color of a property center never expects that it will not be changed immediately. In this case, the center unintentionally deferred its work. If the property is stately, semantically coupled with the y, and you want to use such a nice in construction than the property, at least should not be a part off a public contract. To recap. I should say that properties and methods are very different from the perspective. Off usage scenarios use cases say no toe any multi threading synchronization, externally pickles, CPU intensive calculations and even simple. Yet each time returning different results pieces off gold inside of your properties 32. 05 Impl Abstract Classes: really you'll often create your own class hierarchy. Ists. I wouldn't say too often, but sometimes we really need to harness the power off inheritance in Opie languages. In this puzzle, I want to say a couple of words about abstract glasses. At first I want to give a couple of general advice is regarding abstract glasses implementation. And after that we will get to the actual puzzle. I want to mention three important things regarding abstract glasses. Implementation. The first advice is never exposed. Public constructors in abstract glasses No one can create an instance off a Napster class with us. This is absolutely meaningless. To expose public constructors, consider in bad design and good design. Take it as an established agreement between C shop developers. As the second advice, I would say that you shouldn't start from cramming all the reusable stuff into the absurd class, implements some minimum amount of logic in the Absar class and then implement at least one inheritor. This will help to better understand the hierarchy before you'll force inheritors to bear unwanted members and logic from the base glass. And now we get straight to the puzzle. Let's switch to visual studio and look at a very unfortunate behavior that can be caused by inaccurate implementation. So the third consideration concerns the initialization problem. Sometimes you want to enforce some kind off initialization in the abstract class by calling virtual methods, which should be overridden by inheritors. Here you can see that the device Absar class goals a virtual method from its constructor. This method is called initialize, and it is marked by the abstract keyword. That means that an inheritor has to implement this method, so the developer off the device glass, wants to force the initialization process. And don't forget that we write a log, a record here in the constructor before the virtual call. The second glasses named Phone Here and Eat, inherits from the device glass. Let's consider how it is implemented. The phone class defines infallible read only Bolan Field called WiFi module his own and false is assigned to this field right here. This is done so because off a tricky behavior you'll see soon this field is initialized within the phones constructor, right after writing a symbol logging record constructor, it's signs true to that field. The implementation off the initialized method just writes a logging record about the state off the WiFi module. The client is very simple. We just create an instance off the phone class and called the initialized method. So the question is what will be printed out to the console? Pause the video, take your time, think a little bit right down your answer, and then compare it with the right one. - I'll around the application. And here's the output. The most astonishing thing here, for many see shop developers, is that the first record is made from the base glass constructor. How's that? Why we create an instance of the phone class. But the first constructor being called his base class constructor and then sort of spirit is simple. Any constructor off the derived glass at first calls the constructor of the base class, and it will happen until the end of the hierarchy. Reaching the end, the spiral starts to twist back. Constructors of based glasses, one after another will be executed until the constructor off the most derived glasses being reached in our case. The sequence, of course, is the following. The phone's construct recalls the devices constructor scenes device doesn't inherit from other classes. Its constructor gets executed in the constructor. There is a call to the initialize method, which is overridden in the derived class. This goal drills down to the initialized method off the phones class. Since the phones constructor has not been executed yet, the phones object is not initialized properly. One would think that since the phones object has not been properly initialized yet, the value off the fuel should be now, since now is the default value for any available type. However, we see forcing out. This is because field initialize er's run even before constructors and only after the construction is finished. We make the second call to the initialize method, and only now we get the value expected to see. There are no exceptions and no real harm in this example related to that ugly virtual call in the constructor of the base class. However, imagine what could happen if you work with the UN initialized object off the derive time literally anything could happen, and this is very dangerous. For example, if we had a non primitive callable field and tried to make a colony, we would get a null reference exception. Long story short. All this stuff smells badly again. Let's repeat one more time. If you make a virtual method, call in a constructor and it is not the most derived type in its inheritance hierarchy that it will be called on the class whose constructor has not been run and therefore may not be in a suitable state to have the method called. Okay, then let's get to the conclusion. Let's wrap up what we learned in this section. 33. 06 Conclusion: congratulations. You reach the end of the section. You learned a lot, so let's briefly wrap up what he learned in this section. You learned that it is better to avoid over loads through inheritance. You also learn that it is better to avoid method hiding. Be careful with this feature. It can lead to an unexpected behavior. Sometimes it is better to turn methods. Arguments into properties from the A. P I perspectives. Optional parameters are almost never used in public AP eyes. Be careful with virtual calls from constructors. Avoid them when you can. Here is the sequence of constructing an instance of a type which participates in inheritance relationships. Remember that field initialize er's execute first. After that constructors get from the most derived type up to the top class in the hierarchy . Constructors start to execute one after another until the most derived glasses reached and executed at last, and finally the construction is finished. Remember, avoid calls. A virtual members from the base glasses you can to use this feature in order to impose calls on the derived type. Consider to redesign your FBI in such cases in the next section, we're going to learn a lot of very interesting facts about working with date and time values. I hope to see you soon 34. 01 Outline: Hi. This is Engineer Spark from engineers bag dot com, and the section is going to be somewhat unique. Yes, you'll see some puzzles in this section, however, it is not full of them, and the main goal here is to teach you some very important facts and concepts about which many questions are asked at Sea Shop Interviews. Iran A survey for some time ago about topics in which my students are interested in the 1st 2 winners are the following topics. Advanced. See shop puzzles and see shop. Interview. I decided to combine these two topics since they're similar in some points. By the way puzzles are very popular at interviews. I'm not sure if I'm going to create a separate course dedicated to see shop interviews. You'll see the most popular questions asked at interviews related to she shop here in this section. So we're going to cover the following topics. Abstract glasses versus interfaces. How to properly implement I disposable. What is encapsulation and what is the difference between encapsulation and information hiding? You'll see a simple example of proper encapsulation what is in turning and how strings are stored constant versus a read only lock versus Monitor. How to properly re throw exceptions and string builder votes a string. And it's possible that the section is going to be updated from time to time. Okay, let's get straight to business and learn the difference between Absar classes and into faces in the next lecture. 35. 02 Concepts: people tend to make assumptions and use approximations, talking about time and measuring it. For example, we easily can say that now is 11 40 a meeting the seconds completely a computer can do that computer also doesn't have sense off a M or B. M. 11 hours, 14 minutes and 30 seconds are usually represented in PC as this. If you have some programming experience, Human noticed that actually, we very often need a finer precision than seconds off course. We also have milliseconds and even nanoseconds. So, most likely in the previous example, we around it the final value. Maybe it was a little bit last than 30 seconds. Maybe it was 29 800 milliseconds. Daytime structure in dot net about which we're going to talk about in much more details later in the course, supports precision off $100 seconds What is also called a tick. So in the end of the current time and PC mammaries, just an integer value may be a long one off course. In then stored in binary, every computer has a special clock cheap, which provides certain precision. Computer clock chips are not as precise as atomic clocks, which defined the only one absolutely correct current time. That's why operating systems implement the feature of times in Quran ization. Another question is how computers track time. They can't be in sync with you to see it. Every point on the timeline continues. Synchronization would be at least inefficient. So operating systems implement the anti P protocal to synchronize local time on PC with UTC From time to time, UTC stands for coordinated universal time. Don't ask me why it is called UTC instead off. See you t. There is an explanation. Just go to Wikipedia if you want to know more, so you to see nowadays is the motor in time Standard UTC is based on Thai, but they're not equal as off 31st of December in 2016 when another leap second was added. Tie is exactly 37 seconds ahead of UTC. The difference in 37 seconds results from the initial difference off 10 seconds at the start off 1972 plus 27 leap seconds in UTC since 1972. So since 1972 you to see is the civil time standard. UTC is the primary time standard by which the world regulates clocks and time. Universal time lasts continuously without any transitions to daylight saving time. We'll talk more about daylight saving time in the corresponding lecture. For now, you should understand that universal time can be represented. It's an infi Nite continue scale countries except universal time as the standard on which local times are based. We will talk more about local time in the lecture about time zones. Jim T is another common abbreviation, which stands for Green, which, meantime, this is the mean solar time in London. Jim T. Was formerly used as the international civil time, but now it's completely superseded in that function by you to see. For most purposes, UTC is considered interchangeable with Jim T. But GMT is no longer precisely defined by the scientific community. The only thing you should know is that in 99% of cases you should say you to see and right UTC you can almost forget about Jim T. Jim T and UTC are completely synchronised nowadays, so you can consider Jim T or you to see is the reference points. Yes, I mentioned before they're used to define the local times or time zones. UTC is synchronized between devices by the anti P. The protocol will write a mentioned Now let's briefly touch the topic off time zones. Perspective is a little bit harder to grasp. The concept of his cope perspective defines the source off time or where it lasts. It may sound a bit vague, but you'll understand everything any minute. The 1st 1 perspective is called unspecified. When you create a daytime, valiant see shop, the perspective of the value will be set toe unspecified by default. The daytime structure contains a property which is named daytime kind, and it supports three modes, unspecified local and the UTC. So what is unspecified? Unspecified means that we don't know where from the time value came from. Here's an example. Look at this data value. The problem with this value is that we don't know where it came from. Is it a UTC value or the time value from the Washington Time zone? No one knows, and this may lead to unfortunate consequences. Since we can't perform any mathematical operations on such a value, we don't know if this is a UTC, and if not, what is the offset from UTC? We don't know who's time is it? It doesn't mean that daytime values with unspecified perspective cannot be useful. Such time values are called floating times. Here's a good example. Let's say we want to broadcast a TV show at 8 p.m. In different time zones. So in each time zone, the TV show will be shown at 8 p.m. But in reality, that would happen a different moments on the UTC time line because off various offsets from UTC in various time zones, so we can use floating times in such scenarios, it can be helpful. Such time float from one time zone to another, and that's why it is called floating. The key moment here is that the value doesn't change in different time zones. Another perspective is the UTC perspective. Here's an example of such a value You to see is the most useful and less error prone perspective. Since it represents an other biggest moment on the global timeline, it's very convenient to use from the pro grammatical point off you. It is very hard to calculate something wrong when calculations are based on the universal time. Another perspective is gold local. The local perspective is what people usually imply when they use the unspecified value, by the way. But these are different things, and developers have to understand that we usually don't know to the local perspective by using either the offset or the time zone identify or the time zone segment. The local time sat with an offset is not a bad way of representing local time. It represents an unambiguous moment in time as well as the global perspective. The second way is to use the name of a time zone. Using this way, we can take into account transitions between DST and standard time. The third way is the worst unfortunate. There is no standard for abbreviations. CST may mean central standard time in the U. S. Or Central standard time in Australia China list under time and other, you can display the time valuers in this format with local perspective only for the end user. Never use it internally in the applications business. Logic finally, and this is the best way of denoting the local perspective is to use both the offset and the time zone name. This format preserves all the necessity information related to the current time in the specific time zone. Knowing the offset, we don't need to dig the database for retrieving it and knowing the name of the time zone. We convict the history of timekeeping rules in this particular time zone if we need to. The zone daytime type from the nota type library supports the last and the best for mint off working with a local perspective. 36. 03 General Puzzles: in this lecture, we're going to consider some finding general puzzles about dates and times. And here's the 1st 1 taking into account that the fifth off October in 15 82 doesn't exist . How do you think what will happen if we write the following code in C shop using standard Basile Library? If you thought that there would be an exception, you are wrong. Nothing bad will happen. That date will be created successfully. Why is this? So? One might ask, and the answer is quite simple. The default calendar behind the daytime structure is the Gregorian calendar, and the Gregorian calendar is the so called prolactin calendar. Prolapse tick means that we pretend like the Gregorian calendar was always in a fact. So all dates are still there in they're all valid. Yes, I already said not all the problems are related to human beings. Some of the problems are caused by the universe itself. Even Children know that there are 60 seconds in a minute. So if you're a smart guy, answer the following question. How do you think? Is it possible than one minute can last 61 seconds? If yes, why? I say no it's impossible. But what do you think? And here is the answer. Have you heard about leap or so called coordination seconds? The thing is that the rotation speed of Earth is not constant. It slows down a little bit on from time to time. We need to introduce that leap seconds. Sometimes we introduced them once in a year, sometimes once in a couple of years. Why is this important? The importance of such things depends on the case for coordination off events in space. It might be very important to keep track off leap seconds, especially in high frequent scenarios. Most people are not concerned about leap seconds and even have never heard of them. That's because no one cares off such time recisions. But you as a programmer always have a chance to stumble upon problems related to time measurement. Everything depends on the type of software you're working on. For example, in 2016 December 31 at 59 59 59 b. M, the next tick will set the falling time. In reality, the Universal coordinated Time will just pretend that the last 59th 2nd in the year lasts two seconds. Instead, of one. Do you think that no one cares about leap seconds? If you think so, then you are wrong. Your clocks on your PC take into account those leap seconds. Since they're synchronized with UTC, the anti P stands for network time. Protocol is a protocol off time synchronization that makes PC's all around the world aware of flip seconds. Synchronization of clocks sometimes plays a very important role in people's lives. Here's an example. Did you know that a day on Mars? Leszcz for 24 hours and 40 minutes? So people who observes and controls the rover on Mars have to wake up 40 minutes later every day to keep their lives in sync with life off that rover. This is because the rower has to operate at certain hours on Mars. Can you imagine how hard it is to leave such lives? People eventually end up waking up at night. It is just plain craziness. Anyone knows that the 29th of February doesn't exist. Non leap years. How do you think? Is it possible that the 30th of December didn't exist somewhere and not in the far past? I'm talking about modern days. Indeed, on 29th off 2011 at midnight. Some are in island in the Pacific changed their offset from 10 hours behind UTC, too, 14 hours ahead of UTC. What caused this? Keep off the December 13th. If you are interested in why Samadi this you can visit the link I attached to this lecture insured prime minister of some are sad in doing business with New Zealand and Australia. We're losing out on two working days a week while it's Friday. Here it's Saturday in New Zealand, and when we're church on Sunday, they're already conducting business in Sydney and Brisbane. So that transition helped to conduct business with other countries very much. How do you think? Is it possible that four transitions can a cure during the year in a certain time zone? Indeed, it can be in Egypt in 2010 and Morocco in 2013. There were four transitions during the year. The conclusion is that working with date and time values, you have never, ever assume anything. Your assumptions will be wrong. The only way is to rely on the time zone database named Diana. If you want to learn more than take my course date and time Fundamentals in the Net and sequel server 37. 04 DateTime Roundtrip Puzzle: I live in Moscow, Russia, so I'll show you an example with my time zone. Moscow time zone rules were tweaked several times, so it is simple to use it. For example, one of the last transition in the Moscow time zone a cured in 2014 the 26th off October at 2 a.m. Clocks were shifted on one hour backward. Let's think logically. Before that transition Moscow time zone was four hours ahead of UTC. After transition, it became three hours ahead of UTC. Thus, for example, 1 30 after midnight on the local time, a cure twice the first time it took place on the 25th off October at 9:30 p.m. And the second time on the same date. But at 10 30 PM with all that said, Let's great to date time instances with a you to see perspective, you see the gold snippet on the slight. After that, we convert both instances to the local perspective on my machine, where the time is only set to Moscow separately. I compared to results after that conversion. If you call to string in I sir format on local one and local two instances you'll see the values I commanded out above those instances. And here's the interesting question. What will be printed out as a result, off local one and local to comparison, the right answer is true. Date time just compares date in time and doesn't take into account the perspective at all. Thus offsets will just be omitted uring the comparison. Let's go further. Here is the same example. The only difference is that we're interested in the second value. The first value is the same as in the prayers example, and we talk about the Moscow time zone Look more closely here when I do seems nonsensical, since I explicitly said the kind off local one to the same kind, I just reset it local to local. Reasonable and meaningful implementation will just ignore such a call. Okay, After that, I convert both values with the local perspective back to you to see and bring out the time part. Without aid, the date will be the 20 feet off October. So the question is, how do you think what will happen with time in both cases thing? And here's the right answer. The first value was correctly converted back to you to see. It was set to 9:30 p.m. Cool, while the second value, which had to be a full clone off the 1st 1 somehow was shifted on the one clock had. How the hell is this possible? Why, without that magical reset of the perspective, the value can be converted back to you to see correctly and with their set, it can. Why? Let's reveal what the hell is going on here. The daytime stores time and perspective in a 64 bit field off top and signed long. The 1st 62 beats store the number of ticks from the midnight off the year won the first of January. In the remaining two beats, it stores the value off the daytime kind. Two beats can store four values, and the daytime kind of liberation has only three unspecified the local and the UTC. But there is a secret one he didn't perspective. The time defines the following constant to represent that secret perspective. Here it is. It is called kind, local, ambiguous DST cool name. Yep, the problem is hiding in this secret state. It allows date time to take into account transitions between standard and daylight saving time after conversion from UTC to local daytime sets its perspective to local ambiguous DST instead of keeping the value local. It seems like it is a cool feature, since it allows the time to perform a round trip conversions without data loss. But if you think carefully, you'll realize that the date times a p I lies to the user about its perspective. What leads to great confusion and unexpected behavior? The intention was good, but the implementation is horrible. Such an A p I allows to show some badly documented magic. As you saw in this example, the time actually can work with offsets, but the support of offsets is very limited. You can't set an offset explicitly. For instance, that's why another type was implemented by the dot net team. It is named daytime offset. 38. 05 Arithemic on Dates: arithmetic on dates is all about dark magic. Let's start with an example. I noticed that it seems like math works somehow differently than usual here. For example, if you add one month and one day to 28 or 29 off January 2017 in both cases you will get the first off March. However, if U. S symmetrically subtract one month and one day from the first of March 2017 you'll get the 31st of January 2017. In math. Backwards operations usually result in the initial value, but in this case is you see it doesn't happen. You should be very careful working with aromatic on dates, especially if you decide to write your own daytime type. Look it another simple example. At first we create one date, then we create another one, adding one year to the 1st 1 What will happen? The argument out of French exception will be thrown. Since 2017 is not a leap year, which doesn't have the 29th of February. However, you can at the year correctly, working with the daytime type arithmetic on dates is implemented by special methods. Here they are for adding you should use methods from add years to add milliseconds for subtracting. You can use the same methods with negative values. Let's look at what will happen when we have some time to a daytime instance, crossing the transition to a standard time. I use the same example in Moscow time zone again, where transition to a standard time A cured on 26th of October in 2014 at two AM, I add toe hours to the initial value, crossing the transition moment. The question is what time will be. Bring it out to the console and here is the answer. The date time, even with the local perspective, doesn't take into account any transitions. All the things the date time will do is that it will just at the number of past in hours and said the correct offset according to the result. After adding in this case, the output will be 2 a.m. with offset said 23 hours ahead of UTC daytime officer doesn't solve this problem. It also doesn't take into account in your transitions so you can end up with the wrong value. Performing such operations in order to correctly add two hours crossing a transition. You need to convert the initial value to UTC firstly, then add two hours and finally convert back to a certain time zone. Here is a code snippet How you can achieve this? The result will be correct here while I am with the offset set to three hours ahead of UTC . 39. 06 Calculating the Age: a separate interesting topic is the problem of calculating the age of a person. It seems like calculating the age is a trivial thing. However, it's not a simple as it seems. If you Google for how to calculate the age of a person into the shop, you'll find dozens of answers that provide the following function. You see that function on the slide. What this function does is that it subtracts the birthday from the current date and then divide. The result on 365.24 2199 2400 provides a correction for leap years. For most of cases, this function works fine, but it's not sufficient to have a function which doesn't work in certain cases. For example, according to this function, a human born on the second off March 2007 in the newly Pierre will be in age of one year on second off March 28 which is a leap year, while a human born on second of March 2008 which is a leap year, will be in age off zero years on Second of March in 2009 which is a non leap year. Don't ask me why is this so the short answer would be It's just mathematics. Nothing personal. Another problem with this function is that it relies on daytime. Now we don't know whose birthday it is. Depending on the times on, the difference in one day may easily a cure. Let's look at the correct function. This method takes a birthday and the time zone for which we want to perform the calculation . At first, it converts the current time on UTC to the current date according to the requested time zone. After that, it calculates the difference in years. And if the birthday hasn't a cured yet in the current year, subtract one year always pretty simple and works correctly for any dates. However, there is still one corner cases hiding. Question is, which day should we treat as a birthday non leap years for persons who were born on 29th off February in a leap year? The thing is that in different countries, law defines this case differently. Some countries state in a law that the birthday should a cure on 28th of February, while other countries stayed that it should a cure on first of March. This function implies that in this corner case, the birthday should a cure on 28th of February. You might think that this is a bullshit. Who cares about such things and you would be wrong. This is a very important thing from the law. Point of view. Criminal code has to define the precise way of calculating a person's age because it needs a way to determine the day when a person becomes criminally responsible. Here is the function which calculates the age and in the corner case we discussed the second ago. It implies that the birthday should secure on the first of March. In this case, we explicitly check the month and the day. So the birthday in that corner case will a cure on Lee on the next month on the first of March. There is not a quite exotic case. Don't laugh at it. Uh, though, why not laugh if you want to. So here's the story. Assuming that the baby was born on 31st off December 2016 how many years will that baby being on first of January 2017? And here's the answer. It would be illogical to answer that the baby will be zero. You resolved. However, in certain East Asian cultures, the baby would be two years old. How this is possible, you may ask. The thing is that in that cultures they start to count age from one, not from zero, and they increment a number of years when a person crosses a New year, not on their birthdays. Sounds crazy. Yes, it does. And this is the world will. Even so, if you write software for some Asian fortune teller, don't forget about such a peculiarity. I've heard about an interesting case on a Moscow .net meet up. Developers from Kaspersky told that once they got reports where they discovered the following problem daytime. Now, through exceptions, they started to investigate the problem. And finally they found out the reason off that unfortunate behaviour. There were dozens off users who somehow said the current year in Heber calendar to something like 8906 and those users real had that culture as the local of their machines. I mean, hey bru. Nowadays it is 5777 year on habit calendar, the year 8906 on the Hebrew calendar due to differences in the length off years inhabit and Gregorian calendars resulted in roughly a year 13,000 on the Gregorian calendar. Daytime supports the year 9999 at Max, so the date out of French exception was thrown. If you want to work with different calendars, I would strongly command you to use the note a time library. 40. 07 Conclusion: what problems related to standard daytime tops do exist. First, along the section, we found out that the local perspective is highly deceptive. Local implies the local time off a certain machine without involving any time zones. The local time zone is used, but without keeping all the time zone related information along. Second, the local perspective silently gets dropped after crossing any bound er's. You passed date time to the third party, and they will be completely unaware of where from this time value came. If that third party passes you back the time value, you also lose any possibility to determine the source of that value. Third, daytime hides rotten eggs in the form off. Seek implementation off. Tracking the perspective. You saw the problem on the example when we performed a round trip conversion off a value which is on the verge of a transition. We used UTC and local perspectives and figured out that daytime hides another secret option called ambiguous DST, which allows to demonstrate some magic. Fourth comparison off to date time values completely ignores the perspective and offset few . The major drawback off the daytime offset is that this time doesn't present a certain time zone. In reality, the instance of daytime offset can be created from a certain time zone. However, the instance itself doesn't carry any time zone related information except the offset. As you remember at time Zone is not an office it and this is the problem. Despite that problem, the advantage of the daytime offset is that it presents an unambiguous moment on the timeline you to keeping the offset. That's why these type is not so bad for arithmetic operations on date and time valuers and conversions between time zones with help off the time zone in FA type. Now a couple of words concerning the time zoning for class the most significant disadvantage off the time zone in for it's not the fault off the times. Only in for type is that it is based on the Microsoft Time Zones database. In cases when your application has to massively work with time zones, tracking events in the past scheduling events in the future, you'll face old times on naming, resulting in the necessity to map of those old names two names in i n a database and possibly you'll face the problem off a shallow history of changes in time zones. In fact, the database from Microsoft stores some incorrect and incomplete information about transitions between standard and daylight saving time in certain time zones. I'm not going to demonstrate you those box. I'll just attach the link to a block post where John Skit show such box. Taking into account all the things you learned in the section, it becomes apparent that B cell lacks a top that can unambiguously defined a moment on the timeline, keeping all the information about the time zone simultaneously. It is apparent, as well, that BCL lacks types that can represent date and time values separately, using daytime values. Ignoring one part or another is not the Samos using special types for presenting dates and times separately. In general, a P I off date and time related types in BCL is very subtle and hides many people so you can easily stumble upon AP I off Basile. Daytime related types allow you to work with date and time valuers without an understanding off what is going on under the hood. It might seem that it's a good thing when an a p I hides internal details. However, this is really good when it's done without fooling the user. A user for Nipah has to understand the behavior semantics, off objects he's working with. While those AP eyes are hard to understand, in many cases, thanks Roberts in the majority off cases. If you understand the internals of BCL daytime early, the types you can write reliable code that works with date and time values. However, if your application works with date and time values massively, if it should implement scheduling events in the future. If it digs historical dates, then I would stronger command you to stick with no time library or quartz enterprise scheduler dot net Depending on the requirements. No, the time replaces older standard types with a much more reliable FBI. Quartz is more suited for scheduling. Both projects are open source. It is not sufficient to know about problems and pitfalls. Off date. Time related tops, toe work with date and time. Baylor's properly. Don't forget that arithmetic on dates is very tricky. It's very hard to implement your own arithmetic on dates and use accurate formulas to calculate age. Strive to take into account a time zone, and don't forget about the 29th of February. Pate fall 41. 01 Outline: Hi. This is Engineer Spark from engineers bag dot com, and the section is going to be somewhat unique. Yes, you'll see some puzzles in this section, however, it is not full of them, and the main goal here is to teach you some very important facts and concepts about which many questions are asked at Sea Shop Interviews. Iran A survey for some time ago about topics in which my students are interested in the 1st 2 winners are the following topics. Advanced. See shop puzzles and see shop. Interview. I decided to combine these two topics since they're similar in some points. By the way puzzles are very popular at interviews. I'm not sure if I'm going to create a separate course dedicated to see shop interviews. You'll see the most popular questions asked at interviews related to she shop here in this section. So we're going to cover the following topics. Abstract glasses versus interfaces. How to properly implement I disposable. What is encapsulation and what is the difference between encapsulation and information hiding? You'll see a simple example of proper encapsulation what is in turning and how strings are stored constant versus a read only lock versus Monitor. How to properly re throw exceptions and string builder votes a string. And it's possible that the section is going to be updated from time to time. Okay, let's get straight to business and learn the difference between Absar classes and into faces in the next lecture. 42. 02 Abstract Class vs Interface: the majority of experienced C sharp developers think that they understand the difference between an abstract glass and an interface very well. But when I asked Developer to explain the difference, I hear almost always the same answer, which explains only the mechanical difference between the two concepts. However, there is a deeper semantical difference between them. But first things first. Let's consider the mechanical and semantic difference between abstract classes and into faces one by one. The main mechanical difference is that an abstract glass can have a default implementation . Whereas an interface is just a bunch of member declarations. It defines their signatures. Here we clearly see that the abstract glass is capable of defining virtual members with implementations. The interface is not capable of doing such things. Let's talk about the semantic prelude off abstract glasses and interfaces. Very often, you can hear that interfaces defiant contracts. This statement becomes more convincing with the fact that we treat into faces and contracts equally in W. Cf. In W. C. F. A service contract can only be represented by an interface in the real world, including the real world. Outside of programming contracts have some semantic paled usually they determine some kind off relationships between people, writes objects and so on into faces have no any semantic payload. They determine nothing except signatures, but signatures don't bearing a significant semantic payload and into face represents just a shape. Thus, interfaces are not contracts. Here's an example Off a true contract provided by Christoph Kulina. This contract says that when an item is added to the collection, the Count property is incriminated by one. Also, this contract is locked for all subtypes. This is a real contract. Since it imposes semantic. Let's consider the difference between an abstract class and an interface from the A. P. I design point of view into faces are made of stone. They can be easily changed without breaking existing clients at the same time, into faces are easily extendable by clients. A client can extend an interface by extension methods, and by the way, if a client wants to implement it into face on a class which already inherits from another class, a client can easily do that. A client couldn't do that with an abstract class instead of an interface, since multiple inheritance in C sharp is depreciated. So in the end and interface is more supple from the client's perspective. Any class can implement this many interfaces as it wants to, Unfortunately, and into face is more rigid from the developers perspective, it cannot be easily changed, and it doesn't support reusability. An abstract glass supports reasonability off logic. It supports encapsulation, and it can be extended without breaking existing clients. So in the end, an abstract glass is supple from the developers perspective and more region from the client's perspective. With all that said, it's become clear why AP I developers so often used abstract glasses for building internally guys while into faces for providing external points off extension. Remember, this is not a dogma. Every design case is unique. The goal of this discussion is to give you a deeper understanding of the difference between abstract glasses and interfaces. Let's look at an example from an open source project. The Beat Matt Tricks is an abstract glass, which exposes a lot of her usable code. The square bit metrics of arrives the width and height and reuses the base class logic while stays abstract by itself, the hierarchy goes even deeper. I will not provide gold examples off interface from the BCL. Just recall that BCL provides the I collection. I at least I notified property Changed and towns of father interfaces. This is done so because extensive bility from the client's perspective is more important. In these cases, you can find a great example off extends ability, problems connected with interfaces and Absar classes in the book Framework Design Guidelines by Christoph Kulina. You'll find this book on Amazon. I attached the corresponding linked to this lecture. 43. 03 Implementing Dispose Pattern: very often you'll be asked at interviews about the disposed pattern. Why do we need it and how to implement it? Why do we need finalize er's in this lecture? I'm going to give you the answers, debunking some myths along the way. The FC being C sharp developers, we write managed code. It means that the common language runtime CLR inshore takes responsibility for managing memory automatically. As a consequence, we don't need to the allocate memory manually for explicitly the garbage collector GC insured automatically removes all the eligible objects from memory. These significantly simplifies the software development under the dot net platform. Unfortunately, this is not the end of the story. The dot net platform does not leave in a vacuum and a meaningful program. Acquire system resources such as files, handles, sockets, de beacon actions and so on. If you forget to remove them from memory, then you likely will get a so called memory leak. Garbage collector will remove the managed object, which contains an unmanaged resource from memory and as a result, that unmanaged resource will consume memory until the program will be closed. The dot net framework provides to capabilities intended to deal with unmanaged resources. Firstly, the system object, which is a route for all the types in C. Sharp exposes of the virtual finalized Method GC calls the finalized method before reclaiming the memory allocated for an object in the heap. GC calls the finalized method only for the objects which override the base finalized method Objects which override the finalized method are called Finalize Herbal GC adds Finalize herbal objects to a special finalization. Cute. The support of the finalization mechanism provides a seam for inserting the code which releases unmanaged resources such as in PTR. The finalization mechanism has some peculiarities. Let's consider them the moment off. Finalization is undetermined. This completely depends on the wheel off the CLR. You can't force the seller to finalize a particular object by any means as a calorie. You can be sure about the current state of the program at the moment when finalization starts. When CLR finalized an object, it boots off the actual reclaiming of the Objects Memory GC will reclaim the memory on in the next collection process. This is quite unfortunate in high performance scenarios. The second feature is provided by the BCL itself. It is the I disposable interface which exposes on lee one method. Avoid dispose. The intention of this method is to allow the explicit removal off the unmanaged resources. One of the side benefits of the eye disposable interface implementation is that such disposable types can be used in the using statements. Consider the following code sleeping. This code will be compiled as the following. It guarantees that the object wrapped in a using statement will be disposed very handy. That was a brief introduction into the disposal mechanisms since the shop. How do you think? Do we need to implement I disposable and override the finalized method at the same time each time we deal with acquiring resources. To answer this question, let's start with a classic disposed veteran proposed by the DOT net team long ago, who have a class named resource holder here which implements the both the I disposable interface and the finalization method. These glass contains two different types of resources and unmanaged resource off the in PDR type and managed resource of the safe handle type. It is important to understand that we have only two types of resources in .net, managed and unmanaged how to distinguish them well. Unmanaged resources are represented by the interpreter rapper and pure unmanaged memory. Allocated with unmanaged code. All the other resources are managed. If a resource contains the unmanaged resource but implements I disposable along the finalized method, it is a managed resource so safe I'll handle is a great example of a managed resource. Safe I'll handle contains an unmanaged resource inside itself, but safe I'll handle should be treated as a managed resource, since it takes all the responsibilities to dispose its internal and managed resources. If someone forgot to call the dispose method off a say file handle in the end, CLR will called finalize er of the safe I'll handle so we will not get a memory leak. Next, let's look at the dispose method. It goes the virtual dispose method passing true as the argument. The dispose method, which takes a Boolean flag, is a method which actually performs all the cleanup. After calling the dispose, there's a call to GC. Suppress, finalize passing these as the argument this call insurers so that the CLR will not call the final Isar. We need to suppress finalization since we know at this moment that the manual cleanup is going on, there is no meaning to finalize the object. The flag, which we pass as the argument to the virtual dispose method, determines the mode of cleanup. True means that we're doing a manner or explicit disposal. We pass false from the finalized method. Remember that you have to first lick all the dispose method, and only after that suppress finalization, not vice versa. This is because finalization should be suppressed Onley if the object is successfully disposed. This is an unfortunate temporal coupling between these two calls about which you should be aware of and remember it now. Remember that in the case off explicit disposal, we need to dispose both the managed and unmanaged resource is where, as in the case of finalization, we should clean on land managed. This is because we don't know the state off managed resource at the moment of finalization . Moreover, since we're already in the finalization stage and we have already missed the opportunity to gain some performance benefits, there's almost no meaning to clean up managed resources. The second reason is that you actually can't predict the state off managed resources at the stage of finalization. One would say that this is too complicated and I would say, Yeah, exactly. This is really too much. We started from simple things and with what we ended up, we ended up with a complicated pattern where we have to know all the peculiarities in order to avoid troubles. Can we avoid such a complicated approach for disposing resources? Yes. Actually, we can look at this code. Don't you feel that there is something wrong taking into account that presumably this glass contains some useful business logic except storing a couple of resources. This glass violates the single responsibility principle, except it sound responsibility. This class has to deal with disposing and unmanaged resource. The problem arises from the fact that we mixed here both managed and unmanaged resources. First of all, for almost all existing unmanaged resources, we have special managed rappers in dark Net. Such a safe I'll handle in 99% of cases, you can rely on them if you have to deal with in PTR or you want to create your own type, which works with memory directly through the unsafe gold, then it would be better to roll out your own managed rapper like safe I'll handle. What I want to say is that you always can avoid the design where you mix managed and unmanaged resources. If your class contains only managed resources, then you don't have to implement the final Isar since it will be actually meaningless. The only thing you want is to implement the I disposable interface, if declined consciously used to the dispose method than everything just fine and still professed regarding the mammary cleanup. If a caller forgot to manual, dispose your object, then it's not so bad because your object contains only managed resources which implement finalize er's internally. Thus, no memory leaks will a cure. So only the most low level objects which directly work with memory through the unsafe goat have to implement. Finalize er's S a Corolla re. We can say that in 99% of cases, you don't need to implement the finalization method. Just implement that I disposable and you'll be fine. Finally, I want to add a couple of rules on implementing disposal mechanisms. If the disposable class is not sealed, then you have to define the dispose method which takes the Bolan flag s virtual. Since there can be inheritors If the disposable classes sealed, then you have to make that method private. The disposable object can also keep track off its state in a field like boo is disposed. This field will serve as an indicator off the current state. You can check this flag in public methods and throw the object disposed exception in the case, a color tries to use the disposed object. All these nasty checks can be compiled in automatically by a library named for the janitor . Check out the link attached to this lecture. If an application domain gets unloaded, then there is no guarantee that finalize er's will be invoked. If you want to finalize an object even in such circumstance, like unloading off the application domain, then you need to inherit your finalize herbal object from the critical finalize er object glass. This gives some additional, but we guarantees. First, finalize ER's off. Such types are pre compiled by Jeet, so in the case off insufficient memory finalize ER's will be invoked. Most likely second CLR guarantees that finalize ER's off types, which do not inherit from the critical Finalize er object, will be invoked before those which do so. Actually, it means that if your class does not inherit from the critical finalize er object and it contains a safe handle which does inherit the critical finalize er object, you can use that safe handle in the final Isar. Since you can be sure that safe handle will be collected after your object. But s we have already discussed implementing your old finalize ear's is an extremely rare case. In the end, I just want to show you the simple version off the I disposable implementation where you don't implement a finalizing method that seat no special flex, no finalize er's no suppressing finalization calls and all the related logical complications. 44. 04 Encapsulation and Information Hiding: the question. What is encapsulation and information hiding and what is the difference between them is a very common question. At interviews. There are many false, widespread opinions and statements about these terms. Because of that, a great number of developers, even intermediate developers, are confused when they need to talk about encapsulation and information hiding. You have to understand these concepts not only because you need to pass an interview, but because you want to be a better developer. At least I hope you want to. I like the definition off encapsulation given by Mark Semen, the author, off best selling book dependency injection in that that the definition from Mark Semen. This is what encapsulation is all about, exposing a solution to a problem without requiring the consumer to fully understand the problem domain. That may sound too broad. However. This definition is great on defines encapsulation precisely to imagine what is encapsulation. I'll give you some examples. If you have ever worked with WBF or Windows forms or Zamarripa, then you should know that to draw controls on the screen, you don't need to actually draw them. You just put controls on the designers office and everything is done seems very simple, but there is a town off intricate details of how toe actually render that control. There are 10 layers hidden behind that control. You drop on the designer Sofus. The framework encapsulate all the stuff related toe building your eyes. You don't need to understand the internals off those frameworks to use them, achieving the goals you have first of full. Try to look back and answer to the following question. Do you build your applications on top of reusable components? I'm sure on 100% that you answered. Yes, I do. Of course you do. If you program on Java or C shop than your applications stand on top off a whole damn framework. And the following question is, do you find yourself reading the source code off that reusable components? If it's available on a regular basis, most likely you don't from time to time. We need to read the source code of BCL, for example. But that's a rare case. This is because those components are encapsulated. They allow to use them without digging their internals. We don't need to understand the kitchen off reusable components to use them. This is what encapsulation is encapsulation allows to reuse components without understanding off their internal implementation. Encapsulation is based on two major concepts. Information. Hiding and in variance protection. The class must hide the information it encapsulate in order to protect it against naive users so that the code should be a foolproof. It should be protected from a stupid user. Wikipedia defines information hiding like this. Hiding the internals off the object protects its integrity by preventing users from setting the internal data off the component intern invalid or inconsistent state. We always strive to hide that information, which is irrelevant for clients. When a client sees what it doesn't need, it makes more difficult to understand such an A p I so encapsulation is a fail safe mechanism. At the same time, encapsulation doesn't imply hiding off complexity, saying that I mean that the intrinsic complexity off a problem the main rarely can be properly hidden. For example, the problem domain off dates and times is extremely complex. However, BCL developers implemented the date time structure, which hides all the complexity off the problem domain. As a result, it's easy and convenient to work with daytime type unless you face the complex cases when you need to handle time zones. This is where daytime type fails to do its job. It fools its users, and they start to draw all in the complex details and bell implementation off the daytime time. If you want to learn more about the problems of daytime, take my course Dayton time fundamentals in dot net and Sequel server. So encapsulation is not about hiding complexity but, conversely exposing complexity in the fail safe manner. Another part off encapsulation concerns the so called in variance in variants are the statements that have to stay true in each moment, often object existence. For example, we have a class that represents a human being. A human being has the age, so the class has the corresponding property. In such a case, one off it's in variance could be described by the following statement. A human beings age has to be greater or equal to zero and less than 160 in any moment. The state of the human beings instance has to be correct, preserving the encapsulation by defending the in variance Look at the example off a poorly encapsulated class. Here it is. It might seem that this is a silicon example, but I've seen a lot of such gold basis. Off course. This is the worst case. But even one AP I member implemented badly can lead to serious unfortunate consequences. What's wrong with this? A. P I look at the pace celery method. Why does it return a string value? Is it a code off response? Is it a customer? I d return? Who the hell might know what can be encapsulated by string value? It takes the amount represented by string. What is expected here, a decimal or what may be an integer look further, the get customer method returns void toe. Understand how this method returns? A customer a client of the SAPI I has to know about the customer received event and the last one remove customer method. It returns an integer again. Anything can be represented by an integer value. In such a case, I've seen once how a C programmer used integers to return bulletins as ones and zeros in C shop. Yes, I've seen even such a scary trash look at how this code might look like. Here is the pay celery which returns void and accepts decimal. Everything is understandable. Now it is a command which accepts the money value in decimal. Another option is to return a result moment, which is out of the scope of this course. If you're interested in building robust AP eyes regarding errors with using the result moment considered to take my course a p i N c. Shop the best practices of design and implementation on you Timmy, another method get customer now returns a customer. Everything is quite clear. Another option is to return. And maybe of customer maybe is also so cold moment which is out of the scope of this course . You also can learn about it. In my course I already mentioned they remove customer can either return the void or a result we use result Mona to explicitly state in a signature that the operation may fail If it returns void. It means they're the operation is successful Always. This is an example off a good, clear FBI. The intention off encapsulation is to protect the in variance by making invalid states impossible. Command query separation principle is one of the most important principles related to encapsulation. And then I want to joke that You should always remember that you should write code so that the reader off your code might be a psychopathic mass murder. Who knows your home address? Sleep well, my dear student. Okay, let's briefly look at the practical moments off this topic in the next lecture. Unfortunately, we can talk about this very important topic too long since a whole separate course can be dedicated to encapsulation. 45. 05 Encapsulation in Practice: Let's pretend that we need to implement a type which represents a character. That character has a name, health and speed sounds like a game, but that doesn't matter. Actually, the example is synthetic, but enough good to explain the concepts. The in variance imposed by the problem domain are the following. Health has to be greater or equal to zero and less or equal 100. Speed has to be greater or equal to zero, and the last than or equal 25 name should not be empty. We also have the following requirements. A character can move and respond to some requests like Is it alive? Is it running and so on? Well, the task is pretty simple. Let's implement it with proper encapsulation. At first, let's define three fields and one property. Health, speed and engine, which managers all the rendering process and the property cold name. - Right now, anyone can construct an instance off this class, and by default the name will be. Now what violates one of the in variance, an object of type character that has no name is in invalid state. We need to protect the in variant. For that we can rely on the one of the best ways to protect in variance a constructor. - Now the default constructor is no longer available for the users. A user can only create an instance by our constructor, which takes three parameters, and it doesn't allow to pass now or white space as the name of the character. However, health and speed are not protected. Anyone can use our constructor passing negative values as health and speed. What violates the in variance imposed by the problem domain? We can either right the defense here in the constructor, or we can encapsulate our fields by properties and defending variants there. Since I know that there will be other places from which speed and health are going to be modified, I'll prefer properties. - The in variance now are protected. There is no way to get dr and instance into an invalid state. Let's exposed to queries notice that clients cannot modify the state of health and speed directly via properties or fields. Direct access is hidden from the clients. Very often, clients cannot even get the current value. Since there is no getter just a row field. These two methods do not expose data to clients as well. They encapsulate some logic that defines who are alive and who are Ronnie. Clients do not see the logic that they can only use the properties, getting the results as he's so to speak. A client doesn't set speed directly, and we also want to expose method of damaging. I noticed that clients do not incur any damage directly. Everything is encapsulated. The rendering engine is completely hidden from the sight of clients. This is how insured encapsulation works. 46. 06 Interning: Sometimes interviewers want to know if a candidate does understand how strings are processed by CLR. I bet you know that strings are immutable in C sharp. That means we can modify any string as a result of modification. We end up with a newly created instance. The original instance stays unchanged. It is also apparent that strings are referenced types taking into account what was sad. Consider the following puzzle. Here we have a very simple method. We declare to string variables is signing the same string, literal to them. In the last line of code, we check the referential identity off A and B. I hope you remember that string is a reference type. So but the question is what will be printed out, true or false? Maybe. I just want to confuse you and the result will be false. Who knows? Take your time. Think a little bit right down your answer and get back. - Let's around the code and the result is true. For the majority of developers, this result is astonishing. How the hell is it possible? We created two different variables off a reference type. They off course have two point on the different addresses in memory. However, there is a trick which concerns how CLR handle strings. If you take a regular enterprise application and run it. Attaching a memory profiler like dot memory, you'll see that the number of string instances is 10 times bigger than the number of any other primitive types. It happens that the majority of data is represented via the string type. Because of that, we need some kind off optimization is related to keeping strings in memory in order to reduce memory consuming and CLR implements such an optimization. That optimization is called in turning. CLR keeps an internal hash table where unique references are associated with string liberals. With this optimization, Sylar tries to avoid creation off string objects, which hold the same literal in case CLR detects that you're trying to. Instead, she ate a string instance with a literal, which is already contained in the hash table. It will just use the reference associated with that string literal. It will not allocate new memory for keeping the same value. CLR itself takes the control over decisions about which liberals to in turn and which do not. In turn, however, if we want CLR two in turn a particular string. We can request that by calling the special function called in turn. You can see that intel a Sense says that there are two methods related to interning. The 1st 1 is called in turn, which takes a string and return the string. It searches for a literal passed in, and if it finds such a literal, it returns the corresponding reference. If it can find that literal, it will in turn it or add to the hash tab, in other words, and return the reference Let's in turn and you string. Now let's use another method called is in turn, is Interned is very similar to the intern method. Is in turn takes a string as the argument. It searches for a string, and if it finds it, it returns the corresponding reference. Otherwise it returns. Now we explicitly requested CLR two in turn, Hello to string literal so we can expect that is in turn, will return hello to let's run the code and check if it works great. Everything works as expected. Manual in turning is the feature that is used in rare cases, specifically when you need to improve performance in scenarios where you intensively create a huge number of string liberals and you want to be sure that Depp lick it literally are in turned. Do not rely on this advanced feature If you're not sure that you are absolutely needed apart from that CLR itself actively uses in turning without our interventions. 47. 07 Const vs Readonly: one of the simplest questions you may face concerns the difference between constant and read. Only a great number of developers do not fully understand the difference between constant and read only for some reason, the obvious difference is mechanical. For example, everyone knows that constant is only applicable to primitive types, while read only can be applied to both primitive and custom types such as daytime. However, the internal so to speak difference between them is that CONST. Variables are resolved at compile time. Well read only our result in run time. This fact determines the most important implications. Look at the following example. The class defines two fields here. The 1st 1 is declared as CONST. Then the 2nd 1 is declared a state secret. Donley from the FBI Perspectives. These fields are the same. However they work differently. Consider the following two functions one uses in its calculations of the constant field and the second uses. The state agreed on the field. The first case after the process of compilation will look exactly like this, so the variable was just replaced by the value. The most important distinction is that read only values are resolved at runtime the I L generated when you reference arid, only constant references the read only variable, not the value. These difference has fire reaching implications on maintenance over time, compile time constants generate the same ill as though you've used then humor Constance in your code, even across a semblance, a constant in one assembly is still replaced with the value when used in another assembly, the way in which compile time and run time constants are evaluated effects runtime compatibility. So the hot swap off dependencies can be dangerous. In case you don't re compile the assembly, which uses somewhere constants from those dependencies, old values will stay baked into the main assembly. Without explicitly compilation. However, constants have some benefits over it, only fields. The main benefit, of course, is performance. However, any gains are slide and should be weighted against the decreased flexibility. Be sure to profile performance differences before giving up the flexibility. CONST must be used when the value must be available at compile time. Attribute parameters and animal definitions on those rare times when you mean to define the value that doesn't change from release to release. For everything else, prefer the increased flexibility off read only constants 48. 08 Lock vs Monitor: If you're getting hired to high position like senior developer, then expect questions about multi threading. One of the possible questions concerns the difference between using the lock key word directly and using the monitor class to construct the lock manually. Indeed, sometimes we need to use monitor explicitly before going further. Consider the following cold. We have a class here which defines an object on which we're going to acquire locks, and we have to integer variables to just emulate potential concurrent access to these variables. The example is quite synthetic, but it doesn't matter for our discussion. So the task is to acquire a lock and perform some operational to integer variables. The first way to do this is to use the lock key word. The first method does exactly that. We take the locker using the locker object, and if Val to is not equal zero, we divide Val one Biovail to passing the result to console right line. Any developer knows that Locke during compilation, is expanded into the code, which is demonstrated in the second method. We acquire a lock here calling the enter method on the monitor class. Everything else is wrapped into try finally block all the logic is comprised within the try block, and we released the lock in the finally block. Seems like this has to work properly. Indeed, in most cases this code will work absolutely fine. Moreover, the code that we just demonstrated is exactly what the sea shop 12 and three compilers produced in translating L'Arche statement, my boss very often took locks using exactly the code, which is shown in the second method he used monitor directly. However, this code is not absolutely correct. Here is a subtle vulnerability in this code. Consider the unlikely event often exception being thrown within the implementation off, monitor, enter or between the call to monitor, enter and the try block. Due to perhaps aboard being called all the threat or an out off Mary exception being thrown in such a scenario, the lock may or may not be taken. If the lock is taken, it won't be released because we will never enter the try. Finally block. This will result in a leaked lock to wait. This danger seal are forced, designers added the overloaded monitor Enter method. Here's an example of fusing that overload. The thing is that Locke taking is false after the call to the enter method, if and only if the inter method throws an exception and the lock wasn't taken. If you need to use monitor instead of flog, please consider this weight off taken the lock. 49. 09 Rethrowing Exceptions: this lecture is one of the easiest ones. Despite that, the topic is quite well known. I have seen many developers who didn't know how to properly re throw exceptions. Sometimes we face a situation when we catch an exception. We perform some logic that tries to compensate the problems caused the exception or compensate the consequences off the a cured exception. And very often we can't just suppress the exception. In such cases, we tend to perform some logic and re throw that exception, hoping that the higher level knows how to handle. That exception has enough courage to suppress it. Let's look at an example which relates to these kind of circumstances. At the bottom level, we have a class with a method which for some reason throws an exception. That glass, which implements some logic, is used by another class, which wraps the call into the try catch statement in the catch block. It tries to do something and then just re throws the exception at the top level who have a client which in its turn wraps the calling to trackage statement in the catch block, eat at least needs to log the information about the exception being caught. The top level needs to do it to investigate the problem. Afterwards, let's run the code and Lucas what the top level will seem. Let's look at the stack. Trace one of the most important pieces off information that allows to investigate who was the initial source of the error? Who do you see? It says that the exceptional was raised by the perform method. We don't see the initial source. The thing is that the stack trace was rewritten. Well, we're through the exception to preserve the stacked trays. Always re throw by using the throw, keyword or meeting the exception. Instance here is how we almost always want or throw the exception. Except those cases, while we intentionally want to hide the stacked trays for some reason, let's run the application and check if everything is fine now grade. Now we see the initial source and know where to find the reason off a recurring error. In the next lecture, we will look at string builder and string types 50. 10 StringBuilder vs String: this lecture is presumably the easiest one. However, the question about string, builder and string is so popular interviews, especially when beginners are interviewed, that I couldn't receive to the desire to cover this topic. If you are an experienced developer, just keep this lecture. So the question is, what is the difference between string and string? Beehler. To answer this question, let's look at an example right away. We have a method here which runs two loops. The first loop goes from zero up to 30,000 adding a string representation off the current eatery. Her value to the a variable of type stream. The other loop is the same. The only difference is that we had the current iterated value to the S B variable of type string builder. We also measure the time spent on these loops. Let's run the code and see the results. The first loop, which modifies a string variable, works 1000 times slower than the loop, which modifies the string builder variable y string builder works so fast comparing two strings. The thing is that when I said that the first loop modifies the string variable, I actually lied. Strings are immutable when we mutate a string variable every time we get a new instance of type string. Of course, when we need to perform thousands off modifications on a stream, it will result in a very significant performance. Penalty. String builder was designed exactly for such cases. String builder represents a mutable stream so mutating it's instance there are no thousands off allocations off new string instances. We modify the same instance. It doesn't mean that we should use string builder everywhere. When we're talking about up to 10 modifications, it's better to use regular strings. Consider it s a rule of thumb. 51. 11 Conclusion: in this section, you learned that there is not only mechanical difference between abstract classes and interfaces that the main difference is semantical implementing the disposed pattern. It's sufficient to implement the dispose method right away and nothing more. In addition to it, there are two main parts off encapsulation in variants protection and information hiding CLR, store strings in a hash table and were not aware of the precise algorithms that are used by CLR to keep strings in mammary constant is resolved at compile time, while read only is resolved at runtime. Look is not a straightforward monitor. Enter with monitor Exit. Locke is a slicker using off monitor. Avoid throwing exception instances. This will erase apart off stacked trays. Congratulations. You've reached the end of the main part of the course. That was a long journey. However you are here, it means that you learned a lot. If you learn carefully, I hope you enjoy this course. See later 52. 01 Weirdness of Nullable Comparisons: of the puzzle I want you to look at in this lecture is not very practical, but it's quite funny. This puzzle shows that fallible aromatic is deeply weird. The Puzzle was published by Air Clippers. First, check out this little program. What we do here is that we declare to fallible in Terrible's. The 1st 1 equals one in the 2nd 1 equals now. After that, we kick off several comparisons. The first chunk of comparisons compares one and Neil and the second chunk compares Neil against itself. Think a little bit about the results, what will be printed out? How do you think I'll said the break point before the last comparison? Let's run the code to look at the actual results. So it turns out that in the first chunk, neither is greater than or less than the other, However, now are in ordered with respect to loan House, and one is not equal Now, As the last Line says, the second chunk of comparisons says that two things can be equal to each other, but not greater than or equal to each other. Apparently greater than or equal doesn't actually have or semantics. Let's look at the final comparison compare is a base class for the implementation off the I compare off the interface. It's Property default provides a default sorting order. Compare er in this case, we take the default compare for the fallible in type. I'm not going to torture you asking about the result. In this case, one will be considered greater than now. This result contradicts the greater than and less than operators. It says that one is greater than now, but the operators say that neither is the greater. Actually, language designers have hard choices, and the mess is sometimes is unavoidable. S Eric Lippert once said, language designers have to choose evil off the lesser kind. Among several evil choices the built in operators do not provide a total ordering. Rather, they try to make a best effort attempt at a reasonable compromise. The operators produce bulls, equality, semantics, workers, people expect, and non equality comparisons involving now produce false, indicating that we do not have information about how the quantities are ordered. What is the practical upshot here? First, be careful when comparing malleable numbers. Second, if you need to sort a bunch of possibly now values, you cannot simply use the comparison operators. Instead, you should use the default comparison object as it produces a consistent total order with now at the bottom. 53. 02 Out Arguments: Let's look at another very simple, yet cool puzzle. Here is the method. Look at it carefully. The question is what will be bring it out to console as a result of this method. Execution. Always true, Always false. It depends, - and the right answer is it depends out parameters are passed by reference. They're almost identical to ref parameters. So if a client passes the same argument as X and why they will be equal advance of the test method.