एनुम के मूल्य के गुण प्राप्त करना


483

मैं जानना चाहूंगा कि क्या enumमूल्यों का गुण प्राप्त करना संभव है और enumस्वयं का नहीं? उदाहरण के लिए, मान लें कि मेरे पास निम्नलिखित हैंenum :

using System.ComponentModel; // for DescriptionAttribute

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

मैं जो चाहता हूं उसे एनम प्रकार दिया जाता है, एनुम स्ट्रिंग मूल्य के 2-ट्यूपल और इसके विवरण का उत्पादन करें।

मूल्य आसान था:

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

लेकिन मुझे वर्णन विशेषता का मान कैसे प्राप्त करना है, आबाद करने के लिए Tuple.Desc? मैं सोच सकता हूं कि अगर एट्रीब्यूट enumखुद के हैं, तो इसे कैसे करना है, लेकिन मैं इस बात से नुकसान में हूं कि इसे कैसे प्राप्त किया जाए enum


एक अन्य प्रश्न से stackoverflow.com/questions/469287/…
वित्तीय वर्ष


2
विवरण के लिए नामस्थान आवश्यक है। System.ComponentModel
जॉन M

आप केवल System.ComponentModel का उपयोग नहीं कर सकते हैं और केवल अपनी विशेषता प्रकार का उपयोग कर सकते हैं; वहाँ वास्तव में कुछ भी नहीं है कि सभी के बारे में विशेष है DescriptionAttribute
जूनियर

: plesae इस लिंक को देख stackoverflow.com/a/58954215/5576498
AminGolmahalle

जवाबों:


482

यह वही करना चाहिए जो आपको चाहिए।

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;

10
वैकल्पिक रूप से type.GetFields (BindingFlags.Public | BindingFlags.Static) का उपयोग एक ही बार में सभी मेमोफॉइस प्राप्त करने के लिए करें।
ट्रूविल

4
मुझे टाइपोफ़ (फ़नकी एट्रिब्यूटेस ईनम) जाना था, लेकिन इसके अलावा यह अच्छी तरह से काम करता था। धन्यवाद।
ग्रेग रान्डेल

@AlexK मैं नहीं देखता कि Enum वर्ग के पास NameWithoutSpaces1 प्रॉपर्टी है। FunkyAttributesEnum.NameWithoutSpaces1 कहाँ से आता है?
डॉन

2
@, यह ओप के सवाल से एनम सदस्य का नाम है।
मेमोरियल

287

कोड का यह टुकड़ा आपको किसी भी एनम पर एक अच्छा सा विस्तार विधि देना चाहिए जो आपको एक सामान्य विशेषता को पुनः प्राप्त करने देता है। मेरा मानना ​​है कि यह ऊपर लैंबडा फ़ंक्शन के लिए अलग है क्योंकि यह उपयोग करने के लिए सरल है और थोड़ा - आपको केवल सामान्य प्रकार में पास करने की आवश्यकता है।

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

19
उपयोग तब होगा: string desc = myEnumVariable.GetAttributeOfType <DescriptionAttribute> ()। विवरण;
ब्रैड रेम

2
मुझे स्कॉट की तुलना में यह एक अधिक पसंद है, क्योंकि उपयोग यहां क्लीनर (कम टाइपिंग) है, इसलिए +1 :)
nawfal

3
यदि कोई विशेषता मौजूद नहीं है, तो क्या यह फेंक नहीं होगा IndexOutOfRangeException?
एरिक फिलिप्स

6
बेहतर उपयोग type.GetMember (Enum.GetName (प्रकार, enumVal)) ज्ञापन के लिए enumVal.ToString () के रूप में विभिन्न स्थानों के लिए विश्वसनीय नहीं हो सकता है।
लिन सॉन्ग यांग

2
कॉल करने का क्या मतलब है GetCustomAttributes()फिर कॉल करने के बजाय पहले तत्व प्राप्त करें GetCustomAttribute()?
टिग्रो

81

