2010-01-14 10 views
16

Tengo un par de clases que deseo etiquetar con un atributo en particular. Tengo dos enfoques en mente. Una implica el uso de una clase que extiende el atributo. El otro utiliza una interfaz vacío:Interfaces o atributos para etiquetar clases?

Atributos

public class FoodAttribute : Attribute { } 

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

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

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

interfaz

public interface IFoodTag { } 

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

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

estoy reticentes a utilizar los atributos debido a su uso de Reflexión. Al mismo tiempo, sin embargo, dudo en crear una interfaz vacía que realmente solo sirva como etiqueta. He sometido a pruebas de esfuerzo ambos y la diferencia de tiempo entre los dos es solo de unos tres milisegundos, por lo que el rendimiento no está en juego aquí.

+0

preguntaba, ¿Qué haces si un objeto es un alimento? si la interfaz IFood está vacía, ¿para qué los distingues? ... – serhio

+0

Si el objeto es Comida, devolvería FoodEventArguments. Si el objeto fuera, por ejemplo, Bebida, devolvería DrinkEventArguments. Básicamente, hay una clase base común (digamos ConcessionStandItem) que pasa a la función. – Scott

+0

Vea también: http://blogs.msdn.com/ericlippert/archive/2009/02/02/properties-vs-attributes.aspx –

Respuesta

14

Bueno, con los atributos, siempre puedes crear el atributo de tal manera que su función no se propague automáticamente a los tipos descendientes.

Con interfaces, eso no es posible.

Me gustaría ir con atributos.

+0

+1, este es también el punto que perdí en mi respuesta. – Restuta

+1

Microsoft también lo recomienda pero han divergido de sus propias recomendaciones en varios lugares. (por ejemplo, 'IRequiresSessionState' y' IReadOnlySessionState' en ASP.NET). –

+1

ISerializable, lo sé. –

5

Probablemente usted haya respondido su pregunta por su cuenta. Atributos es más lógico aquí, la reflexión no es un GRAN MONSTRUO CON OJOS ROJOS =)

Por cierto, ¿se puede mostrar el código de llamada, donde se determina marcado con los tipos de interfaz? ¿No estás usando la reflexión allí?

+3

+1 para monstruos! –

+1

Nah, solo estoy usando el operador 'is' para verificar si el objeto dado está marcado con una interfaz (vea la última línea del ejemplo de 'Interface'). – Scott

+0

Gracias, ya veo. – Restuta

0

En este caso, como dices, no estás utilizando una interfaz correctamente.

¿Qué hay de malo con el uso de la función de reflexión para obtener atributos? La respuesta habitual es el rendimiento, pero en general no es un problema real en casi todos los casos.

7

Tendré que decir lo contrario. Creo que, para su ejemplo, una interfaz de marcador tiene más sentido.

Eso es porque parece muy probable que algún día podría agregar algunos miembros a IFood.

Su diseño comienza así:

interface IFood {} 

Pero entonces decide agregar algo allí:

interface IFood { 
    int Calories { get; } 
} 

Hay también other ways que se extienden interfaces:

static class FoodExtensions { 
    public static void Lighten(this IFood self) { 
    self.Calories /= 2; 
    } 
} 
Cuestiones relacionadas