Detta är ett utdrag ur en klass som jag hittade i ett exempel för Wilson ORMapper: Exemplet är ju lite trivialt, set-konstruktorn är ju bra ställe att utföra valideringar av datat. I get kan man ju implementera "lazyloads" av underobjekt (har jag för mig att det brukar kallas av de som är lite mer insatta än jag i arkitektur). Det är inte sådana fall jag vänder mig mot, utan just dessa "rena" get och set. Där ser jag ingen mening med att använda dem. En gissning: En massa kod kompilerad mot din dll måste inte nödvändigtvis kompileras om bara för att du ändrar från en variabel till en egenskap för att du måste kontrollera värdet i set-metoden? ;) Kanske det... Hur mycket behöver kompilatorn veta om en klass A som används av en annan klass B för att filen som klass B ligger i skall kunna kompileras? Behöver kompilatorn veta om a.x är en direkt åtkomst av attributet x eller om det sker via get/set? Det är ju som PH skriver vanligt att man vill göra nåt i set-operationerna typ validera, eller skapa nåt i get-operatorerna t.ex ett objekt som måste hämta från db t.ex.. <b>Behöver kompilatorn veta om a.x är en direkt åtkomst av attributet x eller om det sker via get/set?</b> <b>Det är ju som PH skriver vanligt att man vill göra nåt i set-operationerna /.../</b> <b>Som jag försökte säga ovan är det inte dessa fall jag undrar över, utan bara de där man lika gärna kunde ha tilldelat fältet direkt.</b> Den största anledningen till varför man skall använda sig av setters och getters är att man då följer OOP-paradigmen inkapsling. Det är inte bra att en klass visar sina attribut publikt. Att låta andra objekt peta i andras objektsattribut obehindrat kommer att medföra stora problem i längden. Betänk en felsökning. Jag är rätt säker på att det bara handlar om best practices och inget rent tekniskt i Wilsons fall. >följer OOP-paradigmen inkapsling. Martin, hur menar du då? det är ju främst inkapsling det handlar om. Väldigt ofta ser man att folk i första hand verkar ha funderat över vad objektet skall innehålla och sedan skapat getters och setters eftersom de har lärt sig att man skall ha det. När de sedan upptäcker att objektets innehåll behöver ändras måste de ändra interfacet och alla ställen i koden där detta används. >Martin, hur menar du då? det är ju främst inkapsling det handlar om. Martin, varför blandar du in interface. Properties (get/set) är det sätt som man implementerar inkapsling av klassernas egenskaper. Det har inget med Interface att göra. Både jag och Martin blandade in ordet "interface", men jag - och inte heller Martin skulle jag tro - pratar om konstruktionen Interface som finns i C#. Det handlar om gränssnittet man har till klassen, vilka metoder och attribut som syns utåt. Det vill man skall vara oförändrat och naturligt. Konstruktionen Interface har delvis med detta att göra, men närmast som specialfall.Varför krångla till det?
public class Category
{
private int id;
private string name;
private string description;
public int Id {
get { return this.id; }
}
public string Name {
get { return this.name; }
set { this.name = value; }
}
public string Description {
get { return this.description; }
set { this.description = value; }
}
}
Varför skriver man så i stället för följande betydligt kortare kod?
public class Category
{
public readonly int id;
public string Name;
public string Description;
}
Sv: Varför krångla till det?
En annan grej kan ju vara att man vill sätta en flagga när ett värde ändras, eller kanske trigga ett event. Det är ju lätt fixat i set.
public Customer Customers
{
get { if (m_Customers==null)
{
m_Customers=new Customers();
m_Customers.Load();
}
return m_Customers;
}
}
public int Age
{
get { return mAge; }
set { if (mAge>150 || mAge<0)
throw new ArgumentException("Invalid age!!");
mAge=value;
}
}
Sv:Varför krångla till det?
(Om språket inte erbjuder get- och set-konstruktioner, utan man är tvungen att skapa metoderna getXXX() och setXXX(), kan jag däremot acceptera det.)Sv: Varför krångla till det?
Sv:Varför krångla till det?
Sv: Varför krångla till det?
En annan fördel är att du kan stoppa in felhantering med try, catch... t.ex. är du väl glad för att Grid.Datasource=BitmapImage talar om för dig vad som är fel i stället för att krascha med nåt skumt fel som inte säger nåt... Det är snyggt att ha samma tänk i ett affärslager.. t.ex. P.PersonNr = "aaa" ger ApplicationException "ej korrekt personnummer"....
genom att alltid använda Properties (get/set) så följer man ett mönster och all din kod blir konsekvent. Och i det här fallet är ju koden skapad av en generator så det drabbar ju ingen människa att skriva de här extra raderna. (men det underlättar för dig om du vill bygga vidare på den genererade koden).
Men det finns ju ingen lag som säger att du måste göra så.. :) Dock är det enligt min erfarenhet ganska vanligt att om man har "slarvat" och inte använt properties då kommer man ofta till den punkt där man behöver några properties ändå... och då kommer man störa sig på att det är lite blandat och allmänt rörigt, och göra om allt till props... (Eller så kodar man konsekvent och koncentrerar sig på de verkliga problemen man ska lösa.. :)Sv: Varför krångla till det?
I .NET behöver den det, en property get görs i IL som
callvirt get_propertyName()Sv:Varför krångla till det?
<b>En annan fördel är att du kan stoppa in felhantering med try, catch /.../</b>
Som jag försökte säga ovan är det inte dessa fall jag undrar över, utan bara de där man lika gärna kunde ha tilldelat fältet direkt.
<b>Och i det här fallet är ju koden skapad av en generator så det drabbar ju ingen människa att skriva de här extra raderna.</b>
<b>Dock är det enligt min erfarenhet ganska vanligt att om man har "slarvat" och inte använt properties då kommer man ofta till den punkt där man behöver några properties ändå... och då kommer man störa sig på att det är lite blandat och allmänt rörigt, och göra om allt till props...</b>
Okej, detta, tillsammans med att API för IL blir olika, övertygar mig om att jag skall acceptera sådan kod, även om den vid första anblicken ser onödigt omständlig ut.Sv: Varför krångla till det?
I vissa fall fungerar det inte att tilldela direkt utan man måste göra det via properties, har för mig att XML-seraliseringen i .Net kräver properties tex.Sv: Varför krångla till det?
Sv: Varför krångla till det?
han injectar ingen kod i runtime och det vore väldigt lätt att skriva kod som går mot både properties o fält.
Men enligt alla .NET designdokumnet så ska man alltid ha properties om man vill exponera ut värden.
(tror tex kod analyzern i vs2005 kommer gnälla på att du har publika fält, ms FXcop gör det iaf)
//RogerSv:Varför krångla till det?
Inkapsling bygger på att man skall dölja hur objektet fungerar internt. Jag tycker det vanligaste sättet att använda Setters & getters är raka motsatsen?Sv: Varför krångla till det?
Sv:Varför krångla till det?
I stället skall man i första hand fundera över interfacet, och sedan sätta innehåll efter detta.Sv:Varför krångla till det?
Jag tycker inte det är särskilt inkapslat om interfacet bygger på vilka medlemmar klassen har för tillfället. Om du av någon anledning behöver ändra innehållet kommer ju också interfacet att ändras.
Nu har jag iochförsig alltid haft svårt för skrivbara egenskaper så setters tycker jag bara krånglar till det.
Dessvärre så verkar utvecklingen gå mer och mer mot att man har en tom konstruktor och sen bygger objekten med properties så det är väl bara att anpassa sig. Sv: Varför krångla till det?
Sv:Varför krångla till det?