.NET Features: Object Initializer

Door Luuk1983 op woensdag 22 juni 2011 11:20 - Reacties (11)
Categorie: Programmeren, Views: 2.461

Als .NET-programmeur merk ik regelmatig dat andere programmeurs niet op de hoogte zijn van sommige handige en slimme features in het .NET framework die het programmeren een stuk makkelijker kunnen maken. Soms zijn deze features verstopt, of soms zijn ze pas nieuw, maar handig zijn ze altijd. Dit is deel 3 van een serie met kleine voorbeelden van features die je als .NET-programmeur (met name in C#) mogelijk nog niet kent. Deze keer: Object initializers in C#.

Ik zie nog veel programmeurs hun classes en bijbehorende properties op de volgende manier declareren:

C#:
1
2
3
var foo = new Foo();
foo.ABoolean = true;
foo.AnIntegerValue = 1;


Dit is natuurlijk niet fout, maar het kan ook anders. Je kan het aanmaken van het object combineren met het zetten van de waardes. Dit heeft als voordeel dat je code (mogelijk) beter leesbaar wordt. Zeker als er maar weinig properties gezet hoeven te worden kan de object initialisatie plus het zetten van de properties op één regel.

C#:
1
var foo = new Foo {ABoolean = true, AnIntegerValue = 1};


Naar mijn mening verhoogt dit de leesbaarheid van de code. De functionaliteit is toegevoegd vanaf C#3.0 en is te gebruiken vanaf .NET3.5.

Volgende: .NET Features: question mark 06-'11 .NET Features: question mark
Volgende: .NET Features: auto properties 06-'11 .NET Features: auto properties

Reacties


Door Tweakers user Jogai, woensdag 22 juni 2011 11:45

Dit gebruik ik vaak icm linq.
Voorbeeldje ff van so:


code:
1
2
3
List<Bloop> myBlops = new List<Bloops>;
//populate myBloops
List<Razzie> myRazzies = myBloops.Select(x => new Razzie() { FirstName = x.FirstName, LastName = x.LastName}).ToList();


Door Tweakers user Luuk1983, woensdag 22 juni 2011 11:52

Hoi Jogai,

Dat zijn inderdaad implementaties die ik zelf ook gebruik. Ik zou er voor de leesbaarheid er wel een aparte functie van maken:

C#:
1
2
3
4
5
6
7
List<Bloops> myBloops       = new List<Bloops>;
List<Razzie> myRazzies  = myBloops.Select(BloopToRazzie).ToList();

private Razzie BloopToRazzie(Bloops x)
{
    return new Razzie() {FirstName = x.FirstName, LastName = x.LastName};
}


Maar uiteraard doet dat hetzelfde en is het de keus van de programmeur.

Door Tweakers user Voxyn, woensdag 22 juni 2011 11:55

Bedankt voor de tip!

Net even geprobeerd heel handig als je weinig initializers hebt maar zodra je er veel hebt zou ik hem zeker niet gebruiken, word veel te onoverzichtelijk.

Ik kijk uit naar je volgende blogpost!

[Reactie gewijzigd op woensdag 22 juni 2011 11:55]


Door Tweakers user Luuk1983, woensdag 22 juni 2011 11:58

@Voxyn,
Je kan ze zeker wel zonder problemen gebruiken als het er meer zijn, alleen zet je het dan niet meer op één regel, maar zo (code staat niet helemaal goed uitgelijnd, want tabs werken niet in een textbox ;)):

C#:
1
2
3
4
5
return new Razzie()
              {
                FirstName = x.FirstName,
                LastName = x.LastName
              };

[Reactie gewijzigd op woensdag 22 juni 2011 11:59]


Door Tweakers user woutertje, woensdag 22 juni 2011 12:10

Hm, wat is hier precies het voordeel van t.o.v. variabelen meegeven aan de constructor? (Ik programmeer normaal in Java).

Door Tweakers user Puc van S., woensdag 22 juni 2011 12:18

woutertje schreef op woensdag 22 juni 2011 @ 12:10:
Hm, wat is hier precies het voordeel van t.o.v. variabelen meegeven aan de constructor? (Ik programmeer normaal in Java).
Op deze manier kan je je ook al properties initialiseren die bv niet in de constructor staan.

[Reactie gewijzigd op woensdag 22 juni 2011 12:18]


Door Tweakers user Luuk1983, woensdag 22 juni 2011 12:18

Hoi Woutertje,

