C# 将附加信息与.NET枚举关联

C# 将附加信息与.NET枚举关联,c#,.net,enums,C#,.net,Enums,我的问题最好用一个例子来说明 假设我有枚举: public enum ArrowDirection { North, South, East, West } 我想把每个方向对应的单位向量和那个方向联系起来。例如,我想要的东西将返回(0,1)表示北方,返回(-1,0)表示西方,等等。我知道在Java中,您可以在枚举中声明一个方法,该方法可以提供该功能 我目前的解决方案是在定义枚举的类中有一个静态方法,该方法返回一个与按箭头方向传递的值相对应的向量(该方法使用哈希表

我的问题最好用一个例子来说明

假设我有枚举:

public enum ArrowDirection
{
    North,
    South,
    East,
    West
}
我想把每个方向对应的单位向量和那个方向联系起来。例如,我想要的东西将返回(0,1)表示北方,返回(-1,0)表示西方,等等。我知道在Java中,您可以在枚举中声明一个方法,该方法可以提供该功能

我目前的解决方案是在定义枚举的类中有一个静态方法,该方法返回一个与按箭头方向传递的值相对应的向量(该方法使用哈希表来完成查找,但这并不重要)。这似乎。。。不干净

问题:
在.NET中存储与枚举相对应的附加信息是否有最佳实践解决方案?

我在博客上写过

试一下这样的东西


使用自定义属性而不是描述,您可以查看“类型安全枚举”模式。这允许您创建一个枚举,该枚举实际上是一个成熟的静态对象,可以具有方法/属性等


Joshua Bloch在他的书《有效Java》中谈到了这种模式。我在很多不同的情况下使用过它,实际上我更喜欢它而不是普通枚举。(它与语言无关——它在Java、C#或几乎任何OO语言中都能工作)。

我觉得您的静态方法方法非常干净。将枚举和静态方法封装在同一个类中。对枚举的更改集中在单个类中

向枚举中添加方法(根据Java)似乎会增加一些非常简单的概念的复杂性


基于属性的方法很有趣,但与静态方法相比,它似乎又过于复杂了。

在C#3.0中有一种奇妙的新方法可以做到这一点。关键是这个美丽的事实:枚举可以有扩展方法!因此,以下是您可以做的:

public enum ArrowDirection
{
    North,
    South,
    East,
    West
}

public static class ArrowDirectionExtensions
{
     public static UnitVector UnitVector(this ArrowDirection self)
     {
         // Replace this with a dictionary or whatever you want ... you get the idea
         switch(self)
         {
             case ArrowDirection.North:
                 return new UnitVector(0, 1);
             case ArrowDirection.South:
                 return new UnitVector(0, -1);
             case ArrowDirection.East:
                 return new UnitVector(1, 0);
             case ArrowDirection.West:
                 return new UnitVector(-1, 0);
             default:
                 return null;
         }
     }
}
现在,您可以执行以下操作:

var unitVector = ArrowDirection.North.UnitVector();
好极了!我大约一个月前才发现这一点,但这是新C#3.0特性的一个非常好的结果

创建扩展方法以获取描述列表:

public static class Enum<T> where T : struct
{

    /// <summary>
    /// Gets a collection of the enum value descriptions.
    /// </summary>
    /// <returns></returns>
    public static IList<string> GetDescriptions()
    {
        List<string> descriptions = new List<string>();
        foreach (object enumValue in Enum<T>.GetValues())
        {
            descriptions.Add(((Enum)enumValue).ToDescription());
        }
        return descriptions;

    }
}
公共静态类枚举,其中T:struct
{
/// 
///获取枚举值描述的集合。
/// 
/// 
公共静态IList GetDescriptions()
{
列表描述=新列表();
foreach(Enum.GetValues()中的对象枚举值)
{
description.Add((Enum)enumValue.ToDescription());
}
返回说明;
}
}

我也用过,也很喜欢。但直到最近我才发现我更喜欢的东西。您可以将扩展方法放在枚举上!有趣的是这给我带来了多大的快乐。。。但是它真的很好,很酷。虽然我知道扩展,但我从未想过将它们用于enum extensionYeah,一开始我也是这样。一个朋友告诉我了。非常好。我还惊讶地了解到(最近,这里就是如此)可以对空值调用扩展方法。它仍然有效,因为它是一个静态方法。和往常一样,C#团队在考虑这些特性方面做得很好。你会得到公认的答案。我试过了,效果很好。唯一的问题是。我到底应该在哪里声明枚举?如果我把它留在课堂上,它会说它不容易接近。我必须创建一个“ClassName_Enums”类才能使其工作……事实证明,在名称空间级别定义enum是有意义的。接受。是的,我同意在大多数情况下我会使用名称空间级别。这看起来不像一个扩展方法。
这个
参数在哪里?另外,
ToDescription
来自哪里?这应该是扩展方法吗?一个人也可以有好的旧工厂方法。。
using System.ComponentModel;
using System.Reflection;


public enum ArrowDirection
{

[Description("Northwards")]
North,

[Description("Southwards")]
South,

[Description("Eastwards")]
East,

[Description("Westwards")]
West
}
public static class Enum<T> where T : struct
{

    /// <summary>
    /// Gets a collection of the enum value descriptions.
    /// </summary>
    /// <returns></returns>
    public static IList<string> GetDescriptions()
    {
        List<string> descriptions = new List<string>();
        foreach (object enumValue in Enum<T>.GetValues())
        {
            descriptions.Add(((Enum)enumValue).ToDescription());
        }
        return descriptions;

    }
}