Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 如何将属性的PropertyInfo作为属性中的参数传递?_.net_Reflection_Lambda - Fatal编程技术网

.net 如何将属性的PropertyInfo作为属性中的参数传递?

.net 如何将属性的PropertyInfo作为属性中的参数传递?,.net,reflection,lambda,.net,Reflection,Lambda,假设我有两门课: class A { [SortOrder(3)] public string Name { get; set; } } class B : A { [SortBefore(*****)] public string Age { get; set; } } 请注意第二个类中property属性中的星号。在SortBefore属性中指定一个.Name(我想使用表达式)是否可能?请注意,我不是在A的实例中查找Name的值,而是在A中查找属性名称的Prope

假设我有两门课:

class A
{
   [SortOrder(3)]
   public string Name { get; set; }
}

class B : A
{
   [SortBefore(*****)]
   public string Age { get; set; }
}
请注意第二个类中property属性中的星号。在SortBefore属性中指定一个.Name(我想使用表达式)是否可能?请注意,我不是在A的实例中查找Name的值,而是在A中查找属性名称的PropertyInfo,以便在B中使用Age的PropertyInfo时,可以从其超类中检索SortOrder值。

恐怕您不能。这可能在IL中实现——我不确定——但在C#中实现不了

最接近你的可能是:

[排序在(A),“名称”之前]

并获取属性以在执行时查找属性。是的,这是非常脆弱的-如果你这样做,我会添加一个单元测试,它会找到程序集中的所有属性并检查它们是否都有效。

恐怕你不能。这可能在IL中实现——我不确定——但在C#中实现不了

最接近你的可能是:

[排序在(A),“名称”之前]

并获取属性以在执行时查找属性。是的,这是非常脆弱的-如果你这样做,我会添加一个单元测试,它会找到程序集中的所有属性并检查它们是否都有效。

甚至C#
typeof
操作符也由编译器作为
ldtoken
实现,然后调用
Type.GetTypeFromHandle()
PropertyInfo
是一个特别有趣的例子,因为
ldtoken
IL指令不能将属性元数据标记作为参数,并且没有RuntimePropertyHandle类型。但是,可以在IL via中获得getter和/或setter方法(这不是有效的IL,但显示了说明)。不幸的是,在C#中没有直接的方法来生成具有
typeof()
操作符提供的类型安全级别的代码

ldtoken <method>
call MethodBase.GetMethodFromHandle
ldtoken
调用MethodBase.GetMethodFromHandle
的答案显示了如何从MethodInfo获取PropertyInfo

Jon关于您可能必须使用的解决方案的回答是正确的。

即使是C#
typeof
操作符也由编译器实现为
ldtoken
,然后调用
Type.GetTypeFromHandle()
PropertyInfo
是一个特别有趣的例子,因为
ldtoken
IL指令不能将属性元数据标记作为参数,并且没有RuntimePropertyHandle类型。但是,可以在IL via中获得getter和/或setter方法(这不是有效的IL,但显示了说明)。不幸的是,在C#中没有直接的方法来生成具有
typeof()
操作符提供的类型安全级别的代码

ldtoken <method>
call MethodBase.GetMethodFromHandle
ldtoken
调用MethodBase.GetMethodFromHandle
的答案显示了如何从MethodInfo获取PropertyInfo


Jon的答案对于您可能必须使用的解决方案来说是正确的。

只需添加Jon Skeet所说的内容:即使在IL中也不可能。比方说,对于kicks,您可以通过编写自己的编译器,并将属性的元数据标记注入属性,来获取属性的MetadataToken。在运行时,您将无法要求属性来自的模块解析元数据令牌;您将收到以下消息:

此API不支持PropertyInfo令牌

测试这一点的一种方法是获取任何属性的
PropertyInfo
,并向定义包含属性的类型的模块询问
resolvember
,该模块接受元数据标记的
int
值,并向其提供
PropertyInfo.MetadataToken

Console.WriteLine(propInfo.DeclaringType.Module.ResolveMember(propInfo.MetadataToken));
API并不是为这个目的而设计的,属性本身只是元数据,它随程序一起运行,帮助将方法关联到公共上下文,以便与编译器和IDE一起使用。一旦编译器接受了您的代码并发挥了它的魔力,该属性就不会在IL中出现一次

如果可以将属性的
MetadataToken
推送到属性中,那么最好的办法是也将类型的
MetadataToken
推送到属性中,并让它通过迭代类型的属性来检索
PropertyInfo
对象,而具有匹配的
MetadataToken
的将是您的目标

重要的是要理解,
MetadataToken
s仅在其所在模块的范围内是唯一的。我会说组装,但多个模块组装扼杀了这个想法


我只从编写ECMA-335元数据解析器中了解到这一点。

只是为了添加Jon Skeet所说的上下文:即使在IL中也不可能。比方说,对于kicks,您可以通过编写自己的编译器,并将属性的元数据标记注入属性,来获取属性的MetadataToken。在运行时,您将无法要求属性来自的模块解析元数据令牌;您将收到以下消息:

此API不支持PropertyInfo令牌

测试这一点的一种方法是获取任何属性的
PropertyInfo
,并向定义包含属性的类型的模块询问
resolvember
,该模块接受元数据标记的
int
值,并向其提供
PropertyInfo.MetadataToken

Console.WriteLine(propInfo.DeclaringType.Module.ResolveMember(propInfo.MetadataToken));
API并不是为这个目的而设计的,属性本身只是元数据,它随程序一起运行,帮助将方法关联到公共上下文,以便与编译器和IDE一起使用。一旦编译器接受了您的代码并发挥了它的魔力,该属性就不会在IL中出现一次

如果可以将属性的
MetadataToken
推送到属性中,那么最好的办法是也将类型的
MetadataToken
推送到属性中,让它检索
PropertyInfo
ob