c# oo
Constructor
ctor cannot be inherited.
ctor order
- Class C1, Class C2: C1, Class C3: C2 (C1->C2->C3)
- C3 calls C1's ctor, C2's ctor, and then C3's ctor ctor order: C1->C2->C3
Destructor
~className() { ... }
called by garbage-collector and is only an alias of .Finalize().
~MyClass(){ // stuff }
is identical to writing
MyClass.Finalize(){
// stuff
base.Finalize();
}
order ex:
Class C1, Class C2: C1, Class C3: C2 (C1->C2->C3) C3 calls C3's dtor, C2's Dtor, then C1's Dtor dtor order: C3->C2->C1
Inheritance
class <className>: <parentClass> { }
virtual modifier: all derived method can be overriden
override : derived virtual method
abstract : no implementation
- base : parent's class. Use it to refer to parent's member from derived class
- void print() { base.print() ;... } // calls parent's print()
new : hides the parent's method. Without ""new"", it will generate warning msg.
ex:
public class Base { public void doit(); }
public class derived { new public void doit() ... }
To call base, use .base:
public class derivedC { new public void doit() { base.doit();} }
Interface
similar to C++ abstract class. Methods must be implemented.
interface IPrintable {
void print();
}
...
public class Doc: IPrintable {
public void print() {... }
}
Interface can be inherited and also supports multiple inheritance:
public class Doc: IPrintable, IStorable {...}
interface IPrintable2 : IPrintable {...}
interface IPrintableAndStorable: IPrintable, IStorable {}
Accessing obj method via interface:
Doc doc = new Doc(); IPrintable idoc=doc; idoc.print();
Casting:
object obj = new Doc(); IPrintable idoc = (IPrintable)obj;
- Explicit Interface
- class obj can't access it. Only interface obj can access it. Remove "public" from impl method. Also add interface name "table." to method.
public Doc : IPrintable {
void IPrintable.Paint() { ... }
}
...
doc.print(); // ERROR!
idoc.print(); // OK
Access Modifier
- private: not accessible from any other class.
- public:
- protected: accessible to all derived class only
- internal: similar to C++'s ""friend"". Accessible only by classes in the same assembly.
- override :
Sub/Method Parameters
in: Passed by value by default (""in"")
ref: passed by reference. calling func must explicitly mention ref as well:
myFunc(ref x, ref y);
- out: passes by ref, initial value is unimportant. Only out is really needed.
- void f(out string a, out int b) {...}
passing arrays: func( arr[] ) { ... }
params <type[]> args: varargs, can pass as value or as arrays.
void myFunc(int x, params int[] args) { }
myFunc(1,2,3,4);
myFunc(1,myArr); // equivalent, myArr=2,3,
Example from Oreilly
static int Add(params int[ ] iarr) {
int sum = 0;
foreach(int i in iarr)
sum += i;
return sum;
}
static void Main( ) {
int i = Add(1, 2, 3, 4);
Console.WriteLine(i); // 10
}
Delegate
sim to function pointer, pass function safely to evaluate, etc.
func( Function f) { f(...) }
delegate void delfunc(int x, int y); // param must match the func it encompasses.
...
class Sprite() {
public void move(int x, int y);
}
Sprite sprite = new Sprite();
SomeClass cl = new SomeClass(); // assume another class...
...
delfunc moveAll = new delfunc(sprite.move);
moveAll(3,4); // move sprite to 3,4
delegate printSomething = new delegate (c1.print);
moveAll+= printSomething; // add another delegate func to moveAll
moveAll(5,10); // will perform move(5,10), print(5,10).
// One can chain as many delegate functions...
moveAll-=printSomething; // remove a delegate func from the chain
chain many functions. Delegates are invoked in the order they are added.
moveAll += anotherDelFunc; moveAll += new moveAll(c1.climb); moveAll -= anotherDelFunc; // remove this delegate from chain moveAll = null; // set to empty
To pass as a parameter:
void display(moveAll f) { f(5,4); }
Event
Uses delegate to do event-handling
event <delegateFunc> <eventName>
- add(<event>)
- remove(<event>)
- event is a shortcut to a class that implements delegate func's +=,-=.
delegate <eventHandler> (object source, System.Eventargs arg);
Arg can be derived to have custom arg.
delegate void MoveEventHandler(object source, MoveEventArgs e);
// from Oreilly's C# Essential
public class MoveEventArgs : EventArgs {
public int _newPosition;
public bool cancel;
public MoveEventArgs(int newPosition) { // ctor
_newPosition = newPosition; }
}
Firing Event:
public class Slider {
int _position;
public event MoveEventHandler Move;
public int Position {
get { return _position; }
set {
if (position != value) { // if position changed
if (Move != null) { // if invocation list not empty
MoveEventArgs args = new MoveEventArgs(value);
Move(this, args); //--- fire event!!!
if (args.cancel)
return;
}
position = value;
}
}
}
}
Finally, in form:
class Form {
static void Main( ) {
Slider slider = new Slider( );
// register with the Move event
slider.Move += new MoveEventHandler(slider_Move);
// -----ADD ANOTHER func, see slider_Move() BELOW....
slider.Position = 20;
slider.Position = 60;
}
// vvv--- THIS GETS added to MoveEventHANDLER()
static void slider_Move(object source, MoveEventArgs e) {
if(e.newPosition < 50)
Console.WriteLine(""OK"");
else {
e.cancel = true;
Console.WriteLine(""Can't go that high!"");
}
}
}
Property
get{} returns a value
set{} always uses ""value"" as param.
Can be either read-only(get) or read-write able(get/set)
public int count {
get { return _count; }
set { _count=value; }
}
Indexer
if this is a container of multiple items, indexer can be used to be iterated.
public object this[int index] {
get { return items[index];}
set { ... }
}
Event Methods
public event EventHandler changed;
Operator Methods
public static bool operator ==(List a, List b) {
return Equals(a, b);
}
Exception
try { ... }
catch ( ExceptionA ) { ... }
catch ( ExceptionB ) { ... }
finally { } // executes whether exception occured or not.
try {inputFile = new System.IO.StreamReader(""data\\test.txt"");}
catch (System.IO.IOException) {
- Exception vs Exception Var
- catch (IOException e) vs (IOException). first case generates warning/error msg
