{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "510c27dd-0e91-4813-a502-7380e111bf2b",
   "metadata": {},
   "source": "# Properties\n"
  },
  {
   "cell_type": "markdown",
   "id": "3b17f457",
   "metadata": {},
   "source": "## Properties\n\nAlthough the content are still valid, this section will be updated later to reflect\nthe more current syntax and discussion of properties such as in [Using Properties](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/using-properties#the-get-accessor).\n\nA property is a member that provides a flexible mechanism to read, write, or compute\nthe value of a data field. Properties appear as public data members, but they’re\nimplemented as special methods called accessors."
  },
  {
   "cell_type": "markdown",
   "id": "3b72af2a",
   "metadata": {},
   "source": "```{index} OOP; getter\n```\n\n(getters)=\n\n### Getters\n\nIn instance methods you have an extra way of getting data in and out of the method:\nReading or setting instance variables (fields). The simplest methods do nothing but reading\nor setting instance variables. We start with those:\n\nThe `private` in front\nof the field declarations was important to keep code outside the\nclass from messing with the values. On the other hand we do want\nothers to be able to *inspect* the name, phone and email,\nso how do we do that? Use **public methods**.\n\nSince the fields are accessible anywhere *inside* the class’s instance methods,\nand public methods can be used from *outside* the class, we can simply code\n\n```{literalinclude} ../../examples/contact1/contact1.cs\n:end-before: labels\n:start-after: getter\n```\n\nThese methods allow one-way communication of the name, phone and email\nvalues out from the object.\nThese are examples\nof a simple category of methods: A *getter* simply returns the value of a part\nof the object’s state, without changing the object at all.\n\nNote again that there is no `static` in the method heading.\nThe field value for the *current* Contact is returned.\n\nA standard convention that we are following:\nHave getter methods names start with “Get”,\nfollowed by the name of the data to be returned.\n\nIn this first simple version of Contact we add one further method, to\nprint all the contact information with labels.\n\n```{literalinclude} ../../examples/contact1/contact1.cs\n:end-before: chunk\n:start-after: labels\n```\n\nAgain, we use the instance variable names, plugging them into a format string.\nRemember the `@` syntax\nfor multiline strings gives us verbatim string literals that are interpreted literally\nwithout escape sequences.\n\nYou can see and see the entire Contact class\nin [contact1/contact1.cs](https://github.com/mstbit/introcs-csharp-examples/blob/master/contact1/contact1.cs).\n\nThis is your first complete class defining a new type of object.\nLook carefully to get used to the features introduced, before we add\nmore ideas:\n\n```{index} class; Contact version 2\n```"
  },
  {
   "cell_type": "markdown",
   "id": "3a6bfe13",
   "metadata": {},
   "source": "```{index} OOP; this keyword\n```\n\n### This Object\n\nWe will be making an elaboration on the Contact class from here on. We introduce\nnew parts individually, but the whole code is in\n[contact2/contact2.cs](https://github.com/mstbit/introcs-csharp-examples/blob/master/contact2/contact2.cs).\n\nThe current object is *implicit* inside a constructor or instance method definition,\nbut it can be referred to *explicitly*. It is called `this`.\nIn a constructor or instance method, `this` is automatically a legal\nlocal variable to reference.\nYou usually do not need to\nuse it explicitly, but you could. For example the current `Contact` object’s\n`name` field could be referred to as either `this.name` or the shorter plain `name`.\nIn our next version of the Contact class we will see several places where\nan explicit `this` is useful.\n\nIn the first version of the constructor, repeated here,\n\n```{literalinclude} ../../examples/contact1/contact1.cs\n:end-before: getter\n:start-after: constructor\n```\n\nwe used different names for the instance variables and the formal\nparameter names that we used to initialize the instance variables. We\nchose reasonable names, but we are adding extra names that we are not going\nto use later, and it can be confusing. The most obvious names for the formal\nparameters that will initialize the instance variables are the *same* names.\n\nIf we are not careful, there is a problem with that. An instance variable,\nhowever named, and a local variable are not the same. This is\nnonsensical:\n\n    public Contact(string name, string phone, string email)\n    {\n       name = name; // ????\n       ...\n\nLogically we want this pseudo-code in the constructor:\n\n> instance variable `name` `=` local variable `name`\n\nWe have to disambiguate the two uses. The compiler always looks for\n*local* variable identifiers *first*, so plain `name` will refer to the local\nvariable `name` declared in the formal parameter list.\nThis local variable identifier *hides* the matching instance variable\nidentifier. We have to do something else to refer to the instance variable.\nThe explicit `this` object comes to the rescue: `this.name` refers to\na part of this object. It must refer to the\ninstance variable, not the local variable. Our alternate constructor is:\n\n```{literalinclude} ../../examples/contact2/contact2.cs\n:end-before: getter\n:start-after: constructor\n```"
  },
  {
   "cell_type": "markdown",
   "id": "a02bc96d",
   "metadata": {},
   "source": "### Setters\n\nThe original version of Contact makes a Contact object be\n*immutable*: Once it is created with the constructor, there is no way\nto change its internal state. The only assignments to the private\ninstance variables are the ones in the constructor. In real life\npeople can change their email address. We might like to allow that\nwith our Contact objects. Users can read the data in a Contact with the\n*getter* methods. Now we need *setter* methods. The naming conventions\nare similar: start with “Set”. In this case we must supply the new data,\nso setter methods need a parameter:\n\n```{literalinclude} ../../examples/contact2/contact2.cs\n:end-before: chunk\n:start-after: setter methods\n```\n\nIn `SetPhone`, like in our original constructor, we illustrate using a\n*new* name for the parameter that sets the instance variable. For\ncomparison we use the alternate identifier matching approach in the\nother setter:\n\n```{literalinclude} ../../examples/contact2/contact2.cs\n:end-before: chunk\n:start-after: SetEmail\n```\n\nNow we can alter the contents of a Contact:\n\n    Contact c1 = new Contact(\"Marie Ortiz\", \"773-508-7890\", \"mortiz2@luc.edu\");\n    c1.SetEmail (\"maria.ortiz@gmail.com\");\n    c1.SetPhone(\"555-555-5555\");\n    c1.Print();\n\nwould print\n\n``` none\nName:  Marie Ortiz\nPhone: 555-555-5555\nEmail: maria.ortiz@gmail.com\n```"
  },
  {
   "cell_type": "markdown",
   "id": "e84e079d",
   "metadata": {},
   "source": "```{index} ToString; override\n```\n\n(tostring)=\n\n## ToString Override\n\nAll object in C# have a `ToString` method because all types inherit from the base class\nSystem.Object. It converts an object to its string representation for display. It is used\nto perform internal string concatenation and Write."
  },
  {
   "cell_type": "markdown",
   "id": "9f8d9944",
   "metadata": {},
   "source": "### Default ToString behavior\n\nBy default, ToString returns returns the `fully qualified name` of the type of the Object. For example:"
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2f0b4f98",
   "metadata": {
    "mystnb": {
     "syntax_highlight_language": "none"
    }
   },
   "outputs": [],
   "source": [
    "namespace IntroCSCS\n",
    "{\n",
    "class Animal\n",
    "{\n",
    "public string name;\n",
    "public Animal(string name)\n",
    "{\n",
    "this.name = name; }\n",
    "}\n",
    "}\n",
    "\n",
    "public class TestAnimal\n",
    "{\n",
    "public static void Main()\n",
    "{\n",
    "Animal frog = new Animal(\"Froggy\");\n",
    "Console.WriteLine(frog.ToString()); ///// print: IntroCSCS.Animal; Animal is the type\n",
    "Console.WriteLine(frog.name); ///// print: Froggy\n",
    "}\n",
    "}\n",
    "}\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5b909044",
   "metadata": {},
   "source": [
    "### Overriding ToString\n",
    "\n",
    "    Think more generally about string representations:\n",
    "    All the built-in type values can be concatenated into strings with the '+' operator,\n",
    "    or displayed with `Console.Write`. We would like that behavior with our custom types,\n",
    "    too.\n",
    "\n",
    "    Types frequently `override` the Object.ToString method to provide a more suitable string\n",
    "    representation or display of a particular type instead of the default fully qualified type name.\n",
    "    For example:\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cf8e32d6",
   "metadata": {
    "mystnb": {
     "syntax_highlight_language": "none"
    }
   },
   "outputs": [],
   "source": [
    "    class Employee\n",
    "    {\n",
    "       public string Name { get; set; }\n",
    "       public int Salary { get; set; }\n",
    "\n",
    "       public override string ToString()\n",
    "       {\n",
    "          return \"Employee: \" + Name + \" \" + Salary;      ///// returns object data\n",
    "       }\n",
    "    }\n",
    "\n",
    "    class Test\n",
    "    {\n",
    "       public static void Main()\n",
    "       {\n",
    "          Employee employee = new Employee { Name = \"John\", Salary = 100000 };\n",
    "          Console.WriteLine(employee.ToString());   ///// print: Employee: John 100000\n",
    "          Console.WriteLine(employee);              ///// print: Employee: John 100000\n",
    "                                                    /////        as ToString is the default output\n",
    "\n",
    "       }\n",
    "    }\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9983b23b",
   "metadata": {},
   "source": "See what the ToString method does now: it uses the object state (e.g., the values of variables name and\nsalary in this case) and implicitly covert and *return* a single string representation of the object."
  },
  {
   "cell_type": "markdown",
   "id": "920da3f7",
   "metadata": {},
   "source": "### Print() Customization\n\nYou can further customize the ToString overriding. For example, in the preceding `Employee` class,\nin addition to the following `ToString` override, you might like to have a convenience method\n`Print` using `ToString`. We want one instance method, `Print` to call another instance\nmethod `ToString` for the *same* object:\n\n    public void Print()\n    {\n       Console.WriteLine(ToString());\n       // Console.WriteLine(this);         ///// \"this\" returns the same as ToString()\n    }\n\nNow take a look at the test and output:\n\n    Employee employee = new Employee { Name = \"John\", Salary = 100000 };\n    Console.WriteLine(employee.ToString());\n    Console.WriteLine(employee);\n    employee.Print();"
  },
  {
   "cell_type": "markdown",
   "id": "dd5dc720",
   "metadata": {},
   "source": [
    "``` bash\n",
    "tcn85@mac:~/workspace/introcscs/Ch10ClassesLab$ dotnet run\n",
    "Employee: John 100000\n",
    "Employee: John 100000\n",
    "Employee: John 100000\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f7afcc28",
   "metadata": {},
   "source": [
    "\n",
    "% When we use `Console.WriteLine` on this current object, which is *not*\n",
    "\n",
    "% already a string, there is an automatic call to `ToString`.\n",
    "\n",
    "% .. index:: redeclaring instance variables error\n",
    "\n",
    "% compiler error; before error in text\n",
    "\n",
    "% instance variable; redeclaring error\n",
    "\n",
    "% .. \\_local-variables-hiding-instance-variables:\n",
    "\n",
    "% Local Variables Hiding Instance Variables\n",
    "\n",
    "% ——————————————\n",
    "\n",
    "% A common error is for students to try to declare the instance variables twice,\n",
    "\n",
    "% once in the regular instance variable declarations,\n",
    "\n",
    "% *outside of any constructor or method* and then again *inside* a\n",
    "\n",
    "% constructor, like::\n",
    "\n",
    "% public Contact(string fullName, string phoneNumber, string emailAddress)\n",
    "\n",
    "% {\n",
    "\n",
    "% string name = fullName; // LOGICAL ERROR!\n",
    "\n",
    "% string phone = phoneNumber; // LOGICAL ERROR!\n",
    "\n",
    "% string email = emailAddress; // LOGICAL ERROR\n",
    "\n",
    "% }\n",
    "\n",
    "% This is deadly. It is worse than redeclaring a local variable, which at least will\n",
    "\n",
    "% trigger a compiler error.\n",
    "\n",
    "% .. warning::\n",
    "\n",
    "% Instance variable *only* get declared outside of all\n",
    "\n",
    "% functions and constructors. Same-name\n",
    "\n",
    "% local variable declarations hide the\n",
    "\n",
    "% instance variables, but *compile just fine*. The local variables disappear\n",
    "\n",
    "% after the constructor ends, leaving the instance variables\n",
    "\n",
    "% *without* your desired initialization. Instead the hidden instance variables\n",
    "\n",
    "% just get the default initialization, `null` for an object\n",
    "\n",
    "% or 0 for a number.\n",
    "\n",
    "% There is a related strange compiler error. This is not likely to happen frequently,\n",
    "\n",
    "% but thinking through its logic (or illogic) could be helpful in understanding\n",
    "\n",
    "% local and instance variables:\n",
    "\n",
    "% Generally when you get a compiler error, the error is at or *before* the location the\n",
    "\n",
    "% error is referenced, but with local variables covering instance variables,\n",
    "\n",
    "% the real cause can come later in the text of the method. Below, when you first\n",
    "\n",
    "% refer to `r` in `Badnames`, it appears to be correctly referring to the\n",
    "\n",
    "% instance variable `r`::\n",
    "\n",
    "% class ForwardError\n",
    "\n",
    "% {\n",
    "\n",
    "% private int r = 3;\n",
    "\n",
    "% // …\n",
    "\n",
    "% void BadNames(int a, int b)\n",
    "\n",
    "% {\n",
    "\n",
    "% int n = a*r + b; // legal in text* just\\* to here; instance field r\n",
    "\n",
    "% //…\n",
    "\n",
    "% int r = a % b; // r declaration makes *earlier* line wrong\n",
    "\n",
    "% //…\n",
    "\n",
    "% }\n",
    "\n",
    "% The compiler scans through *all* of `BadNames`, and sees the `r` declared locally\n",
    "\n",
    "% in its scope.\n",
    "\n",
    "% The error may be marked on the earlier line, where the compiler then assumes\n",
    "\n",
    "% `r` is the later declared local `int` variable, not the instance variable.\n",
    "\n",
    "% The error it sees is a local variable used before declaration.\n",
    "\n",
    "% This is based on a real student example.\n",
    "\n",
    "% This example points to a second issue: using variable names that\n",
    "\n",
    "% that are too short and not descriptive of the variable meaning, and so may\n",
    "\n",
    "% easily be the same name as something unrelated.\n",
    "\n",
    "% .. index:: lifetime; vs. scope\n",
    "\n",
    "% scope; vs. lifetime\n",
    "\n",
    "% Lifetime and Scope Exercise/Example\n",
    "\n",
    "% ~\n",
    "\n",
    "% Be careful to distinguish lifetime and scope. Either a local variable or\n",
    "\n",
    "% an instance variable can be temporarily out of scope, but still be alive.\n",
    "\n",
    "% Can you construct an example to illustrate that? One of ours is\n",
    "\n",
    "% :repsrc:`lifetime_scope/lifetime_scope.cs`.\n",
    "\n",
    "`{rubric} footnote`\n",
    "\n",
    "[1] See the answer at [What is the difference between a field and a property?](https://stackoverflow.com/questions/295104/what-is-the-difference-between-a-field-and-a-property)\n",
    "\n",
    "[2] [Accessibility Levels (C# Reference)](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/accessibility-levels).\n",
    "\n",
    "[3] See [internal](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/internal)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "footnotes",
   "metadata": {},
   "source": "```{rubric} Footnotes\n```\n"
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": ".NET (C#)",
   "language": "C#",
   "name": ".net-csharp"
  },
  "language_info": {
   "name": "csharp"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}