116

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?

nawfal
  • 70,104
  • 56
  • 326
  • 368
mafu
  • 31,798
  • 42
  • 154
  • 247

9 Answers9

200

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

Alex J
  • 9,905
  • 6
  • 36
  • 46
18
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.

nawfal
  • 70,104
  • 56
  • 326
  • 368
13

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) ...
H H
  • 263,252
  • 30
  • 330
  • 514
9

This should work:

   myClass.GetType().GetConstructors()
                    .All(c=>c.GetParameters().Length == 0)
BrokenGlass
  • 158,293
  • 28
  • 286
  • 335
  • 2
    Not what I meant, but please don't delete - it's a related issue and a nice information. – mafu Jan 13 '11 at 16:34
  • 2
    Indeed, the correct expression for the OP's request should be `myClass.GetType().GetConstructors().Any(c=>c.GetParameters().Length == 0)`. Note the use of **Any** instead of **All**. – Glenn Slayden Mar 25 '19 at 22:21
  • @GlennSlayden is correct. It should be .Any() instead of .All(). Otherwise the you will be checking if your type has only one constructor, that one constructor being parameter-less. – Cogent Oct 31 '22 at 06:10
4

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.

KeithS
  • 70,210
  • 21
  • 112
  • 164
  • Actually, there's a very useful pattern for bridging the lands of static and dynamic invocation: a static generic caching class [e.g. `EqualityComparer.Default`]. For any given type `T`, one will only have to use Reflection once to build an object whose instance type will be statically known to qualify for any required constraints, and store a reference to it in a field that does not impose any constraints that a caller might not be able to supply. – supercat Apr 30 '13 at 16:12
3

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))
Aaron D
  • 5,817
  • 1
  • 36
  • 51
3

If anyone is interested in an "official" version, the following was found via .NET Reflector:

from: System.Activities.Presentation.TypeUtilities
in 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.

You can also expand the GetConstructor call out as follows, if you feel like micro-optimizing away one stack frame:

…t.GetConstructor(BindingFlags.Public|BindingFlags.Instance, null, Type.EmptyTypes, null)…
Glenn Slayden
  • 17,543
  • 3
  • 114
  • 108
1

Yes, you have to use reflection.

object myObject = new MyType();
Type type = myObject.GetType();
ConstructorInfo conInfo = type.GetConstructor(new Type[0]);
Mel Harbour
  • 371
  • 1
  • 9
0

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();
jrivam
  • 1,081
  • 7
  • 12