I have a custom attribute which I would like to restrict to methods with return type void.
I know I can restrict to methods using [AttributeUsage(AttributeTargets.Method)]
but there doesn't seem to be a way to restrict the return type or any other aspect of the methods signature.
The [System.Diagnostics.Conditional]
attribute has exactly the kind of limitation I want. Adding it to a non-void method results in the compiler error:
The Conditional attribute is not valid on '(SomeMethod)' because its return type is not void
and IntelliSense says:
Attribute 'System.Diagnostics.ConditionalAttribute' is only valid on attribute classes or methods with 'void' return type.
If I F12 to the ConditionalAttribute
I see that it is decorated with the following attributes:
[Serializable]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
[ComVisible(true)]
None of which says anything about the return type.
How is it done for the Conditional
attribute and can I do the same for my custom attribute?
Turns out in my particular case there was a solution since I was using PostSharp.
My custom attribute inherits from PostSharp.Aspects.MethodInterceptionAspect
(which inherits from Attribute
) which has an overridable CompileTimeValidate(MethodBase method)
method.
This allows to emit compiler errors during build time:
public override bool CompileTimeValidate(MethodBase method)
{
Debug.Assert(method is MethodInfo);
var methodInfo = (MethodInfo)method;
if (methodInfo.ReturnType != typeof(void))
{
Message.Write(
method, SeverityType.Error, "CX0001",
"The Foo attribute is not valid on '{0}' because its return type is not void",
method.Name);
return false;
}
return true;
}
Most attributes are simply metadata that gets attached to classes and that can be examined at runtime. However, some attributes are used by the compiler. System.ObsoleteAttribute
for example can be used to have the compiler emit errors or warnings if the method, class etc is used. System.Diagnostics.ConditionalAttribute
is another example of an attribute used by the compiler. As such, the compiler itself is free to impose rules on its use that cannot be applied to other attributes (such as void methods only).
Unfortunately, at this time, it's not possible to affect the compiler though custom attributes. With Rosalyn being written in C#, the way is then opened up to have the compiler run code within the attribute as part of the compilation phase. Your example of restriction an attribute to void methods would be one such use of this feature, if it were implemented.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With