954 Stimmen

String-Darstellung einer Enum

Ich habe die folgende Aufzählung:

public enum AuthenticationMethod
{
    FORMS = 1,
    WINDOWSAUTHENTICATION = 2,
    SINGLESIGNON = 3
}

Das Problem ist jedoch, dass ich das Wort "FORMS" benötige, wenn ich nach AuthenticationMethod.FORMS frage, und nicht die ID 1.

Ich habe die folgende Lösung für dieses Problem gefunden ( Link ):

Zunächst muss ich ein benutzerdefiniertes Attribut namens "StringValue" erstellen:

public class StringValue : System.Attribute
{
    private readonly string _value;

    public StringValue(string value)
    {
        _value = value;
    }

    public string Value
    {
        get { return _value; }
    }

}

Dann kann ich dieses Attribut zu meinem Enumerator hinzufügen:

public enum AuthenticationMethod
{
    [StringValue("FORMS")]
    FORMS = 1,
    [StringValue("WINDOWS")]
    WINDOWSAUTHENTICATION = 2,
    [StringValue("SSO")]
    SINGLESIGNON = 3
}

Und natürlich brauche ich etwas, um diesen StringValue abzurufen:

public static class StringEnum
{
    public static string GetStringValue(Enum value)
    {
        string output = null;
        Type type = value.GetType();

        //Check first in our cached results...

        //Look for our 'StringValueAttribute' 

        //in the field's custom attributes

        FieldInfo fi = type.GetField(value.ToString());
        StringValue[] attrs =
           fi.GetCustomAttributes(typeof(StringValue),
                                   false) as StringValue[];
        if (attrs.Length > 0)
        {
            output = attrs[0].Value;
        }

        return output;
    }
}

Gut, jetzt habe ich die Werkzeuge, um einen String-Wert für einen Enumerator zu erhalten. Ich kann ihn dann wie folgt verwenden:

string valueOfAuthenticationMethod = StringEnum.GetStringValue(AuthenticationMethod.FORMS);

Okay, das funktioniert alles prima, aber ich finde es eine Menge Arbeit. Ich habe mich gefragt, ob es eine bessere Lösung für dieses Problem gibt.

Ich habe auch etwas mit einem Wörterbuch und statischen Eigenschaften versucht, aber auch das war nicht besser.

5 Stimmen

Auch wenn Sie das vielleicht langatmig finden, so ist es doch ein ziemlich flexibler Weg, um andere Dinge zu erledigen. Wie einer meiner Kollegen bemerkte, könnte dies in vielen Fällen verwendet werden, um Enum Helpers zu ersetzen, die Datenbankcodes auf Enum-Werte usw. abbilden.

3 Stimmen

Es handelt sich um eine "Aufzählung", nicht um einen "Enumerator".

29 Stimmen

MSDN empfiehlt, Attributklassen mit dem Suffix "Attribute" zu versehen. Also "Klasse StringValueAttribute" ;)

0voto

Ramil Shavaleev Punkte 151

Sie können die Aufzählung und das Wörterbuch deklarieren, in dem der Schlüssel der Wert der Aufzählung sein wird. In Zukunft können Sie auf das Wörterbuch verweisen, um den Wert zu erhalten. So wird es möglich sein, Parameter an Funktionen als Typ der Aufzählung zu übergeben, aber den tatsächlichen Wert aus dem Wörterbuch zu erhalten:

using System;
using System.Collections.Generic;

namespace console_test
{
    class Program
    {
        #region SaveFormat
        internal enum SaveFormat
        {
            DOCX,
            PDF
        }

        internal static Dictionary<SaveFormat,string> DictSaveFormat = new Dictionary<SaveFormat, string>
        {
            { SaveFormat.DOCX,"This is value for DOCX enum item" },
            { SaveFormat.PDF,"This is value for PDF enum item" }
        };

        internal static void enum_value_test(SaveFormat save_format)
        {
            Console.WriteLine(DictSaveFormat[save_format]);
        }
        #endregion

