在c#中扩展枚举

在java中我用来扩展枚举值或重写这样的方法:

enum SomeEnum { option1("sv") { public String toString() { return "Some value"; } }, option2; private String PassedValue; public SomeEnum(String somevalue) { this.PassedValue = somevalue; } public SomeEnum() { this.PassedValue = "Default Value"; } public String getPassedValue() { return this.PassedValue; } } 

有没有办法在c#中做类似的事情,或者c#中的枚举更有限

我希望枚解在.Net中更强大。 我喜欢.Net! 您可以使用属性来完成同样的事情。 写下面的代码一次,到处使用它。 这将是一个很长的答案,但我认为这是一个非常好的解决方案,所以要有耐心!

用法

 SomeEnum e = SomeEnum.ValueTwo; string description = e.GetDescription(); 

恩欧姆

使用属性来描述枚举及其值。

 [DescriptiveEnumEnforcement(DescriptiveEnumEnforcement.EnforcementTypeEnum.ThrowException)] public enum SomeEnum { [Description("Value One")] ValueOne, [Description("Value Two")] ValueTwo, [Description("Value 3")] ValueThree } 

DescriptionAttribute

 /// Indicates that an enum value has a description. [AttributeUsage(AttributeTargets.Field)] public class DescriptionAttribute : System.Attribute { /// The description for the enum value. public string Description { get; set; } /// Constructs a new DescriptionAttribute. public DescriptionAttribute() { } /// Constructs a new DescriptionAttribute. /// The initial value of the Description property. public DescriptionAttribute(string description) { this.Description = description; } /// Returns the Description property. /// The Description property. public override string ToString() { return this.Description; } } 

DescriptiveEnumEnforcementAttribute

确保正确配置枚举的属性。

 /// Indicates whether or not an enum must have a NameAttribute and a DescriptionAttribute. [AttributeUsage(AttributeTargets.Enum)] public class DescriptiveEnumEnforcementAttribute : System.Attribute { /// Defines the different types of enforcement for DescriptiveEnums. public enum EnforcementTypeEnum { /// Indicates that the enum must have a NameAttribute and a DescriptionAttribute. ThrowException, /// Indicates that the enum does not have a NameAttribute and a DescriptionAttribute, the value will be used instead. DefaultToValue } /// The enforcement type for this DescriptiveEnumEnforcementAttribute. public EnforcementTypeEnum EnforcementType { get; set; } /// Constructs a new DescriptiveEnumEnforcementAttribute. public DescriptiveEnumEnforcementAttribute() { this.EnforcementType = EnforcementTypeEnum.DefaultToValue; } /// Constructs a new DescriptiveEnumEnforcementAttribute. /// The initial value of the EnforcementType property. public DescriptiveEnumEnforcementAttribute(EnforcementTypeEnum enforcementType) { this.EnforcementType = enforcementType; } } 

获得描述

 /// Provides functionality to enhance enumerations. public static partial class EnumUtil { /// Returns the description of the specified enum. /// The value of the enum for which to return the description. /// A description of the enum, or the enum name if no description exists. public static string GetDescription(this Enum value) { return GetEnumDescription(value); } /// Returns the description of the specified enum. /// The value of the enum for which to return the description. /// A description of the enum, or the enum name if no description exists. public static string GetDescription(object value) { return GetEnumDescription(value); } /// Returns the description of the specified enum. /// The value of the enum for which to return the description. /// A description of the enum, or the enum name if no description exists. public static string GetEnumDescription(object value) { if (value == null) return null; Type type = value.GetType(); //Make sure the object is an enum. if (!type.IsEnum) throw new ApplicationException("Value parameter must be an enum."); FieldInfo fieldInfo = type.GetField(value.ToString()); object[] descriptionAttributes = fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false); //If no DescriptionAttribute exists for this enum value, check the DescriptiveEnumEnforcementAttribute and decide how to proceed. if (descriptionAttributes == null || descriptionAttributes.Length == 0) { object[] enforcementAttributes = fieldInfo.GetCustomAttributes(typeof(DescriptiveEnumEnforcementAttribute), false); //If a DescriptiveEnumEnforcementAttribute exists, either throw an exception or return the name of the enum instead. if (enforcementAttributes != null && enforcementAttributes.Length == 1) { DescriptiveEnumEnforcementAttribute enforcementAttribute = (DescriptiveEnumEnforcementAttribute)enforcementAttributes[0]; if (enforcementAttribute.EnforcementType == DescriptiveEnumEnforcementAttribute.EnforcementTypeEnum.ThrowException) throw new ApplicationException("No Description attributes exist in enforced enum of type '" + type.Name + "', value '" + value.ToString() + "'."); return GetEnumName(value); } else //Just return the name of the enum. return GetEnumName(value); } else if (descriptionAttributes.Length > 1) throw new ApplicationException("Too many Description attributes exist in enum of type '" + type.Name + "', value '" + value.ToString() + "'."); //Return the value of the DescriptionAttribute. return descriptionAttributes[0].ToString(); } } 

C#中的枚举仅适用于(整数)值; 他们不能像Java那样拥有特殊的方法或构造函数。

但是,您可以定义对枚举起作用的扩展方法,以实现几乎相同的效果:

 public enum MyEnum { Foo = 1, Bar = 2, Default = Foo } public static class MyEnumExtensions { public static Widget ToWidget(this MyEnum enumValue) { switch (enumValue) { case MyEnum.Foo: return new Widget("Foo!"); case MyEnum.Bar: return new Widget("Bar..."); default: return null; } } } 

然后你可以说:

 var val = MyEnum.Foo; var widget = val.ToWidget(); 

C#中的枚举基本上只是命名基元。 它们通常基于int ,但可以基于任何数字原语。 因此,C#几乎不提供Java枚举所具有的function。 权衡是C#枚举更轻,而Java枚举是完全成熟的对象。

 public enum FooBar : int { Foo = 1, Bar = 2 } 

上面的枚举与int没什么不同,除了我们现在可以使用FooBar.Foo而不是文字1 。 你可以在int之间来回转换EnumEnum有一些辅助function,可以在使用枚举时提供帮助。 但这就是C#,它们很像C或C ++枚举。

您可以使用Extension方法在C#中执行类似的操作。

 enum Test { Value1, Value2, Value3 } static class TextExtensions { public static string Value(this Test value) { string stringValue = default(String); switch (value) { case Test.Value1: { stringValue = "some value 1"; } break; case Test.Value2: { stringValue = "some value 2"; }; break; case Test.Value3: { stringValue = "some value 3"; }; break; } return stringValue; } } class Program { static void Main(string[] args) { Console.Write(Test.Value1.Value()); Console.ReadLine(); } }