यह चयन के लिए एक लैम्ब्डा का उपयोग करके एक सामान्य कार्यान्वयन है

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

इसे इस तरह से कॉल करें:

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

4
यह भी खूब रही। हमें बस केयरफुल होना है अगर दिए गए एन्यूमरेशन वैल्यू एक संयोजन (द्वारा अनुमत FlagsAttribute) है। इस मामले में, enumeration.GetType().GetMember(enumeration.ToString())[0]विफल हो जाएगा।
रिमियो

सबसे छोटा आप लिख सकते हैं: value.GetType().GetField(value.ToString()).GetCustomAttributes(false).OfType<T>‌​().SingleOrDefault()लेकिन अपना स्पष्ट तरीका स्वीकार करना बेहतर है।
नवफाल

2
मैं सार्वजनिक स्थैतिक स्ट्रिंग GetDescription (यह Enum enumeration) {वापसी enumeration.GetAttributeValue <DescriptionAttribute, स्ट्रिंग> (x => x.Description) भी जोड़ता हूं; } इस तरह से अपने लक्ष्य।
मार्ककिग्रीनवे

65

मैंने उत्तर के एक जोड़े को थोड़ा और अधिक विलक्षण समाधान बनाने के लिए यहाँ मिला दिया है। मैं इसे भविष्य में किसी और के लिए उपयोगी होने पर प्रदान कर रहा हूँ। मूल पोस्टिंग यहाँ

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

}

यह समाधान Enum पर विस्तार विधियों की एक जोड़ी बनाता है। पहले आपको अपने मूल्य से जुड़ी किसी भी विशेषता को पुनः प्राप्त करने के लिए प्रतिबिंब का उपयोग करने की अनुमति देता है। दूसरा विशेष रूप से कॉल पुनर्प्राप्त करता है DescriptionAttributeऔर इसका Descriptionमूल्य है।

एक उदाहरण के रूप में, DescriptionAttributeसे विशेषता का उपयोग करने पर विचार करें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
}

उपरोक्त एक्सटेंशन विधि का उपयोग करने के लिए, आप अब बस निम्नलिखित कॉल करेंगे:

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

या

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

अंतिम पंक्ति पर, आपका मतलब है "एट्रिब्यूशन। डिस्क्रिप्शन"? वापसी विशेषता == अशक्त? value.ToString (): विशेषता। विवरण;
जेसन मार्तजया

2
मुझे यह समाधान पसंद है, लेकिन इसमें एक बग है। GetAttribute विधि मानती है कि Enum मान में विवरण विशेषता है और इसलिए जब विशेषता लंबाई 0. होती है तो अपवाद छोड़ देता है। "Return (T) विशेषताएँ [0] बदलें;" "वापसी के साथ (विशेषताएँ। गति> 0;? (टी) विशेषताएँ [0]: अशक्त);"
साइमन गिमर

@SimonGymer सुझाव के लिए धन्यवाद - मैंने तदनुसार अपडेट किया है। :)
ट्रॉय अल्फोर्ड

38

एडमक्रॉफोर्ड प्रतिक्रिया के अलावा , मैंने और अधिक विशिष्ट विस्तार विधियां बनाई हैं जो विवरण प्राप्त करने के लिए इसे फीड करती हैं।

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

इसलिए, विवरण प्राप्त करने के लिए, आप या तो मूल एक्सटेंशन विधि का उपयोग कर सकते हैं

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

या आप विस्तार विधि को यहाँ कह सकते हैं:

string desc = myEnumVariable.GetAttributeDescription();

जो उम्मीद है कि आपके कोड को थोड़ा और पठनीय बनाना चाहिए।


16

धाराप्रवाह एक लाइनर ...

यहाँ मैं उपयोग कर रहा हूँ DisplayAttributeजिसमें गुण Nameऔर Descriptionगुण दोनों हैं।

public static DisplayAttribute GetDisplayAttributesFrom(this Enum enumValue, Type enumType)
{
    return enumType.GetMember(enumValue.ToString())
                   .First()
                   .GetCustomAttribute<DisplayAttribute>();
}

