webForumDet fria alternativet

Instansering i propertyn eller i konstruktorn?

.NET

24 svar · 858 visningar · startad av Lukaspojken · sida 2 av 2

Frågan, av Lukaspojken

Jag såg denna variant av list instansering. Vad tycker ni om det? Skulle ni välja det framför instansering i konstruktorn? En fördel som jag spontant känner är att detta sätt borde spara lite minne genom att inte skapa en instans om den inte används. public class Category { public List\<Product\> Products { get { if (null == \products) { \products = new List\<Product\>(); }

Läs frågan i sin helhet →
Medlem sedan aug. 20003 575 inlägg
#21

Lukaspojken skrev:

-> Nickemannen
Du skriver att du vill ha alla instanseringar på en plats för att få struktur. Kan du inte ha dessa i stället vid deklareringarna?

Nej jag kan inte alla där eftersom vissa kanske sätts via konstruktoranropet.
Man måste ju inte ha två konstruktorer som jag har här, eller det kanske inte är bästa lösningen att skicka in orderItemslistan till en order men det kan ge en liten hint om hur man kan göra i ett annat scenario.

Om man tittar på detta så kan man inte sätta Customer på något annat sätt än genom konstruktorn och därför tycker jag att man lika gärna kan ha allting där.
Men som jag skrivit detta är vad jag tycker jag tror nog att detta är en smaksak även om jag tycker att det är snyggare om man gör det i konstruktorn. Där man även kan anropa metoder som sätter listor eller objekt osv.

private readonly IList<OrderItem> orderItems;
private readonly Customer customer;

public Order(Customer customer)
    : this(customer, new List<OrderItem>)
{
}

public Order(Customer customer, IList<OrderItem> orderItems)
{
    this.customer = customer;
    this.orderItems = orderItems;
}
Medlem sedan okt. 200850 inlägg
#22

Lukaspojken skrev:

Ser du några nackdelar i att instansera vid deklareringen? Nickemannen tar upp att det skapar bättre struktur att göra all form av instansering i konstruktorn. Hur ser du på det?

Skönheten sitter i betraktarens ögon..

Skulle valt detta:

private readonly IList<OrderItem> orderItems new List<OrderItem>();

för detta:

private readonly IList<OrderItem> orderItems;

public MyClass()
{
    this.orderItems = new List<OrderItem>();
}

Gillar lite kod och båda resulterar i samma sak..

Medlem sedan maj 20011 312 inlägg
#23

-> fredrikn och Nickeman
Nu kommer filosofen fram i mig :) Jag håller med om att "skönheten sitter i betraktarens ögon" men jag tycker dock man bör undvika att trilla ner i en alltför subjektivitiskt synsätt och vifta bort att det mesta är en smaksak :) Det finns vissa saker som oftast bidrar till upplevd skönhet liksom motsatsen. Det hela bygger på hur vi människor är funtade. I vissa fall kan det också vara så att betraktarens ögon inte ser klart eller att betraktaren går misste om att se vissa vinklar på grund av tex okunskap.

Om vi tittar på alternativen igen

1. Alternativ ett bygger på att instansera allt som går att instansesera vid deklaringen och resten i konstruktorn. Fördelerna är att det blir mindre kod samt att risken för onödiga nullreferens-fel minskar. Nackdelen är att all instansering inte sker på ett och samma plats.

2. Alternativ två bygger på att göra all form av instansering i konstruktorn. Fördelen är att all instansering sker på en plats (om det görs rätt). Nackdelen är att det blir mer kod samt att risken för nullreferens fel ökar en aning.

Ur effektivitetssynpunkt skulle jag nog säga att alternativ 1 är bäst. Ur förvaltningssynpunkt så är det nog alternativ 2.

Samtidigt kan man fråga sig hur vanligt det är med Nickemans-"special"-instansering i konstruktorn. Min erfarenhet är att det sällan inträffar och i de fall det inträffar så kan det vara bra att det är så lite kod som möjligt i konstruktorn som stör en utvecklares koncentration, dvs få bort all annan instanseringskod från konstruktorn som inte bidrar till att öka förståelsen för vad konstruktorn gör i det speciella fallet.

Så alternativ 1 vinner och det baseras inte på smaksak utan på ett förnuftigt resonemang! :)

Medlem sedan maj 20012 812 inlägg
#24

lukaspojken skrev:

Samtidigt kan man fråga sig hur vanligt det är med Nickemans-"special"-instansering i konstruktorn.

Det är vanligt om man använder TDD eftersom man skickar med de instanser till konstruktor som skall användas i klassen. Helt enkelt för att man enkelt skall kunna byta ut dem och köra med egna "test objekt" istället för de riktigta som skall användas i produktion.

- M

Medlem sedan maj 20011 312 inlägg
#25

Ah, bra påpekande! Detta handlar om "dependency injection". Jag har tyvärr ännu inte hunnit testa det men detta görs inte på domänentiteterna utan på tex repositoryn m.m.

Det är även väldigt sällan repositories m.m. har listor eller liknande som attribut/members i klasserna. Dessa ligger i regel i domänentiteterna.

Så det var ett bra försök :) Du fick mig att tänka till men alternativ 1 håller fortfarande bra :)

253 ms totalt · 4 externa anrop · v20260731065814-full.a51de22e
123 ms — deklarationer (db)
0 ms — hämta statistik (cache)
123 ms — hämta tråd, inlägg och bilagor (db)
126 ms — ändringar (db)