Is it possible to read custom attributes when set on an Action.
The below fails for example.
var simpleAction = new Action<string, string>((
[CustomAttr(DisplayName = "MyFirstArg")] a,
[CustomAttr(DisplayName = "MySecondArg")] b) => { });
var parameters = simpleAction.GetType().GetMethod("Invoke")!.GetParameters();
foreach(var parameter in parameters)
{
parameter.GetCustomAttribute<CustomAttr>()?.ShouldNotBeNull();
}
I understand that I could use a strict delegate
declaration and it works.
But my question is wether anyone has any reflection hacks to allow me to get these custom attributes.
The method can be accessed through the Delegate.Method
property.
var parameters = simpleAction.Method.GetParameters();
1
To elaborate on @shingo’s answer, the reason why this doesn’t work is because the attributes aren’t declared on the parameters of Action<string, string>
, they’re declared on the parameters of the function that’s being converted to an Action<string, string>
.
When you create a custom delegate, they will be declared on the delegate type itself e.g.
delegate void CustomAction(
[CustomAttr(DisplayName = "MyFirstArg")] string arg1,
[CustomAttr(DisplayName = "MySecondArg")] string arg2);
However, the same behaviour applies to the CustomAction
, in that the function being converted can have different attributes to the delegate type itself.
Example:
var customAction = new CustomAction((
[CustomAttr(DisplayName = "AnotherFirstArg")] a,
[CustomAttr(DisplayName = "AnotherSecondArg")] b) => { });
var typeParameters = customAction
.GetType().GetMethod(nameof(customAction.Invoke))!.GetParameters();
typeParameters[0].GetCustomAttribute<CustomAttr>()?.DisplayName; // MyFirstArg
typeParameters[1].GetCustomAttribute<CustomAttr>()?.DisplayName; // MySecondArg
var funcParameters = customAction.Method.GetParameters();
funcParameters[0].GetCustomAttribute<CustomAttr>()?.DisplayName; // AnotherFirstArg
funcParameters[1].GetCustomAttribute<CustomAttr>()?.DisplayName; // AnotherSecondArg