उदाहरण

public enum ModesOfTransport
{
    [Display(Name = "Driving",    Description = "Driving a car")]        Land,
    [Display(Name = "Flying",     Description = "Flying on a plane")]    Air,
    [Display(Name = "Sea cruise", Description = "Cruising on a dinghy")] Sea
}

void Main()
{
    ModesOfTransport TransportMode = ModesOfTransport.Sea;
    DisplayAttribute metadata = TransportMode.GetDisplayAttributesFrom(typeof(ModesOfTransport));
    Console.WriteLine("Name: {0} \nDescription: {1}", metadata.Name, metadata.Description);
}

उत्पादन

Name: Sea cruise 
Description: Cruising on a dinghy

2
मैं भी इसका उपयोग करता हूं, यह सभी उत्तरों में सबसे साफ है! +1
माफिया

यह काफी उपयोगी प्रतीत होता है! Thnx
इरफ

7

यहाँ एक प्रदर्शन विशेषता से जानकारी प्राप्त करने के लिए कोड है। यह विशेषता को पुनः प्राप्त करने के लिए एक सामान्य विधि का उपयोग करता है। यदि विशेषता नहीं पाया जाता है यह धर्मान्तरित पास्कल / ऊंट मामले के साथ एक स्ट्रिंग के लिए enum मूल्य शीर्षक केस में परिवर्तित (कोड प्राप्त यहाँ )

public static class EnumHelper
{
    // Get the Name value of the Display attribute if the   
    // enum has one, otherwise use the value converted to title case.  
    public static string GetDisplayName<TEnum>(this TEnum value)
        where TEnum : struct, IConvertible
    {
        var attr = value.GetAttributeOfType<TEnum, DisplayAttribute>();
        return attr == null ? value.ToString().ToSpacedTitleCase() : attr.Name;
    }

    // Get the ShortName value of the Display attribute if the   
    // enum has one, otherwise use the value converted to title case.  
    public static string GetDisplayShortName<TEnum>(this TEnum value)
        where TEnum : struct, IConvertible
    {
        var attr = value.GetAttributeOfType<TEnum, DisplayAttribute>();
        return attr == null ? value.ToString().ToSpacedTitleCase() : attr.ShortName;
    }

    /// <summary>
    /// Gets an attribute on an enum field value
    /// </summary>
    /// <typeparam name="TEnum">The enum type</typeparam>
    /// <typeparam name="T">The type of the attribute you want to retrieve</typeparam>
    /// <param name="value">The enum value</param>
    /// <returns>The attribute of type T that exists on the enum value</returns>
    private static T GetAttributeOfType<TEnum, T>(this TEnum value)
        where TEnum : struct, IConvertible
        where T : Attribute
    {

        return value.GetType()
                    .GetMember(value.ToString())
                    .First()
                    .GetCustomAttributes(false)
                    .OfType<T>()
                    .LastOrDefault();
    }
}

और यह शीर्षक मामले में बदलने के लिए तार के लिए विस्तार विधि है:

    /// <summary>
    /// Converts camel case or pascal case to separate words with title case
    /// </summary>
    /// <param name="s"></param>
    /// <returns></returns>
    public static string ToSpacedTitleCase(this string s)
    {
        //https://stackoverflow.com/a/155486/150342
        CultureInfo cultureInfo = Thread.CurrentThread.CurrentCulture;
        TextInfo textInfo = cultureInfo.TextInfo;
        return textInfo
           .ToTitleCase(Regex.Replace(s, 
                        "([a-z](?=[A-Z0-9])|[A-Z](?=[A-Z][a-z]))", "$1 "));
    }

4

मैंने इस विस्तार पद्धति को लागू किया ताकि एनम मूल्यों से विवरण प्राप्त किया जा सके। यह सभी तरह के एनम के लिए काम करता है।

public static class EnumExtension
{
    public static string ToDescription(this System.Enum value)
    {
        FieldInfo fi = value.GetType().GetField(value.ToString());
        var attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
        return attributes.Length > 0 ? attributes[0].Description : value.ToString();
    }
}

