একটি এনুমের স্ট্রিং প্রতিনিধিত্ব


911

আমার নিম্নোক্ত গণনা রয়েছে:

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

তবে সমস্যাটি হ'ল যখন আমি প্রমাণীকরণ মেথড.ফর্মগুলি জিজ্ঞাসা করি তখন আইডি 1 নয়, তবে "ফর্মস" শব্দটি প্রয়োজন।

আমি এই সমস্যার ( লিঙ্ক ) নীচের সমাধান পেয়েছি :

প্রথমে আমাকে "স্ট্রিংভ্যালু" নামে একটি কাস্টম অ্যাট্রিবিউট তৈরি করতে হবে:

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

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

    public string Value
    {
        get { return _value; }
    }

}

তারপরে আমি আমার গুণকের কাছে এই বৈশিষ্ট্যটি যুক্ত করতে পারি:

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

এবং অবশ্যই সেই স্ট্রিংভ্যালুটি পুনরুদ্ধার করার জন্য আমার কিছু দরকার:

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

        //Check first in our cached results...

        //Look for our 'StringValueAttribute' 

        //in the field's custom attributes

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

        return output;
    }
}

ভাল এখন আমি একজন গণকের জন্য স্ট্রিংয়ের মান পাওয়ার সরঞ্জাম পেয়েছি। আমি তখন এটির মতো এটি ব্যবহার করতে পারি:

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

ঠিক আছে এখন এই সমস্ত কাজ কবজির মতো তবে আমি এটি পুরোপুরি কাজ দেখতে পাই। আমি ভাবছিলাম যে এর জন্য আরও ভাল সমাধান আছে কিনা।

আমি অভিধান এবং স্থিতিশীল বৈশিষ্ট্যগুলির সাথেও কিছু চেষ্টা করেছি তবে এটিও ভাল ছিল না।


8
নিস! আমি এনাম মানগুলিকে স্থানীয়ীকৃত স্ট্রিংয়ে অনুবাদ করতে এটি ব্যবহার করতে পারি।
vyvind Skaar

5
আপনি এই দীর্ঘ বয়ে যাওয়া দেখতে পাবেন, অন্য জিনিস জন্য এটি আসলে একটি বেশ নমনীয় উপায়। আমার এক সহকর্মী নির্দিষ্ট, এই অনেক ক্ষেত্রে ব্যবহার করা যেতে পারে Enum সাহায্যকারী প্রতিস্থাপন যে মানচিত্র ডাটাবেসের কোড মান enum করতে ইত্যাদি ...
BenAlabaster

27
এমএসডিএন প্রত্যয় গুণাবলী "অ্যাট্রিবিউট" প্রত্যয় সহ পাঠ্য প্রত্যাহার করে। সুতরাং "শ্রেণি স্ট্রিংভ্যালুঅ্যাট্রিবিউট";)
সেরিও

14
আমি @ বেনাব্লাবাস্টারের সাথে একমত, এটি আসলে বেশ নমনীয়। এছাড়াও, আপনি আপনার স্থিতিশীল পদ্ধতিতে কেবল thisসামনে রেখে এটি একটি এক্সটেনশন পদ্ধতি তৈরি করতে পারেন Enum। তারপরে আপনি এটি করতে পারেন AuthenticationMethod.Forms.GetStringValue();
জাস্টিন পিহনি

5
এই পদ্ধতির বৈশিষ্ট্যের মানগুলি পড়তে প্রতিবিম্বটি ব্যবহার করা হয় এবং যদি আপনি আমার অভিজ্ঞতায় অনেকবার গেটস্ট্রিংভ্যালু () কল করতে হয় তবে এটি খুব ধীরে। টাইপ-সেফ-এনাম প্যাটার্নটি দ্রুত।
আরএন 222

উত্তর:


868

টাইপ-সেফ-এনাম প্যাটার্ন চেষ্টা করুন ।

public sealed class AuthenticationMethod {

    private readonly String name;
    private readonly int value;

    public static readonly AuthenticationMethod FORMS = new AuthenticationMethod (1, "FORMS");
    public static readonly AuthenticationMethod WINDOWSAUTHENTICATION = new AuthenticationMethod (2, "WINDOWS");
    public static readonly AuthenticationMethod SINGLESIGNON = new AuthenticationMethod (3, "SSN");        

    private AuthenticationMethod(int value, String name){
        this.name = name;
        this.value = value;
    }

    public override String ToString(){
        return name;
    }

}

আপডেট স্পষ্ট (বা অন্তর্নিহিত) ধরণের রূপান্তর দ্বারা করা যেতে পারে

  • ম্যাপিংয়ের সাথে স্থির ক্ষেত্র যুক্ত করা হচ্ছে

    private static readonly Dictionary<string, AuthenticationMethod> instance = new Dictionary<string,AuthenticationMethod>();
    • এনবি, "এনাম সদস্য" ক্ষেত্রের সূচনাটি যখন ইনস্ট্রাক্টর কনস্ট্রাক্টরকে কল করার সময় কোনও নালরফেরানএক্সেপশন নিক্ষেপ না করে, আপনার ক্লাসে "এনাম সদস্য" ক্ষেত্রের আগে অভিধান ক্ষেত্রটি স্থাপন করা নিশ্চিত হন। কারণ স্ট্যাটিক ফিল্ড ইনিশিয়ালারদের ডিক্লেয়ারেশন অর্ডারে ডাকা হয় এবং স্ট্যাটিক কনস্ট্রাক্টরের আগে একটি অদ্ভুত এবং প্রয়োজনীয় তবে বিভ্রান্তিকর পরিস্থিতি তৈরি করে যে সকল স্ট্যাটিক ফিল্ড আরম্ভ করার আগে এবং স্ট্যাটিক কনস্ট্রাক্টর বলা হওয়ার আগে উদাহরণ কনস্ট্রাক্টরকে ডাকা যেতে পারে।
  • উদাহরণস্বরূপ নির্মাণকারী এই ম্যাপিং পূরণ

    instance[name] = this;
  • এবং ব্যবহারকারী সংজ্ঞায়িত ধরণের রূপান্তর অপারেটর যুক্ত করা

    public static explicit operator AuthenticationMethod(string str)
    {
        AuthenticationMethod result;
        if (instance.TryGetValue(str, out result))
            return result;
        else
            throw new InvalidCastException();
    }

17
এটি দেখতে এনামের মতো তবে এটি এনুম নয়। আমি ধারণা করতে পারি যে লোকেরা যদি প্রমাণীকরণমাঠগুলির তুলনা করতে শুরু করে তবে কিছু আকর্ষণীয় সমস্যা সৃষ্টি করছে। আপনার সম্ভবত বিভিন্ন সমতা অপারেটরগুলিও ওভারলোড করতে হবে।
পিঁপড়া

36
@ অ্যান্ট: আমার দরকার নেই। যেহেতু আমাদের কাছে প্রতিটি প্রমাণীকরণের একটি মাত্র উদাহরণ রয়েছে মেথডের সাথে রেফারেন্স সমতাটি অবজেক্ট থেকে উত্তরাধিকার সূত্রে কাজ করে।
জাকব Šturc

10
@ ইয়াইটার: সংকলক করেন। কনস্ট্রাক্টর ব্যক্তিগত তাই আপনি নতুন উদাহরণ তৈরি করতে পারবেন না। এছাড়াও স্থির সদস্যদের উদাহরণের মাধ্যমে অ্যাক্সেসযোগ্য নয়।
জাকুব Šturc

21
@ জাকব খুব আকর্ষণীয় এটি কীভাবে ব্যবহার করতে হয় তা নির্ধারণ করতে এবং এর সুবিধাগুলি উপলব্ধি করতে আমাকে এটি খেলতে হয়েছিল। এটি একটি সর্বজনীন, অ স্থির শ্রেণি, তবে তা ইনস্ট্যান্ট করা যাবে না এবং আপনি কেবল এর স্থির সদস্যদের অ্যাক্সেস করতে পারবেন। মূলত, এটি এনামের মতো আচরণ করে। তবে সেরা অংশটি ... স্থির সদস্যরা ক্লাসে টাইপ করা হয় এবং জেনেরিক স্ট্রিং বা ইনট নয়। এটি একটি ... [এটির জন্য অপেক্ষা করুন] ... নিরাপদ এনাম টাইপ করুন! আমাকে বুঝতে সাহায্য করার জন্য ধন্যবাদ।
tyriker

6
@ কিরান আমি নীচে জাকুব urturc এর উত্তরের একটি সামান্য পরিবর্তিত সংস্করণ পোস্ট করেছি যা এটি স্যুইচ-কেস স্টেটমেন্টগুলির সাথে ব্যবহার করতে দেয়, সুতরাং এখন এই পদ্ধতির কোনও খারাপ দিক নেই :)
প্রাণঘাতী

228

পদ্ধতি ব্যবহার করুন

Enum.GetName(Type MyEnumType,  object enumvariable)  

হিসাবে হিসাবে (অনুমান Shipperএকটি সংজ্ঞায়িত এনুম)

Shipper x = Shipper.FederalExpress;
string s = Enum.GetName(typeof(Shipper), x);

এনাম ক্লাসে আরও কিছু স্থিতিশীল পদ্ধতি রয়েছে যা তদন্তেরও দরকার ...


5
যথাযথভাবে। আমি একটি স্ট্রিং বর্ণনার জন্য একটি কাস্টম বৈশিষ্ট্য তৈরি করেছি, তবে এটি কারণ যে আমি একটি ব্যবহারকারী-বান্ধব সংস্করণ চাই (স্পেস এবং অন্যান্য বিশেষ অক্ষর সহ) যা সহজেই একটি কম্বোবক্স বা এর মতো আবদ্ধ হতে পারে।
এলসি

5
এনাম.গেটনাম এনামের মাঠের নামগুলি প্রতিফলিত করে - .ToString () এর মতো। পারফরম্যান্স যদি সমস্যা হয় তবে এটি সমস্যা হতে পারে। আপনি যদিও এ্যামামের ভারে রূপান্তর না করেন তবে আমি এটি নিয়ে চিন্তা করব না।
কিথ

