views:

62

answers:

2

Is there a way to enforce a compile requirement for certain attributes on a class or interface implementation?

For example, let's say my application uses a series of static classes that contain const int resource values. I'd like to decorate the class in a Description attribute to describe its contents. In concept, I'd like to apply this attribute requirement to an interface, then each static class would implement it with its required Description. I could write a run-time check or a unit test to check compliance. But really a compile-time check would be best.

Is there such a thing?

+5  A: 

No, there's nothing like this. Unit tests are the best you can do, as far as I'm aware.

If you can identify the classes automatically (by name, or some other attribute that the class is decorated with) then you can easily write a unit test for all the classes in an assembly.

Jon Skeet
+1 I second unit-tests for that, easy to write and though it won't make the compiler complain, it will alert you early to missing information.
Lasse V. Karlsen
+1  A: 

It is possible in runtime, via Reflection.

Here is a unit test method for you:

...
using System.Reflection;
using System.Diagnostics;
using System.Linq;
...

[TestMethod]
public void CheckAttributes()
{
    var notAttributed = Assembly.GetAssembly(typeof(SomeClass))
        .GetTypes()
        .Where(t => t.GetCustomAttributes(typeof(MyAttribute), true).Count() == 0);

    Assert.AreEqual<int>(0, notAttributed.Count());
}

Where MyAttribute is the type of your attribute, and SomeClass is a class in the assembly you want to check.
You may also want to filter the types you want to check this way. (Only if you don't require every class in an assembly to use that attribute, of course.)


If you want to do it in production code, place a Conditional("DEBUG") attribute on it to make sure that it is only executed in DEBUG mode.
(Because Reflection is not fast, and it really doesn't make sense to run this in production mode, does it?)

Venemo
It makes sense to run it in your *unit tests* against production code. Why would you make it conditional and put the test itself in your production code?
Jon Skeet
@Jon - I edited it, now it is a unit test. Does it make sense now? :P
Venemo
@Venemo: All except you're testing the executing assembly, which is a unit test assembly and thus unlikely to be your production code :) (I'd use `typeof(SomeWellKnownType).Assembly`.)
Jon Skeet
@Jon - Thanks for reviewing, all fixed now. :)
Venemo