एक ही समाधान का सामान्य संस्करण पहले से ही पोस्ट किया गया है। इमो, बेहतर।
नवाफल

4

Enum से शब्दकोश प्राप्त करें।

public static IDictionary<string, int> ToDictionary(this Type enumType)
{
    return Enum.GetValues(enumType)
    .Cast<object>()
    .ToDictionary(v => ((Enum)v).ToEnumDescription(), k => (int)k); 
}

अब इस तरह से कॉल करें ...

var dic = typeof(ActivityType).ToDictionary();

EnumDecription Ext विधि

public static string ToEnumDescription(this Enum en) //ext method
{
    Type type = en.GetType();
    MemberInfo[] memInfo = type.GetMember(en.ToString());
    if (memInfo != null && memInfo.Length > 0)
    {
        object[] attrs = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
        if (attrs != null && attrs.Length > 0)
            return ((DescriptionAttribute)attrs[0]).Description;
    }
    return en.ToString();
}

public enum ActivityType
{
    [Description("Drip Plan Email")]
    DripPlanEmail = 1,
    [Description("Modification")]
    Modification = 2,
    [Description("View")]
    View = 3,
    [Description("E-Alert Sent")]
    EAlertSent = 4,
    [Description("E-Alert View")]
    EAlertView = 5
}

3

यहाँ एडम। क्रॉफर्ड के जवाब का .NET कोर संस्करण है, System.Reflection.TypeExtensions का उपयोग कर ;

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>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());
        IEnumerable<Attribute> attributes = memInfo[0].GetCustomAttributes(typeof(T), false);
        return (T)attributes?.ToArray()[0];
    }
}

मुझे विश्वास नहीं है कि .NET कोर (या बल्कि, अभी स्टैंडर्ड) में गेटमेयर है इसलिए मुझे यकीन नहीं है कि यह कैसे काम करेगा।
जेफ

यह System.Reflection.TypeExtensions में है, मैंने इसे सूचीबद्ध करने के लिए अपने उत्तर को संशोधित किया है।
जीत

1
गोचर, धन्यवाद। मुझे लगा कि प्ले में कुछ एक्सटेंशन हो सकते हैं।
जेफ

3

नेट फ्रेमवर्क और नेटकोर के लिए मेरा समाधान जोड़ना।

मैंने इसे अपने नेट फ्रेमवर्क कार्यान्वयन के लिए उपयोग किया है:

public static class EnumerationExtension
{
    public static string Description( this Enum value )
    {
        // get attributes  
        var field = value.GetType().GetField( value.ToString() );
        var attributes = field.GetCustomAttributes( typeof( DescriptionAttribute ), false );

        // return description
        return attributes.Any() ? ( (DescriptionAttribute)attributes.ElementAt( 0 ) ).Description : "Description Not Found";
    }
}

यह NetCore के लिए काम नहीं करता है इसलिए मैंने इसे करने के लिए इसे संशोधित किया:

public static class EnumerationExtension
{
    public static string Description( this Enum value )
    {
        // get attributes  
        var field = value.GetType().GetField( value.ToString() );
        var attributes = field.GetCustomAttributes( false );

        // Description is in a hidden Attribute class called DisplayAttribute
        // Not to be confused with DisplayNameAttribute
        dynamic displayAttribute = null;

        if (attributes.Any())
        {
            displayAttribute = attributes.ElementAt( 0 );
        }

        // return description
        return displayAttribute?.Description ?? "Description Not Found";
    }
}

गणना उदाहरण:

public enum ExportTypes
{
    [Display( Name = "csv", Description = "text/csv" )]
    CSV = 0
}

या तो स्थिर के लिए नमूना उपयोग जोड़ा गया:

var myDescription = myEnum.Description();

2

कुछ नई C # भाषा सुविधाओं का लाभ उठाते हुए, आप लाइन की संख्या को कम कर सकते हैं:

