580 Stimmen

Attribute des Enum-Wertes abrufen

Ich würde gerne wissen, ob es möglich ist, Attribute der enum Werte und nicht der enum selbst? Angenommen, ich habe zum Beispiel folgendes enum :

using System.ComponentModel; // for DescriptionAttribute

enum FunkyAttributesEnum
{
    [Description("Name With Spaces1")]
    NameWithoutSpaces1,    
    [Description("Name With Spaces2")]
    NameWithoutSpaces2
}

Was ich will, ist der Enum-Typ gegeben, produzieren 2-Tupel von Enum-String-Wert und seine Beschreibung.

Der Wert war einfach:

Array values = System.Enum.GetValues(typeof(FunkyAttributesEnum));
foreach (int value in values)
    Tuple.Value = Enum.GetName(typeof(FunkyAttributesEnum), value);

Aber wie erhalte ich den Wert des Attributs description, um die Tuple.Desc ? Ich kann mir vorstellen, wie man es macht, wenn das Attribut zum enum selbst, aber ich weiß nicht, wie ich ihn aus dem Wert der enum .

0 Stimmen

Aus einer anderen Frage stackoverflow.com/questions/469287/

3 Stimmen

Der für die Beschreibung erforderliche Namespace ist System.ComponentModel

545voto

Bryan Rowe Punkte 8987

Das sollte genügen.

try
{
  var enumType = typeof(FunkyAttributesEnum);
  var memberInfos = 
  enumType.GetMember(FunkyAttributesEnum.NameWithoutSpaces1.ToString());
  var enumValueMemberInfo = memberInfos.FirstOrDefault(m => 
  m.DeclaringType == enumType);
  var valueAttributes = 
  enumValueMemberInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);
  var description = ((DescriptionAttribute)valueAttributes[0]).Description;
}
catch
{
    return FunkyAttributesEnum.NameWithoutSpaces1.ToString()
}

380voto

AdamCrawford Punkte 4638

Dieses Codestück sollte Ihnen eine nette kleine Erweiterungsmethode für jedes Enum geben, mit der Sie ein generisches Attribut abrufen können. Ich glaube, dass sie sich von der obigen Lambda-Funktion unterscheidet, weil sie einfacher zu verwenden ist - Sie müssen nur den generischen Typ übergeben.

public static class EnumHelper
{
    /// <summary>
    /// Gets an attribute on an enum field value
    /// </summary>
    /// <typeparam name="T">The type of the attribute you want to retrieve</typeparam>
    /// <param name="enumVal">The enum value</param>
    /// <returns>The attribute of type T that exists on the enum value</returns>
    /// <example><![CDATA[string desc = myEnumVariable.GetAttributeOfType<DescriptionAttribute>().Description;]]></example>
    public static T GetAttributeOfType<T>(this Enum enumVal) where T:System.Attribute
    {
        var type = enumVal.GetType();
        var memInfo = type.GetMember(enumVal.ToString());
        var attributes = memInfo[0].GetCustomAttributes(typeof(T), false);
        return (attributes.Length > 0) ? (T)attributes[0] : null;
    }
}

94voto

Scott Belchak Punkte 1119

Dies ist eine generische Implementierung, die ein Lambda für die Auswahl verwendet

public static Expected GetAttributeValue<T, Expected>(this Enum enumeration, Func<T, Expected> expression)
    where T : Attribute
{
    T attribute =
      enumeration
        .GetType()
        .GetMember(enumeration.ToString())
        .Where(member => member.MemberType == MemberTypes.Field)
        .FirstOrDefault()
        .GetCustomAttributes(typeof(T), false)
        .Cast<T>()
        .SingleOrDefault();

    if (attribute == null)
        return default(Expected);

    return expression(attribute);
}

Sagen wir es so:

string description = targetLevel.GetAttributeValue<DescriptionAttribute, string>(x => x.Description);

86voto

Troy Alford Punkte 25723

Ich habe ein paar der Antworten hier zusammengeführt, um eine etwas erweiterbare Lösung zu schaffen. Ich stelle sie nur zur Verfügung, falls sie in Zukunft für andere hilfreich sein sollte. Ursprünglicher Beitrag aquí .

using System;
using System.ComponentModel;

public static class EnumExtensions {

    // This extension method is broken out so you can use a similar pattern with 
    // other MetaData elements in the future. This is your base method for each.
    public static T GetAttribute<T>(this Enum value) where T : Attribute {
        var type = value.GetType();
        var memberInfo = type.GetMember(value.ToString());
        var attributes = memberInfo[0].GetCustomAttributes(typeof(T), false);
        return attributes.Length > 0 
          ? (T)attributes[0]
          : null;
    }

    // This method creates a specific call to the above method, requesting the
    // Description MetaData attribute.
    public static string ToName(this Enum value) {
        var attribute = value.GetAttribute<DescriptionAttribute>();
        return attribute == null ? value.ToString() : attribute.Description;
    }

}

Mit dieser Lösung wird ein Paar von Erweiterungsmethoden für Enum erstellt. Mit der ersten können Sie Reflection verwenden, um jedes mit Ihrem Wert verbundene Attribut abzurufen. Die zweite ruft speziell die DescriptionAttribute und gibt seine Description Wert.

Ein Beispiel ist die Verwendung der DescriptionAttribute Attribut von System.ComponentModel

using System.ComponentModel;

public enum Days {
    [Description("Sunday")]
    Sun,
    [Description("Monday")]
    Mon,
    [Description("Tuesday")]
    Tue,
    [Description("Wednesday")]
    Wed,
    [Description("Thursday")]
    Thu,
    [Description("Friday")]
    Fri,
    [Description("Saturday")]
    Sat
}

Um die obige Erweiterungsmethode zu verwenden, müssten Sie nun einfach Folgendes aufrufen:

Console.WriteLine(Days.Mon.ToName());

ou

var day = Days.Mon;
Console.WriteLine(day.ToName());

38voto

FunksMaName Punkte 2101

Zusätzlich zu AdamCrawford-Antwort Ich habe außerdem eine speziellere Erweiterungsmethode erstellt, die sich daraus speist, um die Beschreibung zu erhalten.

public static string GetAttributeDescription(this Enum enumValue)
{
    var attribute = enumValue.GetAttributeOfType<DescriptionAttribute>();
    return attribute == null ? String.Empty : attribute.Description;
} 

Um die Beschreibung zu erhalten, können Sie daher entweder die ursprüngliche Erweiterungsmethode als

string desc = myEnumVariable.GetAttributeOfType<DescriptionAttribute>().Description

oder Sie könnten einfach die Erweiterungsmethode hier als aufrufen:

string desc = myEnumVariable.GetAttributeDescription();

Das sollte Ihren Code hoffentlich etwas lesbarer machen.

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