8
আরেকটি বিকল্প বিবেচনার জন্য, যদি আপনার অতিরিক্ত ফান্টিয়্যোনালিটি সহ একটি এনামের প্রয়োজন হয় তবে এটি একটি স্ট্রাক্ট ব্যবহার করে "রোল ইয়ারের নিজস্ব" হয় ... আপনি কাঠামোর পৃথক দৃষ্টান্ত তৈরি করে এমন কনস্ট্রাক্টরগুলিতে শুরু হওয়া এনাম মানগুলিকে উপস্থাপনের জন্য স্ট্যাটিক রিডনলি নামযুক্ত বৈশিষ্ট্য যুক্ত করেন ...
চার্লস ব্রেটানা

1
তারপরে আপনি এই "এনাম" এর যে কোনও কার্যকারিতা চান তা প্রয়োগ করতে আপনি অন্য কাঠামোগত সদস্যদের যুক্ত করতে পারেন ...
চার্লস ব্রেটানা

2
এখানে সমস্যাটি হ'ল getName স্থানীয়করণযোগ্য নয়। এটি সর্বদা উদ্বেগের বিষয় নয়, তবে এটি সচেতন হওয়ার মতো বিষয়।
জোয়েল কোহোর্ন

79

আপনি ToString () ব্যবহার করে মানের চেয়ে নামটি উল্লেখ করতে পারেন

Console.WriteLine("Auth method: {0}", AuthenticationMethod.Forms.ToString());

ডকুমেন্টেশন এখানে:

http://msdn.microsoft.com/en-us/library/16c1xs4z.aspx

... এবং যদি আপনি পাস্কাল কেসে আপনার এনামদের নাম দেন (যেমন আমি করি - যেমন এই আইস্মিনিউমালিয়ু = 1 ইত্যাদি) তবে আপনি বন্ধুত্বপূর্ণ ফর্মটি মুদ্রণের জন্য খুব সাধারণ রেজেেক্স ব্যবহার করতে পারেন:

static string ToFriendlyCase(this string EnumString)
{
    return Regex.Replace(EnumString, "(?!^)([A-Z])", " $1");
}

যে কোনও স্ট্রিং থেকে সহজে কল করা যেতে পারে:

Console.WriteLine("ConvertMyCrazyPascalCaseSentenceToFriendlyCase".ToFriendlyCase());

আউটপুট:

আমার ক্রেজি পাস্কল কেস সাজাটিকে বন্ধুত্বপূর্ণ কেসে রূপান্তর করুন

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

আরও জটিল পরিস্থিতিতে যদিও আপনার মূল সমাধানটি আমি পছন্দ করি। আপনি আপনার সমাধানটি আরও একধাপ এগিয়ে নিয়ে যেতে এবং আপনার গেটস্ট্রিংভ্যালুকে আপনার এনামের একটি এক্সটেনশন পদ্ধতিতে পরিণত করতে পারেন এবং তারপরে আপনার স্ট্রিংইনাম.গেটস্ট্রিংভ্যালুর মতো রেফারেন্সের প্রয়োজন হবে না ...

public static string GetStringValue(this AuthenticationMethod value)
{
  string output = null;
  Type type = value.GetType();
  FieldInfo fi = type.GetField(value.ToString());
  StringValue[] attrs = fi.GetCustomAttributes(typeof(StringValue), false) as StringValue[];
  if (attrs.Length > 0)
    output = attrs[0].Value;
  return output;
}

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

Console.WriteLine(AuthenticationMethod.SSO.GetStringValue());

2
"বন্ধুত্বপূর্ণ নাম" এর কোনও জায়গার প্রয়োজন হলে এটি সহায়তা করে না। যেমন "ফর্ম প্রমাণীকরণ"
রে বুয়েন

4
সুতরাং নিশ্চিত হয়ে নিন যে এনামের নাম ফর্মস অ্যাটেন্টিফিকেশনের মতো ক্যাপের সাথে রয়েছে এবং শুরুতে নয় এমন কোনও ক্যাপের আগে একটি স্থান সন্নিবেশ করান। স্ট্রিংয়ের মধ্যে কোনও স্থান in
োকানো

4
পাস্কল কেসের নামের অটো-স্পেসিং সমস্যাযুক্ত হয়ে ওঠে যদি সেগুলিতে সংক্ষিপ্ত বিবরণ থাকে যা উদাহরণস্বরূপ, এক্সএমএল বা জিপিএস করা উচিত।
রিচার্ড ইভ

2
@ রিচার্ডএভ, এর জন্য কোনও নিখুঁত রেজেক্স নেই তবে সংক্ষিপ্তসারগুলির সাথে এখানে আরও কিছুটা ভাল কাজ করা উচিত। "(?!^)([^A-Z])([A-Z])", "$1 $2"। তাই HereIsATESTহয়ে যায় Here Is ATEST
স্পারবাইটস

এই ছোট্ট "হ্যাকগুলি" করার ইজেন্টেন্ট নয় যা তারা তা। ওপি যা বলছে আমি তা পেয়েছি এবং আমি একই জাতীয় সমাধান खोजানোর চেষ্টা করছি যেমন এনুমসের কমনীয়তা ব্যবহার করে তবে সহজেই সম্পর্কিত বার্তাটি অ্যাক্সেস করতে সক্ষম হয়েছি। আমি যে সমাধানটিই ভাবতে পারি তা হ'ল এনাম নাম এবং একটি স্ট্রিংয়ের মানের মধ্যে এক ধরণের ম্যাপিং প্রয়োগ করা তবে স্ট্রিংয়ের ডেটা বজায় রাখার বিষয়টি প্রায়শই পাওয়া যায় না (তবে এটি আপনাকে এমন একাধিক অঞ্চল থাকা প্রয়োজন এমন পরিস্থিতিতে তৈরি করার ক্ষেত্রে ব্যবহারিক করে তোলে etc )
তাহির খালিদ

72

দুর্ভাগ্যক্রমে এনামগুলিতে অ্যাট্রিবিউটগুলি পাওয়ার প্রতিবিম্ব বেশ ধীর:

এই প্রশ্নটি দেখুন: এনাম মূল্যের উপর কাস্টম বৈশিষ্ট্যগুলি পেতে কোনও দ্রুত উপায় জানেন?

.ToString()খুব enums উপর বেশ ধীর।

আপনি enums জন্য এক্সটেনশন পদ্ধতি লিখতে পারেন যদিও:

public static string GetName( this MyEnum input ) {
    switch ( input ) {
        case MyEnum.WINDOWSAUTHENTICATION:
            return "Windows";
        //and so on
    }
}

এটি দুর্দান্ত নয়, তবে দ্রুত হবে এবং বৈশিষ্ট্য বা ক্ষেত্রের নামের প্রতিচ্ছবি প্রয়োজন হবে না।


সি # 6 আপডেট

আপনি সি # 6 ব্যবহার করতে পারেন তাহলে নতুন nameofঅপারেটর enums জন্য কাজ করে তাই হয়, nameof(MyEnum.WINDOWSAUTHENTICATION)রূপান্তরিত হবে "WINDOWSAUTHENTICATION"কম্পাইল সময় , এটা enum নাম পেতে দ্রুততম উপায়ে উপার্জন।

নোট করুন যে এটি সুস্পষ্ট এনামকে একটি অন্তর্নিহিত ধ্রুবকে রূপান্তর করবে, সুতরাং এটি আপনার চলকযুক্ত এনমগুলির জন্য কাজ করে না। তাই:

nameof(AuthenticationMethod.FORMS) == "FORMS"

কিন্তু ...

var myMethod = AuthenticationMethod.FORMS;
nameof(myMethod) == "myMethod"

24
আপনি একবারে বিশিষ্ট মানগুলি আনতে পারেন এবং ঘোষণামূলক দিকটি রাখার জন্য এগুলি একটি অভিধানে <মাইইনাম, স্ট্রিং> এ রাখতে পারেন।
জন স্কিটি

1
হ্যাঁ এটাই আমরা অ্যাপগুলিতে প্রচুর এনাম নিয়ে কাজ শেষ করেছি যখন আমরা জানতে পারলাম যে প্রতিবিম্বটি বোতল-ঘাড়।
কিথ

ধন্যবাদ জোন এবং কেথ, আপনার অভিধানের পরামর্শটি ব্যবহার করে আমি শেষ করেছি। দুর্দান্ত (এবং দ্রুত!) কাজ করে।
ক্লিইন

@ জোনস্কিট আমি জানি এটি পুরানো। তবে কীভাবে কেউ এ অর্জন করবে?
ব্যবহারকারী 919426

2
@ ব্যবহারকারী919426: অর্জন করতে চান? এগুলি একটি অভিধানে রাখছি? আদর্শ সংগ্রহের সূচনা দিয়ে কেবল একটি অভিধান তৈরি করুন ... আপনি কী চাইছেন তা পরিষ্কার নয়।
জন স্কিটি

59

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

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

এখন দিয়ে সাজান enum:

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

আপনি কল যখন

AuthenticationMethod.FORMS.ToDescription()আপনি পাবেন "FORMS"


1
আমাকে আরও যোগ করতে হয়েছিল using System.ComponentModel;, এই পদ্ধতিটি কেবল তখনই কাজ করে যদি আপনি স্ট্রিংয়ের মান এনামের নামের সাথে একই হয়। ওপি একটি আলাদা মান চেয়েছিল।
এলকুল

2
আপনি যখন ফোন করবেন মানে না AuthenticationMethod.FORMS.ToDescription()?
নিকোডেমাস 13

41

শুধু ToString()পদ্ধতিটি ব্যবহার করুন

public enum any{Tomato=0,Melon,Watermelon}

স্ট্রিংটি উল্লেখ করতে Tomato, কেবল ব্যবহার করুন use

any.Tomato.ToString();

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

7
কেন সবাই এটিকে অতিরিক্ত জটিল করে তুলছে?
ব্রেন্ট