public static TAttribute GetEnumAttribute<TAttribute>(this Enum enumVal) where TAttribute : Attribute
{
    var memberInfo = enumVal.GetType().GetMember(enumVal.ToString());
    return memberInfo[0].GetCustomAttributes(typeof(TAttribute), false).OfType<TAttribute>().FirstOrDefault();
}

public static string GetEnumDescription(this Enum enumValue) => enumValue.GetEnumAttribute<DescriptionAttribute>()?.Description ?? enumValue.ToString();

2

मैं एक शानदार विशेषताओं से एक कॉम्बो बॉक्स सेटअप करने के लिए यह उत्तर देता हूं जो बहुत अच्छा था।

फिर मुझे रिवर्स कोड करने की आवश्यकता थी ताकि मैं बॉक्स से चयन प्राप्त कर सकूं और सही प्रकार से एनम को वापस कर सकूं।

मैंने उस मामले को संभालने के लिए कोड को भी संशोधित किया जहां एक विशेषता गायब थी

अगले व्यक्ति के लाभों के लिए, यहां मेरा अंतिम समाधान है

public static class Program
{
   static void Main(string[] args)
    {
       // display the description attribute from the enum
       foreach (Colour type in (Colour[])Enum.GetValues(typeof(Colour)))
       {
            Console.WriteLine(EnumExtensions.ToName(type));
       }

       // Get the array from the description
       string xStr = "Yellow";
       Colour thisColour = EnumExtensions.FromName<Colour>(xStr);

       Console.ReadLine();
    }

   public enum Colour
   {
       [Description("Colour Red")]
       Red = 0,

       [Description("Colour Green")]
       Green = 1,

       [Description("Colour Blue")]
       Blue = 2,

       Yellow = 3
   }
}

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

        // check if no attributes have been specified.
        if (((Array)attributes).Length > 0)
        {
            return (T)attributes[0];
        }
        else
        {
            return 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;
    }

    /// <summary>
    /// Find the enum from the description attribute.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="desc"></param>
    /// <returns></returns>
    public static T FromName<T>(this string desc) where T : struct
    {
        string attr;
        Boolean found = false;
        T result = (T)Enum.GetValues(typeof(T)).GetValue(0);

        foreach (object enumVal in Enum.GetValues(typeof(T)))
        {
            attr = ((Enum)enumVal).ToName();

            if (attr == desc)
            {
                result = (T)enumVal;
                found = true;
                break;
            }
        }

        if (!found)
        {
            throw new Exception();
        }

        return result;
    }
}

}


1
यार मैंने बहुत सारे बेवकूफ और अस्पष्टीकृत समाधान देखे हैं, और तुम्हारा इसे मार दिया है। बहुत बहुत धन्यवाद <3
काज

2

यदि आपके enumमूल्य में ऐसा होता है जैसे Equalsआप यहां बहुत से उत्तरों में कुछ एक्सटेंशन का उपयोग करके कुछ बगों में टकरा सकते हैं। ऐसा इसलिए है क्योंकि यह आम तौर पर माना जाता है कि typeof(YourEnum).GetMember(YourEnum.Value)केवल एक ही मूल्य होगा, जो कि MemberInfoआपका है enum। यहां एडम क्रॉफर्ड का जवाब थोड़ा सुरक्षित है ।

public static class AttributeExtensions
{
    #region Methods

    public static T GetAttribute<T>(this Enum enumValue) where T : Attribute
    {
        var type = enumValue.GetType();
        var memberInfo = type.GetMember(enumValue.ToString());
        var member = memberInfo.FirstOrDefault(m => m.DeclaringType == type);
        var attribute = Attribute.GetCustomAttribute(member, typeof(T), false);
        return attribute is T ? (T)attribute : null;
    }

    #endregion
}

1

यह एक्सटेंशन विधि अपने XmlEnumAttribute का उपयोग करके एक एनम मान का एक स्ट्रिंग प्रतिनिधित्व प्राप्त करेगी। यदि कोई XmlEnumAttribute मौजूद नहीं है, तो यह enum.ToString () में वापस आ जाता है।

