31 Stimmen

Erweitern von Enums in c#

In Java bin ich es gewohnt, Enum-Werte zu erweitern oder Methoden wie diese zu überschreiben:

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

    }

gibt es eine Möglichkeit, etwas Ähnliches in c# zu tun oder sind enums mehr in c# begrenzt

43voto

Josh M. Punkte 24748

Ich wünschte, Enums wären in .Net leistungsfähiger. Und ich liebe .Net! Sie können Attribute verwenden, um das Gleiche zu erreichen. Schreiben Sie den folgenden Code einmal und verwenden Sie ihn überall. Dies wird eine lange Antwort sein, aber ich denke, es ist eine ziemlich gute Lösung, also haben Sie Geduld!

Verwendung

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

Das Enum

Verwenden Sie Attribute, um die Aufzählung und ihre Werte zu beschreiben.

[DescriptiveEnumEnforcement(DescriptiveEnumEnforcement.EnforcementTypeEnum.ThrowException)]
public enum SomeEnum
{
    [Description("Value One")]
    ValueOne,

    [Description("Value Two")]
    ValueTwo,

    [Description("Value 3")]
    ValueThree
}

BeschreibungAttribut

/// <summary>Indicates that an enum value has a description.</summary>
[AttributeUsage(AttributeTargets.Field)]
public class DescriptionAttribute : System.Attribute
{
    /// <summary>The description for the enum value.</summary>
    public string Description { get; set; }

    /// <summary>Constructs a new DescriptionAttribute.</summary>
    public DescriptionAttribute() { }

    /// <summary>Constructs a new DescriptionAttribute.</summary>
    /// <param name="description">The initial value of the Description property.</param>
    public DescriptionAttribute(string description)
    {
        this.Description = description;
    }

    /// <summary>Returns the Description property.</summary>
    /// <returns>The Description property.</returns>
    public override string ToString()
    {
        return this.Description;
    }
}

DescriptiveEnumEnforcementAttribute

Ein Attribut, das sicherstellt, dass Ihre Enum's richtig konfiguriert sind.

/// <summary>Indicates whether or not an enum must have a NameAttribute and a DescriptionAttribute.</summary>
[AttributeUsage(AttributeTargets.Enum)]
public class DescriptiveEnumEnforcementAttribute : System.Attribute
{
    /// <summary>Defines the different types of enforcement for DescriptiveEnums.</summary>
    public enum EnforcementTypeEnum
    {
        /// <summary>Indicates that the enum must have a NameAttribute and a DescriptionAttribute.</summary>
        ThrowException,

        /// <summary>Indicates that the enum does not have a NameAttribute and a DescriptionAttribute, the value will be used instead.</summary>
        DefaultToValue
    }

    /// <summary>The enforcement type for this DescriptiveEnumEnforcementAttribute.</summary>
    public EnforcementTypeEnum EnforcementType { get; set; }

    /// <summary>Constructs a new DescriptiveEnumEnforcementAttribute.</summary>
    public DescriptiveEnumEnforcementAttribute()
    {
        this.EnforcementType = EnforcementTypeEnum.DefaultToValue;
    }

    /// <summary>Constructs a new DescriptiveEnumEnforcementAttribute.</summary>
    /// <param name="enforcementType">The initial value of the EnforcementType property.</param>
    public DescriptiveEnumEnforcementAttribute(EnforcementTypeEnum enforcementType)
    {
        this.EnforcementType = enforcementType;
    }
}

Die Beschreibung erhalten

/// <summary>Provides functionality to enhance enumerations.</summary>
public static partial class EnumUtil
{
    /// <summary>Returns the description of the specified enum.</summary>
    /// <param name="value">The value of the enum for which to return the description.</param>
    /// <returns>A description of the enum, or the enum name if no description exists.</returns>
    public static string GetDescription(this Enum value)
    {
        return GetEnumDescription(value);
    }

    /// <summary>Returns the description of the specified enum.</summary>
    /// <param name="value">The value of the enum for which to return the description.</param>
    /// <returns>A description of the enum, or the enum name if no description exists.</returns>
    public static string GetDescription<T>(object value)
    {
        return GetEnumDescription(value);
    }

    /// <summary>Returns the description of the specified enum.</summary>
    /// <param name="value">The value of the enum for which to return the description.</param>
    /// <returns>A description of the enum, or the enum name if no description exists.</returns>
    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();
    }
}

28voto

Cameron Punkte 91138

Enums in C# sind nur für (ganzzahlige) Werte; sie können keine speziellen Methoden oder Konstruktoren wie in Java haben.

Allerdings müssen Sie kann definieren Erweiterungsmethoden, die mit Enums arbeiten, um fast den gleichen Effekt zu erzielen:

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

Dann könnte man sagen:

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

3voto

Matt Greer Punkte 58978

Enums in C# sind im Grunde nur benannte Primitive. Sie basieren typischerweise auf int , kann aber auf jedem numerischen Primitiv basieren. C# bietet also nicht annähernd die Funktionalität, die Java-Enums bieten. Der Nachteil ist, dass C#-Enums viel leichter sind, während Java-Enums vollwertige Objekte sind.

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

Die obige Aufzählung unterscheidet sich nicht wesentlich von einer int mit der Ausnahme, dass wir jetzt FooBar.Foo anstelle der wörtlichen 1 . Sie können die Aufzählung zwischen Ints hin- und herwechseln, und Enum hat einige Hilfsfunktionen, die bei der Arbeit mit Enums hilfreich sein können. Aber das war's dann auch schon für C#, sie sind ähnlich wie C oder C++ Enums.

2voto

Brandon Moretz Punkte 7322

In C# können Sie etwas Ähnliches mit Erweiterungsmethoden erreichen.

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X