        internal static void Main(string[] args)
        {
            enum_value_test(SaveFormat.DOCX);//Output: This is value for DOCX enum item
            Console.Write("Press any key to continue . . . ");
            Console.ReadKey(true);
        }
    }
}

0voto

Swati Punkte 21

Der Ansatz, den ich für die Internationalisierung von Enums oder immer Text von Enums aus den jeweiligen Ressourcendateien gefunden habe, besteht darin, eine Attributklasse zu erstellen, indem die DescriptionAttribute-Klasse geerbt wird

public class EnumResourceAttribute : DescriptionAttribute
{

    public Type ResourceType { get; private set; }
    public string ResourceName { get; private set; }
    public int SortOrder { get; private set; }
    public EnumResourceAttribute(Type ResourceType,
                         string ResourceName,
                         int SortOrder)
    {

        this.ResourceType = ResourceType;
        this.ResourceName = ResourceName;
        this.SortOrder = SortOrder;
    }
}

Erstellen Sie eine weitere Static-Klasse, die Erweiterungsmethoden für GetString und GetStrings bereitstellt.

public static class EnumHelper
{
    public static string GetString(this Enum value)
    {
        EnumResourceAttribute ea =
       (EnumResourceAttribute)value.GetType().GetField(value.ToString())
        .GetCustomAttributes(typeof(EnumResourceAttribute), false)
         .FirstOrDefault();
        if (ea != null)
        {
            PropertyInfo pi = ea.ResourceType
             .GetProperty(CommonConstants.ResourceManager);
            if (pi != null)
            {
                ResourceManager rm = (ResourceManager)pi
                .GetValue(null, null);
                return rm.GetString(ea.ResourceName);
            }

        }
        return string.Empty;
    }

    public static IList GetStrings(this Type enumType)
    {
        List<string> stringList = new List<string>();
        FieldInfo[] fiArray = enumType.GetFields();
        foreach (FieldInfo fi in fiArray)
        {
            EnumResourceAttribute ea =
                (EnumResourceAttribute)fi
                     .GetCustomAttributes(typeof(EnumResourceAttribute), false)
                     .FirstOrDefault();
            if (ea != null)
            {
                PropertyInfo pi = ea.ResourceType
                                    .GetProperty(CommonConstants.ResourceManager);
                if (pi != null)
                {
                    ResourceManager rm = (ResourceManager)pi
                                          .GetValue(null, null);
                    stringList.Add(rm.GetString(ea.ResourceName));
                }
            }
        }
        return stringList.ToList();
    }
}

Und auf die Elemente Ihrer Enum können Sie schreiben :

public enum Priority
{
     [EnumResourceAttribute(typeof(Resources.AdviceModule), Resources.ResourceNames.AdviceCreateAdviceExternaPriorityMemberHigh, 1)]
    High,
     [EnumResourceAttribute(typeof(Resources.AdviceModule), Resources.ResourceNames.AdviceCreateAdviceExternaPriorityMemberRoutine, 2)]
    Routine
}

Wo Resources.ResourceNames.AdviceCreateAdviceExternaPriorityMemberHigh & Resources.ResourceNames.AdviceCreateAdviceExternaPriorityMemberRoutine sind Konstanten in der Ressourcendatei, oder man kann sagen, die Strings, deren Werte in verschiedenen Kulturen verfügbar sein können.

Wenn Sie Ihre Webanwendung in einer MVC-Architektur implementieren, erstellen Sie eine Eigenschaft

private IList result;
public IList Result
{
    get
    {
        result = typeof(Priority).GetStrings();
        return result;
    }
}

und in Ihrer .cshtml-Datei können Sie die Aufzählung einfach an Ihre Dropdown-Liste binden wie :

@Html.DropDownListFor(model => Model.vwClinicalInfo.Priority, new SelectList(Model.Result))

Danke Ratnesh

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