Tuesday, February 25, 2014

Summary - Jeff

NULLABLE VALUE TYPE:

  • Structure has two fields - value and bool hasValue (indicate if it's null).
  • Good use in LINQ to integrate with queries.
  • Java support null datetime, .Net doesn't so if Java is calling a web service with date time it can be null this can be handled by nullable type.
  • If the nullable type is null, Boxing doesn't happen CLR checks and just return Null.
  • Generally there is no memory allocation for Unboxing but if unboxing a value type into a nullable version CLR might have to allocate memory. it's because while boxing there is only value but for unboxing there is value + hasValue field.
  • GetType on nullable type get the actual value type as Int32 etc.
  • Casting from Nullable to IComparable works fine even though Nullable doesn't implement Icomparalbe but Int32 does, this is b'coz of special handling of CLR to nullable type.
  • Nullable == int32?.

CUSTOM ATTRIBUTES
  • Custom Attributes are instance of a type, derived from System.Attribute class.
  • All nonabstract attributes must contain at least one public constructor. but class can't offer any public method, events or other members.
  • Two important attributes are:
    • Target - where this attribute can be applied such as Enum
    • IsInherited - If the derive class of the class on which attribute is applied inherit the attribute behavior.
    • AllowMultiple - attribute can be applied multiple times, usually good for bit flag attribute for OR operator.
  • Attribute class whose constructor takes an array is not CLS compliant.
  • Important Methods:
    • IsDefined : efficient as doesn't construct object. Defined in System.Attribute and System.Reflection.
    • GetCustomAttributes : Defined in System.Attribute and system.Reflection. it desearilize and construct the array of attributes applied on type. System.Attribute method returns array of attribute while reflection return array of object.
    • GetCustomAttrubute: Define in system.attribute - return an instance of attribute class.
    • These method also checks derived attribute classes also so while defining your attribute class it's better to define it as Sealed.
  • Any time a attribute is returned by reflection a new instance is created so for comparison you might override System.Attribute.Match method as by default it simply calls Equal. So override - Match, Equals and GetHashCode for your attribute class to compare instances correctly. (basically comparing the fields in your attribute instance.)
  • Conditional attribute : When conditional attribute is applied on attribute class compiler will emit attribute information into metadata only when conditional symbol is defined in the code (#define TEST.... [Conditional("TEST")]) - good use in NUNIT as all nuint attributes are defined as conditional attributes so that test info is emitted when code is executed for nunit. this is done to avoid bloating meta data in prod run.
  • System.refleciton.CustomattributeDat. GetCustomAttributes - can be used to get attribute information without creating the instance of attribute class. Generally used to analyze CA when assembly is loaded using Assembly.reflectionOnlyLoad mthod.
GENERICS:
  • Generic Reference type, value type, Delegate type, interface type is allowed. Generic enumerated type is not allowed.
  • Advantages : Type safety, Reduce casting and boxing and this enhance performance.
  • For List and Arraylist of string performance is almost same but for generics code is cleaner.
  • Type with Generic type parameter is open type List and type with actual type is closed List. Instances of open type can't be created. Number are called Arity. list arity =1, dictionary arity = 2.
  • Each close type of same open type is treated as different type so if a type has static filed / constructor each close type will have it's own static field and const will exec separately.
  • Generics Identity : For simplicity use using instead of deriving from generic type as deriving will break the type identity. 
  • Code Explosion : For each method / Type combination diff native code should be generated - code explosion. But CLR does optimization to avoid this - for Each method/type combination native code is generated only once in appdomain. For all reference type code is generated only once (as ref type is just a pointer) but for value type code is generated for each value type. there will be code for List and List but native code is generated only once for List and List.
  • Type Inference : For clean and readability compiler tries to inference the type for calling a method. For ex 
    • Swap(ref T o1, ref T o2)
    • Ideal call - Swap(ref n1, ref n2) ; n1,n2 are int.
    • Inference call Swap(ref n1,ref n2). without
    • Swap(ref str, ref obj) - str ="1" -string and obj ="2" - object. Error - Type can't be inferred. B'coz for inference C# uses the variable's data type not the actual type of the object referred to by the variable.
  • Constraints:
    • Primary constraints : 0 or 1. special type - Class (not sealed) or struct. Nullable, object, array, delegate, enum etc is not allowed.
    • Secondary type : 0 or N.  represents an interface constraints. Other is type parameter constraints / Naked type constraints - define relationship between the types  where T:TBase.
    • Constructor constraints - 0-1. : constraint type is non abstract and offer public parameter less constructor.
  • Method can't be overloaded on type parameter names or constraints overload is allowed only on Arity.
  • When overriding a virtual generic method, overriding method must specify the same number of parameters and inherit the same constraints. can't add any constraints.
  • To set the default value of T use "default(T)". 
  • Using unconstrained T take care of what could be done as it could be value type or ref type etc. as if(o1==o2) gives error as o might be value type and all value type (defined struct) doesn't have == override all ref type though have by the virtue of being inherited from object.


DELEGATES:
  • Type safe call back mechanism.
  • Delegate d = new Delegate( callback method) : Delegate object is a wrapper around a method, allowing method to be called back indirectly via wrapper.
  • Private method of a class can be invoked using public Delegate wrapper. 
    • Public MyDelegate GetWrapper() { return new MyDelegate(private method);}
  • Delegate supports Covariance in return type and Contravariance in input parameter type. covariance and contravariance is supported only for ref type not for value type.
  • Delegate translates into a class which inherits from System.MulticastDelegate which in turn inherits from System.delegate, following methods are created for any defined delegate:
    • Constructor
    • Public virtual void Invoke (same signature as call back method)
    • BeginInvoke
    • EndInvoke
  • Methods of delegate class : Target - Instance of class, Method - call back method pointer and InvocationList - Array of delegates to invoke - Delegate chain.
  • += and -= are overload method for Delegate.Combine and Delegate.Remove which add/remove delegate to invocationlist array.
  • Array of delegates are invoked in loop - issue is the result of only last delegate/callback method can be retrieved and also if there is exception in executing one delegate all are impacted. To handle these scenario Delegate class provide GetInvocationList method which returns the array of delegates to be invoked to user and user can handle each invocation.
  • Delegate can also be created at run time using reflection information. System.delegate offers CreateDelegate method for this as:
    • Public static Delegate CreateDelegate(Type,MethodInfo) - both these parameters can be retrieved using reflection.
    • There are couple of other overloads for CreateDelegate mthod.
    • Create delegate return an instance of delegate class (d).
    • Delegate DynamicInvoke instance method allows to dynamically invoke delegates. d.DynamicInvoke(CallbackArgs).
INTERFACES:
  • Interfaces is a CAN DO relationship. Abstract is ISA relationship. Is a set of method.
  • Events / Properties / Indexers can be defined as these all translate to methods. Can't define an instance field as Interface can't be instantiated.
  • Though CLR does allowed static methods/fields/constants/constructor but C# doesn't allow any of these static members.
  • Interface is like a type so just like type it can be nested in another type and any visibility/accessibility can be set on interface.
  • C# compiler requires that all interface method must be marked public.
  • CRL requires that interface method must be marked as virtual.
    • If we don't mark interface method as virtual, compiler with mark the method as virtual and sealed, which means derived class can't override it (it's like non virtual) But derive class can re-inherit the same interface and provides it's own implementation (with new keyword).
    • If we explicitly marked interface method as virtual compiler doesn't mark it as sealed, which means derive class can override interface method.
    • When calling an interface method on an object, the implementation associated with the object's type is called.
    • Class Base : Idisposable { public void dispose ())} //implicit - Virtual sealed.
    • Class derive : Idisposalbe { new public void dispose()}
    • Base b = new derived(); b.dispose() // Base dispose as dispose is like non virtual called on type of variable.
    • Idisposable d = new derive(); - // Derive dispose.
  • Using variable on interface type all method of an interface + all method define by an System.object can be called.
  • Variable from one interface can be cast to another interface as long as the object implements both interfaces.
  • Value type can also implement interfaces. But using value type with interface variable requires boxing because interface variable is a reference that must point to an object on the heap.
  • EIMI - Explicit interface method implementaion : If a class explicitly implements an interface method (Idisposable.Dispose()...) than that method can be called only by interface variable and can't be called by type variable. 
    • C# doesn't allow to mark any accessibility on EIMI method as compiler marks them private to prevent calling it from class instance, can only be called from interface variable.
    • EIMI method can't be marked as virtaul as they are not actually part of type object model.
    • EIMI method should be avoided as much as possible. use of generic interface offer some help in avoiding EIMI.
  • Generic interface can be defined for compile time type safety. can be used for by value types to avoid boxing. 
  • A type can implement Generic interface multiple time each with different type .
  • Generics and interface constraints can be used to make sure that input type is implementing all constrains interface.
    • Public static void M(T t) where t : Icomparable, Iconvertible => that method M will accept only types that implements both Icomparable and Iconvertible.

ARRAYS:
but for DateTime[] darray type will implement only . This means darray could not be passed to M3 ( void M3(IEnumerable oenum) whiel farray could be.
  • System.Array : System.Object.
  • Jagged arrays - Arrays of arrays.
  • Memory is allocated when you create a new array with new keyword
  • Single-dimensional, zero-based arrays are also referred as SZ arrays or Vectors.
  • For value type array memory is allocated on managed heap which hold unboxed values of value type for ref type arrays memory hold the reference to actual ref type object.
  • Casting is allowed from one ref type array to other ref type array implicitly or explicitly but casting is not allowed for value type. object[] o = new int[10] - Error.
  • value type can be casted using Array.Copy method. Copy just not copy but also does boxing/unboxing and if required widening as required in casting from int to double. Also downcast ref type if direct casting is not compatible for ex object[] to IFormattable[]  if every object implements IFormatable.
  • Array.Copy - does the shallow copy so if the array elements are ref type the new array will refer to the already existing objects.
  • Type safety - All elements in an array are of same type it checks at run time. if an array of object is assigned string and then int then assignment of int will throw type mismatch error at run time. since int derive from object compiler allows assignment at compile time.
  • All arrays implements IEnumerable, IColleciton and IList (all non generic versions). Internally compiler implements Generic version of these interface. For ref type generic version of the type + all its base type is implemented for value type only generic version of value type is implemented. For FileStream[] farray - the type will implement all three interfaces for , and
  • Each array in Memory has array elements plus some overhead information like number of dimensions, lower bound of each dimension length of each dimension and element type.
  • Creating Non-Zero-Lower Bound arrays : System.Array.CreateInstance : Can create instance at run time it take array overhead parameters as input and allocates a memory on heap and return it's reference. This can be used to create non-zero bound arrays.
  • CLR does support non-zero bound array but their use is discouraged due to performance issue and language portability issues.
  • CLR does some optimization for zero bound arrays such as Length is checked and cached and index is checked before the loop to avoid these to be performed for each element access. These performance can also be acheived using unsafe array access but that's allowed only for some primitive type....?? Unsafe access avoid index bound checking.
  • Accessing Jagged array is more efficient than accessing Rectangular arrays (multi dimensional).
  • For performance critical app use stackalloc to allocate array on thread stack and use unsafe array access to access elements. stackalloc can be used only for vectors of value type and value type should not contain any reference type field.**

ENUMS
  • Use to define name value pair. Compiler treat it as primitive type.
  • System.Enum : System.ValueType : System.Object
  • Compiler convert enum type to a structure with each element as constant and one instance filed (but instance field can't be accessed). The constants fields are emitted to assembley's meta data and can be accessed via Reflection.
  • Since it's convert to constants it's turn out to be a compile time feature where ever it's used directly but if it's used in method like parsing etc then enum assembly is required at run time.
  • The underlying type for an enum could be byte,int,short,ushort,sbyte.
  • Enum doesn't offer any support for localization, so toString() can be used to format values.
  • If [Flags] is applied on Enum then each enumerated type represent a set of bits, some of which are on and some of which are off. Used to convert a numeric values into string of flags and vise versa. IsDefined will not work on Bit Flags enums because input comma separated values treated as single string which wouldn't match and input numeric value will also not matched with bits.

STRINGS:
  • System.Char - Value type a structure.
  • Letter casing is culture dependent while Comparison is not culture sensitive.
  • System.String : System.Object - Ref Type - Array of characters.
  • Can't create string object with new keyword unless using unsafe code. string s = new string("gauri") - Error. String have some constructor which takes char*/SByte* as input and return string object (unsafe though).
  • Strings are immutable once created can't be modified.  Which also means that there is no thread synchronization issues when manipulating or accessing a string.
  • string class is tightly integrated with CLR which has lot of optimization for string class that's why this class is sealed to make sure none of the optimization assumption CLR is making goes for a toss in derived classes.
  • String comparison has two param - Culture and Casing. Explicitly mention this for good programming. For programmatic strings (not to be shown on UI) use Ordinal comparison - StringComparison.Ordinal / StringComparison.OrdinalIgnoreCase (culture insensitive) that is fast.
    • Use ToUpper instead of ToLower as toupper is optimized by CLR.
    • CompareTo performs culture sensitive comparison while equals performs ordinal comparison.
    • In culture sensitive comparison different looking same characters will compared as equal. as German "B" and English "B" will be equal. Also string of different length can be considered equal.
    • System.StringComparer - Use If same type of comparison has to be performed repeatedly for many string .
  • String Interning : To avoid copying of same string and use the intern string instead, this will reduce the memory foot falls.
  • String Pooling : Many compilers including C# write the same literal string into module's metadata only once to avoid memory bloating.
  • StringBuilder:
    • Use to manipulate string efficiently.
    • MaxCapacity (int32.MaxValue), Capacity (default is 16) and Char Array are important properties of string builder.
    • If size of character array increases than capacity, string builder create new array with double of capacity - that hurts performance so keep the capacity large enough to hold required characters.
    • Equals method returns true if both StringBuilder objects have same max capacity, capacity and characters in array.
  • All base types built into FCL such as int,byte,double override toString method to return culturally aware string.
  • IFormatProvider : When a type implement this interface, it is saying that an instance of the type is able to provide culture specific formatting information and culture information associated with the calling thread should be ignored.
    • Numeric type also support picture format strings.
    • In FCL just three types implement IFormatProvider - CultureInfo, NumberFormatInfo and DateTimeFormatInfo.
  • Encodings : In .net all characters are represented as 16-bit Unicode values.
    • Transferring 16 bit values over network is not very efficient as half of the bytes written would contain zero.
    • Encoding is typically done when string is send to a file or network by using System.Io.BinaryWriter or System.IO.StreamWriter similarly decode is used while reading using BinaryReader and StreamReader.
    • UTF-16 : All char as 2Bytes, no compression so performance is excellent. Also known as Unicode encoding. Can covert little endian to big endian (little left number is smallest and vise versa).
    • UTF-8 : This default and it uses 1-4 bytes for diff chars. Extremely popular but less efficient than UTL-16.
    • ASCII encode : Encode 16 bit char into ASCII characters But all characters can't be converted to ASCII so those are lost.
  • FCL type also supports secure string which is mandated by some Gov transaction. System.Security.SecureString - using this object allocates unmanaged memory to keep it away from garbage collector, secure string is encrypted

C# Types
  • Default accessibility for a class is internal i.e visible to assembly. It's also possible to access  internal members of a assembly from other assembly, By marking other assembly as Friend assembly. Friend is declared by decorating it with attribute [assebmly : InterVisibileTo(Assembly name, public key token)]
  • For method default visibility is Private. Derive class overriding method must have the same visibility as base class method(C#) but CLR allowed less restrictive accessibility modifier for overriding methods.
  • Static classes are marked as Abstract and sealed by compilers.
  • CLR nothing knows about partial classes so they must be written into same programming language to compile them into single unit. two partial classes can't reside in different assemblies. Two classes in same assembly can't have different languages.
  • Readonly fields are written only within constructor method, other then this Reflection can be used to modify readonly fields.
  • Constants are like Static read only field with only difference is static read only get the value at Run time and it's less efficient than constants.
  • For reference type Readonly field only reference is immutable not the object it's referencing. so If read only field refer to Array, array values can be changed.
CONSTRUCTORS and METHODS:
  • Instance constructor and Static Constructors.
  • Instance Constructor for Ref Type:
    • Compiler generates a default parameter less constructor which calls the base constr.
    • Object can also be created without executing constr, using object.MemberwiseClone method which allocate memory and copies byte by byte.
    • Inline Initialization code for instance variable will be put in all constructors so it's better to define one initialization constr and call it from other constr.
  • Instance constructor for value type:
    • C# doesn't allow parameter less constr for value type. But CLR does.
    • Const need to call explicitly no compiler support for automatic calling.
    • Any defined constr should initialize all instance field else compile time error.
    • Inline initialization is not allowed as parameterless constr is not allowed.
  • Static Constructors / Type Initializers / Class constructor :
    • Can't be applied to Interfaces (C#) . CLR allow this.
    • Type cnstr is marked private by Compiler, can't mark private explicitly.
    • C# doesn't allow parameterized static constructor as it's private no use.
    • Can be define on Ref/Value type. Value type allows static parameterless constructor and inline initialization for static instance fields.
    • CLR make sure that it execute only once in appdomain and any type can't have more than one type constructor.
    • JIT emit the type constructor call in two ways : Precise semantics or before-field-init semantics (preferred). In before init constr is called some time before the code that is accessing the static field. before init is used when Inline initialization is done, precise is done when explicitly type constr is defined for field initialization.
  • Operator overload are feature of compiler and languages, CLR doesn't know anything about operator overload for CLR it's just a method. method should be public and static. 
    • public static Complex Operator+(Complex c1, Complex c2) - this translate into op_Addition(Complex c2, Complex c2)
    • Core FCL type int etc, don't define any operator overload method as overloading will cause runtime performance hit, because for these primitive type compiler put appropriate IL instructions.
    • If a language doesn't support operator overloading it must provide op+* methods directly for interoperability (such as op_Addition)
  • Conversion Operator Method:
    • For converting one type to other the source type can offer constructor, ToXXX methods or conversion operator. For casting a int type from Rational type.
    • public Rational(int32 num){} - Constructor.
    • public int32 ToInt32(){return new int(...)} - Method. 
    • public static Implicit Operator Rational(int32 num) { return new Rational(num) }  - To allow implicit conversion from int to rational. Rational r1 = 5;
    • public static explicit operator Int32(Rational r) { return r.toInt32();} - To allow explicit casting. Int32 i = (Int32) r1;
    • op_Implicit / op_Explicit.
  • By default CLR assumes that all method parameters are passed by value.
  • Passing value type as ref, changed value in caller will be available to callee while if passed as val changed value will not be available to callee.
  • Passing ref type as ref, will pass the pointer as ref type so if pointer is change to point new object callee will get this new object. if ref type is passed by value and pointer is changed to point to new object callee object will not change but any changes in the actual object will be available to callee in both ref/val for ref type.
  • ex : http://msdn.microsoft.com/en-us/library/s6938f28.aspx
  • Properties:
    • Simplified way of calling a method. Fields are objects's state.
    • OOPs - type's field should never be publicly exposed as it breaks data encapsulation principle as caller can modify the field in any way.
    • Define properties for data encapsulation, properties are get and set method which should modify the type fields. These fields should be parked as private. these fields are commonly referred as backing fields. 
    • Properties can't be overloaded.
    • Properties vs Fields : read/write, can throw exception, can't passed as ref or out param to a method, should not be used if thread synchronization is required, should not be used in remote objects (implementing MarshalByRefObjects) as it's very slow in marshaling, can return diff value on each call (dateTime.Now - now is property).
    • Parameter properties are called indexers. 
      • C# doesn't allow static indexers.
      • C# uses this[..] syntax to access indexers. Developer can't name the indexers. default compiler generate is get_item/set_item.
      • Developer can choose to rename this default _item name by decorating it with [Indexername] attribute (say "Bit", name would be get_Bit/set_Bit).
      • Indexers can be overloaded as long as they have diff number of parameters.
    • Property itself be marked with less restrictive accessibility than any one on the accessor methods. property - Public and either get or set can be Protected.
PRIMITIVE, REFERENCE AND VALUE TYPE:
  • Any data type which has direct support of compilers are called Primitive type.
  • string - primitive type which is mapped to System.String FCL type there is no difference in using them.
  • For primitive type does the casting implicitly or explicitly even for different data type (int32 and int64). C# allows implicit casting when conversion is safe and no data loss is possible.
  • Overflow exception : while casting if overflow checked is enabled it throws exception else casting is done with loss of value. by default C# overflow is not checked so no exception. keyword is checked/unchecked. Checked((BYte) 100+200) or code block can also be created - checked {....}.
  • System.Decimal type is considered as primitive type by C# but not by CLR so CLR doesn't have IL instruction to know how to manipulate decimal type, so manipulating decimal type is slower and checked/unchecked operators and compiler switches have no effect. that's why operation on decimal always throw overflowexception if the operation can't be performed safely.
  • When a type offers no member to alter it's fields we say the type is immutable. 
  • Value type : 
    • Value type is either structure or enum.
    • System.Enum(abs) : System.ValueType (abs) : System.Object.
    • All value types are sealed.
    • Use value type if you don't need inheritance, it's immutable, size is small because by default arguments are passed by value, which causes fields in these value type to be copied on caller stack similarly for return type if it's value it's again get copied.
    • Value type can exists in two form - Boxed and Unboxed.
    • Each value type overwrites Equals and GetHashcode method to return true if value is equal and include value in hash code.
    • Assigning a value type variable to another variable, a field by field copy is made.
    • Unboxed value type are allocated on stack and get's cleared as soon as method defining them get inactive => value type instance don't receive notification when it's memory is reclaimed.
    • C# doesn't allow finalize method in value type.
  • Boxing : Reference to an instance of value type. - Memory allocation, values are copied to memory and address of memory is returned.
  • Unboxing : Getting the address of the field of value type object. 
    • Unboxing is less costly as it just get the address and unlike boxing it doesn't involve the copying of any bytes in memory.But unboxing is always followed by field copy as caller reads the boxed values after getting the address.
  • All objects on heap has two overhead fields - type object pointer and sync block index. Since unbox value on stack doesn't have sync block index - synchronization is not required for multi-threaded application.
  • Since value types are sealed, CLR calls value type virtual methods non virtually. Equals, GetHashCode and ToString virtual methods of object are overridden in value types and are called non virtually by passing unboxed ref of value type in "this" argument. But some non virtual methods GetType and MembwiseClone are defined in object and so expect "this" argument as ref to boxed value type. so when these methods are called, boxing happens.
  • Object Equality and Identity:
    • Identity - Two references point to same object. 
    • Equal is a virtual method in object class and it's default implementation is to check identity.
    • Since Equal can be overridden, it should not be used to check identity equality, for identity check use Object.ReferenceEquals static method.
    • Overriding Equals logic : x.Equals(obj)
      • If Obj is null - return false.
      • if this and obj refer to object of different type - return false.
      • Compare each field to check equality and call base.Equals to let base class also checks it fields for equality.
    • System.Valuetype overrides Equals method with same logic but don't call base(object's) equal method. For comparing it uses reflection so for custom value type it's always good to override equal and write logic to compare values and avoid reflection for that (don't call base.equals else it will go to reflection again.
    • Also a type can implemetn System.IEquatable interface equals method.
    • Also overload operators == and != to call type safe overridden equals method.
    • If your type is being used in comparison such as in sorting - implement IComparable CompareTo method and also provide overload for different comparison operators liek <, >, >= etc.
    • If you are overriding Equals, you also need to override GetHashCode virtual method of System.Object. (if not compile will issue warning....). This is mandatory because Hashtable and Dictionary required that two objects that are equal must have the same hash code.
    • System.Object.GetHashCode return an unique identity for an object in the appdomain. after object is garbage collected that identity can be reused. If GetHashCode is overridden,Unique identity for an object is not guaranteed so to get a object's unique identity use System.RunTime.RunTimeHerper.GetHashCode.
    • Value type GetashCode uses reflection so it's slow.
  • Strong Assemblies are first looked into GAC and than in AppBase, weak assembly are first looked into AppBase. For strong assemblies CLR looks into AppBase only if no codeBase element is specified. codeBase element can also be used with weak assemblies. For weak assembly Private path can be used in publisher policy xml to probe the assembly.