用于标记类的接口或属性?

时间:2010-01-14 11:55:37

标签: c# attributes interface

我希望使用特定属性标记几个类。我有两种方法。一个涉及使用属性扩展类。另一个使用空接口:

属性

public class FoodAttribute : Attribute { }

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

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

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

接口

public interface IFoodTag { }

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

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

由于使用了Reflection,我对使用属性犹豫不决。然而,与此同时,我对创建一个仅用作标记的空接口犹豫不决。我对两者进行了压力测试,两者之间的时差仅为3毫秒左右,因此性能不会受到影响。

5 个答案:

答案 0 :(得分:15)

嗯,使用属性,您始终可以创建属性,使其功能不会自动传播到后代类型。

使用接口,这是不可能的。

我会选择属性。

答案 1 :(得分:7)

我不得不另外说。我认为,对于你的例子,标记界面更有意义。

那是因为您可能有一天可能有一天会将某些成员添加到IFood

你的设计是这样开始的:

interface IFood {}

但是你决定在那里添加一些东西:

interface IFood {
  int Calories { get; }
}

还有other ways来扩展接口:

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

答案 2 :(得分:5)

您可能已经自己回答了问题。属性在这里更合乎逻辑,反射不是一个有红眼的大怪物=)

顺便说一句,你能显示调用代码,你确定用接口类型标记了吗?你不是在那里使用反射吗?

答案 3 :(得分:0)

在这种情况下,正如您所说,您没有正确使用界面。

使用反射获取属性有什么问题?通常的答案是性能,但在几乎所有情况下这通常都不是真正的问题。

答案 4 :(得分:0)

这是一个古老的问题,但也许有人像我一样偶然发现了这个问题。 在这种情况下似乎:

“”如果对象是Food,则将返回FoodEventArguments。如果该对象是例如Beverage,则将返回DrinkEventArguments。基本上,有一个通用的基类(例如ConcessionStandItem)被传递到功能”

使用接口或属性标记,然后使用if语句进行检查不是唯一的选择。

对于访问者模式来说可能也是一种有效的方案,它也为每个'ConcessionStandItem'提供了类似FoodEventArguments CreateEventArgs(Pizza pizza)....的实现。

在这种情况下,也许为其他人带来了思考。 (双关语意)。