有没有办法通过反射检测notnull约束?

问题描述 投票:0回答:1

我试图通过反射将约束应用于(类型或方法的)类型参数。对于大多数约束,我都成功做到了(为了简单起见,我在此处使用类型,但如果您有相应的

MethodInfo
,下面的表达式对于方法是相同的):

  • typeof(Constrained<>).GetGenericArguments()[0].GenericParameterAttributes
    检测类或 new() 等约束(分别使用
    ReferenceTypeConstraint
    DefaultConstructorConstraint
  • typeof(Constrained<>).GetGenericArguments()[0].GetGenericParameterConstraints()
    检测基本类型约束(返回包含约束的 Type[])
  • 有时它是两者的混合,例如结构体是
    NotNullableValueTypeConstraint | DefaultConstructorConstraint
    和基本类型
    System.ValueType

现在说到 notnull,我最终得到

None
和一个空的 Type[] (无基本类型)。

我尝试找出生成的 IL 中的差异,并且(根据我的理解)只有一个

NullableAttribute
(来自
System.Runtime.ComplierServices
)应用于泛型方法、其声明类型或具有 notnull 约束的类型参数,具体取决于类型或方法的定义。

由于属性的位置并不总是相同,并且我很确定它可以通过其他方式出现,因此我认为寻找此属性不是一个可靠的解决方案。

给出 Foo 的这两个定义(为了简单起见,再次使用类型):

  • class Foo<T> where T : notnull { }
  • class Foo<T> { }

如何通过反射来区分它们?

c# generics reflection generic-constraints
1个回答
-1
投票

如何区分

public void GenericMethod<T>()
public void GenericMethod<T>() where T : notnull
(原文如此)

最后是一段代码。

快速浏览一下,确实会在这种情况下显示泛型类型的

Nullable
属性,但您必须记住,泛型约束是编译时功能,它们仅生成附带的 IL 代码。如果你愿意的话,就可以使用它,你已经到达那里了。

不过,我要重申的是,您正在寻找的是编译时数据,并且您已经为此奠定了坚实的基础:源生成器。您可以轻松编写一个源生成器,通过解析语法树并找到您的

notnull
约束,来查看您的类型并构建您想要的任何元数据的公共静态数组。

© www.soinside.com 2019 - 2024. All rights reserved.