I have a class, which uses an empty interface as a "marker interface", like this:
namespace MyNameSpace
{
public interface IMessage
{
//nothing in common here...
}
public class MyMessage : IMessage
{
public void SendMyMessage()
{
//Do something here
}
}
}
I read in some other posts, but also on MSDN (http://msdn.microsoft.com/en-us/library/ms182128.aspx) that this should be avoided, and you should use custom attributes instead of this empty interface. So, I could refactor my code like this:
namespace MyNameSpace
{
public class MessageAttribute : Attribute
{
//nothing in common here...
}
[MessageAttribute]
public class MyMessage
{
public void SendMyMessage()
{
//Do something here
}
}
}
Everything works fine, but the main question is:
When I have a generic method elsewhere in my program, for instance:
public IEnumerable<T> GetAll<T>() where T : IMessage
{
//Return all IMessage things here
}
In the above function, I do need to add some generic type constraints on T
, so only IMessages
are allowed.
How could I accomplish this when using a custom attribute instead of an empty interface?
And does this justify the use of an empty interface? Or should I use an empty abstract class Message
(instead of interface IMessage
, since MyMessage
is actually a Message
).
Very curious about what you think about this.
Interface Type Constraint You can constrain the generic type by interface, thereby allowing only classes that implement that interface or classes that inherit from classes that implement the interface as the type parameter.
Constraints can specify interfaces, base classes, or require a generic type to be a reference, value, or unmanaged type. They declare capabilities that the type argument must have, and must be placed after any declared base class or implemented interfaces.
(Every type implements at least zero methods.) Empty interfaces are used by code that handles values of unknown type. For example, fmt. Print takes any number of arguments of type interface{} .
How could i accomplish this when using a custom attribute instead of an empty interface??? And does this justify the use of an empty interface?
You can't - at least, not at compile-time. You could of course check for an attribute at run-time.
Or should i use an empty abstract class Message
Base-classes are more restrictive than interfaces; personally I would impose the least overhead necessary. But I wonder whether even the artificial interface (which gives you nothing) is itself just overhead, and another option would be simply: don't place any such demands. Making people add an interface just so a method compiles doesn't give you an awful lot more than just having a generic method without a constraint in the first place.
As C# currently does not offer any attribute-based generic constraint, you have little other choice than to go with the marker interface.
Interestingly, the documentation page on CA1040 states the following exception to the rule:
It is safe to suppress a warning from this rule when the interface is used to identify a set of types at compile time.
Identifying "a set of types at compile time" seems to be exactly what is needed when evaluating generic constraints, and I am wondering now whether the author of that doc page had exactly this in mind.
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