【问题标题】:How to test if a type is instantiable?如何测试类型是否可实例化?
【发布时间】:2018-11-02 04:17:15
【问题描述】:

我输入了T,我想检查它是否可以安全地传递给Activator.CreateInstance(T)。

我想到的是这样做:

if(!T.IsInterface && !T.IsAbstract)
{
    instance = (T)Activator.CreateInstance(T);
}

但是:

  • 这就够了吗?我没有错过必要的测试吗?一个类型是否有可能不是接口,也不是抽象类,但仍然无法实例化?鉴于我对 C# 的了解还很初级,我认为我很可能错过了一两个极端案例。
  • 我必须手动编写测试吗?有没有类似T.IsInstantiable 或语言中包含的内容?

编辑:不,T 不是来自通用约束。这是T 的代码来自:

var instances = System.Reflection.Assembly.GetExecutingAssembly().GetTypes()
    .Where(
        // some other constraints
    ).Where(
        // can be instantiated, I'm trying to figure this part in my question
    ).Select(
        T => Activator.CreateInstance(T)
    );

【问题讨论】:

  • @RyanWilson 是的,我告诉过你我一定错过了什么:)
  • 另外,需要一个不带任何参数的构造函数。
  • 私有构造函数呢?你不能在它们自己的方法之外实例化这些类。
  • if(T.GetConstructor(Type.EmptyTypes) != null && !T.IsAbstract) 应该这样做。这将检查以确保类不是抽象的,并将检查以确保有一个空的构造函数。
  • @gaazkam 我对静态的看法是错误的,静态类作为抽象和密封返回,但这里还有其他优点,比如关于私有构造函数。这篇 SO 帖子看起来会为您提供所需的一切 (stackoverflow.com/questions/1175888/…)

标签: c# .net .net-core instantiation


【解决方案1】:

如果T 是一个通用参数,只需对其使用new() 约束即可。这样 compiler 将强制执行此操作,而不是 runtime

【讨论】:

  • 不是。 T来自System.Reflection.Assembly.GetExecutingAssembly().GetTypes().Where(/*otherconstraints*/).Where(/*canBeInstantiated*/).Select(T => Activator.CreateInstance(T)
  • @gaazkam k。这很公平,但你将无法施放它。
猜你喜欢
  • 1970-01-01
  • 2022-08-10
  • 2011-07-31
  • 1970-01-01
  • 2011-08-09
  • 2014-03-31
  • 2017-11-09
  • 2018-08-19
  • 1970-01-01
相关资源
最近更新 更多