Marker Interfaces and C# Attributes
The marker interface is an interface that is empty. It does not implement any properties nor methods. It is used to mark the capability of a class as implementing a specific interface at run-time. In languages that do not provide support for associating metadata to a class, this approach can be useful. In C#, metadata attributes are available to apply to a class, and according to the .NET Framework 3.5 Design Guidelines for Developing Class Libraries, marker interfaces should be avoided.
When I first noticed these marker interfaces in project I immediately thought it was a code smell. It just did not seem “right.” Why provide an interface that defines nothing? Why provide a marker interface that implements a non-marker interface? Obviously there must be a reason for this?
Two sources encourage me to avoid using marker interfaces and to use attributes in C#. Interface Design and .NET Type Design Guidelines – Interface Design.
There advice is to avoid this…
public interface IFooAssignable {}
public class FooAssignableAttribute : IFooAssignable
{
// ...
}
And to embrace this approach…
[FooAssignable]
public class Foo
{
// ...
}
public class FooAssignableAttribute : Attribute
{
// ...
}
There appears to be more work involved in writing “good” code.
If I am using “marker” interfaces, I can do this…
if(foo is IFooAssignable)
{
// ...
}
If I am using attributes, I can do something like this…
object[] attributes = foo.GetType().GetCustomAttributes(false);
foreach (string attribute in attributes)
{
if(attribute == "FooAssignable")
{
// ...
}
}
Or, thanks to Jarod Ferguson’s suggestions on using extension methods and LINQ, I could have this…
public static class AttributeExtensions
{
public static bool IsAttributedAs<T>(this object obj)
{
if(obj.GetType().GetCustomAttributes(false).Where(x => x is T).ToList().Count == 1)
return true;
return false;
}
}
// Then wherever I want to check for the attribute marker...
if (foo.IsAttributedAs<FooAssignableAttribute>())
{
// ...
}
At this point, while “marker” interfaces are a code smell to me, I am still on the fence when it comes to using them versus custom attributes. I will more than likely tend to favor the attribute approach, unless I can prove that the cost of reflection is too expensive for my situation. I admit, I will do what I can to omit marker interfaces, perhaps by using some other interface where possible.
What are you doing in situations like this? Can you offer me a more elegant solution?


