এনামের মূল্যের বৈশিষ্ট্য পাওয়া


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/...
finnw


2
বর্ণনার জন্য প্রয়োজনীয় নেমস্পেসটি হ'ল সিস্টেম.কম্পোনেন্টমোডেল
জন এম

আপনি কেবল সিস্টেম.কম্পোনমেন্টমোডেল ব্যবহার করতে পারবেন না এবং কেবল নিজের নিজস্ব বৈশিষ্ট্য প্রকারটি ব্যবহার করতে পারেন; সত্যিই বিশেষ কিছু নেই DescriptionAttribute
জুন 8:38 এ 12h

: 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
Allচ্ছিকভাবে সমস্ত স্মৃতি একবারে পাওয়ার জন্য টাইপ.গেটফিল্ডস (বন্ডিংফ্লাগস.পাবলিক | বাইন্ডিংফ্লাগস.স্ট্যাটিক) ব্যবহার করুন।
ট্রুউইল

4
আমাকে টাইপফোন (ফানকিএট্রিবিউটসইনাম) যেতে হয়েছিল, তবে এটির চেয়েও ভাল এটি কাজ করেছিল। ধন্যবাদ।
গ্রেগ র্যান্ডাল

অ্যালেক্সকে আমি দেখতে পাচ্ছি না এনাম ক্লাসের নেম উইথআউটস্পেস 1 সম্পত্তি রয়েছে। FunkyAttributesEnum.NameWithoutSpaces1 কোথা থেকে এসেছে?
ডন

2
@ ডন, এটি ওপির প্রশ্ন থেকে এনাম সদস্যের নাম।
MEMark

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
এরপরে ব্যবহারগুলি হবে: স্ট্রিং desc = myEnumVariable.GetAttributeOfType <বিবরণঅ্যাট্রিবিউট> ()। বিবরণ;
ব্র্যাড রেম

2
আমি স্কট-এর চেয়ে এটিকে আরও পছন্দ করি, কারণ ব্যবহারটি এখানে পরিষ্কার (কম টাইপ করা), সুতরাং +1 :)
নওফাল

3
যদি কোনও অ্যাট্রিবিউট উপস্থিত না থাকে, তবে এটি একটি নিক্ষেপ করবে না IndexOutOfRangeException?
এরিক ফিলিপস 0

6
ম্যানইমফোর জন্য এনামওয়াল হিসাবে টু স্ট্রিং () আলাদাভাবে ব্যবহার করতে পারেন।
লিন সং ইয়াং

2
কল করার মানে কী GetCustomAttributes()তখন কল করার পরিবর্তে প্রথম উপাদানটি পান GetCustomAttribute()?
tigrou

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
আমি পাবলিক স্ট্যাটিক স্ট্রিং গেটডেস্ক্রিপশনও যোগ করি (এই এনুমিউমেশন) {ফেরত গণনা.গেটঅ্যাট্রিবিউটভ্যালু <বিবরণঅ্যাট্রিবিউট, স্ট্রিং> (x => x. বিবরণ); } এইভাবে তার ঠিক টার্গেটলিভেল.গেটডেস্ক্রিপশন ();
মার্ক কেগ্রাইনওয়ে

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

}

এই দ্রষ্টব্য এনামে একজোড়া এক্সটেনশন পদ্ধতি তৈরি করে। প্রথমটি আপনাকে আপনার মানের সাথে সম্পর্কিত কোনও বৈশিষ্ট্য পুনরুদ্ধার করতে প্রতিবিম্বটি ব্যবহার করতে দেয়। দ্বিতীয়টি বিশেষত কলগুলি পুনরুদ্ধার করে 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
আমি এই সমাধানটি পছন্দ করি তবে এটিতে একটি বাগ রয়েছে। গেটএট্রিবিউট পদ্ধতিটি ধরে নিয়েছে যে এনাম মানটির বিবরণ বিশিষ্টতা রয়েছে এবং বৈশিষ্ট্যের দৈর্ঘ্য 0 হলে একটি ব্যতিক্রম ছুঁড়ে ফেলে "রিটার্ন (টি) বৈশিষ্ট্য [0] প্রতিস্থাপন করুন;" "রিটার্ন (গুণাবলী। দৈর্ঘ্য> 0? (টি) বৈশিষ্ট্য [0]: নাল) সহ"
সাইমন গাইমার

