Blog Dla Programistów C#/.NET

Cześć! Dziś opowiem o refleksji (Reflection) w C#. To potężny mechanizm pozwalający na podejrzenie (i w pewnym stopniu modyfikację) kodu w czasie wykonywania. Dzięki refleksji możemy m.in. dynamicznie tworzyć obiekty na podstawie nazw klas, wywoływać metody, odczytywać atrybuty i wiele więcej.

Refleksja w C#/.NET: Jak Zaglądać pod Maskę Twoich Klas i Metod

Czym jest refleksja w .NET?


Refleksja pozwala na badanie i manipulowanie metadanymi typów w czasie wykonywania aplikacji. Oznacza to, że możemy np.:

    • Odpytać klasę o jej konstruktor, metody, właściwości, pola czy atrybuty.
    • Utworzyć obiekt klasy bezpośrednio ze stringa zawierającego jej pełną nazwę.
    • Wywołać metodę, nawet jeśli normalnie nie mielibyśmy do niej dostępu wprost.

W praktyce najczęściej wykorzystywane są przestrzenie nazw z rodziny System.Reflection, np. Type, MethodInfo, PropertyInfo.


Podstawowy przykład: Pobieranie informacji o typie


Załóżmy, że mamy prostą klasę:

public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }

public void Introduce()
{
Console.WriteLine($"Cześć, jestem {FirstName} {LastName}.");
}
}

 W kodzie aplikacji możemy skorzystać z refleksji, by pobrać informacje o właściwościach i metodach klasy Person:

using System;
using System.Reflection;

public class ReflectionDemo
{
public static void Main(string[] args)
{
// Uzyskujemy obiekt typu dla klasy Person Type personType = typeof(Person);

// Wypisujemy nazwy właściwości Console.WriteLine("Właściwości klasy Person:");
foreach (PropertyInfo propInfo in personType.GetProperties())
{
Console.WriteLine($"- {propInfo.Name} ({propInfo.PropertyType})");
}

// Wypisujemy nazwy metod Console.WriteLine("\nMetody klasy Person:");
foreach (MethodInfo methodInfo in personType.GetMethods())
{
// Filtrujemy tylko te metody, które zdefiniowaliśmy (pomijając wbudowane z System.Object) if (methodInfo.DeclaringType == typeof(Person))
{
Console.WriteLine($"- {methodInfo.Name}");
}
}
}
}

Po uruchomieniu zobaczysz w konsoli m.in. nazwy właściwości FirstName, LastName i metodę Introduce.


Tworzenie obiektu dynamicznie i wywoływanie metod


Możemy nie tylko "podejrzeć" definicję klasy, ale też utworzyć jej instancję i wywołać na niej metodę, nie używając operatora new w tradycyjny sposób.

public class ReflectionInstantiationDemo
{
public static void Main(string[] args)
{
// Pobieramy typ Person Type personType = typeof(Person);

// Tworzymy instancję klasy Person przy pomocy Activator object personInstance = Activator.CreateInstance(personType);

// Ustawiamy właściwości var firstNameProperty = personType.GetProperty("FirstName");
var lastNameProperty = personType.GetProperty("LastName");

firstNameProperty.SetValue(personInstance, "Jan");
lastNameProperty.SetValue(personInstance, "Kowalski");

// Wywołujemy metodę Introduce var introduceMethod = personType.GetMethod("Introduce");
introduceMethod.Invoke(personInstance, null);

// Efekt w konsoli: "Cześć, jestem Jan Kowalski." }
}

Co tu się dzieje?

