2009-07-24 25 views
22

Diciamo che ho un Type chiamato type.Determinare se un tipo è statico

voglio stabilire se posso fare questo con il mio tipo (senza in realtà fare questo ad ogni tipo):

Se type è System.Windows.Point poi ho potuto fare questo:

Point point1 = new Point(); 

Tuttavia, se type è System.Environment allora questo non volerà:

Environment environment1 = new Environment(); //wrong 

quindi, se io sto scorrendo ogni tipo visibile in un assieme come faccio a saltare tutti i tipi che non riescono a creare un'istanza come la seconda? Sono un po 'nuovo al riflesso quindi non sono ancora eccezionale con la terminologia. Speriamo che quello che sto cercando di fare qui sia abbastanza chiaro.

risposta

53

static classi sono dichiarate abstract e sealed a livello IL. Quindi, puoi controllare la proprietà IsAbstract per gestire entrambe le classi abstract e le classi static in un colpo solo (per il tuo caso d'uso).

Tuttavia, le classi abstract non sono gli unici tipi che non è possibile creare direttamente. È necessario verificare elementi quali interfacce (without the CoClass attribute) e tipi che non dispongono di un costruttore accessibile dal codice chiamante.

+3

Grazie per la risposta, mi ci sarebbe voluto molto tempo per inventarlo da solo. – Beaker

-3

Questo è un modo per ottenere tutti i costruttori pubblici di tutti i tipi in un assieme.

var assembly = AppDomain.CurrentDomain.GetAssemblies()[0]; // first assembly for demo purposes 
var types = assembly.GetTypes(); 
foreach (var type in types) 
{ 
    var constructors = type.GetConstructors(); 
} 
6

è possibile cercare Case costruttrici di pubblici come questo,

O se interessati solo costruttore senza parametri è possibile utilizzare

Type t = typeof(Environment); 
var c = t.GetConstructor(Type.EmptyTypes); 
if (c != null && c.IsPublic && !t.IsAbstract) 
{ 
    //You can create instance 
} 
+2

Si noti che una classe 'abstract' può avere un costruttore' public'. Non è possibile creare necessariamente un'istanza di una classe nel corpo dell'istruzione 'if'. Otterrai "MemberAccessException". –

+0

sì, hai ragione, ho modificato il post. –

10
type.IsAbstract && type.IsSealed 

Questo sarebbe un controllo sufficiente per C# poiché una classe astratta non può essere sigillata o statica in C#. Tuttavia, è necessario fare attenzione quando si gestiscono i tipi di CLR da altre lingue.

1
Type t = typeof(System.GC); 
Console.WriteLine(t.Attributes); 
TypeAttributes attribForStaticClass = TypeAttributes.AutoLayout | TypeAttributes.AnsiClass | TypeAttributes.Class | 
TypeAttributes.Public | TypeAttributes.Abstract | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit; 
Console.WriteLine((t.Attributes == attribForStaticClass)); 

Immagino, questo dovrebbe funzionare.

Problemi correlati