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

发布于 2024-07-15 22:29:39 字数 425 浏览 5 评论 0 原文

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

假设我有枚举:

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

我想将每个方向对应的单位向量与该方向相关联。 例如,我想要返回 (0, 1) 代表北,(-1, 0) 代表西,等等。我知道在 Java 中你可以在枚举中声明一个可以提供该功能的方法。

我当前的解决方案是在定义枚举的类中使用一个静态方法,该方法返回与传入的 ArrowDirection 相对应的向量(该方法使用 HashTable 来完成查找,但这并不重要)。 这看起来……不干净。

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

My question is best illustrated with an example.

Suppose I have the enum:

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

I want to associate the unit vector corresponding to each direction with that direction. For example I want something that will return (0, 1) for North, (-1, 0) for West, etc. I know in Java you could declare a method inside the enum which could provide that functionality.

My current solution is to have a static method -- inside the class that defines the enum -- that returns a vector corresponding to the passed in ArrowDirection (the method uses a HashTable to accomplish the lookup but that's not really important). This seems... unclean.

Question:
Is there a best-practice solution for storing additional information corresponding to an enum in .NET?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

自由如风 2024-07-22 22:29:39

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 新功能的一个非常好的结果。

这是另一个示例我的博客。

There's a FANTASTIC new way to do this in C# 3.0. The key is this beautiful fact: Enums can have extension methods! So, here's what you can do:

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;
         }
     }
}

Now, you can do this:

var unitVector = ArrowDirection.North.UnitVector();

Sweet! I only found this out about a month ago, but it is a very nice consequence of the new C# 3.0 features.

Here's another example on my blog.

无声静候 2024-07-22 22:29:39

我在此处写了关于它的博客。

使用 属性 尝试类似的操作。

  public enum Status {

    [Status(Description = "Not Available")]      

    Not_Available = 1,      

    [Status(Description = "Available For Game")] 

    Available_For_Game = 2,      

    [Status(Description = "Available For Discussion")] 

    Available_For_Discussion = 3,

  }

  public class StatusEnumInfo {

    private static StatusAttribute[] edesc; 

    public static String GetDescription(object e)

    {

      System.Reflection.FieldInfo f = e.GetType().GetField(e.ToString()); 

      StatusEnumInfo.edesc = f.GetCustomAttributes(typeof(StatusAttribute), false) as StatusAttribute[]; 

      if (StatusEnumInfo.edesc != null && StatusEnumInfo.edesc.Length == 1)         

        return StatusEnumInfo.edesc[0].Description; 

      else         

        return String.Empty;

    } 

    public static object GetEnumFromDesc(Type t, string desc)

    {

      Array x = Enum.GetValues(t); 

      foreach (object o in x) {

        if (GetDescription(o).Equals(desc)) {

          return o;

        }

      } return String.Empty;

    }

  }

  public class StatusAttribute : Attribute {

    public String Description { get; set; }

  }



  public class Implemenation {

    public void Run()

    {

      Status statusEnum = (Status)StatusEnumInfo.GetEnumFromDesc(typeof(Status), "Not Available"); 

      String statusString = StatusEnumInfo.GetDescription(Status.Available_For_Discussion);

    }

  }

使用您的自定义属性,而不是描述

I've blogged about it here.

Try out something like this with Attributes.

  public enum Status {

    [Status(Description = "Not Available")]      

    Not_Available = 1,      

    [Status(Description = "Available For Game")] 

    Available_For_Game = 2,      

    [Status(Description = "Available For Discussion")] 

    Available_For_Discussion = 3,

  }

  public class StatusEnumInfo {

    private static StatusAttribute[] edesc; 

    public static String GetDescription(object e)

    {

      System.Reflection.FieldInfo f = e.GetType().GetField(e.ToString()); 

      StatusEnumInfo.edesc = f.GetCustomAttributes(typeof(StatusAttribute), false) as StatusAttribute[]; 

      if (StatusEnumInfo.edesc != null && StatusEnumInfo.edesc.Length == 1)         

        return StatusEnumInfo.edesc[0].Description; 

      else         

        return String.Empty;

    } 

    public static object GetEnumFromDesc(Type t, string desc)

    {

      Array x = Enum.GetValues(t); 

      foreach (object o in x) {

        if (GetDescription(o).Equals(desc)) {

          return o;

        }

      } return String.Empty;

    }

  }

  public class StatusAttribute : Attribute {

    public String Description { get; set; }

  }



  public class Implemenation {

    public void Run()

    {

      Status statusEnum = (Status)StatusEnumInfo.GetEnumFromDesc(typeof(Status), "Not Available"); 

      String statusString = StatusEnumInfo.GetDescription(Status.Available_For_Discussion);

    }

  }

Instead of Description, use your custom Property

§对你不离不弃 2024-07-22 22:29:39
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;

    }
}
using System.ComponentModel;
using System.Reflection;


public enum ArrowDirection
{

[Description("Northwards")]
North,

[Description("Southwards")]
South,

[Description("Eastwards")]
East,

[Description("Westwards")]
West
}

...

Create an extension method to get a list of descriptions:

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;

    }
}
十二 2024-07-22 22:29:39

您可以查看的一件事是“类型安全枚举”模式。 这允许您创建一个实际上是成熟静态对象的枚举,它可以具有方法/属性/等。

http://www.javacamp.org/designPattern/enum.html

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

One thing you could look at is the "Type-Safe Enum" pattern. This allows you to create an enum that is actually a full-fledged static object, which can have methods/properties/etc..

http://www.javacamp.org/designPattern/enum.html

Joshua Bloch talks about this pattern in his book "Effective Java." I've used it in a lot of different situations, and I actually prefer it over plain enums. (It's language-agnostic - it works in Java, C#, or pretty much any OO language).

雾里花 2024-07-22 22:29:39

你的静态方法方法对我来说似乎很干净。 您将枚举和静态方法封装在同一个类中。 对枚举的更改集中在该单个类中。

向枚举添加方法(按照 Java)似乎会增加一些实际上非常简单的概念的复杂性。

基于属性的方法很有趣,但与静态方法相比,事情似乎再次变得过于复杂。

Your static method approach seems quite clean to me. You encapsulate both the enum and the static method within the same class. Changes to the enum are centralised within that single class.

Adding a method to the enumeration (as per Java) seems to add complexity to something that is really a very simple concept.

The attribute based approach is interesting, but once again seems to overcomplicate things when compared to a static method.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文