Alex Mueller on Software and Technology 
Wednesday, July 30, 2008

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?

Wednesday, July 30, 2008 1:01:11 PM (Mountain Standard Time, UTC-07:00) | Comments [0] | Design | Frameworks/Patterns#
MuellerDesigns.net
Search
On This Page
SketchPath XPath Editor
Software Testing - Revisited
Architecting Buildings and Software
NBCOlympics.com with Silverlight
Marker Interfaces and C# Attributes
The Phone Screen
Working with ASP.NET MVC and MvcContrib
Thanks to BDD
Twitter
The Opposite of a Singleton?
Removing Duplicate Code in Functions
Add Vista Themes to Longhorn
Changing File Ownership In Vista and Longhorn
ReSharper Type Completion
Caring for the Team
Most Popular
JavaScript ReplaceAll Functionality
What is polymorphism?
What is composition?
Sorting with IComparable and IComparer
Applying the Observer Pattern in ASP.NET
MVP in ASP.NET
What is abstraction?
What is encapsulation?
What is a class?
What is inheritance?
Authentication in ASP.NET
Calendar Controls
SQL Server 2005 Connection Issues
XPathNavigator.CheckValidity new for 2.0
Auto-attach to process '[####] aspnet_wp.exe' on m...
What is an object?
FreeTextBox
VMWare and VPC
An Example of Reflection using C#
A New NHibernate Blog
Archive
Links
Categories
My Local Blog Map
Blogroll
About
Powered by:

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2008
MuellerDesigns.net

Sign In

Help Those In Need
The Hunger Site
Ronald McDonald House Charities (RMHC) of Western Washington & Alaska