Dennis' Blog

Avonturen in .NET
posts - 37, comments - 633, trackbacks - 0, articles - 0

Saturday, October 08, 2005

Dit keer ga ik het hebben over 2 onderwerpen die nieuw zijn in C# 3.0. Die twee dingen zijn: initializers en anonymous types.

Initializers

Laat ik beginnen met een code-voorbeeld:

class Point {
    private int _x;
    private int _y;
 
    public int X {
        get { return _x; }
        set { _x = value; }
    }
 
    public int Y {
        get { return _y; }
        set { _y = value; }
    }
}

Als we in onze code nu een instance willen maken van Point, dan doen we dat dus zo:

Point myPoint = new MyPoint();
myPoint.X = 42;
myPoint.Y = 32;

Natuurlijk kunnen we een extra constructor maken die de waardes van X en Y instelt, maar in C# 3.0 kan dat ook op een andere manier. Dat ziet er dan zo uit:

Point myPoint = new Point{X=42, Y=32};

En dat maakt het leven een stuk overzichtelijker! Overigens hoef je niet alle properties of public fields mee te geven, alleen de X bijvoorbeeld had ook gekund. Ook de volgorde maakt niet uit, de velden zijn immers benoemd dus de compiler vindt wel waar alles heen moet.

Dit trucje kunnen we ook uithalen met Collections. Het is bekend dat we bijvoorbeeld een array direct kunnen vullen bij het declareren van de variabele:

string[] stringArray = { "Dit", "zijn", "een", "stelletje", "strings." );

Dat kan nu dus ook met collection classes. Eerst even de pre-c# 3.0 code:

List<string> stringList = new List<string>();
stringList.Add("Dit");
stringList.Add("zijn");
stringList.Add("een");
stringList.Add("stelletje");
stringList.Add("strings.");

Ziet er bekend uit, niet waar? Een hoop werk, en nogmaals: daar houden we niet zo van. Dus in C#3.0 ziet het er als volgt uit:

var stringList = new List<string>{"Dit", "zijn", "een", "stelletje", "strings." };

Dat is een stuk korter, overzichtelijker en duidelijker. Let ook op het gebruik van de 'var'. De compiler kan hier immers aan de new List afleiden wat stringList voor een type moet zijn, dus dat hoeven we niet nog een keer aan te geven.

Anonymous types

We hebben gezien hoe we een object makkelijker kunnen instantieren. Kijk nu eens naar de volgende code:

var someType = new {Naam="Dennis", EMail="dvroegop@detrio.nl", Huisnummer=42, Salaris=7800.00};

Dit is uiteraard een fictief voorbeeld: dat salaris ligt in werkelijkheid een stukje hoger.

Een quiz. Wat voor een type is sometype? Als het goed is, kan de compiler zelf bepalen wat voor een type het is, door te kijken wat er na de '=' staat. Dat is immers wat het 'var' keyword betekend. Maar... er staat niet zo veel achter het '=' teken, behalve het 'new' keyword en een initializer. Wat voor een type is dit nou?

Het antwoord daarop is: maakt dat wat uit? Ik kan je wel vertellen dat de compiler nu een class aanmaakt, maar hoe die precies heet weten we niet. De code die de compiler nu genereert ziet er ongeveer als volgt uit:

class __newType {
    private string _Naam = "Dennis";
    private string _EMail = "dvroegop@detrio.nl";
    private int _Huisnummer = 42;
    private double _Salaris = 7800.00;
 
  public string Naam {
      get { return _Naam; }
      set { _Naam = value; }
  }
 
  public string EMail {
      get { return _EMail; }
      set { _EMail = value; }
  }
 
  public int Huisnummer {
      get { return _Huisnummer; }
      set { _Huisnummer = value; }
  }
 
  public double Salaris {
      get { return _Salaris;}
      set { _Salaris = value; }
  }
}

en even verderop:

__newType someType;
someType = new __newType();
 

De waardes hoeven niet meer geinitialiseerd te worden, die staan immers in de class. In werkelijkheid ziet het er iets anders uit, maar voor dit moment is dit goed genoeg. Er wordt dus een anoniem type aangemaakt waarvan we de naam niet kennen, maar hij wordt wel aangemaakt met de juiste velden er in. Dus na de uitbreiding met anonymous methods in C#2.0 hebben we nu zelfs anonymous types. Voor je het weet komen ze met anonymous applications, maar dat zal wel niet zo snel gebeuren.

Volgende keer: lambda expressions!

posted @ 7:52 PM | Feedback (31)