ব্যবহারকারী বান্ধব স্ট্রিং সহ এনাম টোস্ট্রিং


282

আমার এনাম নিম্নলিখিত মানগুলি নিয়ে গঠিত:

private enum PublishStatusses{
    NotCompleted,
    Completed,
    Error
};

যদিও আমি এই মানগুলিকে ব্যবহারকারীর উপযোগী করে আউটপুট করতে সক্ষম হতে চাই।
আমার আবার স্ট্রিং থেকে মান পর্যন্ত যেতে সক্ষম হওয়ার দরকার নেই।



উত্তর:


350

আমি Descriptionসিস্টেমটি থেকে উপাদানটি ব্যবহার করি omp কম্পোনেন্টমোডেল নেমস্পেস। সহজভাবে enum সাজাইয়া:

private enum PublishStatusValue
{
    [Description("Not Completed")]
    NotCompleted,
    Completed,
    Error
};

তারপরে এটি পুনরুদ্ধার করতে এই কোডটি ব্যবহার করুন:

public static string GetDescription<T>(this T enumerationValue)
    where T : struct
{
    Type type = enumerationValue.GetType();
    if (!type.IsEnum)
    {
        throw new ArgumentException("EnumerationValue must be of Enum type", "enumerationValue");
    }

    //Tries to find a DescriptionAttribute for a potential friendly name
    //for the enum
    MemberInfo[] memberInfo = type.GetMember(enumerationValue.ToString());
    if (memberInfo != null && memberInfo.Length > 0)
    {
        object[] attrs = memberInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);

        if (attrs != null && attrs.Length > 0)
        {
            //Pull out the description value
            return ((DescriptionAttribute)attrs[0]).Description;
        }
    }
    //If we have no description attribute, just return the ToString of the enum
    return enumerationValue.ToString();
}

12
এই উদাহরণটি পড়তে সহজ। stackoverflow.com/questions/1415140/...
RayLoveless

31
আমি সন্দেহ করি যে এই সমাধানে বর্ণিত প্রতিবিম্বটি ব্যবহার করার জন্য একটি উল্লেখযোগ্য পারফরম্যান্স হিট হয়েছে। উইফ এর টোফ্রেন্ডলিস্ট্রিং এক্সটেনশন পদ্ধতিটি ব্যবহারের পদ্ধতির কোডটি বোঝা অনেক সহজ এবং এর কার্য সম্পাদনও অত্যন্ত দ্রুত হওয়া উচিত।
হাম্বাদগুলি

1
আমি @RayL এর সাথে সংযুক্ত সংস্করণটি পছন্দ করি এটি কেবল এনামগুলিতে এক্সটেনশন পদ্ধতি যুক্ত করবে। আপনি যদি ArgumentException
এটির জন্যই

4
এর অর্থ এই নয় যে প্রতিটি এনামের নিজস্ব সম্প্রসারণ পদ্ধতি প্রয়োজন। এটি আরও সাধারণ ব্যবহার এবং আরও বেশি কাজ প্রয়োজন, তবে আমরা সম্ভবত কার্য সম্পাদন সিদ্ধান্ত নেওয়ার আগে আপনি "দ্রুত" অর্থ কী তা বোঝাতে চান।
রায় বুয়সেন

2
@ পেটার যা কাজ করে তবে আপনি ব্যবহারকারীদের কাছে বন্ধুত্বপূর্ণ স্ট্রিংগুলি প্রদর্শন করতে চান তা নয়। MY_TYPE এর আন্ডারস্কোর থাকবে এবং কাস্টমাইজযোগ্য নয়।
রায় বুয়েসন

354

আমি এটি এক্সটেনশন পদ্ধতি দিয়ে করি:

public enum ErrorLevel
{
  None,
  Low,
  High,
  SoylentGreen
}

public static class ErrorLevelExtensions
{
  public static string ToFriendlyString(this ErrorLevel me)
  {
    switch(me)
    {
      case ErrorLevel.None:
        return "Everything is OK";
      case ErrorLevel.Low:
        return "SNAFU, if you know what I mean.";
      case ErrorLevel.High:
        return "Reaching TARFU levels";
      case ErrorLevel.SoylentGreen:
        return "ITS PEOPLE!!!!";
      default:
        return "Get your damn dirty hands off me you FILTHY APE!";
    }
  }
}

6
এটি অ্যাট্রিবিউট উত্তরের চেয়ে অনেক বেশি পরিষ্কার। নিস!
পেনিরাভ

3
@ স্পেনেরভে: এহ। প্রচুর ইউআই উপাদানগুলি ডিসপ্লে-নেমঅ্যাট্রিবিউট এবং ডেসক্রিপশনএট্রিবিউট খুঁজে পেতে এবং ব্যবহার করার প্রত্যাশা করে। আসলে, এখন, আমি সহজেই সেইগুলি মানগুলি বের করতে এগুলি এবং একটি এক্সটেনশন পদ্ধতি ব্যবহার করি।

60
এটির সাথে আমি যে সমস্যাটি দেখছি তা হ'ল আপনি ক্রমাগত এই এক্সটেনশন পদ্ধতিগুলি লিখছেন। অ্যাট্রিবিউট মেকানিজম সহ এটি সজ্জিত করার এক সহজ উপায় এবং কেবলমাত্র একটি পদ্ধতি কল করার জন্য।
রে বুয়সেন

5
আপনি কি বোঝাতে চেয়েছেন তা নিশ্চিত না?
রায় বুয়সেন

