private static void classesAndObjects() { // All classes descend from object var x = new object(); Console.WriteLine($"Type of x {x.GetType()}"); Console.WriteLine($"x is object {x is object}"); var number = new MyNumber() { Value = 3 }; Console.WriteLine($"Type of number {number.GetType()}"); Console.WriteLine($"number is object {number is object}"); // Note even though didn't explcitly declare MyNumber as inheriting from object it's inferred // Casting, can cast to any ancestor type in the inheritance object numberasobject = (object)number; Console.WriteLine($"Type of numberasobject {numberasobject.GetType()}"); Console.WriteLine($"numberasobject is object {numberasobject is object}"); // So casting doesn't create a new object // If we have the following OO classes Animal -> Cat : Animal (i.e. Cat inherits from Animal) // Various language can be used, such as: // // Animal is the supertype Cat is the sub type // Cat inherits from Animal // Cat extends Animal // Animal is the parent of Cat // Animal is the base pof Cat // // When casting we can only cast up the chain i.e. from a subtype to a supertype }
private static void valueVsReferenceTypes() { int x = 3; //000000...11 int y = 3; bool result = (x == y); Console.WriteLine($"x == y: {result}"); x = 4; //0000000...100 result = (x == y); Console.WriteLine($"x (changed) == y: {result}"); MyNumber number1 = new MyNumber() { Value = 3 }; MyNumber number2 = new MyNumber() { Value = 3 }; result = (number1.Value == number2.Value); Console.WriteLine($"number1.Value == number2.Value: {result}"); result = (number1 == number2); Console.WriteLine($"number1 == number2: {result}"); MyNumber number3 = new MyNumber() { Value = 3 }; MyNumber number4 = number3; result = (number3 == number4); Console.WriteLine($"number3 == number4: {result}"); number3.Value = 4; result = (number3 == number4); Console.WriteLine($"Again, number3 == number4: {result}"); number3 = new MyNumber() { Value = 4 }; result = (number3 == number4); Console.WriteLine($"Yet again, number3 == number4: {result}"); result = (number3.Value == number4.Value); Console.WriteLine($"number3.Value == number4.Value: {result}"); // Value types (abridged): bool, int, char, enum long, decimal // Reference types: array, string, class, delegate //// Parameter passing int intof3 = 3; var intresult = addOneToInt(intof3); result = intresult == intof3; Console.WriteLine($"result = {result}, intresult = {intresult}, intof3 = {intof3}"); MyNumber numberof3 = new MyNumber() { Value = 3 }; int numberresult = addOneToClassInstance(numberof3); result = numberresult == numberof3.Value; Console.WriteLine($"result = {result}, numberresult = {numberresult}, numberof3.Value = {numberof3.Value}"); intof3 = 3; intresult = addOneToIntByRef(ref intof3); result = intresult == intof3; Console.WriteLine($"result = {result}, intresult = {intresult}, intof3 = {intof3}"); //// Immutable types //string startOfAlphabet = "abc"; //string alphabetresult = addEndOfAlphabet(startOfAlphabet); //Console.WriteLine($"alphabetresult = {alphabetresult}, startofAlphabet = {startOfAlphabet}"); //// Also DateTime, TimeSpan, Uri, Tuple and others //// Nulls and un-assigned values ////int a = null; // Not allowed //MyNumber b = null; // This is ok, why? Note would try and avoid this in real life due to error below ////Console.WriteLine($"Value of b.Value = {b.Value}"); // This will cause runtime error; //b = new MyNumber(); //Console.WriteLine($"Value of b.Value = {b.Value}"); //// For value types can use nullable wrappers //int? c = null; //Console.WriteLine($"Value of c = {c}"); ////Console.WriteLine($"Value of c.Value = {c.Value}"); // Like example above this will cause runtime error //// is equivalent to //Nullable<int> d = null; //// is equivalent to //Nullable<int> e = new Nullable<int>(); //Console.WriteLine($"Value of d = {d}"); //Console.WriteLine($"Value of e = {e}"); ////Console.WriteLine($"Value of d.Value = {d.Value}"); // Again will throw runtime error ////Console.WriteLine($"Value of e.Value = {e.Value}"); // Again will throw runtime error }
private static int addOneToClassInstance(MyNumber number) { number.Value = number.Value + 1; return(number.Value); }