public static string ToStringUsingXmlEnumAttribute<T>(this T enumValue)
    where T: struct, IConvertible
{
    if (!typeof(T).IsEnum)
    {
        throw new ArgumentException("T must be an enumerated type");
    }

    string name;

    var type = typeof(T);

    var memInfo = type.GetMember(enumValue.ToString());

    if (memInfo.Length == 1)
    {
        var attributes = memInfo[0].GetCustomAttributes(typeof(System.Xml.Serialization.XmlEnumAttribute), false);

        if (attributes.Length == 1)
        {
            name = ((System.Xml.Serialization.XmlEnumAttribute)attributes[0]).Name;
        }
        else
        {
            name = enumValue.ToString();
        }
    }
    else
    {
        name = enumValue.ToString();
    }

    return name;
}

1

और अगर आप नामों की पूरी सूची चाहते हैं तो आप कुछ ऐसा कर सकते हैं

typeof (PharmacyConfigurationKeys).GetFields()
        .Where(x => x.GetCustomAttributes(false).Any(y => typeof(DescriptionAttribute) == y.GetType()))
        .Select(x => ((DescriptionAttribute)x.GetCustomAttributes(false)[0]).Description);

0

दोस्तों अगर यह मदद करता है तो मैं आपके साथ अपना समाधान साझा करूंगा: कस्टम विशेषता की परिभाषा:

    [AttributeUsage(AttributeTargets.Field,AllowMultiple = false)]
public class EnumDisplayName : Attribute
{
    public string Name { get; private set; }
    public EnumDisplayName(string name)
    {
        Name = name;
    }
}

अब क्योंकि मुझे HtmlHelper एक्सटेंशन की HtmlHelper परिभाषा के अंदर इसकी आवश्यकता थी:

public static class EnumHelper
{
    public static string EnumDisplayName(this HtmlHelper helper,EPriceType priceType)
    {
        //Get every fields from enum
        var fields = priceType.GetType().GetFields();
        //Foreach field skipping 1`st fieldw which keeps currently sellected value
        for (int i = 0; i < fields.Length;i++ )
        {
            //find field with same int value
            if ((int)fields[i].GetValue(priceType) == (int)priceType)
            {
                //get attributes of found field
                var attributes = fields[i].GetCustomAttributes(false);
                if (attributes.Length > 0)
                {
                    //return name of found attribute
                    var retAttr = (EnumDisplayName)attributes[0];
                    return retAttr.Name;
                }
            }
        }
        //throw Error if not found
        throw new Exception("Błąd podczas ustalania atrybutów dla typu ceny allegro");
    }
}

आशा है ये मदद करेगा


0
    public enum DataFilters
    {
        [Display(Name= "Equals")]
        Equals = 1,// Display Name and Enum Name are same 
        [Display(Name= "Does Not Equal")]
        DoesNotEqual = 2, // Display Name and Enum Name are different             
    }

अब यह इस मामले में त्रुटि पैदा करेगा 1 "बराबर"

public static string GetDisplayName(this Enum enumValue)
    {
        var enumMember = enumValue.GetType().GetMember(enumValue.ToString()).First();
        return enumMember.GetCustomAttribute<DisplayAttribute>() != null ? enumMember.GetCustomAttribute<DisplayAttribute>().Name : enumMember.Name;
    }

इसलिए यदि यह प्रदर्शन नाम के बजाय एक ही रिटर्न एनम नाम है क्योंकि enumMember.GetCustomAttribute () शून्य हो जाता है अगर डिस्प्लेनाम और एनम नाम समान हैं .....


0

वैकल्पिक रूप से, आप निम्न कार्य कर सकते हैं:

List<SelectListItem> selectListItems = new List<SelectListItem>();

    foreach (var item in typeof(PaymentTerm).GetEnumValues())
    {
        var type = item.GetType();
        var name = type.GetField(item.ToString()).GetCustomAttributesData().FirstOrDefault()?.NamedArguments.FirstOrDefault().TypedValue.Value.ToString();
        selectListItems.Add(new SelectListItem(name, type.Name));

    }

