2009-07-24 8 views
22

Disons que j'ai un Type appelé type.Déterminer si un type est statique

Je veux savoir si je peux le faire avec mon type (sans faire réellement ce à chaque type):

Si type est System.Windows.Point alors je pourrais faire ceci:

Point point1 = new Point(); 

Toutefois, si type est System.Environment alors ce ne volerai pas:

Environment environment1 = new Environment(); //wrong 

donc, si je suis Itère chaque type visible dans un assemblage comment puis-je ignorer tous les types qui échoueront à créer une instance comme la seconde? Je suis un peu nouveau à la réflexion, donc je ne suis pas très bon avec la terminologie pour le moment. J'espère que ce que j'essaie de faire ici est assez clair.

Répondre

53

static les classes sont déclarées abstract et sealed au niveau IL. Ainsi, vous pouvez vérifier la propriété IsAbstract pour gérer à la fois les classes abstract et les classes static en une seule fois (pour votre cas d'utilisation).

Toutefois, les classes abstract ne sont pas les seuls types que vous ne pouvez pas instancier directement. Vous devriez vérifier pour les choses comme les interfaces (without the CoClass attribute) et les types qui n'ont pas un constructeur accessible par le code appelant.

+3

Merci pour la réponse, il m'aurait fallu longtemps pour arriver à ce résultat. – Beaker

-3

Ceci permet d'obtenir tous les composants publics de tous types dans un assemblage.

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

vous pouvez rechercher des contructeurs publics comme celui-ci,

Ou si vous ne souhaitez que constructeur parameterless vous pouvez utiliser

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

Notez qu'une classe 'abstract' peut avoir un constructeur' public'. Vous ne pouvez pas nécessairement créer une instance d'une classe dans le corps de votre instruction 'if'. Vous obtiendrez 'MemberAccessException'. –

+0

oui, vous avez raison, j'ai édité le post. –

10
type.IsAbstract && type.IsSealed 

Ce serait un contrôle suffisant pour C# car une classe abstraite ne peut pas être scellée ou statique en C#. Cependant, vous devrez faire attention en traitant des types CLR d'autres langues.

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)); 

Je suppose que cela devrait fonctionner.

Questions connexes