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?






Instead of
.Where(x => x is T)
you can also type
.OfType()
That should be a generic call to OfType with T.
One advantage of marker interfaces is that it allows some scenarios with regards to generics. For example:
public class Repository where T : IAggregateRoot
This gives you compile-time protection for certain scenarios, while attributes are only run-time.
If I am doing a marker interface for just type checking, then o me that is a code smell, maybe a violation of LSP if I am so concerned about the concrete type. But in the upper mapper layers I come across this so I might violate this.
If I understand correctly you are not in favour of using marker interfaces and recommend attributes should rather be used.
Thus in order to find out whether an object is FooAssignable I need to write a helper method (very sexy piece of code I must add!!), which internally uses Reflection and is an extra piece code to be maintained and tested.
I am not against Reflection, I just think it should be used in the appropriate places, and not to replace existing functionality in the framework.
To make a long story short, why write your own code to replace something that can already be achieved through the framework?
This topic is discussed in http://www.amazon.com/Framework-Design-Guidelines-Conventions-Development/dp/0321246756 ..
As already mentionned, if i need compile-time certainty, the marker interface is the only one that can help me… (Otherwise, an attribute is probably a better ‘marker’…)
You could use the Attribute.IsDefined method ?
And even make a little generic helper to make it simple and cool !
Interestingly enough, the MS guideline states:
“Custom attributes are preferred when you can defer checking for the attribute until the code is executing. If your scenario requires compile-time checking, you cannot comply with this guideline.”
However, it doesn’t state why marker interfaces should be avoided. Certainly, there is a convenience to using interfaces. However, the extension method approach for attributes is minimal. Still, as Pieter says, this is code to be maintained and tested.
Unless there is a significant performance concern using marker interfaces (which seems unlikely to be slower than reflection), then I probably would lean toward interfaces over attributes.
Are there other advantages that attributes provide? I suppose, you can include parameters on your attributes to drive behavior.
Hi guys just saw this post now and thought I wanted to give my 2c.
Will – The most significant disadvantage of using interfaces is the inability to control the marker when you start inheriting from the marked class. Attributes lets you specify if the marker should be inherited by derived classes while interfaces doesn’t allow you to have that control.
Also, attributes have the advantage that you can mark other things than classes, such as methods, parameters, constructors, fields, properties etc.
And as Skup points out the correct way to check for marker attributes is to use Attribute.Isdefined() or classInstance.GetType().IsDefined() and as he said you might even make it easier by adding some sort of generic methods or something… So I did.
You can see the result on my blog (http://blog.johannesh.dk).
Marker interfaces can be used to express domain artifacts within the confines of a single object model. Whether this is a good solution or not will, of course, depend on the domain in question. Attributes, on the other hand, are not suitable for such a purpose at all since metadata rests in a dimension outside the object model altogether. The immediate implication here is that with attributes, you don’t get compile-time resolution for all artifacts in a domain model (not to mention the associated loss of in-IDE code hinting).