我希望使用特定属性标记几个类。我有两种方法。一个涉及使用属性扩展类。另一个使用空接口:
属性
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毫秒左右,因此性能不会受到影响。
答案 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)....
的实现。
在这种情况下,也许为其他人带来了思考。 (双关语意)。