@ সিমোনজিমার এই পরামর্শের জন্য ধন্যবাদ - আমি সে অনুযায়ী আপডেট করেছি। :)
ট্রয় অ্যালফোর্ড

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

একটি ডিসপ্লে অ্যাট্রিবিউট থেকে তথ্য পেতে কোড এখানে। এটি বৈশিষ্ট্য পুনরুদ্ধার করতে একটি জেনেরিক পদ্ধতি ব্যবহার করে। যদি বৈশিষ্ট্যটি খুঁজে পাওয়া যায় না তবে এটি এনামুর মানটিকে পাস্কল / উট কেস দিয়ে একটি স্ট্রিংয়ে শিরোনামের ক্ষেত্রে রূপান্তরিত করে (কোডটি এখানে প্রাপ্ত )

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

একই সমাধানের জেনেরিক সংস্করণ ইতিমধ্যে পোস্ট করা হয়েছে। imo, ভাল।
নওফাল

4

এনাম থেকে অভিধান পান।

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

এনামডিক্রিপশন অতিরিক্ত পদ্ধতি

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

এখানে AdamCrawford এর উত্তর .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];
    }
}

আমি বিশ্বাস করি না। নেট কোর (বা বরং এখন স্ট্যান্ডার্ড) এর গেটমেমার রয়েছে সুতরাং আমি নিশ্চিত না যে এটি কীভাবে কাজ করবে।
জেফ

এটি সিস্টেমের মধ্যে রয়েছে efনির্ধারণ.প্রকার এক্সটেনশনগুলি, আমি এটি তালিকাবদ্ধ করতে আমার উত্তরটি সংশোধন করেছি।
Wonea

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

এটি নেটকরের পক্ষে কাজ করে না তাই এটি করার জন্য আমি এটি সংশোধন করেছি:

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

নতুন কয়েকটি সি # ভাষার বৈশিষ্ট্যগুলির সুবিধা নিয়ে আপনি লাইন গণনা হ্রাস করতে পারবেন:

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 উপস্থিত না থাকে তবে এটি এনামে ফিরে যায় T টুস্ট্রিং ()।

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

এইচটিএমএলহেল্পার এক্সটেনশনের এইচটিএমএলহেল্পার সংজ্ঞাটির ভিতরে আমার এটি এখন প্রয়োজন বলে:

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

সুতরাং এটি যদি নামের নামের পরিবর্তে একই রিটার্ন এনাম নাম হয় কারণ এনামমেম্বার.গেটকাস্টমঅ্যাট্রিবিউট () বাতিল হয়ে যায় যদি প্রদর্শনের নাম এবং এনাম নাম একই থাকে .....


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
আপনি কীভাবে 'এটি' সমাধান করেছেন তার চেয়ে বেশি ব্যবহার করে প্রশ্নের উত্তর দেওয়ার কথা বিবেচনা করুন - সমস্যাটি স্বীকার করে এবং এটি কীভাবে 'সমাধান করে' বলে আপনার মনে হয় তা ব্যাখ্যা করে শুরু করুন। মনে রাখবেন আপনার উত্তরটি এখন থেকে কয়েক বছরের মধ্যে প্রসঙ্গের বাইরে নেওয়া যেতে পারে এবং এটি তখন প্রায় অকেজো হয়ে যায়। এটিতে আরও যুক্ত করা, কিছু প্রসঙ্গ যুক্ত করা আপনার উত্তর এবং এর সম্ভাব্য historical
তিহাসিক

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

এটির কেন আরও ভাল পারফরম্যান্স রয়েছে?

কারণ অন্তর্নির্মিত পদ্ধতিগুলিতে সমস্ত কোড এর সাথে খুব একই রকম ব্যবহার করে তবে তারা আমাদের অন্যান্য যত্ন নিয়ে যত্ন নিয়ে নয় এমন অন্যান্য কোডগুলিও চালায় । সি # এর এনুম কোডটি সাধারণভাবে বেশ ভয়ঙ্কর।