18
@ ব্রেন্ট কারণ .ToString()আপনার ব্যবহারকারী-বান্ধব মানটি আপনার প্রয়োজনের চেয়ে বেশিরভাগ ক্ষেত্রেই আলাদা থাকে।
নভিচ্চি এস

2
@ ব্রেন্ট - কারণ এটি জিজ্ঞাসা করা প্রশ্নের চেয়ে আলাদা। আপনাকে জিজ্ঞাসা করা হচ্ছে যে প্রশ্নটি একটি ভেরিয়েবলের কাছ থেকে এই স্ট্রিংটি পাবেন কীভাবে একটি গণনা করা মান দেওয়া হয়েছে। এটি রান টাইমে গতিশীল। এটি টাইপটির সংজ্ঞাটি পরীক্ষা করছে এবং রান টাইমে সেট করে।
হোগান

1
@ হোগান - দ্য টাস্ট্রিং () পাশাপাশি চলকগুলিতেও কাজ করে: any fruit = any.Tomato; string tomato = fruit.ToString();
LiborV

29

নেট নেট এবং এর উপরের সাথে এটির খুব সহজ সমাধান। অন্য কোনও কোডের প্রয়োজন নেই।

public enum MyStatus
{
    Active = 1,
    Archived = 2
}

কেবল ব্যবহার সম্পর্কে স্ট্রিংটি পেতে:

MyStatus.Active.ToString("f");

অথবা

