如何用c#中的属性装饰枚举

时间:2016-10-20 12:06:26

标签: c# design-patterns enums

我的解决方案中有一个辅助库的枚举。 例如

 public enum MyEnum 
 {  
  First,
   Second 
  }

我想在另一个项目中使用MyEnum。我想在每个项目中用这样的属性来装饰这个枚举:

public enum MyEnum 
 { 
 [MyAttribute(param)] 
 First,
 [MyAttribute(param2)]
 Second 
}

如何使用自己的本地属性从另一个库中装饰枚举?

3 个答案:

答案 0 :(得分:2)

你无法做你所描述的 - 你可以做的最好的事情是创建一个使用相同值集的新枚举。然后,无论何时使用它,都需要转换为“真实”枚举。

您可以使用T4模板或类似模板为您生成属性枚举 - 这样会更加安全,因为它可以非常容易地映射错误的值,从而产生一些非常微妙的错误!

Linqpad查询

enum PrimaryColor
{
    Red,
    Blue,
    Green
}

enum AttributedPrimaryColor
{
    [MyAttribute]
    Red = PrimaryColor.Red,
    [MyAttribute]
    Blue = PrimaryColor.Blue,
    [MyAttribute]
    Green = PrimaryColor.Green
}

static void PrintColor(PrimaryColor color)
{
    Console.WriteLine(color);
}

void Main()
{
    // We have to perform a cast to PrimaryColor here.
    // As they both have the same base type (int in this case)
    // this cast will be fine.
    PrintColor((PrimaryColor)AttributedPrimaryColor.Red);   
}

答案 1 :(得分:1)

属性是代码的编译时添加(元数据)。使用已编译的代码程序集时,无法修改它们 (或者如果你是一个顽固的低级别的IL巫师,你也许可以,但我当然不是......)

如果您的enum值需要在不同位置进行修改或参数,那么您应该考虑其他解决方案,例如一个Dictionary甚至一个数据库表。

E.g。使用Dictionary

var values = new Dictionary<MyEnum, int>()
{
    { MyEnum.First, 25 },
    { MyEnum.Second, 42 }
};
var valueForSecond = values[MyEnum.Second]; // returns 42

答案 2 :(得分:-3)

你可以做这样的事情,但这将是乏味的 我们的想法是使用您的项目设置,以便在新项目中导入枚举时允许更改。

首先,您需要2个属性:

// This one is to indicate the format of the keys in your settings
public class EnumAttribute : Attribute
{
    public EnumAttribute(string key)
    {
        Key = key;
    }

    public string Key { get; }
}

// This one is to give an id to your enum field
[AttributeUsage(AttributeTargets.Field)]
public class EnumValueAttribute : Attribute
{
    public EnumValueAttribute(int id)
    {
        Id = id;
    }
    public int Id { get; }
}

然后,这个方法:

// This method will get your attribute value from your enum value
public object GetEnumAttributeValue<TEnum>(TEnum value)
{
    var enumAttribute = (EnumAttribute)typeof(TEnum)
        .GetCustomAttributes(typeof(EnumAttribute), false)
        .First();
    var valueAttribute = (EnumValueAttribute)typeof(TEnum).GetMember(value.ToString())
        .First()
        .GetCustomAttributes(typeof(EnumValueAttribute), false)
        .First();
    return Settings.Default[String.Format(enumAttribute.Key, valueAttribute.Id)];
}

我没有检查类型是否正确,即使它找到任何属性也没有。您必须这样做,否则如果您没有提供正确的类型,您将获得例外。

现在,你的枚举将会是这样的:

[Enum("Key{0}")]
public enum MyEnum
{
    [EnumValue(0)] First,
    [EnumValue(1)] Second
}

最后,在项目设置中,您必须添加与枚举中成员数一样多的行 您必须使用与给予EnumAttribute的参数相同的模式命名每一行。在这里,它是&#34;键{0}&#34;,所以:

  1. Key0:您的第一个值
  2. Key1:您的第二个值
  3. 等...
  4. 像这样,您只需要更改设置值(不是键)来导入枚举并将属性更改为另一个项目。

    用法:

    /*Wherever you put your method*/.GetEnumAttributeValue(MyEnum.First);
    

    它将返回你&#34;你的第一个价值&#34;。