9
আমার মতে, defaultকেস বাস্তবায়নের ফিরে আসার অনুমতি দেওয়া me.ToString()এবং আপনি যে এনাম মানগুলিকে ওভাররাইড করতে চান তার জন্য কেবল স্যুইচ কেস স্টেটমেন্ট সরবরাহ করে। আপনার উদাহরণে, আমি পেয়েছি যে এগুলি সমস্ত আলাদা কিন্তু বাস্তব ব্যবহারের ক্ষেত্রে, আমি সন্দেহ করি যে বেশিরভাগ একক-শব্দ এনাম মানগুলি যথেষ্ট হবে এবং আপনি কেবলমাত্র বহু-শব্দ এনাম মানগুলির জন্য ওভাররাইড সরবরাহ করবেন be
স্কট

78

হয়তো আমি কিছু মিস করছি, তবে এনাম.গেটনামের সাথে কী হয়েছে?

public string GetName(PublishStatusses value)
{
    return Enum.GetName(typeof(PublishStatusses), value)
}

সম্পাদনা: ব্যবহারকারী-বান্ধব স্ট্রিংয়ের জন্য, আন্তর্জাতিকীকরণ / স্থানীয়করণের জন্য আপনাকে একটি উত্সের মধ্য দিয়ে যেতে হবে এবং এনাম কী-এর উপর ভিত্তি করে একটি নির্দিষ্ট কী ব্যবহার করা তত্ক্ষণাতিকভাবে ডেকরেটার বৈশিষ্ট্যের চেয়ে ভাল হবে।


12
আমি এনামের আক্ষরিক মানটি ফিরিয়ে দিই, কিছু ব্যবহারকারী বান্ধব নয়।
বরিস কলেনস

2
ও - ভাল, তবে এই মানটির উপর ভিত্তি করে আপনাকে স্ট্রিং রিসোর্স লাইব্রেরিটি পেরোতে হবে এমন একটি চমত্কার বড় কেস আছে, কারণ বিকল্প (ডেকোরেটর প্রাপ্তি) I18N সমর্থন করবে না
অনাকাঙ্কা

1
আই 18 এন এর ক্ষেত্রে আমি একটি অনুবাদিত স্ট্রিংয়ের জন্য উত্স লিবিতে গেটডেস্ক্রিপশন () পদ্ধতি অনুসন্ধান করব এবং বিবরণে ফিরে এসে আবার আক্ষরিক হয়ে পড়ব।
বরিস কলেনস

3
স্থানীয়করণের জন্য রিসোর্স কী হিসাবে MyEnum.ToString () এর জন্য +1। আমি বছরের পর বছর ধরে এটি করছি
জ্যাকভিসওয়ার্ল্ড

1
@ নানকাতা আমরা আসলে এল 18 এন এর সমর্থন অন্তর্ভুক্ত করার জন্য অ্যাট্রিবিউট প্রক্রিয়াটি প্রসারিত করেছি, এটি আসলে একটি সাধারণ পরিবর্তন simple
রায় বুয়সেন

23

আমি বিবরণটিকে এনাম মূল্যে রূপান্তর করতে একটি বিপরীত এক্সটেনশন পদ্ধতি তৈরি করেছি:

public static T ToEnumValue<T>(this string enumerationDescription) where T : struct
{
    var type = typeof(T);

    if (!type.IsEnum)
        throw new ArgumentException("ToEnumValue<T>(): Must be of enum type", "T");

    foreach (object val in System.Enum.GetValues(type))
        if (val.GetDescription<T>() == enumerationDescription)
            return (T)val;

    throw new ArgumentException("ToEnumValue<T>(): Invalid description for enum " + type.Name, "enumerationDescription");
}

15
আমি দুঃখিত, তবে সাহায্য করার চেষ্টা করার জন্য ধন্যবাদ! যদিও এটি একটি প্রশ্নোত্তর সাইট, উত্তরগুলি সরাসরি প্রশ্নের উত্তর দেওয়ার চেষ্টা করা উচিত । এবং প্রশ্নটি সুনির্দিষ্টভাবে বলেছে যে " আমার আবার স্ট্রিং থেকে আবার মানতে সক্ষম হওয়ার দরকার নেই " "আবারও, ধন্যবাদ!
জেসি

8
ইতিবাচক সমালোচনার জন্য ধন্যবাদ। কোনও সাইটে নতুন হওয়া এবং এর সংস্কৃতি এবং সংক্ষিপ্তসারগুলি সম্পর্কে শিখতে সবসময়ই সমস্যা। আমি খুশি যে আপনার মতো লোক যারা নতুন ছেলেদের সোজা করেছিলেন set আবারও, নতুন লোকটিকে না ছড়িয়ে দেওয়ার জন্য ধন্যবাদ।
ব্রায়ান রিচার্ডসন

6
@ জেসি এবং 4 বছর পরে কেউ এখানে বিরিচার্ডসন কোড পেয়ে খুশি! সুতরাং একটি প্রশ্নোত্তর সাইট হতে পারে, তবে এর অর্থ এই নয় যে উত্তরগুলি দেওয়ার পরে প্রশ্নগুলি মারা গেছে।
জন

18

এখানে সবচেয়ে সহজ সমাধানটি হ'ল একটি কাস্টম এক্সটেনশন পদ্ধতি ব্যবহার করা (অন্তত .NET 3.5 এ - আপনি কেবল এটি পূর্ববর্তী ফ্রেমওয়ার্ক সংস্করণগুলির জন্য একটি স্ট্যাটিক সহায়ক পদ্ধতিতে রূপান্তর করতে পারেন)।

