I’m coding custom attributes instead marker interfaces
public class FooAssignableAttribute : Attribute
{
...
}
[FooAssignable]
public class Foo
{
...
}
Can’t I code a dictionary like this?
Dictionary<string, FooAssignable> dictionary;
Avoiding marker interfaces, I’m trying to use custom attrutes. Why can’t I write the above code?
No, this doesn’t work. The parametric types of a generic collection (or other generic) in C# must be declarable types, and attributes exist only as metadata.
You cannot have an object of type FooAssignable. You can have an object that has the attribute FooAssignable, but this isn’t the same as having it as a supertype. FooAssignable is not a class or interface, and isn’t a valid type specifier. FooAssignableAttribute is, but that is the type that refers to the attribute itself, not items tagged with that attribute.
Consider that in a Dictionary, the out type for the indexer is the out type you’ve provided. But you can’t have a variable of type FooAssignable- you can have a variable of a type that has been tagged with FooAssignable, but there is no single base class that all those types fit. Since that type declaration is illegal, this Dictionary would have an illegal, nonexistent type as the return type for the getter from its indexer, among many other places. A C# type check cannot be spontaneously replaced via generic mechanisms with an attribute presence check.
Anything you want the type system to check for you has to be part of the type system. Attribute evaluation does not define types, so the type system can’t do this for you; meanwhile, generics are the part of the language that most directly interacts with the type system. You’ll have to actually go through the type system to perform a check like this, and that does mean promoting FooAssignableAttribute to an interface (IFooAssignable?) instead.