mafu
mafu

Reputation: 32640

How do I check if a type provides a parameterless constructor?

I'd like to check if a type that is known at runtime provides a parameterless constructor. The Type class did not yield anything promising, so I'm assuming I have to use reflection?

Upvotes: 118

Views: 40966

Answers (9)

Glenn Slayden
Glenn Slayden

Reputation: 18749

If anyone is interested in an "official" version, the following code exists in the System.Activities.Presentation.TypeUtilities class, in the .NET Framework WPF base class library System.Activities.Presentation.dll, Version=4.0.0.0:

public static bool CanCreateInstanceUsingDefaultConstructor(this Type t) => 
        t.IsValueType || 
        !t.IsAbstract && t.GetConstructor(Type.EmptyTypes) != null;

Notice the check for t.IsAbstract, which is not mentioned elsewhere on this page. This property is true for .NET interface types as well as static and abstract reference types.

You can also expand the GetConstructor call inline, if you feel like micro-optimizing away one stack frame, or if you need the method to work on BindingFlags.NonPublic types as well:

public static bool CanCreateInstanceUsingDefaultConstructor(this Type t) => 
      t.IsValueType || 
      !t.IsAbstract && t.GetConstructor(    //  v-- includes 'private' classes
           BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, 
           null,
           Type.EmptyTypes,
           null) != null;

Upvotes: 5

jrivam
jrivam

Reputation: 1101

To get the one that has more optional parameters or an empty constructor at all, use:

    typeof(myClass)
    .GetConstructors()
    .OrderBy(x => x.GetParameters().Length - x.GetParameters().Count(p => p.IsOptional))
    .FirstOrDefault();

Upvotes: 1

Aaron D
Aaron D

Reputation: 5876

I needed to count constructors with only optional parameters the same as true parameter-less constructors. To do this:

myClass.GetType().GetConstructors()
    .All(c => c.GetParameters().Length == 0 || c.GetParameters().All(p => p.IsOptional))

Upvotes: 4

Alex J
Alex J

Reputation: 10205

The Type class is reflection. You can do:

Type theType = myobject.GetType(); // if you have an instance
// or
Type theType = typeof(MyObject); // if you know the type

var constructor = theType.GetConstructor(Type.EmptyTypes);

It will return null if a parameterless constructor does not exist.


If you also want to find private constructors, use the slightly longer:

var constructor = theType.GetConstructor(
  BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, 
  null, Type.EmptyTypes, null);

There's a caveat for value types, which aren't allowed to have a default constructor. You can check if you have a value type using the Type.IsValueType property, and create instances using Activator.CreateInstance(Type);

Upvotes: 205

nawfal
nawfal

Reputation: 73163

type.GetConstructor(Type.EmptyTypes) != null

would fail for structs. Better to extend it:

public static bool HasDefaultConstructor(this Type t)
{
    return t.IsValueType || t.GetConstructor(Type.EmptyTypes) != null;
}

Succeeds since even enums have default parameterless constructor. Also slightly speeds up for value types since the reflection call is not made.

Upvotes: 20

Henk Holterman
Henk Holterman

Reputation: 273169

Yes, you have to use Reflection. But you already do that when you use GetType()

Something like:

var t = x.GetType();
var c = t.GetConstructor(new Type[0]);
if (c != null) ...

Upvotes: 13

KeithS
KeithS

Reputation: 71565

Depending on your situation, you could also use a generic type restriction:

public void DoSomethingWith<T>(T myObject) where T:new() {...}

The above method declaration will restrict the parameter type to any Object that can be instantiated with a parameterless constructor. The advantage here is that the compiler will catch any attempt to use the method with a class that doesn't have a parameterless constructor, so as long as the type is known SOMEWHERE at compile-time, this will work and will alert you to a problem earlier.

Of course if the type really is known only at runtime (i.e. you're using Activator.CreateInstance() to instantiate an object based on a string or a constructed Type) then this won't help you. I generally use reflection as the absolute last option, because once you've gone to dynamic land you pretty much have to stay in dynamic land; it's usually difficult or even messier to dynamically instantiate something and then start dealing with it statically.

Upvotes: 4

BrokenGlass
BrokenGlass

Reputation: 160852

This should work:

   myClass.GetType().GetConstructors()
                    .All(c=>c.GetParameters().Length == 0)

Upvotes: 10

Mel Harbour
Mel Harbour

Reputation: 381

Yes, you have to use reflection.

object myObject = new MyType();
Type type = myObject.GetType();
ConstructorInfo conInfo = type.GetConstructor(new Type[0]);

Upvotes: 2

Related Questions