0

यह कैसे मैंने .NET हेल्प 3.1 के साथ कस्टम हेल्पर्स या एक्सटेंशन का उपयोग किए बिना इसे हल किया है।

कक्षा

public enum YourEnum
{
    [Display(Name = "Suryoye means Arameans")]
    SURYOYE = 0,
    [Display(Name = "Oromoye means Syriacs")]
    OROMOYE = 1,
}

उस्तरा

@using Enumerations

foreach (var name in Html.GetEnumSelectList(typeof(YourEnum)))
{
    <h1>@name.Text</h1>
}

1
इस सवाल का जवाब देने पर विचार करें कि आपने 'इसे' को कैसे हल किया है - समस्या को स्वीकार करने और यह समझने के लिए कि आप इसे 'कैसे हल करते हैं' से शुरू करते हैं। याद रखें कि आपका उत्तर अब से कुछ वर्षों में संदर्भ से बाहर हो सकता है और तब यह लगभग बेकार हो जाएगा। इसे और जोड़ना, कुछ संदर्भ जोड़ना आपके उत्तर और इसके संभावित ऐतिहासिक / अभिलेखीय प्रासंगिकता को
बढ़ा देगा

0

प्रदर्शन मायने रखता है

यदि आप बेहतर प्रदर्शन चाहते हैं तो यह रास्ता है:

public static class AdvancedEnumExtensions
{
    /// <summary>
    /// Gets the custom attribute <typeparamref name="T"/> for the enum constant, if such a constant is defined and has such an attribute; otherwise null.
    /// </summary>
    public static T GetCustomAttribute<T>(this Enum value) where T : Attribute
    {
        return GetField(value)?.GetCustomAttribute<T>(inherit: false);
    }

    /// <summary>
    /// Gets the FieldInfo for the enum constant, if such a constant is defined; otherwise null.
    /// </summary>
    public static FieldInfo GetField(this Enum value)
    {
        ulong u64 = ToUInt64(value);
        return value
            .GetType()
            .GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static)
            .Where(f => ToUInt64(f.GetRawConstantValue()) == u64)
            .FirstOrDefault();
    }

    /// <summary>
    /// Checks if an enum constant is defined for this enum value
    /// </summary>
    public static bool IsDefined(this Enum value)
    {
        return GetField(value) != null;
    }

    /// <summary>
    /// Converts the enum value to UInt64
    /// </summary>
    public static ulong ToUInt64(this Enum value) => ToUInt64((object)value);

    private static ulong ToUInt64(object value)
    {
        switch (Convert.GetTypeCode(value))
        {
            case TypeCode.SByte:
            case TypeCode.Int16:
            case TypeCode.Int32:
            case TypeCode.Int64:
                return unchecked((ulong)Convert.ToInt64(value, CultureInfo.InvariantCulture));

            case TypeCode.Byte:
            case TypeCode.UInt16:
            case TypeCode.UInt32:
            case TypeCode.UInt64:
            case TypeCode.Char:
            case TypeCode.Boolean:
                return Convert.ToUInt64(value, CultureInfo.InvariantCulture);

            default: throw new InvalidOperationException("UnknownEnumType");
        }
    }
}

इसका प्रदर्शन बेहतर क्यों है?

क्योंकि बिल्ट-इन मेथड्स कोड के समान ही उपयोग करते हैं, सिवाय इसके कि वे अन्य कोड का एक समूह भी चलाते हैं जिनकी हमें परवाह नहीं है । C # का Enum कोड सामान्य रूप से काफी भयानक है।

उपरोक्त कोड Linq-ified और सुव्यवस्थित किया गया है, इसलिए इसमें केवल वे बिट्स होते हैं जिनकी हम परवाह करते हैं।

अंतर्निहित कोड धीमा क्यों है?

सबसे पहले Enum.ToString () -vs- Enum.GetName (..) के बारे में

