44

Let's say I have a Type called type.

I want to determine if I can do this with my type (without actually doing this to each type):

If type is System.Windows.Point then I could do this:

Point point1 = new Point();

However if type is System.Environment then this will not fly:

Environment environment1 = new Environment(); //wrong

So if I am iterating through every visible type in an assembly how do I skip all the types that will fail to create an instance like the second one? I'm kind of new to reflection so I'm not that great with the terminology yet. Hopefully what I'm trying to do here is pretty clear.

Mehrdad Afshari
  • 414,610
  • 91
  • 852
  • 789
Beaker
  • 2,804
  • 5
  • 33
  • 54

5 Answers5

93

static classes are declared abstract and sealed at the IL level. So, you can check IsAbstract property to handle both abstract classes and static classes in one go (for your use case).

However, abstract classes are not the only types you can't instantiate directly. You should check for things like interfaces (without the CoClass attribute) and types that don't have a constructor accessible by the calling code.

Community
  • 1
  • 1
Mehrdad Afshari
  • 414,610
  • 91
  • 852
  • 789
27
type.IsAbstract && type.IsSealed

This would be a sufficient check for C# since an abstract class cannot be sealed or static in C#. However, you'll need to be careful when dealing with CLR types from other languages.

Joe Chung
  • 11,955
  • 1
  • 24
  • 33
7

you can search for public contructors like this,

Type t = typeof(Environment);
var c = t.GetConstructors(BindingFlags.Public);
if (!t.IsAbstract && c.Length > 0)
{
     //You can create instance
}

Or if you only interested in parameterless constructor you can use

Type t = typeof(Environment);
var c = t.GetConstructor(Type.EmptyTypes);
if (c != null && c.IsPublic && !t.IsAbstract )
{
     //You can create instance
}
Arsen Mkrtchyan
  • 49,896
  • 32
  • 148
  • 184
  • 2
    Note that an `abstract` class can have a `public` constructor. You can't necessarily create an instance of a class in the body of your `if` statement. You'll get `MemberAccessException`. – Mehrdad Afshari Jul 24 '09 at 08:31
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));

I guess, this should work.

shahkalpesh
  • 33,172
  • 3
  • 63
  • 88
  • I believe the only one unique to static classes is the `TypeAttributes.BeforeFieldInit` -- this is what I use to determine static classes. Checking `IsAbstract` and `IsSealed` also guarantees only static types but it's a more involved check. – mhand Aug 12 '21 at 05:23
-4

This is a way to get all public contstuctors of all types in an assembly.

    var assembly = AppDomain.CurrentDomain.GetAssemblies()[0]; // first assembly for demo purposes
var types = assembly.GetTypes();
foreach (var type in types)
{
    var constructors = type.GetConstructors();
}
Paul van Brenk
  • 7,450
  • 2
  • 33
  • 38