【问题标题】:Interfaces or Attributes for Tagging Classes?标记类的接口或属性?
【发布时间】:2011-01-05 01:13:17
【问题描述】:

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

属性

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) { /* ... */ }

由于使用了反射,我对使用属性犹豫不决。然而,与此同时,我对创建一个仅真正用作标签的空接口犹豫不决。我对两者都进行了压力测试,两者之间的时间差只有大约 3 毫秒,因此这里不会影响性能。

【问题讨论】:

  • 只是想知道,如果一个物体是食物,你会怎么做?如果IFood接口是空的,你有什么区别呢?...
  • 如果对象是 Food,我会返回 FoodEventArguments。如果对象是饮料,我会返回 DrinkEventArguments。基本上,有一个通用的基类(比如 ConcessionStandItem)被传递到函数中。
  • 是的,但是在这个 FoodEventArguments 中你有一些常见的食物字段,至于 DrinkEventArguments 你应该有一些饮料常见的字段。您可以在 IFood 接口中声明此字段(属性、方法)然后:)

标签: c# attributes interface


【解决方案1】:

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

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

我会选择属性。

【讨论】:

  • 微软也推荐它,但他们在几个地方与自己的建议有所不同。 (例如 ASP.NET 中的 IRequiresSessionStateIReadOnlySessionState)。
  • ISerializable 不是标记接口。它包含一个成员 (GetObjectData)。实际上他们已经正确地完成了SerializableAttribute
  • 这是我没有想到的。感谢您指出。
【解决方案2】:

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

那是因为很有可能有一天你可能会向IFood 添加一些成员。

你的设计是这样开始的:

interface IFood {}

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

interface IFood {
  int Calories { get; }
}

还有other ways扩展接口:

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

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

    • 不,我只是使用 'is' 运算符来检查给定对象是否标有接口(参见最后一行的 'Interface' 示例)。
    【解决方案4】:

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

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

    【讨论】:

      【解决方案5】:

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

      “如果对象是 Food,我会返回 FoodEventArguments。如果对象是 Beverage,我会返回 DrinkEventArguments。基本上,有一个通用的基类(比如 ConcessionStandItem)被传递到函数"

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

      对于每个“ConcessionStandItem”(如FoodEventArguments CreateEventArgs(Pizza pizza)....)的实现,可能是访客模式的有效场景。

      在这种情况下,也许其他人值得深思。 (双关语)。

      【讨论】:

        猜你喜欢
        • 2011-01-09
        • 2019-06-18
        • 1970-01-01
        • 1970-01-01
        • 2014-07-09
        • 1970-01-01
        • 2011-02-11
        • 2020-01-13
        • 2012-02-21
        相关资源
        最近更新 更多