jeudi 15 juin 2023

Getting generic attribute from a property using reflection without knowing the generic type

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?





Aucun commentaire:

Enregistrer un commentaire