【问题标题】:What is the efficient way to store and read additional information from enums从枚举中存储和读取附加信息的有效方法是什么
【发布时间】:2016-11-07 03:04:56
【问题描述】:

我试图从枚举中存储和检索附加信息。我最终有两种方法。 第一种方法是使用自定义属性。 https://stackoverflow.com/a/22054994/5078531 https://stackoverflow.com/a/35040378/5078531

public class DayAttribute : Attribute
{
    public string Name { get; private set; }

    public DayAttribute(string name)
    {
        this.Name = name;
    }
}

enum Days
{
    [Day("Saturday")]
    Sat,
    [Day("Sunday")]
    Sun
}

public static TAttribute GetAttribute<TAttribute>(this Enum value)
        where TAttribute : Attribute
    {
        var enumType = value.GetType();
        var name = Enum.GetName(enumType, value);
        return enumType.GetField(name).GetCustomAttributes(false).OfType<TAttribute>().SingleOrDefault();
    }

我在这里找到的第二种方法,通过在枚举上编写扩展方法。 https://stackoverflow.com/a/680515/5078531

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

public static class ArrowDirectionExtensions
{
     public static UnitVector UnitVector(this ArrowDirection self)
     {         
         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;
         }
     }
}

如果正在寻找性能,我应该选择哪种方法?或者还有没有其他有效的方法?

【问题讨论】:

  • 两者实际上都很糟糕。如果您想要一个具有预定义值的结构,请使用具有预定义值的结构,例如使用包含预定义值的静态只读字段。如果您想防止人们创建自己的实例,请将构造函数设为私有
  • “如果我正在寻找性能我应该选择哪种方法”:两者都不是。首先,您应该定义您的性能需求(对于生产工作,“尽可能快”很少是可接受的定义),然后您应该选择最易读的方法。那么你应该进行基准测试。如果您的代码的这个特定部分是一个基准,您应该更改它,或者更有可能更改调用代码以减少调用它的频率。

标签: c# .net enums


【解决方案1】:

两者都是有效的实现方式;和许多其他方式一样。就个人而言,我喜欢第一个的便利。反射的性能损失可以通过只处理一次属性和存储(大概在static 字段中)来减轻——如果枚举值是连续的并且基于 0,则可能作为平面数组;否则,可能在字典中。

【讨论】:

    【解决方案2】:

    如果你愿意,你可以让 DayaAttributeCache 更通用,这样它就可以存储其他枚举和属性类型。我只是快速地展示了一种缓存方法。枚举值必须从 0 开始连续,但如果需要,可以更改以处理这种情况。

    public static class DaysAttributeCache
    {
        private static readonly string[] Cache;
    
        static DaysAttributeCache()
        {
            Type enumType = typeof(Days);
            Cache = new string[Enum.GetValues(enumType).Length];
    
            foreach (Enum value in Enum.GetValues(enumType))
            {
              var name = Days.GetName(enumType, value);
    
              DayAttribute attribute = enumType
                  .GetField(name)
                  .GetCustomAttributes(false)
                  .OfType<DayAttribute>()
                  .SingleOrDefault();
    
              string weekDay = attribute?.Name;
              Cache[((IConvertible)value).ToInt32(CultureInfo.InvariantCulture)] = weekDay;
            }
        }
    
        public static string GetWeekday(this Days value)
        {
            return Cache[(int)value];
        }
      }
    

    这样称呼...

    string saturday = Days.Sat.GetWeekday();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-07-04
      • 1970-01-01
      • 2013-05-09
      • 2011-05-24
      • 2011-09-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多