উপরের কোডটি লিনাক-আইয়েড এবং প্রবাহিত হয়েছে সুতরাং এতে কেবল আমাদের যত্ন করা বিট রয়েছে।

বিল্ট ইন কোডটি মন্থর কেন?

এনাম.টোস্ট্রিং () -vs- এনাম.গেটনাম (..) সম্পর্কিত প্রথম

সর্বদা পরেরটি ব্যবহার করুন। (বা আরও ভাল, নিচে পরিষ্কার হয়ে যাবে হিসাবে।)

টোস্ট্রিং () উত্তরোত্তরটি অভ্যন্তরীণভাবে ব্যবহার করে, তবে আবারও, আমরা চাই না এমন অন্যান্য জিনিসগুলির একটি গুচ্ছও ব্যবহার করে, যেমন পতাকাগুলি একত্রিত করার চেষ্টা করে, সংখ্যাগুলি প্রিন্ট আউট ইত্যাদি We আমরা কেবল এনামের ভিতরে সংজ্ঞায়িত ধ্রুবকগুলিতে আগ্রহী।

Enum.GetName পরিবর্তে সমস্ত ক্ষেত্র পায়, সমস্ত নামের জন্য একটি স্ট্রিং অ্যারে তৈরি করে, সমস্ত মানগুলির একটি UInt64 অ্যারে তৈরি করতে তাদের সমস্ত RawConstantValues ​​উপরের ToUInt64 ব্যবহার করে, UInt64 মান অনুসারে উভয় অ্যারে সাজিয়ে তোলে এবং শেষ পর্যন্ত নামটি পেয়ে যায় আমরা যে মানটি চেয়েছিলাম তার সূচকটি খুঁজে পেতে UInt64-অ্যারে বাইনারি অনুসন্ধান করে নাম অ্যারে।

... এবং তারপরে আমরা ক্ষেত্রগুলি ছুঁড়ে ফেলেছি এবং সাজানো অ্যারেগুলি আবার ক্ষেত্র সন্ধানের জন্য সেই নামটি ব্যবহার করে।

একটি শব্দ: "উঘ!"


-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
অবশ্যই, তবে প্রতিচ্ছবি প্রায় লোকের মতো খারাপ হয় না it
ব্রায়ান রোয়ে

এটি খারাপ না বলে - আমি এটি সর্বদা ব্যবহার করি। যদিও এটি প্রায়শই অযথা ব্যবহার করা হয়। :)
ইয়ান পি

44
এই সমাধানটি বিবরণটিকে এনাম থেকে দূরে সরিয়ে দেয়, কমপক্ষে দুটি বড় সমস্যা তৈরি করে। প্রথমত, যদি কেউ একটি নতুন এনাম ধ্রুবক যোগ করে, তবে সেখানে এন্ট্রি যুক্ত করতে তাদের এই অন্য জায়গায় যেতে হবে তা জানতে হবে। বৈশিষ্ট্যগুলি তাদের কী করা দরকার তা রক্ষণাবেক্ষণকারীদের একটি স্পষ্ট লক্ষণ। এটির সাথে আমার দ্বিতীয় সমস্যাটি হ'ল এটি আরও অনেক বেশি কোড। বৈশিষ্ট্যগুলি কমপ্যাক্ট হয়।
স্কোবি

1
@ স্কট করুন তবে এটি আপনাকে নিজের আদেশটি নির্দিষ্ট করতে দেয় এবং আপনি যে মানগুলি প্রদর্শন করতে চান না তা বাদ দেয় যা আমি যা চাই তা প্রায় সর্বদা
সাইমন_উইভার

-2

আপনি যেমন একটি এনাম মানটিও সংজ্ঞায়িত করতে পারেন Name_Without_Spacesএবং যখন আপনি একটি বিবরণ ব্যবহার Name_Without_Spaces.ToString().Replace('_', ' ')করে স্পেসগুলি সহ আন্ডারস্কোরগুলি প্রতিস্থাপন করতে পারেন ।


8
এটি একটি খুব অবহেলিত সমাধান। @ ব্রায়ান দ্বারা সরবরাহিত সমাধানটি ব্যবহার করার বিষয়ে বিবেচনা করুন
জোহান
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.