Is it possible in C# to write MSIL code that will add a preprocessor directive to the code, e.g., #warning
, if a certain condition is met? Or maybe this can be done with reflection, I don't know.
I'm trying to write a custom attribute that, if applied incorrectly to a class's method or property, will generate a compiler warning. Using the existing Obsolete
attribute won't work because then just using my custom attribute causes the warning, and I don't want that. I want the custom attribute constructor to check for a condition, and if that condition is true then cause a compilation warning.
Update: after reading back over my question, I think what I'm asking for is impossible just because I'm mixing compile-time and runtime constraints. I think I'll end up going with a post-build task to check the just-built DLL and have it spit out error messages if the condition is true.
I saw this question coming from your previous thread. To mis-quote the great Jamie Zawinski: "Some people, when confronted with a problem, think "I know, I'll use an attribute." Now they have two problems".
An attribute is merely out-of-band data, compiled into an assembly's metadata. It cannot affect program execution or tool behavior, unless the program or the tool is explicitly programmed to recognize the specific attribute. It needs to do so using Reflection.
What you need to do is write your own tool. It should execute after an assembly is built, using the Post-Build step for a project. It needs to load the assembly and use Reflection to iterate the types in the assembly. For each type, iterate the methods with Type.GetMethods() and use MethodInfo.GetCustomAttributes() to discover and construct an attribute that might have been programmed.
You can use Type.GetInterfaces() to discover which interfaces are implemented by the type. You can now complain when you see that a method is present that implements an interface method but is missing an attribute that says so. And your ultimate goal: you can complain when you see a method with an attribute that says it implements an interface method but the type no longer inherits it.
Use Environment.ExitCode to make the tool fail the build if you see anything objectionable. This takes care of enforcement. Btw: programmers really hate to break the build. That might well encourage them to use the attribute religiously. Or it might encourage them to edit the post build step.
The compiler stores two things for custom attributes:
The constructor is only called when the application is running and someone calls GetCustomAttributes for your Assembyl, Type, MethodInfo, ParameterInfo, etc.
You have some other options to consider:
AttributeUsage
attribute to specify the code items to which the attribute can be applied.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