Cenni preliminari sul descrittore del tipo

L'architettura di TypeDescriptor migliora le funzionalità di reflection di .NET.

Architettura del descrittore del tipo

L'architettura di TypeDescriptor è stata sviluppata sul modulo di reflection di base, a cui sono state aggiunte ulteriori regole e funzionalità. La classe TypeDescriptor, ad esempio, supporta l'unione delle proprietà di estensione da un'interfaccia IContainer, nonché il filtro di proprietà ed eventi tramite un'interfaccia IDesigner.

L'architettura di TypeDescriptor, inoltre, consente di utilizzare diverse funzionalità. Nella tabella seguente sono illustrate le funzionalità dell'architettura.

Funzionalità

Descrizione

Sostituzione di istanze

Consente la creazione di un tipo arbitrario quando viene richiesto un altro tipo.

Sostituzione di metadati

Consente la modifica dei metadati di un oggetto.

Reindirizzamento di attributi

Consente di specificare dinamicamente gli attributi.

Shadowing e sostituzione della destinazione

Consente a un oggetto di sostituirne un altro.

Supporto esteso del descrittore del tipo

Consente di accedere alle proprietà dell'oggetto aggiunte da altri oggetti.

Per supportare queste funzionalità, la classe TypeDescriptor è fortemente integrata con le funzionalità del modello componente .NET Framework. È compatibile con oggetti COM, provider di estensione, finestre di progettazione e proprietà CLR.

Nota

L'architettura di TypeDescriptor può essere utilizzata nel codice di esecuzione nonché in quello di progettazione.

Per supportare l'Extensibility, la classe TypeDescriptor dispone di una classe complementare denominata TypeDescriptionProvider e di un attributo complementare denominato TypeDescriptionProviderAttribute. È possibile utilizzare un oggetto TypeDescriptionProviderAttribute su una classe per introdurre un sistema completamente diverso di esposizione dei metadati in grado di soddisfare gli obiettivi di progettazione.

Classe TypeDescriptionProvider

La classe TypeDescriptionProvider può essere considerata un plug-in per la classe TypeDescriptor. Per una determinata istanza di TypeDescriptor possono esistere più classi di provider di descrizione del tipo e tutte offrono metadati alla classe TypeDescriptor.

Attributo TypeDescriptionProvider

TypeDescriptionProviderAttribute è un attributo che è possibile collocare su una classe. Tale attributo viene utilizzato per indicare che al tipo è associato un provider di descrizione del tipo personalizzato. A sua volta l'attributo, tramite i metadati, fornisce un sistema per installare un provider di descrizione del tipo. Quando il tipo viene passato a un'API sulla classe TypeDescriptor, TypeDescriptor scopre l'attributo, crea un'istanza del provider di descrizione del tipo ivi descritto ed esegue l'hook del provider nelle tabelle interne di TypeDescriptor. Al termine di questa operazione, TypeDescriptor continua l'elaborazione dell'API. L'elaborazione consente a un tipo di installare automaticamente su richiesta un provider di descrizione del tipo personalizzato.

Funzionalità del descrittore del tipo

L'architettura di TypeDescriptor offre ulteriori funzionalità rispetto a quelle fornite dalla reflection di .NET Framework.

Sostituzione di istanze

La sostituzione di istanze si verifica quando si crea un tipo che, una volta creato, risulti diverso da come si era richiesto. La sostituzione di istanze viene effettuata quando si sostituiscono tutte le chiamate a new con chiamate al metodo CreateInstance. Tale metodo ricerca nelle tabelle interne di TypeDescriptor un oggetto TypeDescriptionProvider associato al tipo di dati fornito. Se ne trova uno, delega la chiamata a questo oggetto.

Sostituzione di metadati

La sostituzione di metadati si verifica quando si desidera modificare i metadati disponibili per uno o più oggetti. Un'applicazione comune per la sostituzione di metadati è nell'implementazione delle finestre di progettazione. La sostituzione dei metadati può essere effettuata con i provider di descrizione del tipo, che possono essere aggiunti e rimossi mediante i seguenti metodi su TypeDescriptor:

Reindirizzamento di attributi

In alcuni casi del modello a oggetti .NET Framework il tipo di una proprietà è appositamente creato come non specifico. La proprietà DataSource sulla classe DataGridView, ad esempio, viene tipizzata come tipo object. La progettazione consente all'origine dati di accettare diversi tipi di input, ma non fornisce una posizione comune per aggiungere i metadati e descrivere le caratteristiche della proprietà. Per ogni proprietà dell'origine dati in .NET Framework è necessario che esistano metadati identici per i convertitori di tipo e gli editor di tipi con interfaccia utente.

