Wednesday, 27 May 2015

Generics

Generics allow code reuse with type safety.  A generic is a class that defers specifying the type until it is instantiated by the client.

Generics

In ArrayLists, you store references to objects, and so when retrieving an object from an ArrayList you typically had to cast it into the type you want.  Also, you couldn't prevent objects of the wrong/a different type being added into your array (because the array holds refs to objects).  So an ArrayList of employees would happily accept you adding a string into the array.  You'd probably get an error when retrieving that array item though.  You lost type safety and had to do lots of checks and casts.  If you wanted different types of ArrayLists, e.g. Employees and Projects, you'd have to write practically identical code to create your own custom ArrayList type.

Generics avoid all of that.  Also produce better performance due to no boxing for value types

Generic Collections:-
  • HashSet<T> - Set of items; no duplicates allowed.  (Compiler calculates the hash value of every item being added to ensure no other objects with the same hash)
  • List<T> - Like an array that can dynamically array.  No restrictions on type, duplicates.  Methods to sort, order list.
  • Queue<T> - FIFO list  (Enqueue and Dequeue operations)
  • Stack<T> - LIFO (push and pop operations).
  • Dictionary<Tkey, Tvalue> - Key, Value pair.  Look up by Key using hash codes, not index over a list.

Generic Types for value types, e.g. List<int>.  CLR generates a specialised generic type for that value type.  (So the generic type for a List<int> is different from the generic type for a List<datetime>.  It pre-allocates space on the heap for these types.  Thus the List<int> stores ints, not references to objects, so there is no boxing/unboxing required.

It is slightly different for ref types, e.g. List<employee>.  The Run time creates a specialised generic of ref types, irrespective of what the ref type is.  So List<projects> will create the same specialised generic type as List<employee>.  (Like templates in C++).  Pointers are always the same size for a ref type, hence you can use one specialised ref type for generics holding a ref types.

Public class MagicHat<T>
{
   public void Add(T thing)
  {
      _things.Add(thing);
  }
  List<T> _things;
}

//
Rabbit rabbit = new Rabbit { Name = "Fuffy" };
MagicHat<Rabbit> _rabbitHat = new MagicHat<Rabbit>();
_rabbitHat.Add(rabbit);

Or
Class MagicHat<T> : Queue<T>
{}


Generic Constraints

Restrictions on the type of parameter
Force the type to be a struct or class
Force the type to have a public default constructor
Force the type to implement an interface or derive from a base class

Public class MagicHat<Tanimal> where Tanimal : Ianimal
{
  …
}

Need at least 1 constraint when you want to perform some operation within the generic collection class that isn't supported by System.Object.

Null references and Generic Types

It's ok to compare value types with null (It's always false)
But it's not ok to assign null to a <T> because you can't assign null to a value type.  (Set a constraint where T: class enforces ref types).

Where T: class, new()    <- new() enforces a default constructor (0 params)
To ensure a type has a method, force it to implement an interface.  The interface defines that method.  (Could also be a base class).

Generic Terminology : Type Classifications

Unbound generic types.  Type param hasn’t been specified - List<>
Can be used in reflective code with the typeof operator.  It's a blueprint to create other types.  The opposite is a constructed generic type

Constructed Generic type - two forms
Open Generic Type - has type parameter that still needs to be substitued - List<T>
Closed Generic Type - has no type parameters - List<int>

An object constructed from an instance of a generic type is a concrete object
At runtime, code executes in a closed, constructed type.

Thus in inheritance - when a generic class inherits, you can't inherit from an unbound generic type - must be constructed (but could be open or closed).
Thus:
Public class AnimalCollection<Tanimal> : Icollection<Tanimal> {}
Or
Public class AnimalCollection<Tanimal> : Icollection<int> {}


When defining a non-generic type that inherits, it can only inhert from a closed constructed generic type.  Thus:
Public class RabbitCollection : Icollection<Rabbit> {}


Might see this in Reflection or Inversion of control container programming.

The default keyword

The default keyword can be used to assign a default value to a generic when you don't know if it will be using a value or reference type.  Useful for returning results from a method instead of raising an exception.     You can't return a null as you can't assign a null to a value type.

