Atributi sluze za pridruzivanje nekih podataka klasama i clanovima klase. Koriste se kada je potrebno pridruziti neki bitan podatak koji ce se koristiti u nekom procesu. Na primer, atributi Category, DisplayName i Description se dodaju svojstvima a ti podaci se zatim prikazuju u kontroli PropertyGrid.
Code:
public class MyClass
{
[Category("MyProperty category name")]
[DisplayName("MyProperty alternate name")]
[Description("property description");
public bool MyProperty { get; set; }
}
Ako se Category izostavi svojstvo bi trebalo da bude svrstano pod kategoriju Misc.
Ako se DisplayName izostavi u PropertyGrid-u ce se prikazati stvarno ime svojstva.
Atributi su u sustini klase koje nasledjuju klasu System.Attribute a koriste se tako sto se ispred definicije klase ili nekog njenog clana navede naziv klase u uglastim zagradama.
Po nekom nepisanom pravilu nazivi svih atributa bi trebalo da se zavrsavaju sa Attribute a kada se navode ovaj sufiks nije potrebno navoditi. Na primer:
Code:
[Serializable]
public class MyClass
{
[Serializable]
public bool MyProperty { get; set; }
}
je isto sto i
Code:
[SerializableAttribute]
public class MyClass
{
[SerializableAttribute]
public bool MyProperty { get; set; }
}
Ako kao u ovom slucaju atribut Serializable ima default konstruktor (znaci bez parametara), posle naziva mozes staviti male zagrade a i ne moras. Znaci moglo je i:
Code:
[Serializable()]
public class MyClass
{
[Serializable()]
public bool MyProperty { get; set; }
}
Za svaku klasu i njene clanove se moze vezati veci broj atributa tako sto se svaki za sebe navede izmedju uglastih zagrada ili se svi stave izmedju jednog para uglastih zagrada ali se razdvoje zarezom:
Code:
public class MyClass
{
[Category("category"), DisplayName("name"), Description("desc")]
public bool MyProperty { get; set; }
}
Sistem atributa je moguc zahvaljujuci postojanju refleksije. Refleksija omogucava pregled strukture programa i njegovu izmenu za vreme samog izvrsavanja programa. Putem refleksije mozes da procitas kompletnu strukturu nekog objekta: kog je tipa, naziv, svi njegovi clanovi...
I naravno, putem refleksije mozes da procitas koji su atributi vezani za neku klasu ili clanova neke klase.
Primer kreiranja atributa i koriscenja:
Code:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public class SampleAttribute: Attribute
{
private SampleValue m_Value = SampleValue.Default;
public SampleValue Value
{
get { return m_Value; }
}
public SampleAttribute()
{
}
public SampleAttribute(SampleValue value)
{
m_Value = value;
}
}
public enum SampleValue
{
Default,
One,
Two,
Three
}
Pri samom definisanju svog atributa moras mu navesti kako ce se koristiti a za to se koristi atribut AttributeUsage.
Prvi parametar ukazuje nad kojim tipovima entiteta ce se atribut primenjivati (u ovom slucaju smo naveli da se atribut moze dodeliti klasama i svojstvima). AllowMultiple parametar oznacava da li se jedan atribut moze navesti vise puta za jedan isti entitet. Inherited oznacava da li se atribut nasledjuje prilikom nasledjivanja klasa.
Ovaj nas atribut ima default konstruktor i jedan konstruktor sa jednim parametrom, sto znaci da se moze koristiti ovako:
Code:
[Sample]
public class MyClass
{
[Sample(SampleValue.Two)]
public bool MyProperty { get; set; }
}
Sada kada smo napravili atribut i dodali ga nekim entitetima, potrebno je to i nekako procitati.
Code:
MyClass obj = new MyClass();
object[] attribs = typeof(MyClass).GetCustomAttributes(typeof(SampleAttribute), true);
if(attribs.Length > 0) {
MessageBox.Show("Class value: " + ((SampleAttribute)attribs[0]).Value);
}
attribs = typeof(MyClass).GetProperty("MyProperty").GetCustomAttributes(typeof(SampleAttribute), true);
if(attribs.Length > 0) {
MessageBox.Show("Property value: " + ((SampleAttribute)attribs[0]).Value);
}
Sistem atributa se dosta koristi u samom .NET Frameworku: dodavanja detaljnijeg opisa svim svojstvima kontrola, sakrivanje svojstava od PropertyGrid kontrole, sakrivanje svojstava i polja od editora programskog koda, serijalizacija objekata, importovanje windows API-ja, ...
Ako sam nesto pogresio ispravite me.