使用反射获取属性的通用属性,而不知道通用类型。

huangapple go评论74阅读模式
英文:

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&lt;TValue&gt; : Attribute
{ 
    public virtual TValue ProcessValue(object value) { }
}

public class MyNumberAttribute : MyTypedAttribute&lt;int&gt;
{ 
    public override int ProcessValue(object value) { }
}

public class MyStringAttribute : MyTypedAttribute&lt;string&gt;
{ 
    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&lt;&gt; 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&lt;MyTypedAttribute&lt;&gt;&gt;();

>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&lt;object&gt;?)myProp.GetCustomAttribute(typeof(MyTypedAttribute&lt;&gt;))

>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&lt;TValue&gt; : MyUntypedAttribute
{ 
    public virtual TValue ProcessValue(object value)
    {
        // 不管什么操作
    }

    public override object ProcessValueObject(object value) =&gt;
        ProcessValue(value);
}

public class MyUntypedAttribute : Attribute
{ 
    public abstract object ProcessValueObject(object value);
}

然后你可以这样做

var attr = myProp.GetCustomAttribute&lt;MyUntypedAttribute&gt;();
英文:

You can make a non-generic base class

public class MyTypedAttribute&lt;TValue&gt; : MyUntypedAttribute
{ 
    public virtual TValue ProcessValue(object value)
    {
        // whatever
    }

    public override object ProcessValueObject(object value) =&gt;
        ProcessValue(value);
}

public class MyUntypedAttribute : Attribute
{ 
    public abstract object ProcessValueObject(object value);
}

Then you can do

var attr = myProp.GetCustomAttribute&lt;MyUntypedAttribute&gt;();

huangapple
  • 本文由 发表于 2023年6月16日 04:23:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/76485275.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定