La classe AttributeProviderAttribute consente di risolvere tale situazione. Quando l'attributo viene collocato su una proprietà, le regole per ottenere gli attributi relativi alla raccolta Attributes del descrittore della proprietà cambiano. Di solito, il descrittore della proprietà raccoglie gli attributi locali e li unisce ad attributi provenienti dal tipo di proprietà. Quando si applica l'attributo AttributeProviderAttribute, gli attributi vengono forniti dal tipo restituito da AttributeProviderAttribute, non dal tipo di proprietà vero e proprio. La classe AttributeProviderAttribute viene utilizzata sulle origini dati per consentire al tipo specifico di origine dati di fare riferimento a IListSource, mentre i metadati appropriati vengono collocati su IListSource per consentire l'associazione dati. Il reindirizzamento consente ad applicazioni esterne quali Visual Studio di aggiungere facilmente metadati a tutte le origini dati.

Gli attributi ottenuti da un tipo dichiarato in AttributeProviderAttribute hanno la priorità rispetto agli attributi del tipo di proprietà e agli attributi sulla proprietà. In ordine di priorità, l'insieme completo di attributi disponibili è l'elemento di unione, come illustrato nell'elenco riportato di seguito:

  1. Attributi di proprietà

  2. Attributi del provider di attributi

  3. Attributi del tipo di proprietà

Shadowing e sostituzione della destinazione

La sostituzione della destinazione si verifica quando un oggetto si trova al posto di un altro. Un'applicazione comune per la sostituzione di destinazione è nell'implementazione delle finestre di progettazione.

Nell'architettura di progettazione di .NET Framework è possibile che a un componente sia associata una finestra di progettazione. Tale finestra può implementare l'interfaccia IDesignerFilter e fornire le proprie proprietà. Tali proprietà vengono unite all'insieme di proprietà relativo al componente a cui la finestra di progettazione è associata e possono essere nuove per il componente. È inoltre possibile che dispongano dello stesso nome e tipo delle proprietà già definite sul componente. La condivisione del nome e del tipo di una proprietà esistente da parte di una nuova proprietà viene definita shadowing, in quanto la finestra di progettazione nasconde la proprietà esistente sul componente, ovvero ne esegue lo shadowing. Nell'illustrazione che segue è descritto lo shadowing di una proprietà.

Shadowing della proprietà Text

In questo caso il componente offre due proprietà, proprio come la finestra di progettazione. La proprietà Text viene fornita sia nella finestra di progettazione che nel componente e ne viene eseguito lo shadowing. Il risultato finale di una chiamata a GetProperties è costituito da tre proprietà: una esiste nel componente e le altre due nella finestra di progettazione.

L'operazione di filtro della proprietà viene effettuata mediante l'utilizzo dell'interfaccia ITypeDescriptorFilterService, che viene implementata dall'area di progettazione. Le funzionalità di TypeDescriptor sono necessarie al momento di impostare un valore sulla proprietà. Il codice per impostare un valore sulla proprietà Grid sarebbe analogo a quello riportato di seguito:

    gridProp.SetValue(component, value);

Le informazioni sul tipo effettivo relative alla proprietà fanno riferimento a un'istanza della finestra di progettazione, non al componente. Se si effettuasse una chiamata di reflection per impostare effettivamente la proprietà, la chiamata potrebbe generare una chiamata di destinazione dal momento che l'istanza del componente non corrisponde al tipo di finestra di progettazione.

La classe TypeDescriptor presenta una logica intrinseca che consente di risolvere la situazione. Quando viene effettuata una chiamata alla proprietà, la classe TypeDescriptor verifica se il tipo di membro è un'istanza dell'oggetto passato. In caso affermativo, consente la continuazione della chiamata. In caso contrario, tenta di individuare la finestra di progettazione relativa all'oggetto e se è in grado di trovarla e questa è del tipo corretto, l'istanza del componente viene sostituita dall'istanza della finestra di progettazione.

La sostituzione di destinazione è supportata dai seguenti metodi su TypeDescriptor:

Supporto esteso del descrittore del tipo

Il metodo GetExtendedTypeDescriptor restituisce un descrittore di tipo personalizzato esteso relativo all'oggetto fornito. Per descrittore di tipo esteso si intende un descrittore di tipo personalizzato che offre proprietà che altri oggetti hanno aggiunto all'oggetto ma che non sono effettivamente definite sull'oggetto stesso. Nel modello componente .NET Framework, ad esempio, gli oggetti che implementano l'interfaccia IExtenderProvider sono in grado di associare proprietà ad altri oggetti che risiedono nella stessa interfaccia IContainer. Il metodo GetTypeDescriptor non restituisce un descrittore del tipo che fornisce queste proprietà aggiuntive estese, ma il metodo GetExtendedTypeDescriptor restituisce l'insieme delle proprietà estese. La classe TypeDescriptor unisce automaticamente i risultati delle due raccolte di proprietà.

Nota

Anche se il modello componente .NET Framework supporta solo proprietà estese, il metodo GetExtendedTypeDescriptor può essere utilizzato anche per eventi ed attributi estesi, se tale opzione è supportata dal provider di descrizione del tipo.

Vedere anche

Riferimenti

TypeDescriptor

TypeDescriptionProvider

TypeDescriptionProviderAttribute

ICustomTypeDescriptor

CustomTypeDescriptor

IContainer

IDesigner

Altre risorse

Estensione del supporto in fase di progettazione