Mechanizm refleksji i atrybuty w języku C#

Mechanizm refleksji - dostęp do metadanych.


Refleksja jest to mechanizm, który pozwala na dostęp do metadanych klas lub obiektów. Metadane to informacje przechowywane w plikach wykonywalnych czyli .dll lub .exe opisujące pola, właściwości, metody znajdujące się w tych plikach. Do tworzenia metadanych służą atrybuty. Atrybuty pozwalają dodawać, jako metadane dodatkowe informacje na temat klas lub metod do plików wykonywalnych. Atrybuty są dostarczane przez środowisko CLR. Można również tworzyć własne atrybuty wykorzystywane później w mechanizmie refleksji. Atrybuty muszą być związane z pewnymi elementami programu, elementy te nazywamy adresatami atrybutu.

Dostępne adresaty atrybutów (Rys. 2.16):

adresaty atrybutów

Przykładowy kod z wykorzystaniem atrybutu obsolete:

public static void Main()
{
    StaraMetoda();
}

[Obsolete("Przestarzała metoda użyj NowaMetoda")]
public static void StaraMetoda()
{
    //ciało starej metody
}

public static void NowaMetoda()
{
    //ciało nowej metody
}

Ostrzeżenie zwrócone w czasie kompilacji:

warning CS0618: 'Aplikacja1.Program.StaraMetoda()' is obsolete: 'Przestarzała metoda użyj NowaMetoda'
Atrybut obsolete został zastosowany do metody o nazwie StaraMetoda(), atrybut ten jest stosowany do tych części programu, które nie są już używane. Bardzo często stosowanym atrybutem jest atrybut Serializable, który pozwala na zapis (w naszym przypadku klasy) do pliku na dysku.

Przykład użycia atrybutu Serializable:

[Serializable]
public class Program
{
    public string pole1 = "pole1";
    public int pole2 = 12;
    //ciało klasy
}

class Wykonaj{

    public static void Main()
    {
        Program p = new Program();
        Console.WriteLine(SerializeToXml(p));

        Console.ReadLine();
    }

    static string SerializeToXml(Program p)
    {
        StringWriter writer = new StringWriter();

        XmlSerializer serializer = new XmlSerializer(typeof(Program));
        serializer.Serialize(writer, p);

        return writer.ToString();
    }
}

Wynik działania programu:

wynik dzialania

Proces serializacji jest odwracalny a więc z wygenerowanego pliku możemy stworzyć klasę. Serializacja przydaje się np. w przekazywaniu obiektów pomiędzy klientem a serwerem np. poprzez protokół SOAP. Możliwe jest tworzenie własnych atrybutów. Aby stworzyć własny atrybut należy stworzyć własną klasę dziedziczącą po klasie: System.Attribute.

Do odczytu metadanych, atrybutów, sprawdzania typu oraz dynamicznego tworzenia typów i wywoływania metod w czasie działania programu służy mechanizm refleksji.

Przykładowy program korzystający z refleksji:

public class Testowa
{
    public int pole1;
}
 
public class Wykonaj
{
    public static void Main()
    {
 
        Assembly assembly = Assembly.GetExecutingAssembly();
            
        Type[] typ = assembly.GetTypes();
        int i = 0;
        foreach (Type t in typ)
        {
            Console.WriteLine(t.ToString());
            i++;
        }
            
        Console.ReadLine();
    }  
}
Program zwraca nazwy typów dostępnych w aktualnie wykonywanym programie. Mechanizm refleksji ma bardzo szerokie zastosowanie, dlatego nie sposób opisać wszystkich dostępnych metod. Ponieważ mechanizm refleksji działa w czasie pracy programu i nie jest wcześniej kompilowany działa dużo wolniej niż wywoływanie zwykłych metod. Z refleksji należy korzystać tylko, gdy jest to konieczne. W kolejnych rozdziałach zostanie opisane słowo kluczowe dynamic, które ma dużo wspólnego z mechanizmem refleksji.

Więcej informacji na temat refleksji i atrybutów:

http://msdn.microsoft.com/pl-pl/library/f7ykdhsy.aspx
http://msdn.microsoft.com/pl-pl/library/z0w1kczw.aspx
Komentarze facebook (polub nasz profil na FB aby je zobaczyć):