Een object heeft zelden een constructor waar je alle mogelijke properties in kan stoppen en in alle combinaties. Deze constructie is bedoeld voor op het moment dat je een new object gaat aanmaken en meteen een aantal properties kan zetten. Welke properties je invult kan je zelf weten. Je hoeft niet alles meteen in te vullen.

Een Literal bijvoorbeeld heeft geen constructor met parameters, en het kan zijn dat je gedeeltelijk de properties meteen al kan invullen en sommige later dynamisch. Een heel simpel, stom voorbeeld:


C#:
1
2
3
var literal = new Literal {Mode = LiteralMode.Encode, Visible = true};
if (IsTrue())
    literal.Text = "It's true!";


Door Tweakers user Korben, woensdag 22 juni 2011 12:34

Naar mijn mening verhoogt dit de leesbaarheid van de code. Ik weet overigens niet wanneer deze functionaliteit toegevoegd is aan het .NET framework/Visual studio, maar wat ik zo zie op Internet vanaf ASP.NET 3.0.
Het is onderdeel van C#, niet van .NET of Visual Studio, en uiteraard al helemaal niet van ASP.NET. Object initializers zijn geïntroduceerd met C#3.0.

Disclaimer: Ja, C#3.0 was voor het eerst te gebruiken sinds .NET 3.5, maar dat was omdat er niet eerder een compiler voor beschikbaar was.

Door Tweakers user Luuk1983, woensdag 22 juni 2011 12:56

Korben schreef op woensdag 22 juni 2011 @ 12:34:
[...]
Het is onderdeel van C#, niet van .NET of Visual Studio, en uiteraard al helemaal niet van ASP.NET. Object initializers zijn geïntroduceerd met C#3.0.

Disclaimer: Ja, C#3.0 was voor het eerst te gebruiken sinds .NET 3.5, maar dat was omdat er niet eerder een compiler voor beschikbaar was.
Aangepast :)

Door Tweakers user Snake, woensdag 22 juni 2011 16:51

Dit is een hele functie, totdat je wilt debuggen, je kan namelijk niet regel per regel debuggen. De debugger ziet dit als 1 statement. Zeker als je functies uitvoert. BVB:


C#:
1
2
3
4
5
6
Foo foo = new Foo() 
{
     Prop1 = Bar(anotherVariable),
     Prop2 = true
     Prop3 = GetItems(oneMoreVariable), /* overigens is de laatste komma optioneel */
}



En er gebeurt een fout in Bar of GetItems, dan zie je dat niet direct. Jammer.

Door Tweakers user 90710, zaterdag 25 juni 2011 08:44

woutertje schreef op woensdag 22 juni 2011 @ 12:10:
Hm, wat is hier precies het voordeel van t.o.v. variabelen meegeven aan de constructor? (Ik programmeer normaal in Java).
Gave features als deze heb je niet in java :p
Ik bedoel, dit is vooral handig met anonieme types.

C#:
1
var iets = new { Naam = "Sander", Leeftijd = 27 };



Wat dus ook weer handig in LINQ is.

C#:
1
var namenEnLeeftijden = from p in personen select new { Naam = p.Naam, Leeftijd = l.Leeftijd };

Luuk1983 schreef op woensdag 22 juni 2011 @ 12:18:
Hoi Woutertje,

Een object heeft zelden een constructor waar je alle mogelijke properties in kan stoppen en in alle combinaties. Deze constructie is bedoeld voor op het moment dat je een new object gaat aanmaken en meteen een aantal properties kan zetten. Welke properties je invult kan je zelf weten. Je hoeft niet alles meteen in te vullen.

Een Literal bijvoorbeeld heeft geen constructor met parameters, en het kan zijn dat je gedeeltelijk de properties meteen al kan invullen en sommige later dynamisch. Een heel simpel, stom voorbeeld:


C#:
1
2
3
var literal = new Literal {Mode = LiteralMode.Encode, Visible = true};
if (IsTrue())
    literal.Text = "It's true!";

Dit kan dan ook :p

C#:
1
var literal = new Literal { Mode = LiteralMode.Encode, Visible = true, Text = (IsTrue() ? "It's true!" : string.Empty) };



Trouwens voor mensen die liever in VB werken is dit natuurlijk ook mogelijk:

Visual Basic .NET:
1
Dim p As New Persoon With {.Naam = "Sander", .Leeftijd = 27}


Reactie formulier
(verplicht)
(verplicht, maar wordt niet getoond)
(optioneel)