You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
usingSystem;namespaceTutorial{classProgram{staticvoidswap(objecta,objectb){Console.WriteLine($"{a}{b}");// world helloobjectc;c=a;a=b;b=c;Console.WriteLine($"{a}{b}");// hello world}staticvoidMain(string[]args){strings="world";stringt="hello";Console.WriteLine($"{s}{t}");// world helloswap(s,t);Console.WriteLine($"{s}{t}");// world hello}}}
Value parameters are just copies of their respective arguments
In the above example, the object references are copied
a and s share the same string object
Assignments to value parameters are invisible to the caller
a is rebound, but s is not
Mutation througha would be noticeable through s
But object has no mutator methods
And strings are immutable
ref parameters alias their respective argument variables:
usingSystem;namespaceTutorial{classProgram{staticvoidswap(refobjecta,refobjectb){objectc;c=a;a=b;b=c;}staticvoidMain(string[]args){strings="world";stringt="hello";// cannot convert from "ref string" to "ref object"swap(refs,reft);}}}
In expected OOP fashion, strings are objects
But stringvariables are not objectvariables
Otherwise, we could rebind string variables to non-string objects:
strings="hi";refobjecto=refs;// cannot convert from "ref string" to "ref object"o=42;
usingSystem;namespaceTutorial{structDuration{// Constants are not stored anywhere at runtime.// Usages compile away to their actual value.publicconstintSECONDS_PER_MINUTE=60;publicconstintSECONDS_PER_HOUR=60*60;privatelong_seconds;publiclongSeconds{get=>_seconds;set=>_seconds=value;}publiclongMinutes{get{return_seconds/SECONDS_PER_MINUTE;}set{if(value*SECONDS_PER_MINUTE/SECONDS_PER_MINUTE!=value)thrownewArgumentException($"{value} is too big");_seconds=value*SECONDS_PER_MINUTE;}}publiclongHours{get=>_seconds/SECONDS_PER_HOUR;set{if(value*SECONDS_PER_HOUR/SECONDS_PER_HOUR!=value)thrownewArgumentException($"{value} is too big");_seconds=value*SECONDS_PER_HOUR;}}}classProgram{staticvoidMain(string[]args){Durationdur=newDuration();dur.Hours=2;// 120 minutes is 7200 secondsConsole.WriteLine($"{dur.Minutes} minutes is {dur.Seconds} seconds");}}}
Object-oriented programming
extends C implements I, J, K translates to : C, I, J, K
The default is : object
super(...); or this(...); translate to : base(...) or : this(...)
The default is : base()
Default constructor is generated in the absence of explicit constructors
Only abstract and virtual methods are overridable
Overriding requires override keyword
Missing override does not compile, unlike Java @Override
override interface method not compile, unlike Java @Override
Java in C#
usingSystem;namespaceTutorial{abstractclassAbstractList// : object{// public AbstractList() : base() {}publicabstractintCount();publicvirtualboolIsEmpty(){returnCount()==0;}}classArrayList:AbstractList{privateobject[]data;privateintcount;publicArrayList()// : base(){data=newobject[2];count=0;}publicoverrideintCount(){returncount;}publicvoidAdd(objectelement){intcapacity=data.Length;if(count==capacity){capacity+=capacity/2;Array.Resize(refdata,capacity);}data[count++]=element;}publicobjectGet(intindex){returndata[index];}publicvoidSet(intindex,objectelement){data[index]=element;}}classProgram{staticvoidMain(string[]args){ArrayListal=newArrayList();al.Add("hello");al.Add("world");al.Add("and");al.Add("then");al.Add("goodbye");al.Set(0,"hi");Console.WriteLine(al.Get(4));}}}
usingSystem;usingSystem.Threading;namespaceTutorial{classSubjectExample{publicAction<DateTime>HellFrozeOver;publicvoidFreezeHell(){Console.Write("Freezing hell... ");Thread.Sleep(2000);Console.WriteLine("done!");if(HellFrozeOver!=null){HellFrozeOver(DateTime.Now);}}}classObserverExample{publicvoidLog(DateTimewhen){Console.WriteLine("Hell froze over on "+when);}}classProgram{staticvoidMain(string[]args){varsubject=newSubjectExample();varfirst=newObserverExample();varsecond=newObserverExample();subject.HellFrozeOver+=first.Log;subject.HellFrozeOver+=second.Log;subject.FreezeHell();Console.WriteLine("--------------------------------------");varthird=newObserverExample();// Whoops, accidental = instead of +=subject.HellFrozeOver=third.Log;// Whoops, delegate invocation outside of subjectsubject.HellFrozeOver(newDateTime(1912,4,15));}}}
The event keyword prevents such accidental misuse:
classSubjectExample{publiceventAction<DateTime>HellFrozeOver;publicvoidFreezeHell(){// ...}}// The event SubjectExample.HellFrozeOver can only appear// on the left hand side of += or -=// (except when used from within the type SubjectExample)subject.HellFrozeOver=third.Log;// dittosubject.HellFrozeOver(newDateTime(1912,4,15));