Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Interfaces or Attributes for Tagging Classes?

I have a couple of classes that I wish to tag with a particular attribute. I have two approaches in mind. One involves using an Attribute-extending class. The other uses an empty interface:

Attributes

public class FoodAttribute : Attribute { }

[Food]
public class Pizza { /* ... */ }

[Food]
public class Pancake { /* ... */ }

if (obj.IsDefined(typeof(FoodAttribute), false)) { /* ... */ }

Interface

public interface IFoodTag { }

public class Pizza : IFoodTag { /* ... */ }
public class Pancake : IFoodTag { /* ... */ }

if (obj is IFoodTag) { /* ... */ }

I'm hesitant to use the attributes due to its usage of Reflection. At the same time, however, I'm hesitant on creating an empty interface that is only really serving as a tag. I've stress-tested both and the time difference between the two is only about three milliseconds, so performance is not at stake here.

like image 829
Doctor Blue Avatar asked Jan 14 '10 11:01

Doctor Blue


People also ask

What are tagged interfaces?

A Tag Interface is a Java term. It is an empty interface which a class implements to claim membership in a set. For example, if a class implements the Serializable interface, it is claiming to be serializable -- to be a member of the set of serializable classes.

CAN interfaces have attributes C#?

C# Language Attributes Reading an attribute from interface There is no simple way to obtain attributes from an interface, since classes does not inherit attributes from an interface. Whenever implementing an interface or overriding members in a derived class, you need to re-declare the attributes.

What is an attribute C#?

In C#, attributes are classes that inherit from the Attribute base class. Any class that inherits from Attribute can be used as a sort of "tag" on other pieces of code. For instance, there is an attribute called ObsoleteAttribute . This is used to signal that code is obsolete and shouldn't be used anymore.


3 Answers

Well, with attributes, you can always create the attribute in such a way that its function doesn't propagate to descendant types automatically.

With interfaces, that's not possible.

I would go with attributes.

like image 196
Lasse V. Karlsen Avatar answered Oct 28 '22 14:10

Lasse V. Karlsen


I'll have to say otherwise. I think that, for your example, a marker interface makes more sense.

That's because it seems very likely that you might one day add some members to IFood.

Your design starts like this:

interface IFood {}

But then you decide to add something there:

interface IFood {
  int Calories { get; }
}

There are also other ways to extend interfaces:

static class FoodExtensions {
  public static void Lighten(this IFood self) { 
    self.Calories /= 2;
  } 
}
like image 27
Jordão Avatar answered Oct 28 '22 12:10

Jordão


You probably have answered on you question by your own. Attributes is more logical here, reflection is not a BIG MONSTER WITH RED EYES =)

btw, can you show calling code, where you determine marked with interface types? Aren't you using reflection there?

like image 23
Restuta Avatar answered Oct 28 '22 14:10

Restuta