C# supports Generic Interfaces and Generic Delegates (EventHander, Func, Action and Predicate).
Generics and Variance
Before C# 4.0 generic collections were invariant.  That is they didn't support polymorphism.  If a generic class Dog implemented IAnimal you couldn't pass an object of type Dog into a method that expected an input parameter that implemented IAnimal  Generics were invariant.  This changed in C# 4.0, with exceptions.

  • <T> must be a reference type
  • It only works with some specific generic interfaces - IEnumerable<T>, IEnumerator<T>, IQueryable<T> and IGrouping<T> (These are popular with Linq)




C# and the CLR. Compilation & GC, threads, asyncrhonous programming, reflection and interoperability

JIT Compilation and Garbage Collection

GC cleans up unused memory (on heap, i.e. no refs to memory location). Visits global variables and local variables to determine what is in use.

Frees up and compresses memory - defrag for memory - and fixes refs of objects moved in memory.

You can use the GC problematically via  a class GC with static members and properties. sssss CollectionCount(0), (1), (2) reflect the three generations

When an object is first created it is in generation 0.  If it survives a GC, i.e. still referenced when the GC runs, then they are promoted to generation 1.   If it survives another GC then it is promoted to GC 2.   Generation 0 is  GC'd much more frequently that generations 1 and 2.  Many objects are short lived (with scope only for  method) and hence stay in generation 0 so it is GC'd more frequently.

Threads

System.Threading - low level API for starting, stopping and joining threads
System.Threading.Tasks - high level API for concurrent and asynchronous programming. (New .net 4)

using System.Threading.Tasks
string[] urls = {"http://website1.com", "http://website2.com", "http://website3.com"};

Parallel.ForEach(urls, url => {
   var client = new WebClient();
   var result = client.DownloadString(url);
   // ...
});

Parallel is a higher level API

Asynchronous

WCF Service proxies and other libraries such as the web client class have asynchronous versions of methods.  These are preferable generally as they can use threads from the thread pool and easily recycle them, rather than having to create a new thread.

Low Level API System.Threading


using System.Threading
string[] urls = {"http://website1.com", "http://website2.com", "http://website3.com"};

foreach (var url in urls)
{
    Download(url);
}

private static void Download( string url)
{
  var client = new WebClient();
  client.DownloadStringCompleted +=  client_DownloadStringCompleted;
  client.DownloadStringAsync(new Uri(url), url);
}


public static void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
    var html = e.Result;
    var url = e.UserState as string;
    //Do something here
}

You need to wire up an event handler to DownloadStringCompleted to execute when the thread has finished downloading the string.  The compiler can figure out the type of event handler so you just need to give it the name of the method to execute when ready.

The second parameter in DownloadStringAsync is a user token that you can use to "tunnel" additional information, such as the url being downloaded, into the event handler.

You don't need to fiddle around creating threads, and could potentially reuse a thread if one task completes very quickly.  But your code is splattered through three methods.

High Level API System.Threading.Tasks

Parallel can invoke something directly, or you can iterate over a collection with a .ForEach.  Provide the collection and an expression to tell the task parallel library what to do (using a lambda expression).

using System.Threading.Tasks
string[] urls = {"http://website1.com", "http://website2.com", "http://website3.com"};

Parallel.ForEach(urls, url => {
   var client = new WebClient();
   var result = client.DownloadString(url.ToString());
   // ...
});

