webForumDet fria alternativet

Instansering i propertyn eller i konstruktorn?

.NET

24 svar · 858 visningar · startad av Lukaspojken

Medlem sedan maj 20011 312 inlägg
Frågan#1

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>();
}

		return \_products;
	}
}

}

Medlem sedan aug. 20003 575 inlägg
#2

Tja, det handlar ju egentligen om extremt lite data när det gäller en tom lista.

Jag hade satt den i konstruktorn, du får ju tänka på den extremt prestandakrävande if-kollen ;).. Nä skämt och sido det är kanske en smaksak.

Medlem sedan maj 20012 812 inlägg
#3

I och med att det blir mer kod att skriva om du skall göra det vi propertyn så hade jag lagt det i konstruktorn, eller om listan nu aldrig skall vara tom, så kanske redan vid deklareringen av listan...

- M

Medlem sedan feb. 20041 816 inlägg
#4

Det är inte speciellt intuitivt att tilldela värdet i propertyn. Har någon någonsin sett sådan kod? Jag bara undrar.
Konstruktorn är till för bl.a. just sånt här. Fast jag hade nog satt mina värden direkt vid deklarationen eftersom jag tycker att det blir mindre och mer lättläst kod så.

Medlem sedan feb. 200563 inlägg
#5

Det försämrar läsbarheten i onödan med meningslösa if-satser.
Det kanske inte stör så mycket om man bara använder lazy loading för just denna lista, men om man använder det för alla listor i applikationen blir det mer störande, och om man endast vill använda lazy loading för just denna lista så bör det i så fall finnas en god anledning till detta, t.ex. att man behöver skapa miljontals instanser av Category-objekt, varav många aldrig kommer att använda listan av produkter...
Jag tycker alltså det är fel att p.g.a. en spekulativ prestandavinst använda lazy loading för instansieringen av en tom lista, och anser att det faller inom ramen för premature optimization.
( Citat: "We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil." (Knuth, Donald. Structured Programming with go to Statements, ACM Journal Computing Surveys, Vol 6, No. 4, Dec. 1974. p.268.) )

/ Tomas

Medlem sedan okt. 200850 inlägg
#6

Håller med Tomas..

Medlem sedan maj 20011 312 inlägg
#7

Jag håller nog med er i att detta sätt inte är så snyggt. Om man dock har flera konstruktorer så skulle man kunna få ned koden genom att använda detta sätt.

Gladh tog upp att man kunde göra instansering vid deklaringen. Hur ser ni på det? Bättre eller sämre än att göra det i konstruktorn?

Medlem sedan aug. 20003 575 inlägg
#8

Jag gillar konstruktorn för att jag tycker att det blir tydligare för att just konstruktorn är till för att initiera objektet för mig och då får jag också all initiering på ett och samma ställe (sålänge jag inte har någon initialiserings metod som gör tyngre arbete. Men det är nog en smaksak.

Medlem sedan maj 20011 312 inlägg
#9

Men om du har flera konstruktorer då får du det inte på ett och samma ställe? Eller?

Medlem sedan okt. 200850 inlägg
#10

Om du skriver:

private List<Object> objects = new List<Object>();

Så kommer "this.objects = new List<Object>();" att läggas till i konstruktorn och automaktiskt till alla som är definierade..

så om du tilldelar i konstruktorn eller vid deklaration spelar ingen roll. Fördelen utanför konstruktion vid deklaration, är att kompilatorn ser till så alla vara konstroktorer initierar klasserna.. snyggt va!?

Medlem sedan juni 20019 024 inlägg
#11

Lukaspojken skrev:

Men om du har flera konstruktorer då får du det inte på ett och samma ställe? Eller?

Det är ju bara lägga all kod i en konstruktor och kalla på den från de andra med inparametrar.

Medlem sedan maj 20011 312 inlägg
#12

-> fredrikn
Jag vet inte om det var ironi när du sa "snyggt va" :) Är du för eller mot instansering i deklarationen?

-> Pace
Det är sant men jag ser att det kan finnas en liten risk att för nya utvecklare (som ska skapa en ny konstruktor) missar att göra anrop dit där instatieringen görs av listan. Så är det egentligen inte bättre att göra det i deklationen för att dels minska antalet kodrader och att minska risken för fel?

Medlem sedan aug. 20003 575 inlägg
#13

fredrikn skrev:

Om du skriver:

private List<Object> objects = new List<Object>();

Så kommer "this.objects = new List<Object>();" att läggas till i konstruktorn och automaktiskt till alla som är definierade..

så om du tilldelar i konstruktorn eller vid deklaration spelar ingen roll. Fördelen utanför konstruktion vid deklaration, är att kompilatorn ser till så alla vara konstroktorer initierar klasserna.. snyggt va!?

Det löser man väl oftast med konstruktorerna anropar varandra? :)
Men som sagt smaksak :)

Medlem sedan juni 20019 024 inlägg
#14

Lukaspojken skrev:

-> Pace
Det är sant men jag ser att det kan finnas en liten risk att för nya utvecklare (som ska skapa en ny konstruktor) missar att göra anrop dit där instatieringen görs av listan. Så är det egentligen inte bättre att göra det i deklationen för att dels minska antalet kodrader och att minska risken för fel?

Du missförstår mig. Ett exempel:

Public Sub New()
   Me.New("", True)
End Sub

Public Sub New(Key As String)
   Me.New(Key, True)
End Sub

Public Sub New(Key As String, Whatever As Boolean)
   _MyList = New List(Of Integer)
   _Key = Key
   _Whatever = Whatever
End Sub

