Jun 6, 2009

C# New features

I have move to .net 3.5 and found really cool enhancements in C# language(in VB.Net too).
  • We can create properties like this
    class ProcessData
    {
    public int ID { get; set; }
    public string Name { get; set; }
    public long Memory { get; set; }
    }
    

    Compiler will emits the private variables for properties and nothing diffrent in IL code.

  • Object Initializer
    Lets say we want to populate list of ProcessData class, before C# 3.0 came we have to code like this
    List processList = new List();
    foreach (Process p in Process.GetProcesses())
    {
    ProcessData pd = new ProcessData();
    pd.ID = p.Id;
    pd.Name = p.ProcessName;
    pd.Memory = p.WorkingSet64;
    processList.Add(pd);
    }

    Note its IL code,
    IL_001f: ldloc.2
    IL_0020: ldloc.1
    IL_0021: callvirt instance int32 [System]System.Diagnostics.Process::get_Id()
    IL_0026: callvirt instance void NewFeatures.ProcessData::set_ID(int32)
    IL_002b: nop
    IL_002c: ldloc.2
    IL_002d: ldloc.1
    IL_002e: callvirt instance string [System]System.Diagnostics.Process::get_ProcessName()
    IL_0033: callvirt instance void NewFeatures.ProcessData::set_Name(string)
    IL_0038: nop
    IL_0039: ldloc.2
    IL_003a: ldloc.1
    IL_003b: callvirt instance int64 [System]System.Diagnostics.Process::get_WorkingSet64()
    IL_0040: callvirt instance void NewFeatures.ProcessData::set_Memory(int64)
    IL_0045: nop
    IL_0046: ldloc.0
    IL_0047: ldloc.2
    IL_0048: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0)
    IL_004d: nop

    Do you belive if I write same code in 3 lines?
    var processList = new List();
    foreach (var p in Process.GetProcesses())
    processList.Add(new ProcessData { ID = p.Id, Name = p.ProcessName, Memory = p.WorkingSet64 });

    Note new ProcessData { ID = p.Id, Name = p.ProcessName, Memory = p.WorkingSet64 } is called object initializer notation.
    But it does same thing and no any drawbacks, like performance degrading etc. Check this IL code, it is same as above IL code.
      IL_001f:  ldloc.2
    IL_0020:  ldloc.1
    IL_0021:  callvirt   instance int32 [System]System.Diagnostics.Process::get_Id()
    IL_0026:  callvirt   instance void NewFeatures.ProcessData::set_ID(int32)
    IL_002b:  nop
    IL_002c:  ldloc.2
    IL_002d:  ldloc.1
    IL_002e:  callvirt   instance string [System]System.Diagnostics.Process::get_ProcessName()
    IL_0033:  callvirt   instance void NewFeatures.ProcessData::set_Name(string)
    IL_0038:  nop
    IL_0039:  ldloc.2
    IL_003a:  ldloc.1
    IL_003b:  callvirt   instance int64 [System]System.Diagnostics.Process::get_WorkingSet64()
    IL_0040:  callvirt   instance void NewFeatures.ProcessData::set_Memory(int64)
    IL_0045:  nop
    IL_0046:  ldloc.2
    IL_0047:  callvirt   instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0)
    IL_004c:  nop

    We can see several advantages in the latter.
    + We can initialize an object within just one instruction.
    + We don’t need to provide a constructor to be able to initialize simple objects.
    + We don’t need several constructors to initialize different properties of objects.


Reference: LINQ in Action, Manning Publications 2008

No comments: