【发布时间】:2011-10-24 20:41:21
【问题描述】:
我经常看到并使用带有附加属性的枚举来做一些基本的事情,例如提供显示名称或描述:
public enum Movement {
[DisplayName("Turned Right")]
TurnedRight,
[DisplayName("Turned Left")]
[Description("Execute 90 degree turn to the left")]
TurnedLeft,
// ...
}
并且已经有一套扩展方法来支持属性:
public static string GetDisplayName(this Movement movement) { ... }
public static Movement GetNextTurn(this Movement movement, ...) { ... }
遵循此模式,可以将其他现有或自定义属性应用于字段以执行其他操作。就好像 enum 可以作为简单的枚举值类型,也可以作为具有多个字段的更丰富的不可变值对象:
public class Movement
{
public int Value { get; set; } // i.e. the type backing the enum
public string DisplayName { get; set; }
public string Description { get; set; }
public Movement GetNextTurn(...) { ... }
// ...
}
通过这种方式,它可以在序列化过程中作为一个简单的字段“旅行”、快速比较等,而行为可以“内部化”(ala OOP)。
也就是说,我承认这可能被认为是一种反模式。同时,我的一部分认为这很有用,anti 可能过于严格了。
【问题讨论】:
-
您是否在问在您不会使用枚举的地方使用此模式是否是个坏主意?这是将元数据关联到枚举值的绝佳模式。它不如类的替代品那么好。
-
这可能被认为是对语言的“滥用”;几乎就像在没有保证的情况下一直使用
dynamic。 -
不完全正确(因此评论),但我对编码文本以显示在属性或实体类附近的任何地方有疑虑。一方面,我认为它严重违反了“关注点分离”,另一方面,没有明显的本地化方法。唉,MS 似乎鼓励这种事情,所以也许我出去吃午饭了。
-
@Daniel,根据定义,扩展方法不在实体类附近。特定于 UI 的扩展方法甚至可以完全存在于 UI 层中。
-
@KirkWoll 我指的是“DisplayName”属性。
标签: c# .net extension-methods design-patterns anti-patterns