public static string ToCustomString(this PublishStatusses value)
{
    switch(value)
    {
        // Return string depending on value.
    }
    return null;
}

আমি এখানে ধরে নিচ্ছি যে আপনি এনাম মানের প্রকৃত নাম (যা আপনি কেবল টস্ট্রিং কল করে পেতে পারেন) ব্যতীত অন্য কোনও কিছু ফিরিয়ে দিতে চান।


বৈধ হওয়া সত্ত্বেও, আমি বৈশিষ্ট্যটি আরও পছন্দ করি। এইভাবে আমি আমার টস্ট্রিং পদ্ধতিটি একটি পৃথক লাইব্রেরিতে রাখতে পারি, যখন এনামের সাথে কাস্টম স্ট্রিংয়ের উপস্থাপনা রাখি
বরিস কলেনস

1
যথেষ্ট ফর্সা। আমি মনে করি এই পদ্ধতির একটি সুবিধা হ'ল আপনি কোনও স্টেটের ভেরিয়েবল নির্দিষ্ট করে দেওয়ার পদ্ধতিটির সাথে একটি যুক্তি অন্তর্ভুক্ত করতে পারেন এবং তারপরে স্ট্রিং প্রতিনিধিত্বটি কীভাবে ফিরে আসে তা পরিবর্তন করতে পারেন।
নলডোরিন

1
হ্যাঁ, এগুলি সমস্তই আমার অনুমান পদ্ধতিটির স্কোপের উপর নির্ভর করে। অ্যাট্রিবিউট উপায়টি আরও জেনেরিক হলেও আপনার সমাধানটি আরও স্থানীয়ীকৃত It's শেষ পর্যন্ত এটি সমস্ত প্রয়োজন।
বরিস কলেনস

1
আপনি যে কোনও জায়গায় এক্সটেনশন পদ্ধতি রাখতে পারেন। আপনি কেবল সেগুলি ব্যবহার করতে চান যেখানে এটি উল্লেখ করতে হবে।

হ্যাঁ, তবে এর অর্থ হ'ল প্রতিবারই যখন আপনি একটি নতুন এনাম পরিচয় করিয়েছেন তার জন্য বন্ধুত্বপূর্ণ নাম রাখতে চান তখন এই একটি এক্সটেনশন পদ্ধতিটি আবার লিখতে হবে। এর অর্থ হ'ল আপনার সমস্ত অ্যাপ্লিকেশনগুলি আপনার অন্যান্য সমস্ত অ্যাপ্লিকেশনগুলির জন্য বন্ধুত্বপূর্ণ নামের বহন করবে ...
বরিস কলেনস

13

সেই অন্যান্য পোস্টটি জাভা। আপনি Enums এ সি # তে পদ্ধতি স্থাপন করতে পারবেন না।

এই জাতীয় কিছু করুন:

PublishStatusses status = ...
String s = status.ToString();

আপনি যদি আপনার এনাম মানগুলির জন্য পৃথক ডিসপ্লে মান ব্যবহার করতে চান তবে আপনি বৈশিষ্ট্য এবং প্রতিবিম্ব ব্যবহার করতে পারেন।


3
টাস্টস্ট্রিং সব ক্ষেত্রেই নিরাপদ নয় - একই মান সহ একাধিক এন্ট্রি সহ একটি এনাম (পূর্ণসংখ্যার এনামগুলির জন্য বলুন) পরীক্ষিত আইটেমটির কীটি নয়, প্রথম মিলনের মানটির কীটি ফিরিয়ে দেবে, এ কারণেই এনাম.গেটনামকে অগ্রাধিকার দেওয়া হয়
অন্নাকাটা

4
আচ্ছা, এটি তার নির্দিষ্ট এনামের সবচেয়ে সহজ সমাধান ছিল
লেএমি

9

সবচেয়ে সহজ উপায় হ'ল এই প্রসারণ ক্লাসটি আপনার প্রকল্পের অন্তর্ভুক্ত করা, এটি প্রকল্পের যে কোনও এনামের সাথে কাজ করবে:

public static class EnumExtensions
{
    public static string ToFriendlyString(this Enum code)
    {
        return Enum.GetName(code.GetType(), code);
    }
}

ব্যবহার:

enum ExampleEnum
{
    Demo = 0,
    Test = 1, 
    Live = 2
}

...

ExampleEnum ee = ExampleEnum.Live;
Console.WriteLine(ee.ToFriendlyString());

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

12
যদি এনামের নাম ইতিমধ্যে সুন্দরভাবে দেওয়া থাকে তবে কোনও এক্সটেনশন পদ্ধতির দরকার নেই। কেবলমাত্র বিদ্যমান টস্ট্রিং () পদ্ধতিটি ব্যবহার করুন। string result = "Result: " + ee;
জন

এটি সেরা উত্তর হওয়া উচিত। এটি কোনও এনামের জন্য কাজ করে। এমনকি আপনি এটি ব্যবহার করতে পারবেন এমন নির্দিষ্ট এনাম ব্যবহার করে প্রকৃত এনামকে যে প্রকৃত এনাম ব্যবহার করতে হবে তার প্যারামিটারের পরিবর্তন করে।
জুয়ানু হায়দো

