È possibile aggiungere attributi in fase di esecuzione o modificare il valore di un attributo in fase di esecuzione?
È possibile aggiungere attributi in fase di esecuzione o modificare il valore di un attributo in fase di esecuzione?
Risposte:
Gli attributi sono metadati statici. Assiemi, moduli, tipi, membri, parametri e valori restituiti non sono oggetti di prima classe in C # (ad esempio, la System.Type
classe è semplicemente una rappresentazione riflessa di un tipo). È possibile ottenere un'istanza di un attributo per un tipo e modificare le proprietà se sono scrivibili ma ciò non influirà sull'attributo quando viene applicato al tipo.
Questo dipende davvero da cosa stai esattamente cercando di realizzare.
Le cose System.ComponentModel.TypeDescriptor possono essere usate per aggiungere attributi a tipi, proprietà ed istanze di oggetti, e hanno il limite che devi usarlo per recuperare anche quelle proprietà. Se stai scrivendo il codice che consuma quegli attributi e puoi vivere entro quei limiti, allora lo consiglierei sicuramente.
Per quanto ne so, il controllo PropertyGrid e la superficie di progettazione dello studio visivo sono le uniche cose nel BCL che consumano le cose TypeDescriptor. In effetti, è così che fanno circa la metà delle cose che devono veramente fare.
TypeDescriptor
e TypeDescriptionProvider
non sono implementati?
[Attr(1), Attr(2), Attr(3)]
solo Ex Attr(3)
.
Bene, solo per essere diversi, ho trovato un articolo che fa riferimento a Reflection. Ammettilo.
Ecco il link: http://www.codeproject.com/KB/cs/dotnetattributes.aspx , vorrai anche esaminare alcuni dei commenti in fondo all'articolo, perché vengono discussi i possibili approcci.
YourClass
in YourRuntimeClassWithAttributes
.
YourClass
, è possibile sottoclassarlo in fase di esecuzione e generare una classe identica con un nome leggermente diverso che abbia anche gli attributi desiderati creati dinamicamente e il polimorfismo consentirà al codice di controllo del tipo di identificare ancora la tua base.
No non lo è.
Gli attributi sono metadati e archiviati in forma binaria nell'assieme compilato (ecco perché è possibile utilizzare solo tipi semplici in essi).
Io non ci credo. Anche se sbaglio, il meglio che puoi sperare è aggiungerli a un intero Tipo, mai un'istanza di un Tipo.
Se hai bisogno di qualcosa per poterlo aggiungere dinamicamente, gli attributi c # non sono la strada giusta. Cerca nella memorizzazione dei dati in XML. Di recente ho realizzato un progetto che ho avviato con attributi, ma alla fine sono passato alla serializzazione con XML.
Perché ne hai bisogno? Gli attributi forniscono informazioni extra per la riflessione, ma se sai esternamente quali proprietà desideri non ne hai bisogno.
È possibile archiviare metadati esternamente relativamente facilmente in un database o in un file di risorse.
Ho provato molto con System.ComponentModel.TypeDescriptor senza successo. Ciò non significa che non possa funzionare, ma mi piacerebbe vedere il codice per quello.
In contropartita, volevo cambiare alcuni valori di attributo. Ho fatto 2 funzioni che funzionano bene a tale scopo.
// ************************************************************************
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);
}
}
}
In Java ero solito aggirare questo problema usando una mappa e implementando il mio approccio alla codifica Key-Value.
http://developer.apple.com/documentation/Cocoa/Conceptual/KeyValueCoding/KeyValueCoding.html
TypeDescriptor
- non soloPropertyGrid
.