英文:
Getting generic attribute from a property using reflection without knowing the generic type
问题
C# 11引入了通用属性。是否可以使用GetCustomAttribute
方法(或类似方法)获取附加到PropertyInfo
的属性,而不知道其通用类型,特别是当属性继承自其他属性时?
以下是您的代码:
public class MyTypedAttribute<TValue> : Attribute
{
public virtual TValue ProcessValue(object value) { }
}
public class MyNumberAttribute : MyTypedAttribute<int>
{
public override int ProcessValue(object value) { }
}
public class MyStringAttribute : MyTypedAttribute<string>
{
public override string ProcessValue(object value) { }
}
我的类具有多个具有这些属性的属性,并且我想使用反射获取它们。通常我会使用通用的 PropertyInfo.GetCustomAttribute<>
函数,但是当属性本身也期望有通用参数时(除非通用类型在编译时已知,否则似乎无法工作,在我的情况下不知道通用类型是什么)
PropertyInfo myProp = ...;
var attr = myProp.GetCustomAttribute<MyTypedAttribute<>>();
编译错误:意外使用未绑定的通用名称
似乎我可以使用非通用的等效函数,但是返回的属性类型是Attribute?
,并且似乎我无法在不知道通用类型的情况下进行转换。我们无法在转换时指定空尖括号,因此必须指定类型,但我不知道类型是什么。我唯一想到的是使用object
作为通用类型,但这在运行时失败:
var attr = (MyTypedAttribute<object>?)myProp.GetCustomAttribute(typeof(MyTypedAttribute<>))
运行时错误:无法将类型为 'MyNumberAttribute' 的对象强制转换为类型为 'MyTypedAttribute`1[System.Object]' 的对象。
基本上,我试图获取属性并调用ProcessValue
方法,捕获返回的值。有没有办法做到这一点?
英文:
C# 11 has introduced generic attributes. Is it possible to get the attributes that are attached to a PropertyInfo
using the GetCustomAttribute
method (or similar) without knowing it's generic type, particularly where the attribute inherits from another?
Here's what I have:
public class MyTypedAttribute<TValue> : Attribute
{
public virtual TValue ProcessValue(object value) { }
}
public class MyNumberAttribute : MyTypedAttribute<int>
{
public override int ProcessValue(object value) { }
}
public class MyStringAttribute : MyTypedAttribute<string>
{
public override string ProcessValue(object value) { }
}
My class has properties with a range of these attributes on them, and I want to get them using reflection. I would normally use the generic PropertyInfo.GetCustomAttribute<>
function, but this doesnt seem to work when the attributes themselves also expect a generic parameter (unless the generic type is known at compile time, which in my case they it's not)
PropertyInfo myProp = ...;
var attr = myProp.GetCustomAttribute<MyTypedAttribute<>>();
>Compile error: Unexpected use of an unbound generic name
It seems I can use the non-generic equivalent function, but the returned attribute is of type Attribute?
, and it seems I cannot cast this without knowing the generic type. We cannot specify empty angle brackets when casting, so a type must be specified, but I dont know what the type is. The only thing I can think of doing is using object
as the generic type, but this fails at run time:
var attr = (MyTypedAttribute<object>?)myProp.GetCustomAttribute(typeof(MyTypedAttribute<>))
>Runtime error: Unable to cast object of type 'MyNumberAttribute' to type 'MyTypedAttribute`1[System.Object]'.'
Essentially what I'm trying to do is get the attributes and call the ProcessValue
method, capturing the returned value. Is there any way to do this?
答案1
得分: 1
以下是翻译好的部分:
你可以创建一个非泛型的基类
public class MyTypedAttribute<TValue> : MyUntypedAttribute
{
public virtual TValue ProcessValue(object value)
{
// 不管什么操作
}
public override object ProcessValueObject(object value) =>
ProcessValue(value);
}
public class MyUntypedAttribute : Attribute
{
public abstract object ProcessValueObject(object value);
}
然后你可以这样做
var attr = myProp.GetCustomAttribute<MyUntypedAttribute>();
英文:
You can make a non-generic base class
public class MyTypedAttribute<TValue> : MyUntypedAttribute
{
public virtual TValue ProcessValue(object value)
{
// whatever
}
public override object ProcessValueObject(object value) =>
ProcessValue(value);
}
public class MyUntypedAttribute : Attribute
{
public abstract object ProcessValueObject(object value);
}
Then you can do
var attr = myProp.GetCustomAttribute<MyUntypedAttribute>();
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论