我正在浏览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。
所以我的问题:
ConstructorInfo.DeclaringType可以为null吗?为什么System.Linq.Expressions代码会检查它?
如果DeclaringType可以为null,您能提供一个示例吗?
如果DeclaringType可以为null,这是否意味着CLR支持全局构造函数? (我试过研究这个但找不到任何东西)
答案 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,这也会造成这种情况。