430 likes | 504 Views
Compare C# with C++, master C# syntax & features like arrays, enums, exceptions, structs, and constants. Learn performance tips and useful language insights.
E N D
Introduction • At the end of this lecture you will be able to: • Compare and understand the some of the differences between C# and C++. • Understand the syntax and usage of the different aspects of the C# language
References • Nagel, Christian et al, Professional C# 2005, Wrox Press, 2005 • Chapter 1, Appendix D • Chapter 5 — Improving Managed Code Performance : • http://msdn2.microsoft.com/en-us/library/ms998547.aspx • Rico Mariani's Performance Tidbits: Performance Quiz #11: Ten Questions on Value-Based Programming • http://blogs.gotdotnet.com/ricom/archive/2006/08/31/performance-quiz-11-ten-questions-on-value-based-programming.aspx • Rico Mariani's Performance Tidbits: Six Questions about Generics and Performance • http://blogs.gotdotnet.com/ricom/archive/2004/09/13/229025.aspx
Arrays • Are proper System.Object derived classes, not simply a contiguous chunk of memory as in C++ double [] array; // Simply declares a reference without actually // instantiating an array. array = new double[10]; // Actually instantiates a System.Array object, // and gives it size 10. • Shortcut: double [] array = new double[10];
Arrays • Arrays are sized only when instanced, the declaration [ ] indicates rank • Explicit initialisation: double [] array = new double[10] {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0}; double [] array = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0}; • If not explicitly initialised, default constructor is called
Arrays • Can use .Length property to determine size for (int i=0; i<array.Length; i++) array[i] *= 2.0f;
Arrays • Multi-dimensional Rectangular: int [,] myArray2d; myArray2d = new int[2,3] { {1, 0}, {3, 6}, {9, 12} }; int [,,] myArray3d = new int[2,3,2]; • Indexed: int x = myArray3d[1,2,0] + myArray2d[0,1];
Arrays • Jagged arrays int [][] myJaggedArray = new int[3][]; for (int i=0; i<3; i++) myJaggedArray[i] = new int[2*i + 2]; • Indexed: int x = myJaggedArray[1][3];
Arrays • Bounds checking is performed automatically by the runtime • IndexOutOfBoundsException will be thrown • Arrays are not resizable after they are defined, to use resizable lists etc. consider a class in the System.Collections namespace • Jagged arrays offer performance benefits over mutlidimensional arrays due to MSIL optimisations. • However jagged arrays are not CLS compliant and so cannot be used across languages ( OK for private classes and assemblies though ).
Enumerations enum TypeOfBuilding {Shop, House, OfficeBlock, School} • Numbering elements: enum TypeOfBuilding {Shop, House=5, OfficeBlock, School=10} // Shop will have value 0, OfficeBlock will have value 6 • Name of enumeration must be used to access: TypeOfBuilding MyHouse = TypeOfBuilding.House
Enumerations • Can use methods derived from the System.enum class TypeOfBuilding MyHouse = TypeOfBuilding.House; string Result = MyHouse.ToString(); // Result will contain "House" TypeOfBuilding MyHouse = (TypeOfBuilding)Enum.Parse(typeof(TypeOfBuilding), "House", true); • Select underlying type to store enumerated data enum TypeOfBuilding : short {Shop, House, OfficeBlock, School}; • Defaults to int
Exceptions try { // normal code } catch (MyException e) // MyException derived from System.Exception { // error handling code } // optionally further catch blocks finally { // clean up code }
Exceptions • Exceptions must be derived from System.Exception class • finally block contains code which is always executed after the try block, regardless of whether any exceptions were thrown • It is optional • Useful for cleaning up resources allocated in try block • Also useful for control flow
Structs • Same syntax as classes except keyword struct replaces class • Structs are value types which are created on the stack • Has a default, non-overridable, no-parameter constructor which zero out all member variables • Other parameter constructors can be defined • Must be initialised with new
Classes vs Structs • Consider using Classes when: • There will be subtyping • Synchronisation. • We are interested in keeping track of special instances which have their own ‘identity’ • e.g. RenderSystem • Consider using Structs when: • None of the class benefits above apply. • Large collections of this type are required and will be iterated through. • e.g. Point3D struct.
Constants • Constant member variables: class MyClass { public const int MyConstant = 2; } int SomeVariable = MyClass.MyConstant; • Static Constants: class MyClass { public static readonly int MyConstant; static MyClass() { // work out and assign the initial value of MyConstant here } }
Constants • Instance Constants: class MyClass { public readonly int MyConstInst; MyClass() { // work out and initialize MyConstInst here } } • const keyword define value at compile time, readonly keyword defines value at runtime (hence enable setting of values in static and non-static constructors)
Operator Overloading public static MyClass operator + (MyClass lhs, MyClass rhs) { MyClass Result = new MyClass(); Result.x = lhs.x + rhs.x; return Result; }
Operator Overloading • Can overload the following operators: • Binary arithemetic: +, -, /, *, % • Unary operators: ++, -- (prefix only) • Comparison Operators: !=, ==, <, >, <=, >= • Bitwise operators: &, |, ~, ^, ! • Boolean value: true, false
Operator Overloading • Cannot override the following: • Arithmetic assignment: +=, -=, *=, /=, %=, these are worked out automatically based on the arithmetic operators • Postfix increment operators, these are worked out by calling the prefix increment but returning the old value • Bitwise assignment operators: &=, |=, ^=, >>=, <<= • Boolean operators: &&, ||, these are worked out based on bitwise operators • Assignment operator: =, the meaning of this is fixed • Must override in pairs: == and !=, < and >, <= and >=
Indexers class MyClass { public long this[int x] { get { // code to get element } set { // code to set element. eg. X = value; } } // etc.
Indexers • Can’t override [ ] operator • Indexers allow similar functionality • Parameter in [ ] can be of any type • set is called when [ ] operator is to the left of an assignment • get is called when [ ] operator is to the right of an assignment
Casting Operators public static implicit operator MyDest (MySource Source) { // code to do cast. Must return a MyDest instance } • Must be defined static • implicit: for use implicitly, should always work • explicit: for use explicitly, may result in loss of data or thrown exception
Casting Operators • C# inherently supports casting between base and derived classes, users cannot define these cast operators • Will throw an exception if casting from base to derived • Using as keyword returns null if cast fails, no thrown exception // assume MyDerivedClass is derived from MyBaseClass MyBaseClass MyBase = new MyBaseClass(); MyDerivedClass MyDerived as (MyDerivedClass) MyBase; // this will return null
Pointers and Unsafe Code • Pointers exist in C# and can be used inside an unsafe code block • Methods: public unsafe void MyMethod() { • Classes / Structs: unsafe class MyClass { • All members will be regarded as unsafe • Member variables: private unsafe int* pX; • Code block: unsafe { // statements that use pointers }
Pointers and Unsafe Code • Not permitted to dereference or perform arithmetic operations on void* pointers • Pointers cannot point to reference classes • Must also specify /unsafe flag as a compiler option • Can point to value data inside reference classes if contained within a fixed block
Fixing Data on the Heap class MyClass { public int X; // etc. } // Elsewhere in your code ... MyClass Mine = new MyClass(); // Do processing fixed(int *pX = Mine.X) { // Can use pX in this block. } // nested fixed(int *pX = Mine.X, *pX2 = Mine2.X) { }
Fixing Data on the Heap • Stops Garbage Collector from moving this object around on the heap for the duration of the fixed block • Needed so that the pointer can be correctly dereferenced to the right data
Arrays on the Stack • Low overhead, very similar to C++ arrays ulong *pMyArray = stackalloc ulong [20]; • Can specify size at runtime int X; // Initialize X ulong *pMyArray = stackalloc ulong [X];
Interfaces • Similar to abstract classes interface IMyInterface { void MyMethod(int X); } • No access modifiers • No implementation
Interfaces • Classes can derive from one or more interfaces (called implementing) class MyClass : MyBaseClass, IMyInterface, IAnotherInterface // etc { public virtual void MyMethod(int X) { // implementation } // etc.
Interfaces • Interfaces can derive from one or more interfaces • Can cast classes to interfaces
Delegates • Like function pointers in C++, but can refer to instance methods class MyClass { void MyMethod(int X) { // etc. } } MyClass Mine = new MyClass(); // Instantiate a MyOp delegate. Set it to point to the MyMethod method // of Mine. MyOp DoIt = new MyOp(Mine.MyMethod); DoIt(10);
Delegates // Define a delegate class that represents a method that takes an int and // returns void delegate void MyOp(int X); • Definition of delegate class must include full signature of the wrapped method
Delegates • Multicast delegates: with void return types • More than one method can be wrapped within the delegate using the += and -= operators • Invoking the delegate calls all the methods wrapped within it
Events • Special form of delegates supporting the callback event notification model delegate void EventClass(obj Sender, EventArgs e); • Delcaration: public event EventClass OnClickEvent; • Adding handlers: EventSource.OnClickEvent += MyHandler; • Alerting handlers: OnClickEvent(this, new EventArgs();
Generics • New to C# .NET 2.0 • Similar to C++ templates public class MyGeneric<T> { private T element; public T Method(T parm) { return null; } }
Generics • However, if class members of T were accessed within the class, we must specify either a base class or interface that T derives from. public interface IDemo { void Demo(); } public class MyGeneric<T> where T : IDemo, new() { public void Method() { T obj = new T(); obj.Demo(); } }
Generics • The where clause specifies the interfaces and base classes that the T class must derive from • The new() specifies that the T class must contain a default constructor • Prefer using Generic container classes over the older style container classes such as ArrayList for type safety and performance benefits.
Attributes • Classes which apply to code elements, used for generation documentation or additional compiled code settings • Syntax: [Conditional("Debug")] void DisplayValuesOfImportantVariables() { // etc. • Included with [ ] before the code element it is applied to
Attributes • Examples: • Conditional: Only compiles if symbol is defined by preprocessor • DllImport: Method is defined in external DLL • StructLayout: Contents of struct to be layed out in memory, like C++ union • Obsolete: Compiler generates warning if this method is used
Preprocessor Directives • Reduced subset of C++’s • #include not supported (not required) • #define, #undef • Same as C++, though must occur before any C# code • #if, #elif, #else, #endif, #line, #warning, #error • Same as C++ • #region, #endregion • To block off regions of code, for collapse/expansion formatting by IDEs
Review • Compare and understand the some of the differences between C# and C++. • Understand the syntax and usage of the different aspects of the C# language