/Lectures/Lecture_12/PITCHME.md

https://gitlab.com/zautre/curriculum · Markdown · 176 lines · 168 code · 8 blank · 0 comment · 0 complexity · 48c2503f54b5aa6ea34368f6f9607ef4 MD5 · raw file

  1. ## this & readonly
  2. #HSLIDE
  3. ### The this Keyword
  4. The ***`this`*** keyword is used inside the class and refers to the current *instance* of the class, meaning it refers to the current object.
  5. #HSLIDE
  6. One of the common uses of **this** is to distinguish class members from other data, such as local or formal parameters of a *method*, as shown in the following example:
  7. ```c
  8. class Person {
  9. private string name;
  10. public Person(string name) {
  11. this.name = name;
  12. }
  13. }
  14. ```
  15. #HSLIDE
  16. Here, `this.name` represents the member of the class, whereas `name` represents the parameter of the *constructor*.
  17. >Another common use of **this** is for passing the current instance to a method as parameter: ShowPersonInfo(**this**);
  18. #HSLIDE
  19. ### The readonly Modifier
  20. The **readonly** modifier prevents a member of a class from being modified after construction.
  21. It means that the field declared as **readonly** can be modified only when you declare it or from within a *constructor*.
  22. #HSLIDE
  23. For example:
  24. ```c
  25. class Person {
  26. private readonly string name = "John";
  27. public Person(string name) {
  28. this.name = name;
  29. }
  30. }
  31. ```
  32. If we try to modify the `name` field anywhere else, we will get an error.
  33. There are three major differences between **readonly** and **const** fields.
  34. #HSLIDE
  35. First, a constant field must be initialized when it is declared, whereas a readonly field can be declared without initialization, as in:
  36. ```c
  37. readonly string name; // OK
  38. const double PI; // Error
  39. ```
  40. Second, a **readonly** field value can be changed in a *constructor*, but a constant value cannot.
  41. #HSLIDE
  42. Third, the **readonly** field can be assigned a value that is a result of a calculation, but constants cannot, as in:
  43. ```c
  44. readonly double a = Math.Sin(60); // OK
  45. const double b = Math.Sin(60); // Error!
  46. ```
  47. #HSLIDE
  48. ## Indexers
  49. #HSLIDE
  50. An **indexer** allows objects to be indexed like an *array*.
  51. As discussed earlier, a *string* variable is actually an object of the **String** class.
  52. #HSLIDE
  53. Further, the String class is actually an array of Char objects.
  54. In this way, the *string* class implements an **indexer** so we can access any character (Char object) by its index:
  55. #HSLIDE
  56. ```c
  57. string str = "Hello World";
  58. char x = str[4];
  59. Console.WriteLine(x);
  60. //Outputs "o"
  61. ```
  62. #HSLIDE
  63. >Arrays use ***integer*** indexes, but indexers can use any type of index, such as strings, characters, etc.
  64. #HSLIDE
  65. Declaration of an **indexer** is to some extent similar to a `property`. The difference is that **indexer** accessors require an ***index***.
  66. Like a `property`, you use **get** and **set** accessors for defining an **indexer**.
  67. #HSLIDE
  68. However, where properties return or set a specific data member, indexers return or set a particular value from the object *instance*.
  69. Indexers are defined with the ***`this`*** keyword.
  70. #HSLIDE
  71. For example:
  72. ```c
  73. class Clients {
  74. private string[] names = new string[10];
  75. public string this[int index] {
  76. get {
  77. return names[index];
  78. }
  79. set {
  80. names[index] = value;
  81. }
  82. }
  83. }
  84. ```
  85. #HSLIDE
  86. As you can see, the **indexer** definition includes the ***`this`*** keyword and an index, which is used to get and set the appropriate value.
  87. Now, when we declare an object of class Clients, we use an index to refer to specific objects like the elements of an *array*:
  88. #HSLIDE
  89. ```c
  90. Clients c = new Clients();
  91. c[0] = "Dave";
  92. c[1] = "Bob";
  93. Console.WriteLine(c[1]);
  94. //Outputs "Bob"
  95. ```
  96. >You typically use an ***indexer*** if the class represents a list, collection, or ***array*** of objects.
  97. #HSLIDE
  98. ## Operator Overloading
  99. #HSLIDE
  100. Most operators in C# can be **overloaded**, meaning they can be redefined for custom actions.
  101. #HSLIDE
  102. For example, you can redefine the action of the plus (+) operator in a custom class.
  103. Consider the **Box** class that has **Height** and **Width** properties:
  104. ```c
  105. class Box {
  106. public int Height {get; set;}
  107. public int Width {get; set;}
  108. public Box(int h, int w) {
  109. Height = h;
  110. Width = w;
  111. }
  112. }
  113. static void Main(string[] args) {
  114. Box b1 = new Box(14, 3);
  115. Box b2 = new Box(5, 7);
  116. }
  117. ```
  118. #HSLIDE
  119. We would like to add these two **Box** objects, which would result in a new, bigger Box.
  120. So, basically, we would like the following code to work:
  121. ```c
  122. Box b3 = b1 + b2;
  123. ```
  124. The **Height** and **Width** properties of object b3 should be equal to the sum of the corresponding properties of the b1 and b2 objects.
  125. #HSLIDE
  126. >This is achieved through **operator overloading**.
  127. #HSLIDE
  128. Overloaded operators are methods with special names, where the keyword ***`operator`*** is followed by the symbol for the operator being defined.
  129. Similar to any other *method*, an overloaded operator has a return type and a parameter list.
  130. #HSLIDE
  131. For example, for our **Box** class, we overload the + operator:
  132. ```c
  133. public static Box operator+ (Box a, Box b) {
  134. int h = a.Height + b.Height;
  135. int w = a.Width + b.Width;
  136. Box res = new Box(h, w);
  137. return res;
  138. }
  139. ```
  140. #HSLIDE
  141. The overloaded operator must be **`static`**.
  142. Putting it all together:
  143. ```c
  144. class Box {
  145. public int Height { get; set; }
  146. public int Width { get; set; }
  147. public Box(int h, int w) {
  148. Height = h;
  149. Width = w;
  150. }
  151. public static Box operator+(Box a, Box b) {
  152. int h = a.Height + b.Height;
  153. int w = a.Width + b.Width;
  154. Box res = new Box(h, w);
  155. return res;
  156. }
  157. }
  158. static void Main(string[] args) {
  159. Box b1 = new Box(14, 3);
  160. Box b2 = new Box(5, 7);
  161. Box b3 = b1 + b2;
  162. Console.WriteLine(b3.Height); //19
  163. Console.WriteLine(b3.Width); //10
  164. }
  165. ```
  166. #HSLIDE
  167. >All arithmetic and comparison operators can be overloaded. For instance, you could define greater than and less than operators for the boxes that would compare the Boxes and return a **boolean** result. Just keep in mind that when overloading the greater than operator, the less than operator should also be defined.
  168. #HSLIDE