हमेशा बाद का उपयोग करें। (या बेहतर अभी तक न तो, जैसा कि नीचे स्पष्ट हो जाएगा।)

ToString () आंतरिक रूप से उत्तरार्द्ध का उपयोग करता है, लेकिन फिर से, अन्य सामानों का एक गुच्छा भी करता है जो हम नहीं चाहते हैं, उदाहरण के लिए झंडे को जोड़ने की कोशिश करता है, संख्याओं का प्रिंट आउट करता है आदि हम केवल एनम के अंदर परिभाषित स्थिरांक में रुचि रखते हैं।

Enum.GetName बदले में सभी फ़ील्ड प्राप्त करता है, सभी नामों के लिए एक स्ट्रिंग ऐरे बनाता है, उपरोक्त सभी TOUInt64 का उपयोग करता है अपने सभी RawConstantValues ​​पर सभी मानों का एक UInt64 सरणी बनाने के लिए, दोनों ऐरे को UInt64 मान के अनुसार क्रमबद्ध करता है, और अंत में नाम प्राप्त करता है। नाम-सरणी हमें UInt64-array में एक बाइनरीसर्च करके उस मान के सूचकांक को खोजने के लिए करता है जिसे हम चाहते थे।

... और फिर हम खेतों को फेंक देते हैं और हल किए गए सरणियों को उस नाम का उपयोग करके फिर से फ़ील्ड ढूंढते हैं।

एक शब्द: "उघ!"


-1

वैकल्पिक रूप से, आप निम्न कार्य कर सकते हैं:

Dictionary<FunkyAttributesEnum, string> description = new Dictionary<FunkyAttributesEnum, string>()
    {
      { FunkyAttributesEnum.NameWithoutSpaces1, "Name With Spaces1" },
      { FunkyAttributesEnum.NameWithoutSpaces2, "Name With Spaces2" },
    };

और निम्नलिखित के साथ विवरण प्राप्त करें:

string s = description[FunkyAttributesEnum.NameWithoutSpaces1];

मेरी राय में यह वह करने का एक अधिक कुशल तरीका है जिसे आप पूरा करना चाहते हैं, क्योंकि किसी भी प्रतिबिंब की आवश्यकता नहीं है।


2
ज़रूर, लेकिन प्रतिबिंब लगभग उतना बुरा नहीं है जितना लोग इसे बनाते हैं।
ब्रायन रोवे

यह बुरा नहीं है - मैं इसे हर समय उपयोग करता हूं। यह अक्सर अनावश्यक रूप से उपयोग किया जाता है, हालांकि। :)
इयान पी

44
यह समाधान कम से कम दो बड़ी समस्याओं का निर्माण करते हुए, विवरण को एनम से दूर ले जाता है। सबसे पहले, अगर कोई नया एनम स्थिरांक जोड़ता है, तो उन्हें प्रवेश करने के लिए इस दूसरी जगह पर जाने के लिए भी जानना होगा। विशेषताएँ एक स्पष्ट संकेत हैं कि उन्हें क्या करने की आवश्यकता है। इसके साथ मेरी दूसरी समस्या यह है कि यह अभी बहुत अधिक कोड है। विशेषताएँ कॉम्पैक्ट हैं।
scobi

1
@scott लेकिन यह आपको अपना ऑर्डर निर्दिष्ट करने देता है, और उन मूल्यों को बाहर नहीं करता है जिन्हें आप प्रदर्शित नहीं करना चाहते हैं, जो लगभग हमेशा वही होता है जो मैं वास्तव में चाहता हूं
Simon_Weaver

-2

आप एक enum मान को भी परिभाषित कर सकते हैं Name_Without_Spaces, और जब आप Name_Without_Spaces.ToString().Replace('_', ' ')रिक्त स्थान के साथ अंडरस्कोर को बदलने के लिए विवरण का उपयोग करना चाहते हैं ।


8
यह एक बहुत ही अशुभ उपाय है। @ ब्रायन द्वारा दिए गए समाधान का उपयोग करने पर विचार करें
जोहान
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.