Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Empty Interface vs Attribute, what about generic constraints?

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.

like image 677
Jeroen1984 Avatar asked Nov 25 '13 09:11

Jeroen1984


People also ask

What does the generic constraint of type interface do?

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.

What does the generic constraint of type interface do in C#?

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.

What is the point of an empty interface?

(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{} .


2 Answers

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.

like image 179
Marc Gravell Avatar answered Sep 28 '22 13:09

Marc Gravell


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.

like image 27
O. R. Mapper Avatar answered Sep 28 '22 14:09

O. R. Mapper