6
এই উত্তর এবং সমস্ত মন্তব্য বর্ধিত বিবরণের জন্য মূল অনুরোধটিকে উপেক্ষা করে। আপনি ছেলেরা ব্যায়ামটি পুরোপুরি মিস করেছেন যা ডিফল্ট টোস্ট্রিংয়ের মান বাদে অন্য কোনও কিছু ফেরত দেওয়া। আমি এই উত্তরের জন্য সমস্ত নোট এখানে কমিয়ে দেবো না তবে আমি নিশ্চিত তা চাই।
টনিজি

8

শ্রেণি / রেফারেন্সের ধরণগুলি এড়ানো এমন আরও কয়েকটি প্রাথমিক বিকল্প:

  • অ্যারে পদ্ধতি
  • নেস্টেড স্ট্রাক্ট পদ্ধতি

অ্যারে পদ্ধতি

private struct PublishStatusses
{
    public static string[] Desc = {
        "Not Completed",
        "Completed",
        "Error"
    };

    public enum Id
    {
        NotCompleted = 0,
        Completed,
        Error
    };
}

ব্যবহার

string desc = PublishStatusses.Desc[(int)PublishStatusses.Id.Completed];

নেস্টেড স্ট্রাক্ট পদ্ধতি

private struct PublishStatusses
{
    public struct NotCompleted
    {
        public const int Id = 0;
        public const string Desc = "Not Completed";
    }

    public struct Completed
    {
        public const int Id = 1;
        public const string Desc = "Completed";
    }

    public struct Error
    {
        public const int Id = 2;
        public const string Desc = "Error";
    }            
}

ব্যবহার

int id = PublishStatusses.NotCompleted.Id;
string desc = PublishStatusses.NotCompleted.Desc;

আপডেট (03/09/2018)

এক্সটেনশন পদ্ধতিগুলির একটি সংকর এবং উপরে প্রথম কৌশল technique

আমি এনামগুলিকে সংজ্ঞায়িত করতে পছন্দ করি যেখানে তারা "অন্তর্গত" (তাদের উত্সের উত্সের নিকটতম এবং কিছু সাধারণ, বিশ্বব্যাপী নেমস্পেসে নয়)।

namespace ViewModels
{
    public class RecordVM
    {
        //public enum Enum { Minutes, Hours }
        public struct Enum
        {
            public enum Id { Minutes, Hours }
            public static string[] Name = { "Minute(s)", "Hour(s)" };
        }
    }
}

এক্সটেনশন পদ্ধতিটি একটি সাধারণ অঞ্চলের জন্য উপযুক্ত বলে মনে হয় এবং এনামের "স্থানীয়করণ" সংজ্ঞাটি এখন এক্সটেনশন পদ্ধতিটিকে আরও ভার্জিক করে তোলে।

namespace Common
{
    public static class EnumExtensions
    {
        public static string Name(this RecordVM.Enum.Id id)
        {
            return RecordVM.Enum.Name[(int)id];
        }
    }   
}

এনাম এবং এটির এক্সটেনশন পদ্ধতির ব্যবহারের উদাহরণ।

namespace Views
{
    public class RecordView 
    {
        private RecordDataFieldList<string, string> _fieldUnit;

        public RecordView()
        {
            _fieldUnit.List = new IdValueList<string, string>
            {            
                new ListItem<string>((int)RecordVM.Enum.Id.Minutes, RecordVM.Enum.Id.Minutes.Name()),
                new ListItem<string>((int)RecordVM.Enum.Id.Hours, RecordVM.Enum.Id.Hours.Name())
            };
        }

        private void Update()
        {    
            RecordVM.Enum.Id eId = DetermineUnit();

            _fieldUnit.Input.Text = _fieldUnit.List.SetSelected((int)eId).Value;
        }
    }
}

দ্রষ্টব্য: আমি প্রকৃতপক্ষে Enumমোড়কটি (এবং Nameঅ্যারে) মুছে ফেলার সিদ্ধান্ত নিয়েছি , যেহেতু নামের স্ট্রিংগুলি হার্ড-কোডেড না হয়ে কোনও উত্স (যেমন কনফিগারেশন ফাইল বা ডিবি) থেকে আসে এবং কারণ আমি এক্সটেনশন পদ্ধতিটি শেষ করেছিলাম ViewModelsনেমস্পেস (কেবল একটি আলাদা, "কমনভিএম.cs" ফাইলের মধ্যে)। প্লাস পুরো .Idজিনিস বিভ্রান্তিকর এবং জটিল হয়ে ওঠে।

namespace ViewModels
{
    public class RecordVM
    {
        public enum Enum { Minutes, Hours }
        //public struct Enum
        //{
        //    public enum Id { Minutes, Hours }
        //    public static string[] Name = { "Minute(s)", "Hour(s)" };
        //}
    }
}

CommonVM.cs

//namespace Common
namespace ViewModels
{
    public static class EnumExtensions
    {
        public static string Name(this RecordVM.Enum id)
        {
            //return RecordVM.Enum.Name[(int)id];
            switch (id)
            {
                case RecordVM.Enum.Minutes: return "Minute(s)";                    
                case RecordVM.Enum.Hours: return "Hour(s)";
                default: return null;
            }
        }
    }   
}

এনাম এবং এটির এক্সটেনশন পদ্ধতির ব্যবহারের উদাহরণ।

namespace Views
{
    public class RecordView 
    {
        private RecordDataFieldList<string, string> _fieldUnit

