Czy można dodawać atrybuty w czasie wykonywania lub zmieniać wartość atrybutu w czasie wykonywania?
Czy można dodawać atrybuty w czasie wykonywania lub zmieniać wartość atrybutu w czasie wykonywania?
Odpowiedzi:
Atrybuty to statyczne metadane. Zestawy, moduły, typy, składowe, parametry i wartości zwracane nie są obiektami pierwszej klasy w języku C # (np. System.Type
Klasa jest jedynie odzwierciedleniem reprezentacji typu). Możesz pobrać wystąpienie atrybutu dla typu i zmienić właściwości, jeśli są one zapisywalne, ale nie wpłynie to na atrybut, ponieważ jest stosowany do typu.
To naprawdę zależy od tego, co dokładnie próbujesz osiągnąć.
Element System.ComponentModel.TypeDescriptor może być użyty do dodawania atrybutów do typów, właściwości i instancji obiektów, i ma ograniczenie, że musisz go również użyć do pobrania tych właściwości. Jeśli piszesz kod, który wykorzystuje te atrybuty i możesz żyć w ramach tych ograniczeń, zdecydowanie bym to zasugerował.
O ile wiem, formant PropertyGrid i powierzchnia projektowa studia wizualnego to jedyne rzeczy w BCL, które zużywają rzeczy TypeDescriptor. W rzeczywistości w ten sposób robią mniej więcej połowę rzeczy, które naprawdę muszą zrobić.
TypeDescriptor
i TypeDescriptionProvider
nie są zaimplementowane?
[Attr(1), Attr(2), Attr(3)]
tylko Ex Attr(3)
.
Cóż, żeby być innym, znalazłem artykuł, który odwołuje się do metody Reflection.Emit.
Oto link: http://www.codeproject.com/KB/cs/dotnetattributes.aspx , zajrzyj również do niektórych komentarzy na dole artykułu, ponieważ omówione są możliwe podejścia.
YourClass
do YourRuntimeClassWithAttributes
.
YourClass
, możesz podklasować ją w czasie wykonywania i wygenerować identyczną klasę o nieco innej nazwie, która ma również żądane dynamicznie tworzone atrybuty, a polimorfizm pozwoli kodowi sprawdzającemu typ nadal identyfikować Twoja klasa bazowa.
Nie, nie jest.
Atrybuty są metadanymi i są przechowywane w postaci binarnej w skompilowanym zestawie (dlatego też można w nich używać tylko prostych typów).
Nie wierzę w to. Nawet jeśli się mylę, najlepsze, na co możesz liczyć, to dodanie ich do całego Typu, a nigdy do wystąpienia Typu.
Jeśli potrzebujesz czegoś do dynamicznego dodawania, atrybuty C # nie są odpowiednie. Przyjrzyj się przechowywaniu danych w formacie XML. Niedawno zrobiłem projekt, który zacząłem z atrybutami, ale ostatecznie przeszedłem do serializacji w / xml.
Dlaczego potrzebujesz? Atrybuty dostarczają dodatkowych informacji do refleksji, ale jeśli zewnętrznie wiesz, które właściwości chcesz, nie potrzebujesz ich.
Możesz stosunkowo łatwo przechowywać metadane na zewnątrz w bazie danych lub pliku zasobów.
Bardzo się starałem z System.ComponentModel.TypeDescriptor bez powodzenia. To nie znaczy, że nie może działać, ale chciałbym zobaczyć kod.
Z drugiej strony chciałem zmienić niektóre wartości atrybutów. Zrobiłem 2 funkcje, które działają dobrze w tym celu.
// ************************************************************************
public static void SetObjectPropertyDescription(this Type typeOfObject, string propertyName, string description)
{
PropertyDescriptor pd = TypeDescriptor.GetProperties(typeOfObject)[propertyName];
var att = pd.Attributes[typeof(DescriptionAttribute)] as DescriptionAttribute;
if (att != null)
{
var fieldDescription = att.GetType().GetField("description", BindingFlags.NonPublic | BindingFlags.Instance);
if (fieldDescription != null)
{
fieldDescription.SetValue(att, description);
}
}
}
// ************************************************************************
public static void SetPropertyAttributReadOnly(this Type typeOfObject, string propertyName, bool isReadOnly)
{
PropertyDescriptor pd = TypeDescriptor.GetProperties(typeOfObject)[propertyName];
var att = pd.Attributes[typeof(ReadOnlyAttribute)] as ReadOnlyAttribute;
if (att != null)
{
var fieldDescription = att.GetType().GetField("isReadOnly", BindingFlags.NonPublic | BindingFlags.Instance);
if (fieldDescription != null)
{
fieldDescription.SetValue(att, isReadOnly);
}
}
}
W Javie starałem się to obejść, używając mapy i implementując własne podejście do kodowania klucz-wartość.
http://developer.apple.com/documentation/Cocoa/Conceptual/KeyValueCoding/KeyValueCoding.html
TypeDescriptor
- nie tylkoPropertyGrid
.