如何检查类型是否提供无参数构造函数?

时间:2011-01-13 14:19:01

标签: c# .net reflection constructor types

我想检查运行时已知的类型是否提供无参数构造函数。 Type类没有产生任何有希望的东西,所以我假设我必须使用反射?

9 个答案:

答案 0 :(得分:152)

Type反射。你可以这样做:

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

如果无参数构造函数不存在,它将返回null。


如果您还想查找私有构造函数,请使用稍长的:

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

价值类型有一个警告,aren't allowed to have a default constructor。您可以使用Type.IsValueType属性检查是否有值类型,并使用Activator.CreateInstance(Type)创建实例;

答案 1 :(得分:12)

是的,你必须使用Reflection。但是,当您使用GetType()

时,您已经这样做了

类似的东西:

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

答案 2 :(得分:12)

type.GetConstructor(Type.EmptyTypes) != null

会因struct而失败。最好扩展它:

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

成功,因为即使enum都有默认的无参数构造函数。由于未进行反射调用,因此值类型也略微加快。

答案 3 :(得分:8)

这应该有效:

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

答案 4 :(得分:4)

根据您的具体情况,您还可以使用通用类型限制:

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

上述方法声明会将参数类型限制为可以使用无参数构造函数实例化的任何Object。这里的优点是编译器将捕获任何尝试将该方法与没有无参数构造函数的类一起使用,因此只要该类型在编译时已知为SOMEWHERE,这将起作用并将提醒您问题早了。

当然,如果只在运行时知道类型(即你使用Activator.CreateInstance()来基于字符串或构造的类型实例化对象),那么这对你没有帮助。我通常使用反射作为绝对的最后选择,因为一旦你去了动态的土地,你几乎必须留在充满活力的土地上;动态实例化某些内容然后开始静态处理它通常很困难甚至更加混乱。

答案 5 :(得分:1)

是的,你必须使用反射。

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

答案 6 :(得分:1)

我需要使用 only 可选参数计算构造函数,与真正的无参数构造函数相同。要做到这一点:

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

答案 7 :(得分:0)

如果有人对“官方”版本感兴趣,可以通过.NET Reflector找到以下内容:

来自: System.Activities.Presentation.TypeUtilities
System.Activities.Presentation.dll,版本为4.0.0.0

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

请注意t.IsAbstract的支票,此页其他地方未提及。

如果您想对一个堆栈帧进行微优化,则还可以按如下所示扩展GetConstructor调用:

…t.GetConstructor(BindingFlags.Public|BindingFlags.Instance, null, Type.EmptyTypes, null)…

答案 8 :(得分:0)

要获取具有更多可选参数或完全没有构造函数的参数,请使用:

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