        public RecordView()
        {
            _fieldUnit.List = new IdValueList<string, string>
            {            
                new ListItem<string>((int)RecordVM.Enum.Id.Minutes, RecordVM.Enum.Id.Minutes.Name()),
                new ListItem<string>((int)RecordVM.Enum.Id.Hours, RecordVM.Enum.Id.Hours.Name())
            };
        }

        private void Update()
        {    
            RecordVM.Enum eId = DetermineUnit();

            _fieldUnit.Input.Text = _fieldUnit.List.SetSelected((int)eId).Value;
        }
    }
}

+ 1-1 = 0 ভোট: এই সমাধানটি এনাম সিনট্যাক্স সংরক্ষণ করে এবং প্রতিচ্ছবি বা জটিল কোড ছাড়াই সমস্যাটি সুন্দরভাবে সমাধান করে, সুতরাং +1 করে। তবে এটি এনামদের নিজস্ব বৈশিষ্ট্য হারায়। সুতরাং যখন আইএমও এটি একটি ভাল বিকল্প, এটি প্রকৃত প্রশ্নের উত্তর দেয় না এবং একটি -1 পায়। নেট 0 দুঃখিত, আমাদের কাছে এসওতে এটি আরও ভাল রেকর্ড করার উপায় নেই।
টনিজি

@ টনিজি ফেয়ার যথেষ্ট। প্লুয়ারলাইটলাইট.কম এর নেট নেট এসেসমেন্টে কয়েকটি প্রশ্ন মিস করার পরে আমি বুঝতে পারলাম যে সি # এনুমের গভীরতা কতটা, তাই কোন পদ্ধতি প্রয়োগ করা উচিত (বিশেষত বিস্তৃত ব্যবহারের জন্য, রিফ্যাক্টরিং) সিদ্ধান্ত নেওয়ার আগে কমপক্ষে তাদের দক্ষতা সম্পর্কে জানা ভাল idea কিছুটা সময় হতে পারে;)।
সামিস

7

হিউম্যানাইজ এনামস সম্ভাব্যতার সাথে আপনি হিউম্যানাইজার প্যাকেজ ব্যবহার করতে পারেন । একটি নিদর্শন:

enum PublishStatusses
{
    [Description("Custom description")]
    NotCompleted,
    AlmostCompleted,
    Error
};

তারপরে আপনি Humanizeসরাসরি এনামে এক্সটেনশন পদ্ধতিটি ব্যবহার করতে পারেন :

var st1 = PublishStatusses.NotCompleted;
var str1 = st1.Humanize(); // will result in Custom description

var st2 = PublishStatusses.AlmostCompleted;
var str2 = st2.Humanize(); // will result in Almost completed (calculated automaticaly)

এটি পাশাপাশি প্রতিবিম্ব ব্যবহার করে এবং ক্যাশে হয় না। github.com/Humanizr/ Humanizer
Konrad

এটি প্রথম উত্তরে সমাধানের মতো ধীর হয়ে যাবে রায়
কনরাড

5

রায় বোয়েনের প্রতি শ্রদ্ধা জানায়, কোডটিতে একটি বাগ রয়েছে: ব্যবহারকারী বান্ধব স্ট্রিং সহ এনাম টসস্ট্রিং

এনাম মানগুলিতে আপনাকে একাধিক বৈশিষ্ট্যের জন্য অ্যাকাউন্ট করতে হবে।

public static string GetDescription<T>(this object enumerationValue)
            where T : struct
    {
        Type type = enumerationValue.GetType();
        if (!type.IsEnum)
        {
            throw new ArgumentException("EnumerationValue must be of Enum type", "enumerationValue");
        }

        //Tries to find a DescriptionAttribute for a potential friendly name
        //for the enum
        MemberInfo[] memberInfo = type.GetMember(enumerationValue.ToString());
        if (memberInfo != null && memberInfo.Length > 0)
        {
            object[] attrs = memberInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);

            if (attrs != null && attrs.Length > 0 && attrs.Where(t => t.GetType() == typeof(DescriptionAttribute)).FirstOrDefault() != null)
            {
                //Pull out the description value
                return ((DescriptionAttribute)attrs.Where(t=>t.GetType() == typeof(DescriptionAttribute)).FirstOrDefault()).Description;
            }
        }
        //If we have no description attribute, just return the ToString of the enum
        return enumerationValue.ToString();

4
একাধিক বর্ণনা বৈশিষ্ট্যের জন্য একটি চেক বাদ দেওয়া উদ্দেশ্য অনুসারে। যদি এনামের দুটি থাকে এবং আপনি বিবরণ উত্পন্ন করতে ব্যবহার করছেন তবে আমি ভাবতে চাই যে এটি ব্যতিক্রমী পরিস্থিতি। আমি মনে করি যে আসল বাগটি কোনও ব্যতিক্রম ছোঁড়ার জন্য আমি একটি সিঙ্গল () না করি। অন্যথায় পুরো পদ্ধতিটির স্বাক্ষর কোনও অর্থ দেয় না। GetDescription ()? কোন বর্ণনা? সমষ্টি?
রায় বুয়সেন

4
public enum MyEnum
{
    [Description("Option One")]
    Option_One
}

public static string ToDescriptionString(this Enum This)
{
    Type type = This.GetType();

    string name = Enum.GetName(type, This);

    MemberInfo member = type.GetMembers()
        .Where(w => w.Name == name)
        .FirstOrDefault();

    DescriptionAttribute attribute = member != null
        ? member.GetCustomAttributes(true)
            .Where(w => w.GetType() == typeof(DescriptionAttribute))
            .FirstOrDefault() as DescriptionAttribute
        : null;

    return attribute != null ? attribute.Description : name;
}