All kod ligger i den sista konstruktorn. De andra kallar på den.

Medlem sedan maj 20011 312 inlägg
#15

-> Nickemannen
Nja, jag vet inte om det är en smaksak. Jag tror det finns små effektivitetsvinster att vinna på att instansera tex listor vid deklareringen. Dels genom att minska antal kodrader samt att minska risken för att utvecklaren gör fel (se mitt svar till Pace nedan). Innan har jag alltid instanserat listor m.m. i konstruktorn men från och med nu kommer jag nog inte göra det utan istället instansera sådant i deklaringen. Om du fortfarande tycker det är en smaksak så får du motivera varför onödigt extra arbete som också kan leda till fel bör göras :)

-> Pace
Jo, jag förstår hur du menar men det kräver ändå extra kodrader och det jag menar är att om en ny utvecklare som aldrig jobbat med koden ska lägga till en konstruktor i entiteten då skulle det kunna bli så här:

Public Sub New(Volume As Integer)
   _Volume = Volume
End Sub

Det vill säga utvecklaren missar att anropa nedanstående konstruktor från sin nya konstruktor.

Public Sub New(Key As String, Whatever As Boolean)

Genom att instansera listan vid deklaringen så minimerar du just sådana här onödiga fel som kan uppstå när utvecklaren är tex lite trött, stressad eller liknande.

Medlem sedan aug. 20003 575 inlägg
#16

Lukaspojken skrev:

-> Nickemannen
Nja, jag vet inte om det är en smaksak. Jag tror det finns små effektivitetsvinster att vinna på att instansera tex listor vid deklareringen. Dels genom att minska antal kodrader samt att minska risken för att utvecklaren gör fel (se mitt svar till Pace nedan). Innan har jag alltid instanserat listor m.m. i konstruktorn men från och med nu kommer jag nog inte göra det utan istället instansera sådant i deklaringen. Om du fortfarande tycker det är en smaksak så får du motivera varför onödigt extra arbete som också kan leda till fel bör göras :)

-> Pace
Jo, jag förstår hur du menar men det kräver ändå extra kodrader och det jag menar är att om en ny utvecklare som aldrig jobbat med koden ska lägga till en konstruktor i entiteten då skulle det kunna bli så här:

Public Sub New(Volume As Integer)
   _Volume = Volume
End Sub

Det vill säga utvecklaren missar att anropa nedanstående konstruktor från sin nya konstruktor.

Public Sub New(Key As String, Whatever As Boolean)

Genom att instansera listan vid deklaringen så minimerar du just sådana här onödiga fel som kan uppstå när utvecklaren är tex lite trött, stressad eller liknande.

Jag håller inte med dig, jag tycker att konstruktorn är ett utomordentligt ställe att lägga sina instansieringar eftersom jag gillar struktur.

Jag tycker att min kod blir mer strukturerad om jag gör alla instansieringar på samma ställe dvs i min konstruktor, eftersom här kanske jag får in hälften av instanserna eller fler. Och om jag hade varit i en projektgrupp och fått felet nullpointerexception på en instansvariabel som så vet jag exakt var jag skall kika.

Samma sak att man missar att instansiera sin variabel i konstruktorn kan man missa det vid fältdefineringen enligt mig.

Medlem sedan juni 20019 024 inlägg
#17

Lukaspojken skrev:

-> Pace
Jo, jag förstår hur du menar men det kräver ändå extra kodrader och det jag menar är att om en ny utvecklare som aldrig jobbat med koden ska lägga till en konstruktor i entiteten då skulle det kunna bli så här:

Det du säger är i princip att man ska skriva mer kodrader och lägga all instansiering i respektive property för att minimera fel från en sömndrucken utvecklare. I själva verket introducerar du en högst ovanlig metod som förmodligen få använder och genererar mångdubbelt med extra kodrader.

Att en utvecklare gör fel är ju heller inget argument mot instansiering i konstruktorn. Det är som att säga att man ska undvika att laga mat i köket (och i stället bara använda gasolkök) eftersom man kan göra fel om man inte följer kokboken.

Medlem sedan okt. 200850 inlägg
#18

Att instantiera vid deklaration gör samma sak som att skriva initieringen i konstruktorn. Jag initiering vid deklaration, spec. om det är listor (Vi bör ej publikt returnera en List, den diskutionen har vi redan haft i en annan tråd).

Genom att initiera vid deklaration så slipper jag bry mig om att göra det i min konstruktor eftesom kompilatorn ändå kommer se till att göra det åt mig.

Medlem sedan maj 20011 312 inlägg
#19

-> 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?

-> Pace
Jag tror du missförstår mig. Jag är inte för den form av instansering som mitt första inlägg i denna tråd tog upp. Det var en instansering som jag sett och tänkte få feedback på. Så jag förespråkar alltså inte instansering i propertyn med if-sats. Jag har tidigare alltid instanserat tex listor i konstruktorn men efter denna diskussionstråd så är jag osäker på om det egentligen är det bästa sättet. Jag lutar åt att instansering av listor sker när de deklarares, dvs

List<Product> _products = new List<Product>();

-> fredrikn
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?

Medlem sedan juni 20019 024 inlägg
#20

Lukaspojken skrev:

-> Pace
Jag tror du missförstår mig. Jag är inte för den form av instansering som mitt första inlägg i denna tråd tog upp.

Ja, ser det nu. Fel av mig. :)

269 ms totalt · 4 externa anrop · v20260731065814-full.86ec41c2
123 ms — deklarationer (db)
0 ms — hämta statistik (cache)
137 ms — hämta tråd, inlägg och bilagor (db)
129 ms — ändringar (db)