MyStatus.Archived.ToString("f");`

মানটি "সক্রিয়" বা "সংরক্ষণাগারভুক্ত" হবে।

কল করার সময় বিভিন্ন স্ট্রিং ফর্ম্যাটগুলি (উপরে থেকে "" চ ") Enum.ToStringদেখতে এই এনুমুরেশন ফর্ম্যাট স্ট্রিং পৃষ্ঠাটি দেখুন


28

আমি সিস্টেম থেকে বিবরণ বৈশিষ্ট্যটি ব্যবহার করি omp কম্পোনেন্টমোডেল নেমস্পেস। কেবল এনাম সাজাইয়া রাখুন এবং তারপরে এটি পুনরুদ্ধারে এই কোডটি ব্যবহার করুন:

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

        }

উদাহরণ হিসাবে:

public enum Cycle : int
{        
   [Description("Daily Cycle")]
   Daily = 1,
   Weekly,
   Monthly
}

এই কোডটি এনামগুলিতে খুব সুন্দরভাবে পরিবেশন করে যেখানে আপনার "বন্ধুত্বপূর্ণ নাম" লাগবে না এবং এনামের কেবলমাত্র .TosString () ফিরে আসবে।


27

আমি জাকুব তুরকের উত্তরটি সত্যিই পছন্দ করি তবে এটির অভাব হ'ল আপনি এটি স্যুইচ-কেস স্টেটমেন্ট দিয়ে ব্যবহার করতে পারবেন না। এখানে তার উত্তরের একটি সামান্য পরিবর্তিত সংস্করণ যা একটি স্যুইচ বিবৃতি দিয়ে ব্যবহার করা যেতে পারে:

public sealed class AuthenticationMethod
{
    #region This code never needs to change.
    private readonly string _name;
    public readonly Values Value;

    private AuthenticationMethod(Values value, String name){
        this._name = name;
        this.Value = value;
    }

    public override String ToString(){
        return _name;
    }
    #endregion

    public enum Values
    {
        Forms = 1,
        Windows = 2,
        SSN = 3
    }

    public static readonly AuthenticationMethod FORMS = new AuthenticationMethod (Values.Forms, "FORMS");
    public static readonly AuthenticationMethod WINDOWSAUTHENTICATION = new AuthenticationMethod (Values.Windows, "WINDOWS");
    public static readonly AuthenticationMethod SINGLESIGNON = new AuthenticationMethod (Values.SSN, "SSN");
}

সুতরাং আপনি জাকুব urturc এর উত্তরের সমস্ত সুবিধা পান, এবং আমরা এটির মতো একটি সুইচ বিবৃতি দিয়ে এটি ব্যবহার করতে পারি:

var authenticationMethodVariable = AuthenticationMethod.FORMS;  // Set the "enum" value we want to use.
var methodName = authenticationMethodVariable.ToString();       // Get the user-friendly "name" of the "enum" value.

// Perform logic based on which "enum" value was chosen.
switch (authenticationMethodVariable.Value)
{
    case authenticationMethodVariable.Values.Forms: // Do something
        break;
    case authenticationMethodVariable.Values.Windows: // Do something
        break;
    case authenticationMethodVariable.Values.SSN: // Do something
        break;      
}

একটি সংক্ষিপ্ত সমাধান হ'ল এনামগুলি মুছে ফেলা instead} এবং এর পরিবর্তে আপনি কত এনাম তৈরি করেছেন তার একটি স্থির গণনা রাখবেন। এটি এনাম তালিকায় আপনার তৈরি করা কোনও নতুন উদাহরণ যুক্ত করতে হবে না এমন সুবিধাও দেয়। যেমন public static int nextAvailable { get; private set; }কনস্ট্রাক্টরthis.Value = nextAvailable++;
kjhf

আকর্ষণীয় ধারণা @kjhf। যদিও আমার উদ্বেগটি হ'ল যদি কেউ কোডটি পুনরায় অর্ডার করে, তবে এনাম মানগুলিতে নির্ধারিত মানটিও পরিবর্তিত হতে পারে। উদাহরণস্বরূপ, এনাম মানটি কোনও ফাইল / ডাটাবেসে সংরক্ষণ করা হলে "নতুন প্রমাণীকরণমিথড (...)" রেখার ক্রম পরিবর্তন করা হয় (যেমন একটি অপসারণ করা হয়), এবং তারপরে এটি ভুল এনাম মানটি পুনরুদ্ধার করতে পারে অ্যাপ্লিকেশনটি আবার চালাচ্ছি এবং ফাইল / ডাটাবেস থেকে এনাম মান পুনরুদ্ধার করা; এনাম মানটি সংরক্ষণ করা মেথডের সাথে মেলে না।
মারাত্মক ডগ

ভালো কথা - যদিও আমি আশা করি যে এই বিশেষ ক্ষেত্রে লোকেরা এনামের পূর্ণসংখ্যার মান (বা এনাম কোডটিকে পুনরায় অর্ডার করছে) এর উপর নির্ভর করবে না - এবং এই মানটি নির্ভুলভাবে একটি সুইচ হিসাবে এবং সম্ভবত .Equals () এর বিকল্প হিসাবে ব্যবহৃত হয়। GetHashCode ()। যদি উদ্বিগ্ন হন তবে আপনি সর্বদা "ডোন রেডার" না দিয়ে একটি বিশাল মন্তব্য দিতে পারেন: পি
কেজেএফফ

আপনি কি =স্যুইচটিকে কাজ করার অনুমতি দিতে ওভারলোড করতে পারবেন না ? আমি এটি ভিবিতে করেছিলাম এবং এখন এটি select caseবিবৃতিতে ব্যবহার করতে পারি ।
ব্যবহারকারী 1318499

@ ব্যবহারকারী 1318499 না, সি # এর বিবির চেয়ে স্যুইচ স্টেটমেন্টের চারপাশে কঠোর নিয়ম রয়েছে। আপনি কেস স্টেটমেন্টের জন্য শ্রেণীর উদাহরণ ব্যবহার করতে পারবেন না; আপনি কেবল ধ্রুবক আদিম ব্যবহার করতে পারেন।
মারাত্মক ডগ

13

আমি উপরের বেশ কয়েকটি পরামর্শের সংমিশ্রণটি ব্যবহার করছি, কিছু ক্যাশিংয়ের সাথে মিলিত। এখন, আমি কিছু কোড থেকে ধারণা পেয়েছি যা আমি নেট থেকে কোথাও পেয়েছি, তবে আমি কোথায় পেয়েছি তা খুঁজে পেতে পারি না বা খুঁজে পেতে পারি না। সুতরাং যদি কেউ কখনও সাদৃশ্যযুক্ত এমন কিছু খুঁজে পান তবে অনুগ্রহ করে মন্তব্য করুন।

যাইহোক, ব্যবহারের মধ্যে ধরণের রূপান্তরকারীদের অন্তর্ভুক্ত রয়েছে, সুতরাং আপনি যদি ইউআই-তে বাধ্য হন তবে এটি 'স্রেফ কাজ করে'। স্ট্যাটিক পদ্ধতিতে ধরণের রূপান্তরকারী থেকে আরম্ভ করে আপনি দ্রুত কোড সন্ধানের জন্য জাকুবের প্যাটার্ন দিয়ে প্রসারিত করতে পারেন।

বেস ব্যবহারটি এর মতো দেখায়

[TypeConverter(typeof(CustomEnumTypeConverter<MyEnum>))]
public enum MyEnum
{
    // The custom type converter will use the description attribute
    [Description("A custom description")]
    ValueWithCustomDescription,

   // This will be exposed exactly.
   Exact
}

কাস্টম এনাম ধরণের রূপান্তরকারীটির জন্য কোডটি নিম্নলিখিত:

public class CustomEnumTypeConverter<T> : EnumConverter
    where T : struct
{
    private static readonly Dictionary<T,string> s_toString = 
      new Dictionary<T, string>();

    private static readonly Dictionary<string, T> s_toValue = 
      new Dictionary<string, T>();

    private static bool s_isInitialized;

    static CustomEnumTypeConverter()
    {
        System.Diagnostics.Debug.Assert(typeof(T).IsEnum,
          "The custom enum class must be used with an enum type.");
    }

    public CustomEnumTypeConverter() : base(typeof(T))
    {
        if (!s_isInitialized)
        {
            Initialize();
            s_isInitialized = true;
        }
    }

    protected void Initialize()
    {
        foreach (T item in Enum.GetValues(typeof(T)))
        {
            string description = GetDescription(item);
            s_toString[item] = description;
            s_toValue[description] = item;
        }
    }

    private static string GetDescription(T optionValue)
    {
        var optionDescription = optionValue.ToString();
        var optionInfo = typeof(T).GetField(optionDescription);
        if (Attribute.IsDefined(optionInfo, typeof(DescriptionAttribute)))
        {
            var attribute = 
              (DescriptionAttribute)Attribute.
                 GetCustomAttribute(optionInfo, typeof(DescriptionAttribute));
            return attribute.Description;
        }
        return optionDescription;
    }

    public override object ConvertTo(ITypeDescriptorContext context, 
       System.Globalization.CultureInfo culture, 
       object value, Type destinationType)
    {
        var optionValue = (T)value;

        if (destinationType == typeof(string) && 
            s_toString.ContainsKey(optionValue))
        {
            return s_toString[optionValue];
        }

        return base.ConvertTo(context, culture, value, destinationType);
    }

    public override object ConvertFrom(ITypeDescriptorContext context, 
       System.Globalization.CultureInfo culture, object value)
    {
        var stringValue = value as string;

        if (!string.IsNullOrEmpty(stringValue) && s_toValue.ContainsKey(stringValue))
        {
            return s_toValue[stringValue];
        }

        return base.ConvertFrom(context, culture, value);
    }
}

}


12

আপনার প্রশ্নে আপনি কখনও বলেননি যে আপনার প্রকৃতপক্ষে কোথাও এনামের সংখ্যার মান প্রয়োজন value

আপনার যদি না হয় এবং কেবল টাইপ স্ট্রিংয়ের এনাম প্রয়োজন হয় (যা একটি ইন্টিগ্রাল টাইপ নয় তাই এনামের ভিত্তি হতে পারে না) এখানে একটি উপায়:

    static class AuthenticationMethod
    {
        public static readonly string
            FORMS = "Forms",
            WINDOWSAUTHENTICATION = "WindowsAuthentication";
    }

আপনি এটির উল্লেখ করতে এনামের মতো একই বাক্য গঠন ব্যবহার করতে পারেন

if (bla == AuthenticationMethod.FORMS)

এটি সংখ্যার মানগুলির চেয়ে কিছুটা ধীর হবে (সংখ্যার পরিবর্তে স্ট্রিং তুলনা করে) তবে প্লাস দিকে এটি স্ট্রিং অ্যাক্সেস করতে প্রতিবিম্ব (ধীর) ব্যবহার করছে না using


আপনি যদি "স্ট্যাটিক রিডোনলি" এর পরিবর্তে "কনস্ট" ব্যবহার করেন তবে আপনি স্যুইচ স্টেটমেন্টে কেস লেবেল হিসাবে মানগুলি ব্যবহার করতে পারেন।
এড এন।

11

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

using System.ComponentModel;
public static string GetDescription(this Enum value)
{
    var descriptionAttribute = (DescriptionAttribute)value.GetType()
        .GetField(value.ToString())
        .GetCustomAttributes(false)
        .Where(a => a is DescriptionAttribute)
        .FirstOrDefault();

    return descriptionAttribute != null ? descriptionAttribute.Description : value.ToString();
}

Enum:

public enum OrderType
{
    None = 0,
    [Description("New Card")]
    NewCard = 1,
    [Description("Reload")]
    Refill = 2
}

ব্যবহার (যেখানে o.OrderType একটি এনাম হিসাবে একই নামের একটি সম্পত্তি):

o.OrderType.GetDescription()

যা আমাকে প্রকৃত এনাম মান নিউকার্ড এবং রিফিলের পরিবর্তে "নতুন কার্ড" বা "পুনঃলোড" এর একটি স্ট্রিং দেয়।


সম্পূর্ণতার জন্য আপনার বর্ণনামূলক শ্রেণীর একটি অনুলিপি অন্তর্ভুক্ত করা উচিত।
বার্নি হোয়াইট


11

আপডেট: 8 বছর পরে, এই পৃষ্ঠাটি দেখার জন্য, দীর্ঘ সময়ের জন্য সি # স্পর্শ না করার পরে, দেখে মনে হচ্ছে আমার উত্তরটি এখন আর সেরা সমাধান নয়। আমি সত্যই - বৈশিষ্ট্য-ফাংশনগুলির সাথে আবদ্ধ রূপান্তর সমাধানটি পছন্দ করি।

আপনি যদি এটি পড়ছেন তবে দয়া করে নিশ্চিত হয়ে নিন যে আপনি অন্যান্য উত্তরগুলিও পরীক্ষা করে দেখেছেন।
(ইঙ্গিত: তারা এটির উপরে রয়েছে)


আপনার বেশিরভাগ হিসাবে, আমি জাকুব তুরকের নির্বাচিত উত্তরটি সত্যিই পছন্দ করেছি তবে কপি-পেস্ট কোডটিও আমি সত্যিই ঘৃণা করি এবং এটি যতটা পারি তার চেষ্টা করার চেষ্টা করি।

তাই আমি সিদ্ধান্ত নিয়েছি যে আমি একটি এনামবেস ক্লাস চাই যা থেকে বেশিরভাগ কার্যকারিতা উত্তরাধিকার সূত্রে প্রাপ্ত / অন্তর্নির্মিত হয়, আমাকে আচরণের পরিবর্তে সামগ্রীতে ফোকাস করতে রেখে যায়।

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

আমি জাকুবের উদাহরণ দিয়ে শুরু করব, তবে উত্তরাধিকার এবং জেনেরিক ব্যবহার করে:

public sealed class AuthenticationMethod : EnumBase<AuthenticationMethod, int>
{
    public static readonly AuthenticationMethod FORMS =
        new AuthenticationMethod(1, "FORMS");
    public static readonly AuthenticationMethod WINDOWSAUTHENTICATION =
        new AuthenticationMethod(2, "WINDOWS");
    public static readonly AuthenticationMethod SINGLESIGNON =
        new AuthenticationMethod(3, "SSN");

    private AuthenticationMethod(int Value, String Name)
        : base( Value, Name ) { }
    public new static IEnumerable<AuthenticationMethod> All
    { get { return EnumBase<AuthenticationMethod, int>.All; } }
    public static explicit operator AuthenticationMethod(string str)
    { return Parse(str); }
}

এবং এখানে বেস ক্লাস:

using System;
using System.Collections.Generic;
using System.Linq; // for the .AsEnumerable() method call

// E is the derived type-safe-enum class
// - this allows all static members to be truly unique to the specific
//   derived class
public class EnumBase<E, T> where E: EnumBase<E, T>
{
    #region Instance code
    public T Value { get; private set; }
    public string Name { get; private set; }

    protected EnumBase(T EnumValue, string Name)
    {
        Value = EnumValue;
        this.Name = Name;
        mapping.Add(Name, this);
    }

    public override string ToString() { return Name; }
    #endregion

    #region Static tools
    static private readonly Dictionary<string, EnumBase<E, T>> mapping;
    static EnumBase() { mapping = new Dictionary<string, EnumBase<E, T>>(); }
    protected static E Parse(string name)
    {
        EnumBase<E, T> result;
        if (mapping.TryGetValue(name, out result))
        {
            return (E)result;
        }

        throw new InvalidCastException();
    }
    // This is protected to force the child class to expose it's own static
    // method.
    // By recreating this static method at the derived class, static
    // initialization will be explicit, promising the mapping dictionary
    // will never be empty when this method is called.
    protected static IEnumerable<E> All
    { get { return mapping.Values.AsEnumerable().Cast<E>(); } }
    #endregion
}

আপনি বেস স্ট্যাটিক কনস্ট্রাক্টর থেকে উদ্ভূত স্ট্যাটিক কনস্ট্রাক্টরকে কল করতে সক্ষম হতে পারেন। আমি এখনও এটি সন্ধান করছি, তবে এখনও পর্যন্ত আমি এটির সাথে কোনও সমস্যা পাইনি: স্ট্যাকওভারফ্লো
Cory-G

10

আমি কিথের সাথে একমত, তবে আমি ভোট দিতে পারি না (এখনও)।

আমি যা চাই ঠিক তা ফিরিয়ে দিতে আমি একটি স্থির পদ্ধতি এবং সুইথ স্টেটমেন্ট ব্যবহার করি। ডাটাবেসে আমি টিনিনেন্ট সঞ্চয় করি এবং আমার কোডগুলি কেবল প্রকৃত এনাম ব্যবহার করে, সুতরাং স্ট্রিংগুলি ইউআই প্রয়োজনীয়তার জন্য। অসংখ্য পরীক্ষার পরে এটি ফলাফল সেরা ফলাফল এবং সবচেয়ে আউটপুট উপর নিয়ন্ত্রণ।

public static string ToSimpleString(this enum)
{
     switch (enum)
     {
         case ComplexForms:
             return "ComplexForms";
             break;
     }
}

public static string ToFormattedString(this enum)
{
     switch (enum)
     {
         case ComplexForms:
             return "Complex Forms";
             break;
     }
}

তবে কিছু অ্যাকাউন্টের দ্বারা এটি সম্ভাব্য রক্ষণাবেক্ষণের দুঃস্বপ্ন এবং কিছু কোডের গন্ধ বাড়ে। আমি দীর্ঘ দীর্ঘ এবং প্রচুর এনাম, বা ঘন ঘন পরিবর্তিত এমন এনামগুলির জন্য নজর রাখার চেষ্টা করি। অন্যথায়, এটি আমার জন্য দুর্দান্ত সমাধান হয়ে দাঁড়িয়েছে।


10

আপনি যদি এখানে একটি সহজ "এনুম" বাস্তবায়ন করতে এসেছেন তবে যার মানগুলি ইনটের পরিবর্তে স্ট্রিং হয়, তবে এখানে সহজ সমাধান রয়েছে:

    public sealed class MetricValueList
    {
        public static readonly string Brand = "A4082457-D467-E111-98DC-0026B9010912";
        public static readonly string Name = "B5B5E167-D467-E111-98DC-0026B9010912";
    }

বাস্তবায়ন:

var someStringVariable = MetricValueList.Brand;

2
ব্যবহারের পরিবর্তে ভেরিয়েবল কনস্ট তৈরি করা ভাল static readonly
অ্যান্ডিগিক

1
কনসলেটগুলি সর্বজনীনভাবে অ্যাক্সেসযোগ্য ক্লাসগুলির জন্য ভাল নয়, কারণ তারা সংকলনের সময় বেকড রয়েছে, আপনার সম্পূর্ণ কোডটি কনসেটগুলির সাথে পুনরায় সংশোধন না করে আপনি কোনও তৃতীয় পক্ষের ডিএলএল প্রতিস্থাপন করতে পারবেন না stat
ক্রিস্টিয়ান উইলিয়ামস

7

আমি যখন এই সমস্যার মুখোমুখি হই তখন বেশ কয়েকটি প্রশ্ন থাকে যা আমি প্রথমে উত্তরগুলি খুঁজতে চেষ্টা করি:

  • আমার এনাম মানগুলির নামগুলি কি এই উদ্দেশ্যে যথেষ্ট বন্ধুত্বপূর্ণ, বা আমার কী বন্ধুত্বপূর্ণ সরবরাহ করার প্রয়োজন?
  • আমার কি রাউন্ড ট্রিপ দরকার? এটি হ'ল, আমাকে কি পাঠ্য মানগুলি গ্রহণ এবং এনাম মানগুলিতে পার্স করা দরকার?
  • এটি আমার প্রকল্পের অনেকগুলি এনামের জন্য করা দরকার বা কেবল একটি?
  • আমি কোন ধরণের ইউআই উপাদান এই তথ্য উপস্থাপন করব - বিশেষত, আমি ইউআইয়ের সাথে আবদ্ধ হব, বা সম্পত্তি পত্রক ব্যবহার করব?
  • এটি কি স্থানীয়করণের প্রয়োজন?

এটি করার সহজ উপায় হ'ল Enum.GetValue(এবং ব্যবহারটি রাউন্ড-ট্রিপিং সমর্থন করে Enum.Parse)। এটি প্রায়শই একটি বিল্ডিংয়েরও মূল্যবানTypeConverterস্টিভ মিচামের পরামর্শ অনুসারে, ইউআই বাইন্ডিং সমর্থন করার জন্য । ( TypeConverterআপনি যখন সম্পত্তি পত্রক ব্যবহার করছেন তখন এটি নির্মাণ করার দরকার নেই যা সম্পত্তি শীট সম্পর্কে দুর্দান্ত জিনিসগুলির মধ্যে একটি lord যদিও প্রভু জানেন যে তাদের নিজস্ব সমস্যা আছে))

সাধারণভাবে, যদি উপরের প্রশ্নের উত্তরগুলি নির্দেশ করে যে এটি কার্যকর হচ্ছে না, তবে আমার পরবর্তী পদক্ষেপটি একটি স্ট্যাটিক তৈরি এবং পপুলেট করা Dictionary<MyEnum, string>বা সম্ভবত একটি Dictionary<Type, Dictionary<int, string>>। আমি মধ্যবর্তী সাজসজ্জা-সাথে-কোড-সহ-বৈশিষ্ট্যগুলি ধাপটি এড়িয়ে যাচ্ছি কারণ পরবর্তীতে সাধারণত পাইকের নীচে নেমে আসার বিষয়টি হ'ল ডিপ্লোয়মেন্টের পরে বন্ধুত্বপূর্ণ মানগুলি পরিবর্তন করা প্রয়োজন (প্রায়শই, তবে সর্বদা নয়, স্থানীয়করণের কারণে)।


7

আমি নীচে উদ্ধৃত পোস্টটিতে একটি মন্তব্য হিসাবে এটি পোস্ট করতে চেয়েছিলাম কিন্তু আমার পর্যাপ্ত প্রতিনিধি নেই কারণ পারে না - তাই দয়া করে ভোট দিন না। কোডটিতে একটি ত্রুটি রয়েছে এবং আমি এই সমাধানটি ব্যবহার করার চেষ্টা করা ব্যক্তিদের কাছে এটি নির্দেশ করতে চেয়েছিলাম:

[TypeConverter(typeof(CustomEnumTypeConverter(typeof(MyEnum))]
public enum MyEnum
{
  // The custom type converter will use the description attribute
  [Description("A custom description")]
  ValueWithCustomDescription,
  // This will be exposed exactly.
  Exact
}

হতে হবে

[TypeConverter(typeof(CustomEnumTypeConverter<MyEnum>))]
public enum MyEnum
{
  // The custom type converter will use the description attribute
  [Description("A custom description")]
  ValueWithCustomDescription,

  // This will be exposed exactly.
  Exact
}

Brillant!


5

আমার রূপ

public struct Colors
{
    private String current;

    private static string red = "#ff0000";
    private static string green = "#00ff00";
    private static string blue = "#0000ff";

    private static IList<String> possibleColors; 

    public static Colors Red { get { return (Colors) red; } }
    public static Colors Green { get { return (Colors) green; } }
    public static Colors Blue { get { return (Colors) blue; } }

    static Colors()
    {
        possibleColors = new List<string>() {red, green, blue};
    }

    public static explicit operator String(Colors value)
    {
        return value.current;
    }

    public static explicit operator Colors(String value)
    {
        if (!possibleColors.Contains(value))
        {
            throw new InvalidCastException();
        }

        Colors color = new Colors();
        color.current = value;
        return color;
    }

    public static bool operator ==(Colors left, Colors right)
    {
        return left.current == right.current;
    }

    public static bool operator !=(Colors left, Colors right)
    {
        return left.current != right.current;
    }

    public bool Equals(Colors other)
    {
        return Equals(other.current, current);
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        if (obj.GetType() != typeof(Colors)) return false;
        return Equals((Colors)obj);
    }

    public override int GetHashCode()
    {
        return (current != null ? current.GetHashCode() : 0);
    }

    public override string ToString()
    {
        return current;
    }
}

কোডটি কিছুটা কুৎসিত দেখাচ্ছে, কিন্তু এই কাঠামোর ব্যবহারগুলি বেশ উপস্থাপনযোগ্য।

Colors color1 = Colors.Red;
Console.WriteLine(color1); // #ff0000

Colors color2 = (Colors) "#00ff00";
Console.WriteLine(color2); // #00ff00

// Colors color3 = "#0000ff"; // Compilation error
// String color4 = Colors.Red; // Compilation error

Colors color5 = (Colors)"#ff0000";
Console.WriteLine(color1 == color5); // True

Colors color6 = (Colors)"#00ff00";
Console.WriteLine(color1 == color6); // False

এছাড়াও, আমি মনে করি, যদি এই জাতীয় প্রচুর পরিমাণে এনাম প্রয়োজন হয় তবে কোড জেনারেশন (যেমন টি 4) ব্যবহার করা যেতে পারে।


4

বিকল্প 1:

public sealed class FormsAuth
{
     public override string ToString{return "Forms Authtentication";}
}
public sealed class WindowsAuth
{
     public override string ToString{return "Windows Authtentication";}
}

public sealed class SsoAuth
{
     public override string ToString{return "SSO";}
}

এবং তারপর

object auth = new SsoAuth(); //or whatever

//...
//...
// blablabla

DoSomethingWithTheAuth(auth.ToString());

বিকল্প 2:

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

public class MyClass
{
    private Dictionary<AuthenticationMethod, String> map = new Dictionary<AuthenticationMethod, String>();
    public MyClass()
    {
         map.Add(AuthenticationMethod.FORMS,"Forms Authentication");
         map.Add(AuthenticationMethod.WINDOWSAUTHENTICATION ,"Windows Authentication");
         map.Add(AuthenticationMethod.SINGLESIGNON ,"SSo Authentication");
    }
}

4

আমরা যদি সমস্যাটি সমাধান করার চেষ্টা করছি সে সম্পর্কে আপনি যদি ভাবেন তবে এটি কোনও এনাম নয়। আমাদের এমন একটি বস্তুর প্রয়োজন যা নির্দিষ্ট সংখ্যক মানকে প্রত্যেকের সাথে যুক্ত করতে দেয়; অন্য কথায়, একটি বর্গ সংজ্ঞায়িত করা।

জাকুব urturc এর টাইপ-সেফ এনাম প্যাটার্নটি আমি এখানে দেখছি সেরা বিকল্প।

এটার দিকে দেখ:

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

4

আমার জন্য, ব্যবহারিক পদ্ধতির বর্গের অভ্যন্তর শ্রেণি, নমুনা:

public class MSEModel
{
    class WITS
    {
        public const string DATE = "5005";
        public const string TIME = "5006";
        public const string MD = "5008";
        public const string ROP = "5075";
        public const string WOB = "5073";
        public const string RPM = "7001";
... 
    }

4

.NET এ স্ট্রিং-মানযুক্ত এনাম তৈরির জন্য আমি একটি বেস ক্লাস তৈরি করেছি। এটি কেবলমাত্র একটি সি # ফাইল যা আপনি আপনার প্রকল্পগুলিতে অনুলিপি এবং আটকান করতে পারেন, বা স্ট্রিংইনাম নামের নিউগেট প্যাকেজটির মাধ্যমে ইনস্টল করতে পারেন । গিটহাব রেপো

  • ক্লাসটি যদি এক্সএমএল মন্তব্যে টিকা দেওয়া থাকে তবে ইনটেলিসেন্স এনামের নাম প্রস্তাব করবে <completitionlist>। (সি # এবং ভিবি উভয় ক্ষেত্রেই কাজ করে)

ইন্টেলিজেন্স ডেমো

  • নিয়মিত এনামের মতো ব্যবহার:
///<completionlist cref="HexColor"/> 
class HexColor : StringEnum<HexColor>
{
    public static readonly HexColor Blue = Create("#FF0000");
    public static readonly HexColor Green = Create("#00FF00");
    public static readonly HexColor Red = Create("#000FF");
}
    // Static Parse Method
    HexColor.Parse("#FF0000") // => HexColor.Red
    HexColor.Parse("#ff0000", caseSensitive: false) // => HexColor.Red
    HexColor.Parse("invalid") // => throws InvalidOperationException

    // Static TryParse method.
    HexColor.TryParse("#FF0000") // => HexColor.Red
    HexColor.TryParse("#ff0000", caseSensitive: false) // => HexColor.Red
    HexColor.TryParse("invalid") // => null

    // Parse and TryParse returns the preexistent instances
    object.ReferenceEquals(HexColor.Parse("#FF0000"), HexColor.Red) // => true

    // Conversion from your `StringEnum` to `string`
    string myString1 = HexColor.Red.ToString(); // => "#FF0000"
    string myString2 = HexColor.Red; // => "#FF0000" (implicit cast)

Instalation:

  • আপনার প্রকল্পে নিম্নলিখিত স্ট্রিংইনম বেস ক্লাসটি আটকান। ( সর্বশেষ সংস্করণ )
  • বা ইনস্টল StringEnum NuGet প্যাকেজ, যার উপর ভিত্তি করে তৈরি .Net Standard 1.0তাই এটি উপর সঞ্চালিত হয় .Net Core> = 1.0, .Net Framework> = 4.5, Mono> = 4.6, ইত্যাদি
    /// <summary>
    /// Base class for creating string-valued enums in .NET.<br/>
    /// Provides static Parse() and TryParse() methods and implicit cast to string.
    /// </summary>
    /// <example> 
    /// <code>
    /// class Color : StringEnum &lt;Color&gt;
    /// {
    ///     public static readonly Color Blue = Create("Blue");
    ///     public static readonly Color Red = Create("Red");
    ///     public static readonly Color Green = Create("Green");
    /// }
    /// </code>
    /// </example>
    /// <typeparam name="T">The string-valued enum type. (i.e. class Color : StringEnum&lt;Color&gt;)</typeparam>
    public abstract class StringEnum<T> : IEquatable<T> where T : StringEnum<T>, new()
    {
        protected string Value;
        private static Dictionary<string, T> valueDict = new Dictionary<string, T>();
        protected static T Create(string value)
        {
            if (value == null)
                return null; // the null-valued instance is null.

            var result = new T() { Value = value };
            valueDict.Add(value, result);
            return result;
        }

        public static implicit operator string(StringEnum<T> enumValue) => enumValue.Value;
        public override string ToString() => Value;

        public static bool operator !=(StringEnum<T> o1, StringEnum<T> o2) => o1?.Value != o2?.Value;
        public static bool operator ==(StringEnum<T> o1, StringEnum<T> o2) => o1?.Value == o2?.Value;

        public override bool Equals(object other) => this.Value.Equals((other as T)?.Value ?? (other as string));
        bool IEquatable<T>.Equals(T other) => this.Value.Equals(other.Value);
        public override int GetHashCode() => Value.GetHashCode();

        /// <summary>
        /// Parse the <paramref name="value"/> specified and returns a valid <typeparamref name="T"/> or else throws InvalidOperationException.
        /// </summary>
        /// <param name="value">The string value representad by an instance of <typeparamref name="T"/>. Matches by string value, not by the member name.</param>
        /// <param name="caseSensitive">If true, the strings must match case and takes O(log n). False allows different case but is little bit slower (O(n))</param>
        public static T Parse(string value, bool caseSensitive = true)
        {
            var result = TryParse(value, caseSensitive);
            if (result == null)
                throw new InvalidOperationException((value == null ? "null" : $"'{value}'") + $" is not a valid {typeof(T).Name}");

            return result;
        }

        /// <summary>
        /// Parse the <paramref name="value"/> specified and returns a valid <typeparamref name="T"/> or else returns null.
        /// </summary>
        /// <param name="value">The string value representad by an instance of <typeparamref name="T"/>. Matches by string value, not by the member name.</param>
        /// <param name="caseSensitive">If true, the strings must match case. False allows different case but is slower: O(n)</param>
        public static T TryParse(string value, bool caseSensitive = true)
        {
            if (value == null) return null;
            if (valueDict.Count == 0) System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(typeof(T).TypeHandle); // force static fields initialization
            if (caseSensitive)
            {
                if (valueDict.TryGetValue(value, out T item))
                    return item;
                else
                    return null;
            }
            else
            {
                // slower O(n) case insensitive search
                return valueDict.FirstOrDefault(f => f.Key.Equals(value, StringComparison.OrdinalIgnoreCase)).Value;
                // Why Ordinal? => https://esmithy.net/2007/10/15/why-stringcomparisonordinal-is-usually-the-right-choice/
            }
        }
    }

3

এনামদের সাথে স্ট্রিংগুলি যুক্ত করার কাজটি সম্পাদনের আরও একটি উপায় এখানে রয়েছে:

struct DATABASE {
    public enum enums {NOTCONNECTED, CONNECTED, ERROR}
    static List<string> strings =
        new List<string>() {"Not Connected", "Connected", "Error"};

    public string GetString(DATABASE.enums value) {
        return strings[(int)value];
    }
}

এই পদ্ধতিটিকে এভাবে বলা হয়:

public FormMain() {
    DATABASE dbEnum;

    string enumName = dbEnum.GetString(DATABASE.enums.NOTCONNECTED);
}

আপনি তাদের নিজস্ব কাঠামোতে সম্পর্কিত এনামগুলিকে গ্রুপ করতে পারেন। যেহেতু এই পদ্ধতিটি এনাম টাইপ ব্যবহার করে, আপনি তৈরি করার সময় এনামগুলির তালিকা প্রদর্শন করতে ইন্টেলিসেন্স ব্যবহার করতে পারেনGetString() কল করার ।

আপনি DATABASEস্ট্রাক্টে নতুন অপারেটরটি বিকল্পভাবে ব্যবহার করতে পারেন । এটি ব্যবহার না করার অর্থ Listপ্রথম GetString()কল না হওয়া পর্যন্ত স্ট্রিংগুলি বরাদ্দ দেওয়া হয় না ।


3

এখানে অনেক দুর্দান্ত উত্তর কিন্তু আমার ক্ষেত্রে "স্ট্রিং এনাম" থেকে আমি যা চেয়েছিলাম তা সমাধান করেনি, যা ছিল:

  1. একটি স্যুইচ স্টেটমেন্টে ব্যবহারযোগ্য যেমন সুইচ (মাইনাম)
  2. ফাংশন প্যারামিটারে যেমন foo (myEnum প্রকার) ব্যবহার করা যেতে পারে
  3. যেমন myEnum.FirstElement রেফারেন্স করা যেতে পারে
  4. আমি স্ট্রিং ব্যবহার করতে পারি যেমন foo ("ফার্স্টএলিমেন্ট") == foo (myEnum.FirstElement)

1,2 এবং 4 আসলে একটি স্ট্রিংয়ের সি # টাইপডেফ দিয়ে সমাধান করা যায় (যেহেতু স্ট্রিংগুলি সি # তে পরিবর্তনযোগ্য)

3 স্ট্যাটিক কনস্ট্রিং স্ট্রিংগুলির মাধ্যমে সমাধান করা যায়। সুতরাং আপনার যদি একই চাহিদা থাকে তবে এটিই সহজতম পদ্ধতি:

public sealed class Types
{

    private readonly String name;

    private Types(String name)
    {
        this.name = name;

    }

    public override String ToString()
    {
        return name;
    }

    public static implicit operator Types(string str)
    {
        return new Types(str);

    }
    public static implicit operator string(Types str)
    {
        return str.ToString();
    }


    #region enum

    public const string DataType = "Data";
    public const string ImageType = "Image";
    public const string Folder = "Folder";
    #endregion

}

এটি উদাহরণস্বরূপ অনুমতি দেয়:

    public TypeArgs(Types SelectedType)
    {
        Types SelectedType = SelectedType
    }

এবং

public TypeObject CreateType(Types type)
    {
        switch (type)
        {

            case Types.ImageType:
              //
                break;

            case Types.DataType:
             //
                break;

        }
    }

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

এখন যদি কোনও মান মান আপনার কাছে গুরুত্বপূর্ণ ছিল (সম্ভবত তুলনার গতির জন্য), আপনি জাকুব urturc চমত্কার উত্তর থেকে কিছু ধারণা ব্যবহার করতে পারেন এবং কিছুটা ক্রেজি করতে পারেন, এটি আমার স্ট্যাব:

    public sealed class Types
{
    private static readonly Dictionary<string, Types> strInstance = new Dictionary<string, Types>();
    private static readonly Dictionary<int, Types> intInstance = new Dictionary<int, Types>();

    private readonly String name;
    private static int layerTypeCount = 0;
    private int value;
    private Types(String name)
    {
        this.name = name;
        value = layerTypeCount++;
        strInstance[name] = this;
        intInstance[value] = this;
    }

    public override String ToString()
    {
        return name;
    }


    public static implicit operator Types(int val)
    {
        Types result;
        if (intInstance.TryGetValue(val, out result))
            return result;
        else
            throw new InvalidCastException();
    }

    public static implicit operator Types(string str)
    {
        Types result;
        if (strInstance.TryGetValue(str, out result))
        {
            return result;
        }
        else
        {
            result = new Types(str);
            return result;
        }

    }
    public static implicit operator string(Types str)
    {
        return str.ToString();
    }

    public static bool operator ==(Types a, Types b)
    {
        return a.value == b.value;
    }
    public static bool operator !=(Types a, Types b)
    {
        return a.value != b.value;
    }

    #region enum

    public const string DataType = "Data";
    public const string ImageType = "Image";

    #endregion

}

তবে অবশ্যই "প্রকারের বব = 4;" আপনি প্রথমে সেগুলি সূচনা না করাই অর্থহীন হবে যা বিন্দুটিকে পরাজিত করবে ...

তবে তত্ত্বের ক্ষেত্রে টাইপএ == টাইপবি দ্রুত হবে ...


3

যদি আমি আপনাকে সঠিকভাবে বুঝতে পারি তবে আপনি সহজেই মানটি থেকে এনামের নাম পুনরুদ্ধার করতে .TosString () ব্যবহার করতে পারেন (ধরে নিবেন এটি ইতিমধ্যে এনাম হিসাবে কাস্ট হয়েছে); যদি আপনার নগ্ন অন্তর্ভুক্ত থাকে (কোনও ডাটাবেস বা কোনও কিছু থেকে বলুন) আপনি প্রথমে এটি এনামে কাস্ট করতে পারেন। নীচের দুটি পদ্ধতিই আপনাকে এনামের নাম দেবে।

AuthenticationMethod myCurrentSetting = AuthenticationMethod.FORMS;
Console.WriteLine(myCurrentSetting); // Prints: FORMS
string name = Enum.GetNames(typeof(AuthenticationMethod))[(int)myCurrentSetting-1];
Console.WriteLine(name); // Prints: FORMS

তবে মনে রাখবেন, দ্বিতীয় কৌশলটি ধরে নিয়েছে আপনি কীট ব্যবহার করছেন এবং আপনার সূচকটি 1 ভিত্তিক (0 ভিত্তিক নয়)। তুলনা করে গেটনামস ফাংশনটিও বেশ ভারী, আপনি যতবার ডাকে ততবারে পুরো অ্যারে তৈরি করছেন are যেমন আপনি প্রথম কৌশলটিতে দেখতে পারেন, .ToString () আসলে প্রকৃতপক্ষে বলা হয়। এই দু'টিই ইতিমধ্যে অবশ্যই উত্তরে উল্লেখ করা হয়েছে, আমি কেবল তাদের মধ্যে পার্থক্য পরিষ্কার করার চেষ্টা করছি।


3

পুরানো পোস্ট কিন্তু ...

এর উত্তর আসলে খুব সহজ হতে পারে। Enum.ToString () ফাংশনটি ব্যবহার করুন

এই ফাংশনটির 6 টি ওভারলোড রয়েছে, আপনি স্ট্রিংয়ের মান ফেরত দিতে Enum.Tostring ("F") বা Enum.ToString () ব্যবহার করতে পারেন। আর কিছু নিয়ে বিরক্ত করার দরকার নেই। এখানে একটি ওয়ার্কিং ডেমো রয়েছে

দ্রষ্টব্য যে এই সমাধানটি সমস্ত সংকলকগুলির জন্য কাজ করতে পারে না ( এই ডেমোটি প্রত্যাশার মতো কাজ করে না ) তবে অন্তত সর্বশেষতম সংকলকটির জন্য এটি কাজ করে।


2

এমএসডিএন ভিত্তিক: http://msdn.microsoft.com/en-us/library/cc138362.aspx

foreach (string str in Enum.GetNames(typeof(enumHeaderField)))
{
    Debug.WriteLine(str);
}

str ক্ষেত্রগুলির নাম হবে


2
এটি এনামের নাম দেবে, আপনি এর জন্য টোস্ট্রিং () ব্যবহার করতে পারেন, এটি জিজ্ঞাসা করা হয়নি। চেকআউট msdn.microsoft.com/en-us/library/system.enum.getname.aspx আপনার Bubu সম্পর্কে আরও তথ্যের জন্য
মিকি Perlstein

2

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

public enum Color 
{ Red = 1, Green = 2, Blue = 3}


public static EnumUtils 
{
   public static string GetEnumResourceString(object enumValue)
    {
        Type enumType = enumValue.GetType();
        string value = Enum.GetName(enumValue.GetType(), enumValue);
        string resourceKey = String.Format("{0}_{1}", enumType.Name, value);
        string result = Resources.Enums.ResourceManager.GetString(resourceKey);
        if (string.IsNullOrEmpty(result))
        {
            result = String.Format("{0}", value);
        }
        return result;
    }
}

এখন যদি আমরা উপরের পদ্ধতিটি কল করার চেষ্টা করি তবে আমরা এটিকে কল করতে পারি

public void Foo()
{
  var col = Color.Red;
  Console.WriteLine (EnumUtils.GetEnumResourceString (col));
}

আপনাকে যা করতে হবে তা হ'ল সমস্ত এনুম্যুরেটর মান এবং সংশ্লিষ্ট স্ট্রিং যুক্ত একটি রিসোর্স ফাইল তৈরি করা

সংস্থান নাম রিসোর্স মান
রঙ_আর আমার স্ট্রিং রঙ লাল
কালার_ ব্লু ব্লু
রঙিন_গ্রীন হাল্ক রঙ

আসলে এটি সম্পর্কে খুব সুন্দর এটি হ'ল এটি যদি আপনার অ্যাপ্লিকেশনটির স্থানীয়করণের প্রয়োজন হয় তবে এটি খুব সহায়ক হবে, যেহেতু আপনাকে যা করতে হবে তা কেবল আপনার নতুন ভাষার সাথে অন্য একটি রিসোর্স ফাইল তৈরি করতে হবে! ও ভো-লা!


1

আমি যখন এমন পরিস্থিতিতে আছি তখন নীচের সমাধানটি প্রস্তাব করছি।

এবং একটি গ্রাহক শ্রেণি হিসাবে আপনি থাকতে পারে

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MyApp.Dictionaries
{
    class Greek
    {

        public static readonly string Alpha = "Alpha";
        public static readonly string Beta = "Beta";
        public static readonly string Gamma = "Gamma";
        public static readonly string Delta = "Delta";


        private static readonly BiDictionary<int, string> Dictionary = new BiDictionary<int, string>();


        static Greek() {
            Dictionary.Add(1, Alpha);
            Dictionary.Add(2, Beta);
            Dictionary.Add(3, Gamma);
            Dictionary.Add(4, Delta);
        }

        public static string getById(int id){
            return Dictionary.GetByFirst(id);
        }

        public static int getByValue(string value)
        {
            return Dictionary.GetBySecond(value);
        }

    }
}

এবং দ্বিদ্বিমা অভিধান ব্যবহার করে: এর ভিত্তিতে ( https://stackoverflow.com/a/255638/986160 ) ধরে ধরে যে কীগুলি অভিধানের একক মানের সাথে যুক্ত হবে এবং ( https://stackoverflow.com/a এর অনুরূপ) / 255630/986160 ) তবে কিছুটা মার্জিত। এই অভিধানটিও অগণনীয় এবং আপনি ইনস থেকে স্ট্রিংগুলিতে পিছনে পিছনে যেতে পারেন। এছাড়াও আপনার এই ক্লাসটি ব্যতীত আপনার কোডবেসে কোনও স্ট্রিং থাকার দরকার নেই।

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;

namespace MyApp.Dictionaries
{

    class BiDictionary<TFirst, TSecond> : IEnumerable
    {
        IDictionary<TFirst, TSecond> firstToSecond = new Dictionary<TFirst, TSecond>();
        IDictionary<TSecond, TFirst> secondToFirst = new Dictionary<TSecond, TFirst>();

        public void Add(TFirst first, TSecond second)
        {
            firstToSecond.Add(first, second);
            secondToFirst.Add(second, first);
        }

        public TSecond this[TFirst first]
        {
            get { return GetByFirst(first); }
        }

        public TFirst this[TSecond second]
        {
            get { return GetBySecond(second); }
        }

        public TSecond GetByFirst(TFirst first)
        {
            return firstToSecond[first];
        }

        public TFirst GetBySecond(TSecond second)
        {
            return secondToFirst[second];
        }

        public IEnumerator GetEnumerator()
        {
            return GetFirstEnumerator();
        }

        public IEnumerator GetFirstEnumerator()
        {
            return firstToSecond.GetEnumerator();
        }

        public IEnumerator GetSecondEnumerator()
        {
            return secondToFirst.GetEnumerator();
        }
    }
}

1

বৃহত্তর স্ট্রিং এনাম সেটগুলির জন্য, তালিকাভুক্ত উদাহরণ ক্লান্তিকর হয়ে উঠতে পারে। আপনি যদি স্থিতি কোডগুলির একটি তালিকা বা অন্যান্য স্ট্রিং ভিত্তিক এনামগুলির একটি তালিকা চান তবে একটি অ্যাট্রিবিউট সিস্টেমটি ব্যবহার করতে বিরক্ত করছে এবং নিজের উদাহরণ দিয়ে একটি স্ট্যাটিক বর্গ কনফিগার করতে বিরক্ত করছে। আমার নিজের সমাধানের জন্য, আমি স্ট্রিং-ব্যাকড এনামগুলি আরও সহজ করার জন্য টি 4 টেম্প্লেটিং ব্যবহার করি। এইচটিপিপিথ মেথড ক্লাস কীভাবে কাজ করে তার সমান ফলাফল প্রকাশিত হয়।

আপনি এটি এর মতো ব্যবহার করতে পারেন:

    string statusCode = ResponseStatusCode.SUCCESS; // Automatically converts to string when needed
    ResponseStatusCode codeByValueOf = ResponseStatusCode.ValueOf(statusCode); // Returns null if not found

    // Implements TypeConverter so you can use it with string conversion methods.
    var converter = System.ComponentModel.TypeDescriptor.GetConverter(typeof(ResponseStatusCode));
    ResponseStatusCode code = (ResponseStatusCode) converter.ConvertFromInvariantString(statusCode);

    // You can get a full list of the values
    bool canIterateOverValues = ResponseStatusCode.Values.Any(); 

    // Comparisons are by value of the "Name" property. Not by memory pointer location.
    bool implementsByValueEqualsEqualsOperator = "SUCCESS" == ResponseStatusCode.SUCCESS; 

আপনি একটি Enum.tt ফাইল দিয়ে শুরু করবেন।

<#@ include file="StringEnum.ttinclude" #>


<#+
public static class Configuration
{
    public static readonly string Namespace = "YourName.Space";
    public static readonly string EnumName = "ResponseStatusCode";
    public static readonly bool IncludeComments = true;

    public static readonly object Nodes = new
    {
        SUCCESS = "The response was successful.",
        NON_SUCCESS = "The request was not successful.",
        RESOURCE_IS_DISCONTINUED = "The resource requested has been discontinued and can no longer be accessed."
    };
}
#>

তারপরে, আপনি আপনার স্ট্রিংইনাম.টিনক্লাইভ ফাইলটিতে যুক্ত করুন।

<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Reflection" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ output extension=".cs" #>
<#@ CleanupBehavior processor="T4VSHost" CleanupAfterProcessingtemplate="true" #>

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

using System;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;

namespace <#= Configuration.Namespace #>
{
    /// <summary>
    /// TypeConverter implementations allow you to use features like string.ToNullable(T).
    /// </summary>
    public class <#= Configuration.EnumName #>TypeConverter : TypeConverter
    {
        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        {
            return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);
        }

        public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
        {
            var casted = value as string;

            if (casted != null)
            {
                var result = <#= Configuration.EnumName #>.ValueOf(casted);
                if (result != null)
                {
                    return result;
                }
            }

            return base.ConvertFrom(context, culture, value);
        }

        public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
        {
            var casted = value as <#= Configuration.EnumName #>;
            if (casted != null && destinationType == typeof(string))
            {
                return casted.ToString();
            }

            return base.ConvertTo(context, culture, value, destinationType);
        }
    }

    [TypeConverter(typeof(<#= Configuration.EnumName #>TypeConverter))]
    public class <#= Configuration.EnumName #> : IEquatable<<#= Configuration.EnumName #>>
    {
//---------------------------------------------------------------------------------------------------
// V A L U E S _ L I S T
//---------------------------------------------------------------------------------------------------
<# Write(Helpers.PrintEnumProperties(Configuration.Nodes)); #>

        private static List<<#= Configuration.EnumName #>> _list { get; set; } = null;
        public static List<<#= Configuration.EnumName #>> ToList()
        {
            if (_list == null)
            {
                _list = typeof(<#= Configuration.EnumName #>).GetFields().Where(x => x.IsStatic && x.IsPublic && x.FieldType == typeof(<#= Configuration.EnumName #>))
                    .Select(x => x.GetValue(null)).OfType<<#= Configuration.EnumName #>>().ToList();
            }

            return _list;
        }

        public static List<<#= Configuration.EnumName #>> Values()
        {
            return ToList();
        }

        /// <summary>
        /// Returns the enum value based on the matching Name of the enum. Case-insensitive search.
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static <#= Configuration.EnumName #> ValueOf(string key)
        {
            return ToList().FirstOrDefault(x => string.Compare(x.Name, key, true) == 0);
        }


//---------------------------------------------------------------------------------------------------
// I N S T A N C E _ D E F I N I T I O N
//---------------------------------------------------------------------------------------------------      
        public string Name { get; private set; }
        public string Description { get; private set; }
        public override string ToString() { return this.Name; }

        /// <summary>
        /// Implcitly converts to string.
        /// </summary>
        /// <param name="d"></param>
        public static implicit operator string(<#= Configuration.EnumName #> d)
        {
            return d.ToString();
        }

        /// <summary>
        /// Compares based on the == method. Handles nulls gracefully.
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        public static bool operator !=(<#= Configuration.EnumName #> a, <#= Configuration.EnumName #> b)
        {
            return !(a == b);
        }

        /// <summary>
        /// Compares based on the .Equals method. Handles nulls gracefully.
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        public static bool operator ==(<#= Configuration.EnumName #> a, <#= Configuration.EnumName #> b)
        {
            return a?.ToString() == b?.ToString();
        }

        /// <summary>
        /// Compares based on the .ToString() method
        /// </summary>
        /// <param name="o"></param>
        /// <returns></returns>
        public override bool Equals(object o)
        {
            return this.ToString() == o?.ToString();
        }

        /// <summary>
        /// Compares based on the .ToString() method
        /// </summary>
        /// <param name="other"></param>
        /// <returns></returns>
        public bool Equals(<#= Configuration.EnumName #> other)
        {
            return this.ToString() == other?.ToString();
        }

        /// <summary>
        /// Compares based on the .Name property
        /// </summary>
        /// <returns></returns>
        public override int GetHashCode()
        {
            return this.Name.GetHashCode();
        }
    }
}

<#+

public static class Helpers
{
        public static string PrintEnumProperties(object nodes)
        {
            string o = "";
            Type nodesTp = Configuration.Nodes.GetType();
            PropertyInfo[] props = nodesTp.GetProperties().OrderBy(p => p.Name).ToArray();

            for(int i = 0; i < props.Length; i++)
            {
                var prop = props[i];
                if (Configuration.IncludeComments)
                {
                    o += "\r\n\r\n";
                    o += "\r\n        ///<summary>";
                    o += "\r\n        /// "+Helpers.PrintPropertyValue(prop, Configuration.Nodes);
                    o += "\r\n        ///</summary>";
                }

                o += "\r\n        public static readonly "+Configuration.EnumName+" "+prop.Name+ " = new "+Configuration.EnumName+"(){ Name = \""+prop.Name+"\", Description = "+Helpers.PrintPropertyValue(prop, Configuration.Nodes)+ "};";
            }

            o += "\r\n\r\n";

            return o;
        }

        private static Dictionary<string, string> GetValuesMap()
        {
            Type nodesTp = Configuration.Nodes.GetType();
            PropertyInfo[] props= nodesTp.GetProperties();
            var dic = new Dictionary<string,string>();
            for(int i = 0; i < props.Length; i++)
            {
                var prop = nodesTp.GetProperties()[i];
                dic[prop.Name] = prop.GetValue(Configuration.Nodes).ToString();
            }
            return dic;
        }

        public static string PrintMasterValuesMap(object nodes)
        {
            Type nodesTp = Configuration.Nodes.GetType();
            PropertyInfo[] props= nodesTp.GetProperties();
            string o = "        private static readonly Dictionary<string, string> ValuesMap = new Dictionary<string, string>()\r\n        {";
            for(int i = 0; i < props.Length; i++)
            {
                var prop = nodesTp.GetProperties()[i];
                o += "\r\n            { \""+prop.Name+"\", "+(Helpers.PrintPropertyValue(prop,Configuration.Nodes)+" },");
            }
            o += ("\r\n        };\r\n");

            return o;
        }


        public static string PrintPropertyValue(PropertyInfo prop, object objInstance)
        {
            switch(prop.PropertyType.ToString()){
                case "System.Double":
                    return prop.GetValue(objInstance).ToString()+"D";
                case "System.Float":
                    return prop.GetValue(objInstance).ToString()+"F";
                case "System.Decimal":
                    return prop.GetValue(objInstance).ToString()+"M";
                case "System.Long":
                    return prop.GetValue(objInstance).ToString()+"L";
                case "System.Boolean":
                case "System.Int16":
                case "System.Int32":
                    return prop.GetValue(objInstance).ToString().ToLowerInvariant();
                case "System.String":
                    return "\""+prop.GetValue(objInstance)+"\"";
            }

            return prop.GetValue(objInstance).ToString();
        }

        public static string _ (int numSpaces)
        {
            string o = "";
            for(int i = 0; i < numSpaces; i++){
                o += " ";
            }

            return o;
        }
}
#>

অবশেষে, আপনি আপনার Enum.tt ফাইলটি পুনরায় সংকলন করুন এবং আউটপুটটি দেখতে এমন দেখাচ্ছে:

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

using System;
using System.Linq;
using System.Collections.Generic;

namespace YourName.Space
{
    public class ResponseStatusCode
    {
//---------------------------------------------------------------------------------------------------
// V A L U E S _ L I S T 
//---------------------------------------------------------------------------------------------------



        ///<summary>
        /// "The response was successful."
        ///</summary>
        public static readonly ResponseStatusCode SUCCESS = new ResponseStatusCode(){ Name = "SUCCESS", Description = "The response was successful."};


        ///<summary>
        /// "The request was not successful."
        ///</summary>
        public static readonly ResponseStatusCode NON_SUCCESS = new ResponseStatusCode(){ Name = "NON_SUCCESS", Description = "The request was not successful."};


        ///<summary>
        /// "The resource requested has been discontinued and can no longer be accessed."
        ///</summary>
        public static readonly ResponseStatusCode RESOURCE_IS_DISCONTINUED = new ResponseStatusCode(){ Name = "RESOURCE_IS_DISCONTINUED", Description = "The resource requested has been discontinued and can no longer be accessed."};


        private static List<ResponseStatusCode> _list { get; set; } = null;
        public static List<ResponseStatusCode> ToList()
        {
            if (_list == null)
            {
                _list = typeof(ResponseStatusCode).GetFields().Where(x => x.IsStatic && x.IsPublic && x.FieldType == typeof(ResponseStatusCode))
                    .Select(x => x.GetValue(null)).OfType<ResponseStatusCode>().ToList();
            }

            return _list;
        }

        public static List<ResponseStatusCode> Values()
        {
            return ToList();
        }

        /// <summary>
        /// Returns the enum value based on the matching Name of the enum. Case-insensitive search.
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static ResponseStatusCode ValueOf(string key)
        {
            return ToList().FirstOrDefault(x => string.Compare(x.Name, key, true) == 0);
        }


//---------------------------------------------------------------------------------------------------
// I N S T A N C E _ D E F I N I T I O N 
//---------------------------------------------------------------------------------------------------       
        public string Name { get; set; }
        public string Description { get; set; }
        public override string ToString() { return this.Name; }

        /// <summary>
        /// Implcitly converts to string.
        /// </summary>
        /// <param name="d"></param>
        public static implicit operator string(ResponseStatusCode d)
        {
            return d.ToString();
        }

        /// <summary>
        /// Compares based on the == method. Handles nulls gracefully.
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        public static bool operator !=(ResponseStatusCode a, ResponseStatusCode b)
        {
            return !(a == b);
        }

        /// <summary>
        /// Compares based on the .Equals method. Handles nulls gracefully.
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        public static bool operator ==(ResponseStatusCode a, ResponseStatusCode b)
        {
            return a?.ToString() == b?.ToString();
        }

        /// <summary>
        /// Compares based on the .ToString() method
        /// </summary>
        /// <param name="o"></param>
        /// <returns></returns>
        public override bool Equals(object o)
        {
            return this.ToString() == o?.ToString();
        }

        /// <summary>
        /// Compares based on the .Name property
        /// </summary>
        /// <returns></returns>
        public override int GetHashCode()
        {
            return this.Name.GetHashCode();
        }
    }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.