C# 首次访问后更改枚举属性顺序

C# 首次访问后更改枚举属性顺序,c#,enums,C#,Enums,我们有以下枚举: public enum TrafficLight { [Description("../../images/dot-red.png")] [AwesomeIcon("<i class='fa fa-lg fa-circle v4-red'></i>")] Red = 0, [Description("../../images/dot-yellow.png")] [Aw

我们有以下枚举:

public enum TrafficLight
    {
        [Description("../../images/dot-red.png")]
        [AwesomeIcon("<i class='fa fa-lg fa-circle v4-red'></i>")]
        Red = 0,
        [Description("../../images/dot-yellow.png")]
        [AwesomeIcon("<i class='fa fa-lg fa-circle v4-yellow'></i>")]
        Yellow = 1,
        [Description("../../images/dot-green.png")]
        [AwesomeIcon("<i class='fa fa-lg fa-circle v4-green'></i>")]
        Green = 2,
        [Description("../../images/dot-gold.png")]
        [AwesomeIcon("<i class='fa fa-lg fa-circle v4-gold'></i>")]
        Gold = 3,
        [Description("../../images/dot-grey.png")]
        [AwesomeIcon("<i class='fa fa-lg fa-circle v4-grey'></i>")]
        Grey = 99
    }
问题是,当多次访问枚举描述时,属性的顺序会改变。例如,我们得到的描述如下:

 public static string GetEnumDescription(Enum value, int index = 0)
        {
            var fi = value.GetType().GetField(value.ToString());

            var attributes =
                fi.GetCustomAttributes(typeof (DescriptionAttribute), false) as DescriptionAttribute[];

            if(attributes == null)
            {
                return string.Empty;
            }

            if (attributes.Any() && index <= attributes.Length)
            {
                return attributes[index].Description;
            }   

            return value.ToString();
        }
第二次访问

GetEnumDescription(TrafficLight.Red);
//Returns "../../images/dot-red.png" as expected.
//Debug GetEnumDescription attributes variable
[0]Description
[1]AwesomeIcon
GetEnumDescription(TrafficLight.Yellow);
//Returns "<i class='fa fa-lg fa-circle v4-yellow'></i>" 
// which is the value of AwesomeIcon.
//Debug GetEnumDescription attributes variable
[0]AwesomeIcon
[1]Description
GetEnumDescription(交通灯.黄色);
//返回“”
//这是AwesomeIcon的值。
//调试GetEnumDescription属性变量
[0]了不起的图标
[1] 描述
订单后的每次访问都保持
awesome图标
,然后是
说明

问题是AwesomeIcon继承自描述,并且它正在被拾取。如果数组中的顺序保持不变,就不会有问题,我可以通过索引引用它


我以前从未经历过这种情况,有什么想法吗?

你可以确保你有一个
描述属性(即使它是继承的),比如:

var fi = value.GetType().GetField(value.ToString());
var attributes = fi.GetCustomAttributes(typeof (DescriptionAttribute), false);
var myDescriptionAttribute = 
      attributes.FirstOrDefault(x => x.GetType() == typeof(DescriptionAttribute)) as DescriptionAttribute;
忘了指数吧。属性不能保证顺序,因此索引是相当无用的

通过使用
x=>x.GetType()==typeof(DescriptionAttribute)
可以获得精确的类型匹配

我已经演示了两种可能的方法(使用泛型或仅查找
DescriptionAttribute
):

但基本上:

public static string GetEnumDescription(Enum value)
{
    var fi = value.GetType().GetField(value.ToString());
    var attributes = fi.GetCustomAttributes(typeof (DescriptionAttribute), false);
    var theDescriptionAttribute = attributes.FirstOrDefault(x => x.GetType() == typeof (DescriptionAttribute)) as DescriptionAttribute;
    if (theDescriptionAttribute == null)
    {
        return string.Empty;
    }
    return theDescriptionAttribute.Description;
}
或:

公共静态字符串GetEnumDescription(枚举值)
其中T:DescriptionAttribute
{
var fi=value.GetType().GetField(value.ToString());
var attributes=fi.GetCustomAttributes(typeof(T),false);
var theDescriptionAttribute=attributes.FirstOrDefault(x=>x.GetType()==typeof(T))作为T;
if(theDescriptionAttribute==null)
{
返回字符串。空;
}
返回Description属性。Description;
}
当然,可能需要更多的
null
检查,但我将把它留给您


作为额外提示,
FieldInfo.GetCustomAttributes
从不返回null(它可能返回空数组,但不返回null),因此您可以删除该null检查:-)

作为一种快速修复方法,您可以按名称对属性排序,这将帮助您每次都以相同的顺序获取属性

var attributes =
         fi.GetCustomAttributes(typeof (DescriptionAttribute), false) as object[];

if(attributes.Any())
  {
   // Ascending order
   Array.Sort(attributes, (x, y) => 
    String.Compare(x.GetType().Name, y.GetType().Name)); 
  }
并修复
GetEnumDescription(枚举值,int index=0)中的错误。

if (attributes.Any() && index <= attributes.Length) 

if(attributes.Any()&&index您是否正在尝试查看此答案中是否讨论了这样的问题:?不要使用
AwesomeIconAttribute
继承自
descriptionatriute
感谢您的建议和错误修复!我决定最好不要依赖顺序,而是通过DescriptionAttribute显式获得它。是的,这应该是一种方法。快速修复是不可能的它们迟早会变得痛苦。谢谢!效果很好
var attributes =
         fi.GetCustomAttributes(typeof (DescriptionAttribute), false) as object[];

if(attributes.Any())
  {
   // Ascending order
   Array.Sort(attributes, (x, y) => 
    String.Compare(x.GetType().Name, y.GetType().Name)); 
  }
if (attributes.Any() && index <= attributes.Length) 
if (attributes.Any() && index < attributes.Length)