ConstructorInfo可以没有DeclaringType

时间:2016-08-31 04:00:51

标签: c# reflection constructor clr

我正在浏览GitHub上的System.Linq.Expressions源代码并找到following code

public static NewExpression New(ConstructorInfo constructor, IEnumerable<Expression> arguments)
{
    ContractUtils.RequiresNotNull(constructor, nameof(constructor));
    ContractUtils.RequiresNotNull(constructor.DeclaringType, nameof(constructor));

    // ...
}

我对第二次空检查感到困惑,所以去了MSDN。它有关于ConstructorInfo.DeclaringType:

的以下内容
  

DeclaringType属性检索对声明此成员的类型的Type对象的引用。类型的成员要么由类型声明,要么从基类型继承,因此DeclaringType属性返回的Type对象可能与用于获取当前MemberInfo对象的Type对象不同。

     

如果从中获取此MemberInfo对象的Type对象未声明此成员,则DeclaringType属性将表示其基本类型之一。

     

如果MemberInfo对象是全局成员(即,如果它是从Module.GetMethods方法获取的,它返回模块上的全局方法),则返回的DeclaringType将为null。

因此,对于MemberInfo(ConstructorInfo派生的类),DeclaringType似乎为null。但我不确定它是否可以为ConstructorInfo为null。

所以我的问题:

  1. ConstructorInfo.DeclaringType可以为null吗?为什么System.Linq.Expressions代码会检查它?

  2. 如果DeclaringType可以为null,您能提供一个示例吗?

  3. 如果DeclaringType可以为null,这是否意味着CLR支持全局构造函数? (我试过研究这个但找不到任何东西)

1 个答案:

答案 0 :(得分:1)

以下是ConstructorInfo.DeclaringType的源代码:

public override Type DeclaringType 
{ 
    get 
    { 
        return m_reflectedTypeCache.IsGlobal ? null : m_declaringType; 
    }
}

我没有这个场景的具体示例,但鉴于这是ConstructorInfo类本身,我似乎很清楚它是专门写的,可能是它的DeclaringType属性可以返回null

我怀疑你是否可能因C#代码而发生这种情况,但CLR支持多种语言。对于这种情况,C ++ / CLI似乎是我最可能的罪魁祸首,因为C ++ / CLI程序集随着一堆样板和全局成员而结束,但VB.NET也做了一些全局性的事情。据推测,人们可以直接生成IL,这也会造成这种情况。