    • Activator.CreateInstance(personType) tworzy nowy obiekt klasy Person, ale w sposób dynamiczny, bazując na typie (w runtime).
    • Metoda SetValue() pozwala ustawić wartość właściwości, nie mając w kodzie bezpośrednio personInstance.FirstName = "Jan".
    • Invoke() wywołuje metodę z podanymi parametrami (tu akurat null, bo Introduce() nie przyjmuje żadnych argumentów).


Atrybuty i refleksja


Innym częstym przypadkiem użycia refleksji jest praca z atrybutami (attributes). Możemy np. tworzyć własne atrybuty, które opisują dodatkowo klasy czy właściwości, a potem w runtime odczytywać te informacje i odpowiednio sterować zachowaniem programu.

Przykładowy atrybut:

[AttributeUsage(AttributeTargets.Property, Inherited = false)]
public class DisplayLabelAttribute : Attribute
{
public string Label { get; }

public DisplayLabelAttribute(string label)
{
Label = label;
}
}

Zastosowanie atrybutu:

public class Product
{
[DisplayLabel("Nazwa produktu")]
public string Name { get; set; }

[DisplayLabel("Cena")]
public decimal Price { get; set; }
}

Czytanie atrybutów refleksją:

Type productType = typeof(Product);
foreach (PropertyInfo prop in productType.GetProperties())
{
var displayAttr = prop.GetCustomAttribute<DisplayLabelAttribute>();
if (displayAttr != null)
{
Console.WriteLine($"Właściwość {prop.Name} ma etykietę: {displayAttr.Label}");
}
}

Taka technika przydaje się np. do automatycznego generowania formularzy, mapowania danych czy walidacji.


Kiedy refleksja bywa przydatna?


    1. Tworzenie frameworków i bibliotek – np. automatyczne rejestrowanie klas w kontenerach IoC, skanowanie projektów w poszukiwaniu określonych typów (np. pluginów).
    2. Serializacja i deserializacja – narzędzia jak JSON.NET czy XML Serializer często korzystają z refleksji.
    3. Automatyczne generowanie UI – np. tworzenie formularzy w oparciu o atrybuty i nazwy właściwości.
    4. Testy automatyczne – np. framework testowy może wyszukiwać metody testowe w kodzie (atrybut [TestMethod]) i je wywoływać.


Podsumowanie


Refleksja to potężny mechanizm w .NET, pozwalający na dynamiczne eksplorowanie i modyfikowanie typów w czasie działania programu. Jest nieoceniona przy pisaniu własnych bibliotek, frameworków, systemów wtyczek czy narzędzi do automatycznej generacji kodu i UI. Jednocześnie warto pamiętać, że refleksja jest bardziej zasobożerna niż zwykłe, statyczne wywołania metod – więc trzeba jej używać rozważnie.

Jeśli interesują Cię takie zaawansowane aspekty C# i .NET oraz chcesz krok po kroku przejść przez nieco bardziej rozbudowane tematy programistyczne, zapraszam Cię na moje szkolenie online: "Zostań Programistą .NET". Poznasz w nim nie tylko refleksję, ale też wzorce projektowe, testy, pracę z bazami danych i wiele więcej.

Daj znać w komentarzu, w jaki sposób najchętniej wykorzystujesz refleksję lub co najbardziej Cię w niej zaskakuje!

To wszystkie na dzisiaj. Jeżeli taki artykuł Ci się spodobał, to koniecznie dołącz do mojej społeczności – darmowe zapisy, gdzie będziesz również miał dostęp do dodatkowych materiałów i przede wszystkim bonusów. Do zobaczenia w kolejnym artykule.

Szkolenie Zostań Programistą .NET
Szczegóły == Zostań Programistą .NET ==
Zapisy tylko do piątku do 22:00!
Autor artykułu:
Kazimierz Szpin
Kazimierz Szpin
CTO & Founder - FindSolution.pl
Programista C#/.NET. Specjalizuje się w Blazor, ASP.NET Core, ASP.NET MVC, ASP.NET Web API, WPF oraz Windows Forms.
Autor bloga ModestProgrammer.pl
Dodaj komentarz

Wyszukiwarka

Szkolenie Zostań Programistą .NET
Szczegóły == Zostań Programistą .NET ==
Zapisy tylko do piątku do 22:00!

Zostańmy w kontakcie!

Dołącz do mojej listy mailowej, aby otrzymywać ciekawe informacje ze świata programowania. Dodatkowo będziesz informowany o nowych artykułach na blogu, a także otrzymasz wyjątkowe rabaty na moje kursy i szkolenia.

    Nienawidzę spamu, dlatego będziesz otrzymywał tylko wartościowe maile. Możesz zrezygnować z subskrypcji w dowolnym momencie ✅

    © Copyright 2025 modestprogrammer.pl. Wszelkie prawa zastrzeżone. Regulamin. Polityka prywatności. Design by Kazimierz Szpin
    Serwis wykorzystuje pliki cookies. Korzystając ze strony wyrażasz zgodę na wykorzystywanie plików cookies. dowiedz się więcej.