C# Classes and Inheritance CNS 3260 C#.NET Software Development
Questions for Project 2 does the params array load the integers in sequentially (left to right, top to bottom)? yes Can you overload operator= or operator new? no Can I provide multiple overloads for one operator? yes (and you should) do I need to allow for any order of for the scalar operations (int + Matrix and Matrix + int) It’s easy to do, but I only expect you to do one order (doesn’t matter to me which one it is)
Points to review Immutable strings Inheritance Virtual
Immutable strings Immutable means the string does not change when an operation is performed on it. How do you change a string? After the Replace function what does str contain? “Welcome” To do it right you must reassign to str. str now contains: “We-me” string str = “Welcome”; str.Replace(“lco”, “-”); string str = “Welcome”; str = str.Replace(“lco”, “-”);
Immutable strings static void Main() { string s1 = "original"; ChangeMyString(s1); } static void ChangeMyString(string str) { str = "changed"; } Passing an immutable string to a function After calling ChangeMyString(string str), s1 contians “original”
Immutable strings (again) static void Main() { string s1 = "original"; ChangeMyString(ref s1); } static void ChangeMyString(ref string str) { str = "changed"; } Passing an immutable string to a function After calling ChangeMyString(ref string str), s1 contians “changed”
Access specifiers public: anyone can access protected: only the class and derived classes can access private: only the class can access
Review Overriding vs. Hiding public class Base { protected void fun1(){} protected virtual void fun2(){} } public class Derived : Base { protected new void fun1(){} protected override void fun2(){} } Hides base.fun1() Overrides base.fun1()
Overriding static void Main() { Base b = new Derived(); b.fun1(); b.fun2(); } Calls Base.fun1() Calls Derived.fun2() The vtable is used during runtime to resolve virtual function calls.
Overloading a method Overloading vs. Overriding or hiding Overriding: a derived class method covers (you can override or hide a base class method with a method of the same name.) Overloading: Creating methods of the same name that take a different set of parameters C# allows no default parameters You may change access specifiers on various overloaded methods You cannot overload on the return type alone You can overload a base class method in a derived class Only if the signatures match does it hide the base class method
Overloading Example public string GetValue(string str) { // do work here } public float GetValue(float f) { // do work here } public string GetValue(string str, int index) { // do work here }
Design consideration public Token GetToken() { // do some work here return nextToken; } public Token GetToken(string name) { // don't duplicate work if you can help it Token t = GetToken(); if(t.Name != name) throw(new UnexpectedTokenException()); return t; } Avoid duplicating code:
Properties Look like variables Smell like variables Taste like vegetables? Used like variables BUT are really methods getters -- accessors setters -- mutators
Property Example class MyPropDemo { private int myValue; public int MyValue { get{ return myValue; }//accessor set{ myValue = value; }//mutator }
The value keyword Implicit variable passed to properties and indexers Type is the same as the return type of the property or indexer May be used as a local-variable name or a field class MyPropDemo { private int myValue; public int MyValue { set { myValue = value; }// mutator get { return myValue; }// accessor } type is int
Properties Method in disguise Allows us to change object state Syntactical sugar Allows to control access outside the class: class MyPropDemo { private int myValue; public int MyValue { set { myValue = value; }// mutator get { return myValue; }// accessor }
Recursive Properties Be careful with syntax not to recall the property from within the property class MyClass { private int myClassInt; public int MyClassInt { get { return MyClassInt; // Uh oh } set { myClassInt=value; } }
virtual, abstract, static? yes, yes and yes: public virtual int MyInt { get { return myInt; } set { myInt=value; } } abstract public int MyInt { get; set; } public static int MyInt { get { return myStaticInt; } set { myStaticInt=value; } }
Why not just use public variables? You can have extra functionality in a property if needed: public int MyInt { set { if(value < 0) throw(new SomeExceptionThatMakesSenseHere("Duh")); DoSomeWork(value); DontEvenHaveToInitializeAVariableIfYouDontWant(); } get{ return myInt; } }
Why not just use public variables? Can have just a get or just a set: public int Count { get{return count;} }
Why not just use public variables? Allows you to protect data in a multi-threaded situation: public int MyInt { set { lock(this) { myInt=value; }
Why not just use public variables? Allows you to disguise complex lookups as simple or foreign variables as your own: private int Count { get { return ((SomeObject as SomeOtherObject)[i, j] as object).Container.Count; }
What’s faster (See PropertyVSMemberSpeedTest demo)
New in version 2.0? standard 2.7 working draft p292 allows for changing the access specifier on the get or set or both: class MyPropDemo { private int myValue; public int MyValue { get{ return myValue; }//accessor protected set{ myValue = value; }//mutator }
A quick look at arrays Arrays are stored in contiguous memory Arrays are objects Multidimensional arrays are either jagged or rectangular Single dimensional array syntax: All elements are zeroed (nulled for reference types) int[] intArray = new int[10];
Jagged Arrays int[][] intArray = new int[10][]; for(int i=0; i<10; ++i) intArray[i] = new int[15+i]; An array of arrays 2 nd rank can be an array of any length Works the same for n dimensions Index into the array: intArray[3][5] = 100;
Rectangular Arrays 2 nd rank are all of the same length Works the same for n dimensions Index into the array: int[,] intArray = new int[10,15]; int[,,,] intArray = new int[10,15,6,5]; intArray[3,5] = 100; intArray[4,5,3,2] = 200;
Indexers class MyIndexDemo { private int[] iArray = {10,20,30,40,50}; public int this[int index] { get{ return iArray[index]; } set{ iArray[index] = value; } } Similar to operator[] in C++ Similar to properties in C#
Indexer Allows array-like access into a class Good if you want you’re class to work as a collection Can have get and set, or just one or the other Can be overloaded Can’t have ref or out parameters
Overloading an indexer class MyClass { System.Collections.Hashtable table = new System.Collections.Hashtable(); public object this[int i] { get { return table[i]; } set { table[i] = value; } } public object this[string i] { get { return table[i]; } set { table[i] = value; } }
Jagged-style brackets class Class2 { private int[][] int2DArray = new int[10][]; public int[] this[int index] { get { return int2DArray[index]; } set { int2DArray[index] = value; } } void Main() { Class2 c = new Class2(); c[4][5] = 100; }
Rectangular-style Indexer class Class3 { private int[,] int2DRectangularArray = new int[10, 10]; public int this[int x, int y] { get { return int2DRectangularArray[x, y]; } set { int2DRectangularArray[x, y] = value; } } void Main() { Class3 c = new Class3(); c[4, 5] = 100; } }