3
এটি কেন কাজ করা উচিত এবং কেন ওপি'র হয়নি কেন তা ব্যাখ্যা করে কিছু লেখা লিখতে সবসময় সুন্দর।
ফেব্রেস্ট

শুধু এফওয়াইআই, সি # কোড কনভেনশনগুলি লোয়ার কেসের প্রাথমিক চিঠির সাথে স্থানীয় ভেরিয়েবল এবং পদ্ধতি পরামিতি চায়। একটি ব্যতিক্রম হ'ল thisএক্সটেনশন পদ্ধতিগুলির পরামিতি, যা আপনি Thisওয়েবে বিভিন্ন উদাহরণে ডাকা দেখতে পারেন । এটিকে এর ধরণের মতো কল করা যেমন আপনি করেছেন ( Enum Enum) কোডটি কম পাঠযোগ্য।
ম্যাসিমিলিয়ানো ক্রাউস

4

এনাম ব্যবহারের পরিবর্তে একটি স্ট্যাটিক ক্লাস ব্যবহার করুন।

প্রতিস্থাপন করা

private enum PublishStatuses{
    NotCompleted,
    Completed,
    Error
};

সঙ্গে

private static class PublishStatuses{
    public static readonly string NotCompleted = "Not Completed";
    public static readonly string Completed = "Completed";
    public static readonly string Error = "Error";
};

এটি এভাবে ব্যবহার করা হবে

PublishStatuses.NotCompleted; // "Not Completed"

শীর্ষ "এক্সটেনশন পদ্ধতি" সমাধানগুলি ব্যবহার করে ইস্যু করুন:

একটি ব্যক্তিগত এনাম প্রায়শই অন্য শ্রেণীর অভ্যন্তরে ব্যবহৃত হয়। এক্সটেনশন পদ্ধতির সমাধানটি বৈধ নয় কারণ এটি অবশ্যই নিজের শ্রেণিতে থাকতে হবে। এই সমাধানটি ব্যক্তিগত এবং অন্য শ্রেণিতে এম্বেড করা যেতে পারে।


2

আমি ভিবি.এনইটি ফ্যান হতে পারি, সুতরাং আমার সংস্করণটি এখানে একটি এক্সটেনশন পদ্ধতির সাথে বর্ণনাঅ্যাট্রিবিউট পদ্ধতির সাথে সংযুক্ত করে দেওয়া হয়েছে। প্রথম, ফলাফল:

Imports System.ComponentModel ' For <Description>