However the main thread will block until all parallel tasks complete. (The lower level async coding didn't block).

Reflection and Metadata

Reading metadata of the assembly / code running by reflecting on itself.  Typically starts by getting a reference to a System.Type object using either (at run time) the .GetType method available on every object or (at compile time) the TypeOf operator.

With this type reference you can query the type to get info, e.g. properties, members, etc.  Most only return public members/properties by default.  There is an overloaded version that allows you to pass in binding flags (an enumeration) you can OR together.

using System.Reflection;

static class Program
{
    static void Main(string[] args)
    {
         var type = typeof (Program);
          var members = type.GetMembers(BindingFlags.Static |
                                                                 BindingFlags.Instance | 
                                                                 BindingFlags.NonPublic |
                                                                 BindingFlags.Public);
        foreach (Var memberInfo in members)
        {
              Console.WriteLine(memberInfo.Name);
        }
    }
}

Can also look at attributes (DataAnnotations) on a member or property.  They are baked into the assembly by the compiler.
Attributes are very useful so you can create your own - custom metadata
Your custom attribute is a public class that derives from the System.Attribute class.  Naming convention is to end the name of your class with Attribute.   Specify usage with an attribute [AttributeUssage(AttributesTargets.) enumeration.  You can create a constructor and also define public Properties as appropriate.

To use, just decorate the target thus
[YourAttribute{any, input, params)]


Any input params in the constructor must be provided when using the attribute.  Unlike a class, however, you can additionally provide any additional public properties available in the custom attribute by specifying its name.

You can not only inspect objects using reflection you can create objects and invoke methods and properties too.

Get a reference to a type.
Get a propertyinfo for one of the type's properties.
Get the value of that property held by an object of that type.  It returns an object so cast it as needed.

Could also use GetMethod to get the MethodInfo of a method available on a type.
Invoke the same.  Any input params for the method are passed as an object[].

dynamic keyword
Bypasses any static type checking by the compiler.  It also coerces the returned type into what you want.  The result is cleaner code for the same functionality.  

dynamic someObject = o;
int length = someObject.length;

However there is the risk of a runtime error if the property or method can't be found on the object.

Create Objects using the activator class.
Get a reference to a type
var type = o.GetType();
var newInstance = Activator.CreateInstance(type)

Can create code on the fly!  You create a new DynamicMethod, passing in the name, its return type and any input parameters.  Then you lay out the instructions to execute within the method.  To do this you write IL code by calling the ILGenerator class to load in OpCodes.  Not C#, these are IL instructions.

Processor architecture

There are two CLRs - 32bit or 64bit.  32bit can run on a 64 bit system (as a 32 bit process via emulator), but not vice-versa.  Set these by setting build properites on the project.

x86 platform = 32 bit.
AnyCPU will load your program into the best type of process available.  So on a 32 bit machine it will run your program in a 32 bit process.  On a 64bit platform it will run your progam in a 64 bit process.

The default in VS for projects that create .exe executables is x86 i.e. 32 bit as these can run in most places.   x64 can only run on a 64 bit process (but does have a greater memory address available)

The default in VS for class projects or projects that create DLL assemblies is AnyCPU so that it can load into any executable, i.e. an executable running in either 32bit or 64 bit.

For AnyCPU, if you build an executable under this and load it into a 64 bit process it will run, but if it attempts to load a 32bit dependency this will fail.  You can't load a 32bit library into a running 64 bit process.

Ineroperability

COM was a historical foundation building block of older windows operations.
Mark up code with interop attributes that COM needs.  Then run Assembly registrtation tool (regasm) to register information into the registry for the assembly, so that COM programs can access and use your code.

You can also consume COM components by adding a reference to the COM component.
Less and less important as most functionality in COM is now available in .Net.

Unmanaged code not packaged into a COM component.
Use Platform Invoke - PInvoke - to call into Windows APIs and unmanaged code.

See wiki http://pinvoke.net to see what signatures, etc needed to invoke an API.

Monday, 18 May 2015

Control Flow


Branching

If - else if - else


or for shorthand there's the turnary operator   ? : string pass = score >80? "Yes" : "No"

The values in the result (strings) must match the type of variable being assigned to.

Switch

Restricted to Integers, Characters, Strings and Enums
No "fall throughs" - must have a break;
Case labels are actually constants (hence the restriction)
Default label is optional

switch(name)
{
  case "Name1":
     DoThis();
     break;
  case "Name2":
     DoThat();
     break
  default:
     DoTheOther();
     break; // Even need this break!
}

Can stack multiple cases that lead to the same code.

Iterating

for, while, do-while, foreach

for, and while both execute 0 or more times
do-while executes at least once.

foreach iterates over a collection.   Compiler is looking for a GetEnumerator (that is derived from IEnumerator) method on a type.  If found you can use foreach to iterate over it.
While in a foreach loop you cannot modify the collection.


Jumping

break; continue; goto; return; throw
break - can use from within any loop/iteration (e.g. for or while) as well as selection like switch.
continue - similar but it doesn't exit the loop it just goes to the next iteration (used within loops)
goto - go to somewhere else in code marked with a label.

return - can be used in a void method (just return statement rather than return <variable>)
yield return - lazily build up a collection - return type must be IEnumerable.  Does a continuation.  Can return one item to the calling app, which does some processing then calls into sub routine again.  The subroutine picks up where it left off, e.g. in the middle of a loop.  Handy if the time taken to produce the whole list is long - it returns each result as it is calculated rather than making the caller wait until it is all completed.

yield break - ends the IEnumerable.

Exceptions

Throw

Used to raise an exception.  Type safe, structured error handling
Runtime unwinds the stack until it finds a handler.  May terminate an app if no suitable handler is found.  (ASP.Net won't terminate the webserver.  It catches the exception - optionally returning an error page - so that the web server doesn't get torn down).

Try Catch

Don't need to name a variable when catching an exception, i.e. this is ok:-
try
{
  DoSomething();
}
catch (Exception)
{
}

but you can't get any info from the exception unless you name the exception variable.

Catching System.Exception catches everything - except a few special exceptions.
Chain catch blocks with most specific first.

finally verses using statements
Using statements are another way of ensuring resources are cleaned up properly even if an exception occurs.  However the Type of variable within the using block must expose the IDisposable interface

Re-throwing Exceptions

You can catch and rethrow an exception - either the original or a different exception.
keyword throw;  

You could type in throw ex but that would show the exception as originating in your catch block.  Essentially you've thrown a new exception of the same type.

You could throw an exception of a new type, e.g. for security reasons.  Catch database errors but throw a general exception error to users.  It may be a custom, more meaningful exception type.

Custom Exceptions

Derive from a common base exception, e.g. System.Exception
Classname - suffix of Exception
Make it serializable (Serializable decorator and special constructor that uses serialization information)

Insert Snippet -> Visual C# -> Exception 
and type and tab information I need.







Strings

Strings
Strings are reference types but behave like value types.  They have been optimised within the .Net framework.

Checking for equality performs a string comparison, not an Object.ReferenceEquals that is normally performed when you compare two reference type variables.

When comparing two strings for equality the framework compares the sequence of characters in each string to compare if they have the same value (rather than the same object).

Strings are immutable - can't be modified.  So performing operations that appear to modify a string, such as Trim, don't.  Rather they return a new string with the result, which must be captured if you want to see the effects of the modification.  The original string remains unaltered.  It is immutable.

Types and Passing Parameters

Types

Types are either value types or reference types.

Value Types

A variable is created on the stack and value is held in that variable itself.  Value types are typically small as you don't want huge amounts of stack memory used.  Value types are immutable (but can be overwritten, so an int variable can hold a 4 and that be overwritten with 6).  Aim for <16 bytes of memory used.  Assigning to value types makes an expensive copy operation.

Reference Types

A reference type sees memory used in both the stack and the heap.  Memory is allocated on the heap to hold all the data stored in an instance of a reference type.   (This may be a large amount of memory).  A variable is also created on the stack.  This stack variable holds a pointer to the location on the heap where the actual instance data is held.

Multiple reference variables can reference the same object.
Single variable can point to multiple objects over its lifetime
Objects are allocated on the heap by the new operator

Classes are reference types (as they may be large).
Structs and enums are value types.
(Structs are sealed so you can't inherit from them, nor can you inherit from a base class; They all inherit from System.Object).

Employee e1  = new Employee();
Employee e2;
e2  = e1;

Using either variable to update the object works ok.



String is a special case - Strings are reference types but they act like Value types.

Passing variables is by default pass by value - that is a copy / new instance of variables is created in the called method.  This copy is amended and destroyed once the called method has completed.  A variable of the same name in the "parent" method is unaffected.  This is true even for ref  types.


Passing Parameters

Parameters pass "by value"
Ref types pass a copy of the reference
Value types pass a copy of the value.  Changes to the value don't propagate to the caller

ref and out are used to pass "by reference"
ref parameters require initialized variable (because it will be used by the caller and hence needs to be initialized by the caller).

Invoice invoice = new Invoice();
invoice.ID = 1;
int value = 1;

DoWork(invoice, value);
Assert.IsTrue(invoice.ID == 5);
Assert.IsTrue(value == 1);

void DoWork(Invoice invoice, int value)
{
   invoice.ID = 5;
   value = 3;
}

The above works because when DoWork is called you get a copy of the variable invoice, i.e. a second pointer to the same object on the heap.  Setting the ID via the second pointer affects the memory which is still pointed to by the calling code.  Hence the first Assert.IsTrue passes ok.

But you didn't truly work on the variable in the initial calling code.  You got a copy and that copy pointed to the same object/memory location.  The following would cause the first Assert to fail

void DoWork(Invoice invoice, int value)
{
   invoice = new Invoice();
   invoice.ID = 5;
   value = 3;
}

It fails because you are working on a copy in DoWork.


If you really want to work with that variable, use pass by ref.  Add the ref keyword into both the call and the method signature.  This means you pass a reference to the reference, a reference to the initial variable Invoice (which still points at the same object on the heap).  This also works for value types; you'd in effect pass a ref to the value variable (which holds the value).

public bool DoWork(ref Invoice invoice, out int value)
{
       invoice.ID = 5;
       value++;
       return (value == 2);
}

The ref and out keywords both mean pass by reference.  The difference being that ref parameters must be initialized outside the method as they will be used in the method.  out methods do not need to be initialized.  out alerts the compiler that the value may not be used within the method.  Rather we will be storing the result of some operation in this parameter for returning to the calling method.




Classes

Classes


Classes comprise of members (to hold data essentially) and methods (behaviours).

Fields and Properties

Fields are the actual storage, requiring memory and typically were private.  Naming convention _name
Properties are different; These implement means of getting/setting fields.  Today you usually just implement the property and behind the scenes the compiler quietly creates the underlying fields for you (following the naming convention _name).  Properties have the naming convention Name

Events and Delegates.

Events can be raised (and subscribed to) in order to alert other objects in your (or other) applications that something has happened.  If you define a delegate anyone could add themselves to the subscribed list - but they could also wipe out the subscribed list.  Safer therefore to use events.  Subscribers can only add (subscribe) themselves to listen to your event, or remove themselves from the list.  They can't do anything else to the subscribed list.


Class Features

Static Classes

Static classes are associated with the type/class and not an instance of the type.
E.g. Math.PI.  PI is a static property of the class Math.
A static class can have only static members and can't instantiate a static class.
Only one copy of a static class.
This is done for convenience

Sealed Classes

Sealed classes cannot be inherited.  This is for performance benefits.
String is sealed and cannot be inherited from.

Partial Classes

For extensibility
Allows you to define a class across multiple files - within the same project.
Compiler merges them together into a single class.
Provides extensibility points and is optimized away if no implementation is provided.

Access Modifiers

public - Applies to Class, Member - Meaning: No restrictions
protected - Member - Access limited to class and derived classes
internal - Class & Member - Access limited to the current assembly (Default of a class)
protected internal - Member - Access limited to the current assembly and derived types
private - Member - Access limited to the class (Default of a member)

Abstract

Applies to a class or members
Cannot be instantiated - An abstract class is designated as a base class (e.g. Animal)
Implementation of an abstract method is in the derived class and should use override to implement it.

Virtual

(Implement polymorphism)
Override members in a derived class.
Members are non-virtual by default.
Virtual method could have code in the base/parent class (unlike an abstract method).
Regular methods are dispatched based on the type of the variable
Virtual methods are dispatched based on the type of the object

If you don't override a virtual method in the base class, then the definition in the derived class hides or overlays the definition in the base class.  To get true polymorphism you need to both mark the base method virtual and the derived method as virtual.

Always use the pointy end - C#

After too many years away from regular coding I needed a refresher to get back up to speed with C#, and the newer language features that didn't exist when I was programming.   I'm going to use this blog to keep reminder notes for myself of what I've learned.