Module Module1
  ''' <summary>
  ''' An Enum type with three values and descriptions
  ''' </summary>
  Public Enum EnumType
    <Description("One")>
    V1 = 1

    ' This one has no description
    V2 = 2

    <Description("Three")>
    V3 = 3
  End Enum

  Sub Main()
    ' Description method is an extension in EnumExtensions
    For Each v As EnumType In [Enum].GetValues(GetType(EnumType))
      Console.WriteLine("Enum {0} has value {1} and description {2}",
        v,
        CInt(v),
        v.Description
      )
    Next
    ' Output:
    ' Enum V1 has value 1 and description One
    ' Enum V2 has value 2 and description V2
    ' Enum V3 has value 3 and description Three
  End Sub
End Module

বেসিক স্টাফ: এনাম টাইপ নামে একটি এনাম, যার তিনটি মান ভি 1, ভি 2 এবং ভি 3 রয়েছে। "ম্যাজিক" উপ প্রধান Console.WriteLine কল (), যেখানে গত যুক্তি সহজভাবে হয় এরকম v.Description। এটি ভি 1 এর জন্য "ওয়ান", ভি 2 এর জন্য "ভি 2" এবং ভি 3 এর জন্য "তিন" প্রদান করে। এই বর্ণনা-পদ্ধতিটি আসলে একটি এক্সটেনশন পদ্ধতি যা এনিউম এক্সটেনশন নামে পরিচিত অন্য মডিউলে সংজ্ঞায়িত:

Option Strict On
Option Explicit On
Option Infer Off

Imports System.Runtime.CompilerServices
Imports System.Reflection
Imports System.ComponentModel

Module EnumExtensions
  Private _Descriptions As New Dictionary(Of String, String)

  ''' <summary>
  ''' This extension method adds a Description method
  ''' to all enum members. The result of the method is the
  ''' value of the Description attribute if present, else
  ''' the normal ToString() representation of the enum value.
  ''' </summary>
  <Extension>
  Public Function Description(e As [Enum]) As String
    ' Get the type of the enum
    Dim enumType As Type = e.GetType()
    ' Get the name of the enum value
    Dim name As String = e.ToString()

    ' Construct a full name for this enum value
    Dim fullName As String = enumType.FullName + "." + name

    ' See if we have looked it up earlier
    Dim enumDescription As String = Nothing
    If _Descriptions.TryGetValue(fullName, enumDescription) Then
      ' Yes we have - return previous value
      Return enumDescription
    End If

    ' Find the value of the Description attribute on this enum value
    Dim members As MemberInfo() = enumType.GetMember(name)
    If members IsNot Nothing AndAlso members.Length > 0 Then
      Dim descriptions() As Object = members(0).GetCustomAttributes(GetType(DescriptionAttribute), False)
      If descriptions IsNot Nothing AndAlso descriptions.Length > 0 Then
        ' Set name to description found
        name = DirectCast(descriptions(0), DescriptionAttribute).Description
      End If
    End If

    ' Save the name in the dictionary:
    _Descriptions.Add(fullName, name)

    ' Return the name
    Return name
  End Function
End Module

যেহেতু বর্ণন বৈশিষ্ট্যগুলি ব্যবহার করে খোঁজ করা Reflectionধীর, তাই অনুসন্ধানগুলি একটি প্রাইভেটেও ক্যাশে করা হয় Dictionaryযা চাহিদা অনুসারে জনপ্রিয়।

(ভিবি.এনইটি সমাধানের জন্য দুঃখিত - এটি সি # তে অনুবাদ করার জন্য তুলনামূলকভাবে সোজা হওয়া উচিত এবং আমার সি # এক্সটেনশনের মতো নতুন বিষয়গুলিতে জোরালো)


2

নমুনা সহ উপরের পরামর্শগুলির পরিষ্কার সংক্ষিপ্তসার:

namespace EnumExtensions {

using System;
using System.Reflection;

public class TextAttribute : Attribute {
   public string Text;
   public TextAttribute( string text ) {
      Text = text;
   }//ctor
}// class TextAttribute

public static class EnumExtender {

public static string ToText( this Enum enumeration ) {

   MemberInfo[] memberInfo = enumeration.GetType().GetMember( enumeration.ToString() );

   if ( memberInfo != null && memberInfo.Length > 0 ) {

      object[] attributes = memberInfo[ 0 ].GetCustomAttributes( typeof(TextAttribute),  false );

      if ( attributes != null && attributes.Length > 0 ) {
         return ( (TextAttribute)attributes[ 0 ] ).Text;
      }

   }//if

   return enumeration.ToString();

}//ToText

}//class EnumExtender

}//namespace

ব্যবহার:

using System;
using EnumExtensions;

class Program {

public enum Appearance {

  [Text( "left-handed" ) ]
  Left,

  [Text( "right-handed" ) ]
  Right,

}//enum

static void Main( string[] args ) {

   var appearance = Appearance.Left;
   Console.WriteLine( appearance.ToText() );

}//Main

}//class

1
সি # তে একটি [বিবরণ ("")] বৈশিষ্ট্য রয়েছে, কেন এটি ব্যবহার করছেন না?
স্টেফান কোয়েন

অবশ্যই [বিবরণ ("")] ব্যবহার করা একটি উপায়। তবে আমি চেয়েছিলাম যে নমুনাটি সম্পূর্ণ হোক।
আন্ডারস্কোর 22

2

এনাম.গেটনাম ব্যবহার করুন

উপরের লিঙ্ক থেকে ...

using System;

public class GetNameTest {
    enum Colors { Red, Green, Blue, Yellow };
    enum Styles { Plaid, Striped, Tartan, Corduroy };

    public static void Main() {

        Console.WriteLine("The 4th value of the Colors Enum is {0}", Enum.GetName(typeof(Colors), 3));
        Console.WriteLine("The 4th value of the Styles Enum is {0}", Enum.GetName(typeof(Styles), 3));
    }
}
// The example displays the following output:
//       The 4th value of the Colors Enum is Yellow
//       The 4th value of the Styles Enum is Corduroy

2

এই ডকুমেন্টেশন অনুসারে: https://docs.microsoft.com/pt-br/dotnet/api/system.enum.tostring?view=netframework-4.8

এই জাতীয় ফর্ম্যাট ব্যবহার করে কেবল একজন গণককে স্ট্রিংয়ে রূপান্তর করা সম্ভব:

public enum Example
{
    Example1,
    Example2
}

Console.WriteLine(Example.Example1.ToString("g"));

//Outputs: "Example1"

আপনি এই লিঙ্কে সমস্ত সম্ভাব্য ফর্ম্যাটগুলি দেখতে পাবেন: https://docs.microsoft.com/pt-br/dotnet/api/system.string?view=netframework-4.8


1

এটি রে বুয়সেনের কোডের একটি আপডেট যা জিনিসগুলি আরও পরিপাটি করে তুলতে জেনেরিক গেটকাস্টমঅ্যাট্রিবিউটস পদ্ধতি এবং লিনিকিউ ব্যবহার করে।

    /// <summary>
    /// Gets the value of the <see cref="T:System.ComponentModel.DescriptionAttribute"/> on an struct, including enums.  
    /// </summary>
    /// <typeparam name="T">The type of the struct.</typeparam>
    /// <param name="enumerationValue">A value of type <see cref="T:System.Enum"/></param>
    /// <returns>If the struct has a Description attribute, this method returns the description.  Otherwise it just calls ToString() on the struct.</returns>
    /// <remarks>Based on http://stackoverflow.com/questions/479410/enum-tostring/479417#479417, but useful for any struct.</remarks>
    public static string GetDescription<T>(this T enumerationValue) where T : struct
    {
        return enumerationValue.GetType().GetMember(enumerationValue.ToString())
                .SelectMany(mi => mi.GetCustomAttributes<DescriptionAttribute>(false),
                    (mi, ca) => ca.Description)
                .FirstOrDefault() ?? enumerationValue.ToString();
    }   

আপনার জেনেরিক হওয়ার প্রয়োজন কেন তা ব্যর্থ হচ্ছে? আপনি যদি প্রতিবিম্ব ব্যবহার করতে যাচ্ছেন?
লি লুভিয়ের

@ লিউলভিয়ার প্রধানত বক্সিংটি এড়ানোর জন্য যখন স্ট্রাক্ট (মানের ধরণ) প্যারামিটার হিসাবে পাস হয়।
রিচার্ড অ্যান্টনি হেইন

1
পরিবর্তে সংখ্যার মূল্য। গেটটাইপ () ব্যবহার: টাইপফ (টি)।
স্লাভা

1
(ওয়াইএমএমভি) পঠনযোগ্যতা হারানো ছাড়াই গৃহীত উত্তরের চেয়ে বিশাল এক-লাইন উন্নতি। হ্যাঁ, টাইপফোর (টি) সহ
টনিজি

1

এমনকি ক্লিনার সংক্ষিপ্তসার:

using System;
using System.Reflection;

public class TextAttribute : Attribute
{
    public string Text;
    public TextAttribute(string text)
    {
        Text = text;
    }
}  

public static class EnumExtender
{
    public static string ToText(this Enum enumeration)
    {
        var memberInfo = enumeration.GetType().GetMember(enumeration.ToString());
        if (memberInfo.Length <= 0) return enumeration.ToString();

        var attributes = memberInfo[0].GetCustomAttributes(typeof(TextAttribute), false);
        return attributes.Length > 0 ? ((TextAttribute)attributes[0]).Text : enumeration.ToString();
    }
}

আন্ডারস্কোর বর্ণিত হিসাবে একই ব্যবহার।


0

সহ এনগম ফ্ল্যাগের জন্য।

    public static string Description(this Enum value)
    {
        Type type = value.GetType();

        List<string> res = new List<string>();
        var arrValue = value.ToString().Split(',').Select(v=>v.Trim());
        foreach (string strValue in arrValue)
        {
            MemberInfo[] memberInfo = type.GetMember(strValue);
            if (memberInfo != null && memberInfo.Length > 0)
            {
                object[] attrs = memberInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);

                if (attrs != null && attrs.Length > 0 && attrs.Where(t => t.GetType() == typeof(DescriptionAttribute)).FirstOrDefault() != null)
                {
                    res.Add(((DescriptionAttribute)attrs.Where(t => t.GetType() == typeof(DescriptionAttribute)).FirstOrDefault()).Description);
                }
                else
                    res.Add(strValue);
            }
            else
                res.Add(strValue);
        }

        return res.Aggregate((s,v)=>s+", "+v);
    }

0

আপনি যদি কেবল শব্দের মধ্যে একটি সাদা জায়গা যুক্ত করতে চান তবে এটি সহজ

string res = Regex.Replace(PublishStatusses.NotCompleted, "[A-Z]", " $0").Trim();

0

আমি এনাম / বিবরণ জোড়া এবং বিবরণ পেতে একটি নেস্টেড সহায়ক শ্রেণি সঞ্চয় করার জন্য একটি জেনেরিক ক্লাস ব্যবহার করি।

enum :

enum Status { Success, Fail, Pending }

জেনেরিক শ্রেণি:

দ্রষ্টব্য: যেহেতু জেনেরিক ক্লাসটি এনাম দ্বারা সীমাবদ্ধ করা যায় না আমি তার পরিবর্তে স্ট্রাক্ট দ্বারা বাধা দিচ্ছি এবং কনস্ট্রাক্টরের এনামের জন্য পরীক্ষা করছি ।

public class EnumX<T> where T : struct
{
    public T Code { get; set; }
    public string Description { get; set; }

    public EnumX(T code, string desc)
    {
        if (!typeof(T).IsEnum) throw new NotImplementedException();

        Code = code;
        Description = desc;
    }

    public class Helper
    {
        private List<EnumX<T>> codes;

        public Helper(List<EnumX<T>> codes)
        {
            this.codes = codes;
        }

        public string GetDescription(T code)
        {
            EnumX<T> e = codes.Where(c => c.Code.Equals(code)).FirstOrDefault();
            return e is null ? "Undefined" : e.Description;
        }
    }
}

ব্যবহার:

EnumX<Status>.Helper StatusCodes = new EnumX<Status>.Helper(new List<EnumX<Status>>()
        {
            new EnumX<Status>(Status.Success,"Operation was successful"),
            new EnumX<Status>(Status.Fail,"Operation failed"),
            new EnumX<Status>(Status.Pending,"Operation not complete. Please wait...")
        });

        Console.WriteLine(StatusCodes.GetDescription(Status.Pending));

-2

আমি মনে করি আপনার সমস্যা সমাধানের সর্বোত্তম (এবং সবচেয়ে সহজ) উপায় হ'ল আপনার এনামের জন্য একটি এক্সটেনশন-পদ্ধতি লিখুন:

public static string GetUserFriendlyString(this PublishStatusses status)
    {

    }

1
কেউ 7 বছর আগে ছিল যে
স্টিভেন

-3

আপনি যদি পুরোপুরি অনুকূলিতযোগ্য কিছু চান তবে আমার সমাধানটি এখানে চেষ্টা করে দেখুন:

http://www.kevinwilliampang.com/post/Mapping-Enums-To-Strings-and-Strings-to-Enums-in-NET.aspx

মূলত, পোস্টটি আপনার প্রতিটি এনামের সাথে বর্ণনা বৈশিষ্ট্যগুলি কীভাবে সংযুক্ত করতে হবে এবং এনাম থেকে বর্ণনায় মানচিত্রের একটি জেনেরিক উপায় সরবরাহ করে।


1
এবং এখন সাইট ডাউন আছে।
নিক ফস্টার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.