সি # তে স্ট্রিংগুলির সাথে এনামগুলিকে যুক্ত করা হচ্ছে


361

আমি জানি যে নিম্নলিখিতগুলি সম্ভব নয় কারণ গণনার ধরনটি অন্তর্নিহিত হতে হবে

enum GroupTypes
{
    TheGroup = "OEM",
    TheOtherGroup = "CMB"
}

আমার ডাটাবেস থেকে আমি অসম্পূর্ণ কোড (এবং OEMএবং CMB) এর সাথে একটি ক্ষেত্র পাই । আমি এই ক্ষেত্রটিকে একটি enumবা অন্য কিছু বোধগম্য করে তুলতে চাই। কারণ লক্ষ্যটি যদি পঠনযোগ্যতা হয় তবে সমাধানটি কাটা উচিত।

আমার আর কোন বিকল্প নেই?



12
আমি নিশ্চিত না কেন বেশিরভাগ উত্তর কেবল "কনস্ট্রিং স্ট্রিং" ব্যবহার করে না এবং পরিবর্তে তারা কাস্টম ক্লাস করে চলেছে।
সিটিএস_এই

1
আপনি স্ট্রিং ব্যবহার করতে সক্ষম নাও হতে পারেন তবে আপনি অক্ষরটি ঠিকঠাক ব্যবহার করতে পারেন। আপনি যদি একক-বর্ণের মান ব্যবহার করতে পারেন তবে এটি একটি বিকল্প।
টি। সার

1
সিটিএস_এই দ্বারা উপরে প্রস্তাবিত সমাধানটি শীর্ষ তিনটি উত্তরে কেন নেই তা সম্পর্কে সত্যই বিভ্রান্ত।
সিঞ্জাই

@ সিনজাই সম্পর্কিত মানগুলির সুস্পষ্ট গোষ্ঠীকরণ বিশেষত একটি এপিআই বা পুনঃব্যবহারযোগ্য উপাদানগুলিতে একটি দুর্ভেদ্য কর্মক্ষমতা হ্রাসের জরিমানা ছাড়িয়ে যাবে।
ব্যক্তি

উত্তর:


402

আমি পদ্ধতির পরিবর্তে শ্রেণিতে বৈশিষ্ট্যগুলি ব্যবহার করতে পছন্দ করি , কারণ তারা আরও এনাম-মত দেখায়।

লগারের জন্য এখানে একটি উদাহরণ:

public class LogCategory
{
    private LogCategory(string value) { Value = value; }

    public string Value { get; set; }

    public static LogCategory Trace   { get { return new LogCategory("Trace"); } }
    public static LogCategory Debug   { get { return new LogCategory("Debug"); } }
    public static LogCategory Info    { get { return new LogCategory("Info"); } }
    public static LogCategory Warning { get { return new LogCategory("Warning"); } }
    public static LogCategory Error   { get { return new LogCategory("Error"); } }
}

পরামিতি হিসাবে টাইপ-নিরাপদ স্ট্রিং মানগুলিতে পাস করুন :

public static void Write(string message, LogCategory logCategory)
{
    var log = new LogEntry { Message = message };
    Logger.Write(log, logCategory.Value);
}

ব্যবহার:

Logger.Write("This is almost like an enum.", LogCategory.Info);

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

3
এবং অভিধান <লগক্যাটগরী, অ্যাকশন / ফানক >টিকে একটি স্যুইচ হিসাবে ব্যবহার করা সহজ। :)
আরনিস ল্যাপসা 16

4
@ArnisL। এটি কী হিসাবে কাজ করার পক্ষে যথেষ্ট নয়, আপনাকে সমান () এবং গেটহ্যাশকোড () ওভাররাইড করতে হবে এবং আপনাকে মান সম্পত্তি সেটটারটি ব্যক্তিগত করতে হবে। তবুও, এটি কোনও এনাম নয়।
ডেভ ভ্যান ডেন এয়েণ্ডে

21
আমার নিজের ব্যবহারের জন্য, আমি ToStringফিরে আসার পদ্ধতিটিকে ওভাররাইড করে এই ধারণাটি প্রসারিত করেছি Value। এবং তারপরে এবং স্ট্রিং থেকে অন্তর্ভুক্ত কাস্ট অপারেটর সরবরাহ করে। public static implicit operator String(LogCategory category) { return Value; }
জেরেফেথ

6
সুইচ ক্ষেত্রে এটি ব্যবহার সম্পর্কে কি?
ডেভিড

176

আপনি এক্সটেনশন মডেলটিও ব্যবহার করতে পারেন:

public enum MyEnum
{
    [Description("String 1")]
    V1= 1,
    [Description("String 2")]
    V2= 2
} 

আপনার এক্সটেনশন ক্লাস

public static class MyEnumExtensions
{
    public static string ToDescriptionString(this MyEnum val)
    {
        DescriptionAttribute[] attributes = (DescriptionAttribute[])val
           .GetType()
           .GetField(val.ToString())
           .GetCustomAttributes(typeof(DescriptionAttribute), false);
        return attributes.Length > 0 ? attributes[0].Description : string.Empty;
    }
} 

ব্যবহার:

MyEnum myLocal = MyEnum.V1;
print(myLocal.ToDescriptionString());

3
অন্য এক্সটেনশনের জন্য এবং স্ট্রিং থেকে এনুমে পর্যন্ত বর্ণনা হিসাবে স্ট্যাকওভারফ্লো.com/ প্রশ্নগুলি / 67৩4377২/ / দেখুন See
ডেভ

14
আমি ভাবতে সাহায্য করতে পারি না যে প্রতিবার আপনি পাঠ্যটি প্রদর্শন করতে চান এনাম প্রতিফলিত করা পারফরম্যান্সের দৃষ্টিকোণ থেকে একরকম বেদনাদায়ক শোনায়!
লিথ

4
@ লিয়াথ - দ্য টুস্ট্রিং () `ইতিমধ্যে প্রতিচ্ছবি ব্যবহার করেছে, সুতরাং আপনি এই পদ্ধতির সাথে সত্যিকার অর্থে কোনও কিছু হারাচ্ছেন না এবং পাঠযোগ্যতা অর্জন করছেন
জেমস কিং

1
আপনি কি এক্সটেনশনটিকে জেনেরিক তৈরি করতে পারেন তাই এটি সমস্ত এনামগুলিতে স্বয়ংক্রিয়ভাবে প্রয়োগ হয়?
এরোসবে

3
জেনেরিক তৈরি করতে, public static string ToDescriptionString(this Enum ...স্পষ্টভাবে টাইপ না করেই ব্যবহার করুন MyEnum
লিস্যাবল

100

ধ্রুবকগুলির সাথে স্থির শ্রেণীর ব্যবহার সম্পর্কে কীভাবে?

static class GroupTypes
{
  public const string TheGroup = "OEM";
  public const string TheOtherGroup = "CMB";
}

void DoSomething(string groupType)
{
  if(groupType == GroupTypes.TheGroup)
  {
    // Be nice
  }  
  else if (groupType == GroupTypes.TheOtherGroup)
  {
    // Continue to be nice
  }
  else
  {
    // unexpected, throw exception?
  }
}

9
একমত। আমি আরও জটিল সমাধানগুলির পিছনে উদ্দেশ্যটি দেখতে সমস্যা বোধ করছি, ফলস্বরূপ ফলস্বরূপ "এনাম" এ পরিবর্তন করতে সক্ষম হওয়া ব্যতীত।
ভুয়া লিফট

@ ফেকলেফ্ট আপনি জেনেরিক টাইপ (টেমপ্লেট) সহ স্ট্যাটিক ক্লাস টাইপ এবং অন্য সীমাবদ্ধতা ব্যবহার করতে পারবেন না, আমি মনে করি এই কারণেই লোকেরা "আরও জটিল" সমাধানগুলি পছন্দ করেন।
eselk

2
এই কাজ করার জন্য
ধ্রুবকদের

46
স্ট্যাটিক প্রকারগুলি পরামিতি হিসাবে ব্যবহার করা যায় না।
পেড্রো মোরিরা

2
@ পেডোমুরিরা যেমন উল্লেখ করেছেন, আপনি GroupTypesআর্গুমেন্টের ধরণ হিসাবে পাস করতে পারবেন না কারণ এটি একটি স্ট্যাটিক শ্রেণি। এমনকি মুইনের উত্তর সলভ করে এমন সমস্যা। এই ক্ষেত্রে আপনার পরিবর্তে থাকতে হবে void DoSomething(string groupType), যার অর্থ এর অর্থ যে কোনও স্ট্রিংয়ের মানgroupType থাকতে পারে , এমনকী মানগুলিও যা আপনি প্রত্যাশা করছেন না, যার অর্থ আপনাকে সেই অবৈধ ধরণের জন্য প্রস্তুত থাকতে হবে এবং সেগুলি কীভাবে পরিচালনা করতে হবে (উদাহরণস্বরূপ) একটি ব্যতিক্রম নিক্ষেপ করে)। এমনকি মিয়েনের উত্তর ক্লাস দ্বারা সংজ্ঞায়িত বিকল্পগুলিতে বৈধ ইনপুটগুলির সংখ্যা সীমাবদ্ধ করে সমাধান করে । LogCategory
ফারাপ

30

আপনি গণনায় আইটেমগুলিতে গুণাবলী যুক্ত করতে পারেন এবং তারপরে বৈশিষ্ট্যগুলি থেকে মানগুলি পেতে প্রতিবিম্বটি ব্যবহার করতে পারেন।

আপনাকে এই জাতীয় বৈশিষ্ট্য প্রয়োগ করতে "ক্ষেত্র" নির্দিষ্টকরণকারী ব্যবহার করতে হবে:

enum GroupTypes
{
    [field:Description("OEM")]
    TheGroup,

    [field:Description("CMB")]
    TheOtherGroup
}

তারপরে আপনি এনামের ধরণের স্ট্যাটিক ক্ষেত্রগুলি প্রতিফলিত করতে পারেন (এই ক্ষেত্রে গ্রুপটিপস) এবং DescriptionAttributeপ্রতিফলনটি ব্যবহার করার জন্য আপনি যে মানটি খুঁজছিলেন তা পাবেন:

public static DescriptionAttribute GetEnumDescriptionAttribute<T>(
    this T value) where T : struct
{
    // The type of the enum, it will be reused.
    Type type = typeof(T);

    // If T is not an enum, get out.
    if (!type.IsEnum) 
        throw new InvalidOperationException(
            "The type parameter T must be an enum type.");

    // If the value isn't defined throw an exception.
    if (!Enum.IsDefined(type, value))
        throw new InvalidEnumArgumentException(
            "value", Convert.ToInt32(value), type);

    // Get the static field for the value.
    FieldInfo fi = type.GetField(value.ToString(), 
        BindingFlags.Static | BindingFlags.Public);

    // Get the description attribute, if there is one.
    return fi.GetCustomAttributes(typeof(DescriptionAttribute), true).
        Cast<DescriptionAttribute>().SingleOrDefault();
}

আমি DescriptionAttributeউপরে বর্ণিত বৈশিষ্ট্যটি প্রয়োগ করা হয়েছে কি না তা নির্ধারণ করতে সক্ষম হতে চাইলে উপরেরটি নিজেই ফিরিয়ে আনার সিদ্ধান্ত নিয়েছি ।


যদিও আমি এটি আরও জটিল পরিস্থিতির জন্য মনে রাখব, আমি ওপি
বরিস ক্যালেন্স

26

আপনি আসলে এটি খুব সহজেই করতে পারেন। নিম্নলিখিত কোড ব্যবহার করুন।

enum GroupTypes
{
   OEM,
   CMB
};

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

String oemString = Enum.GetName(typeof(GroupTypes), GroupTypes.OEM);

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


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

আমি কেবল এটির সম্পর্কে সচেতন তা হ'ল আমি বিশ্বাস করি এটি স্ট্রিংটি বের করার জন্য প্রতিবিম্বটি ব্যবহার করে। ফলস্বরূপ যদি আমি একটি ধ্রুবক স্ট্রিংয়ের উপর নজর রাখার সমাধানের পরে থাকি তবে আমি সাধারণত আমার ধ্রুবক স্ট্রিংগুলির বেশিরভাগ সঞ্চয় করার জন্য একটি শ্রেণি ব্যবহার করব। তবে আমার যদি এমন পরিস্থিতি হয় যেখানে এনুম সঠিক সমাধান হয় (আমার এনাম উপাদানগুলির সম্পর্কে বর্ণনামূলক স্ট্রিং নির্বিশেষে) তবে কোথাও চারপাশে ভাসমান অতিরিক্ত স্ট্রিং না করে পরিচালনা করার জন্য আমি বর্ণিত এনাম মানটি ব্যবহার করি।
আর্থার সি

+1 এটি সেরা এবং সহজ উত্তর, এটি প্রমাণ করার জন্য এখানেও উচ্চ ভোট রয়েছে । আপনি যখন পাঠ্যে শূন্যস্থান প্রয়োজন (তখন আরও বিশদ এখানে ) কেবলমাত্র এক্সটেনশন মডেলটি ব্যবহার করা ভাল ।
শার্পসি

14
না, এটি কেবল এনাম মানটির নাম পাচ্ছে, এনুম মানকে স্ট্রিং বরাদ্দ করে না। ওপির লক্ষ্য এনাম মানের থেকে একটি স্ট্রিং থাকা যেমন: দ্যগ্রুপ = "ই এম", থিওগ্রোগ্রপ = "সিএমবি"।
টিম অটিন

3
আমি সম্মত সঙ্গে @ টিম এর মন্তব্য, এই না কি ওপি করতে চেষ্টা করছে। আপনি যদি ভাবছেন যে এর ব্যবহারের ক্ষেত্রটি কী, তবে এমন একটি পরিস্থিতি বিবেচনা করুন যেখানে কোনও ডিভাইস কমান্ড হিসাবে স্ট্রিং নেয়, তবে কমান্ডের একটি "মানব পাঠযোগ্য" সংস্করণও হওয়া দরকার। "আপডেট ফার্মওয়্যার" এর মতো কিছু "UPDATEFW" কমান্ডের সাথে সংযুক্ত করার জন্য আমার এই দরকার ছিল।
জেলথন

20

স্থির শ্রেণিতে ধ্রুবক যুক্ত করার চেষ্টা করুন। আপনি কোনও প্রকার দিয়ে শেষ করবেন না, তবে আপনার পঠনযোগ্য, সংগঠিত ধ্রুবক থাকবে:

public static class GroupTypes {

    public const string TheGroup = "OEM";
    public const string TheOtherGroup = "CMB";

}

3
কোড থেকে বর্ণনামূলক নামে ফিরে যেতে অসুবিধা। একটি ম্যাচ সন্ধান করতে আপনাকে সমস্ত কনস্ট ক্ষেত্রের উপর প্রতিচ্ছবি ব্যবহার করতে হবে।
andleer

1
@ এন্ডলিয়ার আমি আপনার উদ্বেগ বুঝতে পারি না। এই আমি ব্যবহার সমাধান।
ভিএসও

হ্যাঁ এটি আসলে যা আমি চেয়েছিলাম ঠিক তা-ই। এবং এটি আমি দেখতে সবচেয়ে সংক্ষিপ্ত / মার্জিত সমাধান, ঠিক যেমন আমি একটি গণনা ডাব্লু / ইনট মানগুলি সংজ্ঞায়িত করছি - তবে তার পরিবর্তে স্ট্রিং মান সহ। 100% নিখুঁত।
চাদ

3
এটির সাথে সমস্যাটি হ'ল এটি এনাম হিসাবে বিবেচনা করে না যে আমাদের মূল্যবোধের সীমাবদ্ধ তালিকা সহ একটি পৃথক প্রকার থাকবে না। এগুলি প্রত্যাশা করে একটি ফাংশন ফ্রি-ফর্ম স্ট্রিংয়ের সাথে ব্যবহার করা যেতে পারে যা ত্রুটিযুক্ত।
হুয়ান মার্টিনেজ

14

নিম্নলিখিত ডিবিতে আপনার ডিবির জন্য একটি দ্বিতীয় এনাম তৈরি করুন:

enum DBGroupTypes
{
    OEM = 0,
    CMB = 1
}

এখন, আপনি "OEM" এবং "সিএমবি" স্ট্রিং থেকে সঠিক ডিবিগ্রুপ টাইপস মানটি পেতে Enum.Parse ব্যবহার করতে পারেন। তারপরে আপনি এগুলিকে ইনটে রূপান্তর করতে পারবেন এবং আপনার মডেলটিতে আরও সঠিক ডান গণনাটি থেকে সঠিক মানগুলি উদ্ধার করতে পারবেন।


প্রক্রিয়াটির এটি একটি অতিরিক্ত পদক্ষেপ বলে মনে হচ্ছে, কেন একটি শ্রেণি সব কিছু পরিচালনা করে না?
সি। রস

11
বৈশিষ্ট্য এবং প্রতিবিম্ব ব্যবহারের বিরোধিতা হিসাবে?
ডেভ ভ্যান ডেন এেন্ডে

13

একটি ক্লাস ব্যবহার করুন।

সম্পাদনা: আরও ভাল উদাহরণ

class StarshipType
{
    private string _Name;
    private static List<StarshipType> _StarshipTypes = new List<StarshipType>();

    public static readonly StarshipType Ultralight = new StarshipType("Ultralight");
    public static readonly StarshipType Light = new StarshipType("Light");
    public static readonly StarshipType Mediumweight = new StarshipType("Mediumweight");
    public static readonly StarshipType Heavy = new StarshipType("Heavy");
    public static readonly StarshipType Superheavy = new StarshipType("Superheavy");

    public string Name
    {
        get { return _Name; }
        private set { _Name = value; }
    }

    public static IList<StarshipType> StarshipTypes
    {
        get { return _StarshipTypes; }
    }

    private StarshipType(string name, int systemRatio)
    {
        Name = name;
        _StarshipTypes.Add(this);
    }

    public static StarshipType Parse(string toParse)
    {
        foreach (StarshipType s in StarshipTypes)
        {
            if (toParse == s.Name)
                return s;
        }
        throw new FormatException("Could not parse string.");
    }
}

1
কোড থেকে বর্ণনামূলক নামে ফিরে যেতে অসুবিধা। একটি ম্যাচ সন্ধান করতে আপনাকে সমস্ত কনস্ট ক্ষেত্রের উপর প্রতিচ্ছবি ব্যবহার করতে হবে।
andleer

1
আমি আপনার পয়েন্ট দেখুন. আমি পরে এমন এক সংস্করণ আপলোড করব যা পরে তীব্রভাবে কাজ করে তবে আমি স্বীকার করি এটি বেশ ভারী।
সি রস 13


7

সমস্যাটি মোকাবেলার আরেকটি উপায় হ'ল একটি এনাম এবং স্ট্রিংগুলির একটি অ্যারে থাকে যা স্ট্রিংগুলির তালিকার সাথে এনাম মানগুলিকে মানচিত্র করে তোলে:

public enum GroupTypes
{
    TheGroup  = 0,
    TheOtherGroup 
}

string[] GroupTypesStr = {
    "OEM",
    "CMB"
};

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

Log.Write(GroupTypesStr[(int)GroupTypes.TheOtherGroup]);

এটি সিএমবিকে অনুরোধ জানাবে

পেশাদাররা:

  1. সহজ এবং পরিষ্কার কোড।
  2. উচ্চ কার্যকারিতা (বিশেষত ক্লাস ব্যবহার করে এমন পদ্ধতির তুলনায়)

কনস:

  1. তালিকাটি সম্পাদনা করার সময় তালগোল পাকানোর প্রবণতা থাকলেও একটি সংক্ষিপ্ত তালিকার জন্য এটি ঠিক থাকবে।

6

স্ট্রিং হিসাবে এনাম মানটি পেতে আমি যে এক্সটেনশন পদ্ধতিটি ব্যবহার করেছি তা এখানে। প্রথমে এখানে এনাম।

public enum DatabaseEnvironment
{
    [Description("AzamSharpBlogDevDatabase")]
    Development = 1, 
    [Description("AzamSharpBlogQADatabase")]
    QualityAssurance = 2, 
    [Description("AzamSharpBlogTestDatabase")] 
    Test = 3
}

বর্ণনা বৈশিষ্ট্যটি সিস্টেম.কম্পোনমেন্টমোডেল থেকে এসেছে।

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

public static string GetValueAsString(this DatabaseEnvironment environment) 
{
    // get the field 
    var field = environment.GetType().GetField(environment.ToString());
    var customAttributes = field.GetCustomAttributes(typeof (DescriptionAttribute), false);

    if(customAttributes.Length > 0)
    {
        return (customAttributes[0] as DescriptionAttribute).Description;  
    }
    else
    {
        return environment.ToString(); 
    }
}

এখন, আপনি নিম্নলিখিত কোড ব্যবহার করে স্ট্রিং মান হিসাবে এনাম অ্যাক্সেস করতে পারেন:

[TestFixture]
public class when_getting_value_of_enum
{
    [Test]
    public void should_get_the_value_as_string()
    {
        Assert.AreEqual("AzamSharpBlogTestDatabase",DatabaseEnvironment.Test.GetValueAsString());  
    }
}

5

আপনি কি অভিধান ব্যবহার করে একটি সারণী বিবেচনা করেছেন?

enum GroupTypes
{
    TheGroup,
    TheOtherGroup
}

Dictionary<string, GroupTypes> GroupTypeLookup = new Dictionary<string, GroupTypes>();
// initialize lookup table:
GroupTypeLookup.Add("OEM", TheGroup);
GroupTypeLookup.Add("CMB", TheOtherGroup);

তারপরে আপনি স্ট্রিংটি পড়ার পরে গ্রুপটাইপলুকআপ.ট্রিগেটভ্যালু () ব্যবহার করতে পারেন।


আপনি কীভাবে সহজে কোনও প্রদত্ত মূল্যের কীটি পাবেন?
এগ্লাসিয়াস

প্রশ্নটি অন্যভাবে যেতে বললো না। তবে এটি অন্যরকমভাবে চলে এমন একটি অভিধান তৈরি করার পক্ষে যথেষ্ট সহজ। এটি, অভিধান <গ্রুপ টাইপস, স্ট্রিং>।
জিম মিশেল

4
public class DataType
{
    private readonly string value;
    private static readonly Dictionary<string, DataType> predefinedValues;

    public static readonly DataType Json = new DataType("json");
    public static readonly DataType Xml = new DataType("xml");
    public static readonly DataType Text = new DataType("text");
    public static readonly DataType Html = new DataType("html");
    public static readonly DataType Binary = new DataType("binary");

    static DataType()
    {
        predefinedValues = new Dictionary<string, DataType>();
        predefinedValues.Add(Json.Value, Json);
        predefinedValues.Add(Xml.Value, Xml);
        predefinedValues.Add(Text.Value, Text);
        predefinedValues.Add(Html.Value, Html);
        predefinedValues.Add(Binary.Value, Binary);
    }

    private DataType(string value)
    {
        this.value = value;
    }

    public static DataType Parse(string value)
    {
        var exception = new FormatException($"Invalid value for type {nameof(DataType)}");
        if (string.IsNullOrEmpty(value))
            throw exception;

        string key = value.ToLower();
        if (!predefinedValues.ContainsKey(key))
            throw exception;

        return predefinedValues[key];
    }

    public string Value
    {
        get { return value; }
    }
}

3

সি # গণিত স্ট্রিং সমর্থন করে না, তবে বেশিরভাগ পরিস্থিতিতে আপনি পছন্দসই প্রভাব পেতে একটি তালিকা বা অভিধান ব্যবহার করতে পারেন।

যেমন পাস / ব্যর্থ ফলাফল মুদ্রণ করতে:

List<string> PassFail = new List<string> { "FAIL", "PASS" };
bool result = true;
Console.WriteLine("Test1: " + PassFail[result.GetHashCode()]);

2

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

অর্থাৎ,

public class Group
{
    public string Value{ get; set; }
    public Group( string value ){ Value = value; } 
    public static Group TheGroup() { return new Group("OEM"); }
    public static Group OtherGroup() { return new Group("CMB"); }

}

2

আমি কেবল একটি অভিধান তৈরি করব এবং কোডটি কী হিসাবে ব্যবহার করব।

সম্পাদনা করুন: বিপরীত চেহারা (কীটি সন্ধান করা) করার বিষয়ে মন্তব্যটি সম্বোধন করার জন্য, এটি মারাত্মকভাবে দক্ষ হবে না। এটি যদি প্রয়োজন হয় তবে আমি এটি পরিচালনা করতে একটি নতুন ক্লাস লিখব।


এছাড়াও আপনি সহজেই কোনও প্রদত্ত মানের জন্য কীটি দখল করতে পারেন?
উদাগ্রাহ্য

টু সি। রোস - আপনার অর্থ কী তা আমি নিশ্চিত নই। আপনি একটি ডিবি থেকে মানগুলি পড়তে পারেন এবং গতিশীলভাবে অভিধানটি পপুলেট করতে পারেন।
ঝাল

2

আমার প্রথম প্রশ্ন - আপনার নিজেরাই ডেটাবেস অ্যাক্সেস আছে? এটি ডাটাবেসে সাধারণ করা উচিত, আদর্শভাবে, অন্যথায়, কোনও সমাধান ত্রুটির প্রবণ হতে চলেছে। আমার অভিজ্ঞতায়, "OEM" এবং "সিএমবি" পূর্ণ ডেটা ক্ষেত্রগুলি সময়ের সাথে সাথে "oem" এবং অন্যান্য 'ক্র্যাপ ডেটা'-এর মতো জিনিসগুলি মিশ্রিত করে .... আপনি যদি এটি স্বাভাবিক করতে পারেন তবে আপনি কীটি ব্যবহার করতে পারেন টেবিলটিতে আপনার এনুম হিসাবে উপাদানগুলি রয়েছে এবং আপনি অনেক ক্লিনার কাঠামো সহ সম্পন্ন করেছেন।

যদি এটি উপলব্ধ না হয় তবে আমি আপনার এনাম তৈরি করব এবং আপনার স্ট্রিংটি আপনার জন্য এনামে পার্স করার জন্য একটি ক্লাস তৈরি করব। এটি কমপক্ষে আপনাকে এনাম. পার্স / রিফ্লেকশন / ইত্যাদি ব্যবহার করে ওয়ার্কআউন্ডের কোনও কাজ করার চেয়ে ত্রুটিগুলি আটকাতে বা পরিচালনা করার ক্ষেত্রে কমপক্ষে স্বাচ্ছন্দ্য দেয় hand একটি অভিধান কাজ করবে তবে আপনার যদি কেস ইস্যু ইত্যাদি থাকে তবে তা ভেঙে যেতে পারে

আমি একটি ক্লাস লেখার সুপারিশ করব যাতে আপনি এটি করতে পারেন:

// I renamed this to GroupType, since it sounds like each element has a single type...
GroupType theType = GroupTypeParser.GetGroupType(theDBString);

এটি ডিবি পরিবর্তন না করে আপনার বেশিরভাগ পাঠযোগ্যতার সংরক্ষণ করে।


2

আমি যদি সঠিকভাবে বুঝতে পারি তবে আপনার স্ট্রিং থেকে এনামে রূপান্তর দরকার:

enum GroupTypes {
    Unknown = 0,
    OEM = 1,
    CMB = 2
}
static GroupTypes StrToEnum(string str){
    GroupTypes g = GroupTypes.Unknown;
    try {
        object o = Enum.Parse(typeof(GroupTypes), str, true);
        g = (GroupTypes)(o ?? 0);
    } catch {
    }
    return g;
}
// then use it like this
GroupTypes g1 = StrToEnum("OEM");
GroupTypes g2 = StrToEnum("bad value");

আপনি যদি চান তবে এনাম টাইপের জন্য জেনেরিকগুলি দিয়ে এটি আরও অভিনব করতে পারেন।


2

ভিএস 2015 এ, আপনি নাম ব্যবহার করতে পারেন

public class LogCategory
{
    public static string Trace;
    public static string Debug;
    public static string Info;
    public static string Warning;
    public static string Error;
}

ব্যবহার:

Logger.Write("This is almost like an enum.", nameof(LogCategory.Info));

2

গ্লেনুলার এক্সটেনশন পদ্ধতিতে একটি ছোট ঝাঁকুনি, যাতে আপনি কেবল ENUM ব্যতীত অন্য জিনিসগুলিতে এক্সটেনশনটি ব্যবহার করতে পারেন;

using System;
using System.ComponentModel;
namespace Extensions {
    public static class T_Extensions {
        /// <summary>
        /// Gets the Description Attribute Value
        /// </summary>
        /// <typeparam name="T">Entity Type</typeparam>
        /// <param name="val">Variable</param>
        /// <returns>The value of the Description Attribute or an Empty String</returns>
        public static string Description<T>(this T t) {
            DescriptionAttribute[] attributes = (DescriptionAttribute[])t.GetType().GetField(t.ToString()).GetCustomAttributes(typeof(DescriptionAttribute), false);
            return attributes.Length > 0 ? attributes[0].Description : string.Empty;
        }
    }
}

বা লিনক ব্যবহার করে

using System;
using System.ComponentModel;
using System.Linq;

namespace Extensions {


public static class T_Extensions {
        public static string Description<T>(this T t) =>
            ((DescriptionAttribute[])t
            ?.GetType()
            ?.GetField(t?.ToString())
            ?.GetCustomAttributes(typeof(DescriptionAttribute), false))
            ?.Select(a => a?.Description)
            ?.FirstOrDefault() 
            ?? string.Empty;  
    }
}

2

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

এতদূর আমি নিম্নলিখিত ফলাফলগুলি পেয়েছি:

        Console.WriteLine(TestEnum.Test1);//displays "TEST1"

        bool test = "TEST1" == TestEnum.Test1; //true

        var test2 = TestEnum.Test1; //is TestEnum and has value

        string test3 = TestEnum.Test1; //test3 = "TEST1"

        var test4 = TestEnum.Test1 == TestEnum.Test2; //false
         EnumType<TestEnum> test5 = "TEST1"; //works fine

        //TestEnum test5 = "string"; DOESN'T compile .... :(:(

যেখানে যাদুগুলি ঘটে:

public abstract  class EnumType<T>  where T : EnumType<T>   
{

    public  string Value { get; set; }

    protected EnumType(string value)
    {
        Value = value;
    }


    public static implicit operator EnumType<T>(string s)
    {
        if (All.Any(dt => dt.Value == s))
        {
            Type t = typeof(T);

            ConstructorInfo ci = t.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic,null, new Type[] { typeof(string) }, null);

            return (T)ci.Invoke(new object[] {s});
        }
        else
        {
            return null;
        }
    }

    public static implicit operator string(EnumType<T> dt)
    {
        return dt?.Value;
    }


    public static bool operator ==(EnumType<T> ct1, EnumType<T> ct2)
    {
        return (string)ct1 == (string)ct2;
    }

    public static bool operator !=(EnumType<T> ct1, EnumType<T> ct2)
    {
        return !(ct1 == ct2);
    }


    public override bool Equals(object obj)
    {
        try
        {
            return (string)obj == Value;
        }
        catch
        {
            return false;
        }
    }

    public override int GetHashCode()
    {
        return Value.GetHashCode();
    }

    public static IEnumerable<T> All
     => typeof(T).GetProperties()
       .Where(p => p.PropertyType == typeof(T))
       .Select(x => (T)x.GetValue(null, null));



}

আমাকে কেবল তখনই আমার এনামদের জন্য এটি ঘোষণা করতে হবে:

public class TestEnum : EnumType<TestEnum> 
{

    private TestEnum(string value) : base(value)
    {}

    public static TestEnum Test1 { get { return new TestEnum("TEST1"); } }
    public static TestEnum Test2 { get { return new TestEnum("TEST2"); } }
}

এই দুর্দান্ত কাজের জন্য আপনাকে ধন্যবাদ, আমি দীর্ঘ সময়ের জন্য এই জাতীয় পদ্ধতির সন্ধান করছিলাম। আমি মনে করি আপনার
এটির

ওহ আপনাকে এই মন্তব্যের জন্য ধন্যবাদ জানায়, এবং আমাকে এটির স্মরণ করিয়ে দেওয়ার জন্য আপনাকে ধন্যবাদ, আমি যখন এই বিট কোডটি লিখেছিলাম তখন আমি দু'বছর ধরে সি # ব্যবহার করিনি, আমার শীঘ্রই এটি ফিরে পাওয়া উচিত!
লোমিথরানী

@ user3492977 পরিশেষে আমি ফিরে এটা পেয়েছিলাম এবং সেটিকে পুরোপুরি functionnal, আমার এখনও সন্দিহান আছি যদিও যদি এটি একটি মহান ধারণা বা বেহুদা জিনিস: ডি stackoverflow.com/questions/62043138/...
Lomithrani

2

নিউ নেট কোর 3.0 / C # এর 8.0 (যদি আপনার কাজের পরিবেশ আপনার প্রকল্পের আপগ্রেড করতে পারবেন) একটি সংক্ষিপ্ত সরাসরি সুইচ বিবৃতি যে কেমন লাগে কিছুটা enum পর। দিনের শেষে এটি একই পুরানো বোরিং সুইচ বিবৃতিটি আমরা বছরের পর বছর ধরে ব্যবহার করে আসছি।

এখানে কেবল আসল পার্থক্য হ'ল স্যুইচ বিবৃতিটি একটি নতুন স্যুট পেয়েছে।

public static RGBColor FromRainbow(Rainbow colorBand) =>
colorBand switch
{
    Rainbow.Red    => new RGBColor(0xFF, 0x00, 0x00),
    Rainbow.Orange => new RGBColor(0xFF, 0x7F, 0x00),
    Rainbow.Yellow => new RGBColor(0xFF, 0xFF, 0x00),
    Rainbow.Green  => new RGBColor(0x00, 0xFF, 0x00),
    Rainbow.Blue   => new RGBColor(0x00, 0x00, 0xFF),
    Rainbow.Indigo => new RGBColor(0x4B, 0x00, 0x82),
    Rainbow.Violet => new RGBColor(0x94, 0x00, 0xD3),
    _              => throw new ArgumentException(message: "invalid enum value", paramName: nameof(colorBand)),
};

আপনি লক্ষ্য করবেন যে উপরে যে কোডটি আমি এখান থেকে অনুলিপি করেছি তা বাস্তবে একটি পরম হিসাবে এনাম ব্যবহার করছে।

এটি আপনি যা চান ঠিক তা নয় (এবং আমাকে বিশ্বাস করুন, আমি ওপি দীর্ঘ সময়ের জন্য যা অনুরোধ করছি তার অনুরূপ কিছু চাইছিলাম) তবে আমি আসলে এমএসের জলপাইয়ের শাখার মতোই অনুভব করি। JMO।

আশা করি এটি কাউকে সাহায্য করবে!


2

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

    struct ViewTypes
    {
        public const string View1 = "Whatever string you like";
        public const string View2 = "another string";
    }

উদাহরণ ব্যবহার:

   switch( some_string_variable )
   {
      case ViewTypes.View1: /* do something */ break;
      case ViewTypes.View2: /* do something else */ break;
   }

1

আমি এমনকি @ ইভেনের ( class Xএবং public static Xসদস্যদের মাধ্যমে ) পরামর্শ অনুসারে কয়েকটি এনাম প্রয়োগ করেছি , এই দিনগুলির পরে, পরে শুরু করার জন্য। নেট 4.5.৪, সঠিক ToString() পদ্ধতি রয়েছে।

এখন আমি সব কিছু এনামগুলিতে ফিরিয়ে আনছি।


1

এটি দৃ a়ভাবে টাইপিত প্যারামিটার বা স্ট্রিং হিসাবে ব্যবহার করার একটি উপায় :

public class ClassLikeEnum
{
    public string Value
    {
        get;
        private set;
    }

    ClassLikeEnum(string value) 
    {
        Value = value;
    }

    public static implicit operator string(ClassLikeEnum c)
    {
        return c.Value;
    }

    public static readonly ClassLikeEnum C1 = new ClassLikeEnum("RandomString1");
    public static readonly ClassLikeEnum C2 = new ClassLikeEnum("RandomString2");
}

1

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

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

// keep in sync with GroupTypes
public enum GroupTypeCodes
{
    OEM,
    CMB
}

// keep in sync with GroupTypesCodes
public enum GroupTypes
{
    TheGroup = GroupTypeCodes.OEM,
    TheOtherGroup = GroupTypeCodes.CMB
}

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

GroupTypes myGroupType = GroupTypes.TheGroup;
string valueToSaveIntoDatabase = ((GroupTypeCodes)myGroupType).ToString();

তারপরে আপনি যদি এটিকে আরও সুবিধাজনক করতে চান তবে আপনি একটি এক্সটেনশন ফাংশন যুক্ত করতে পারেন যা কেবল এই ধরণের এনামের জন্য কাজ করে:

public static string ToString(this GroupTypes source)
{
    return ((GroupTypeCodes)source).ToString();
}

এবং আপনি ঠিক তখন করতে পারেন:

GroupTypes myGroupType = GroupTypes.TheGroup;
string valueToSaveIntoDatabase = myGroupType.ToString();

এটি একটি খারাপ অভ্যাস: একটি নির্ভরশীলের সাথে enumএকটিতে একটি উদ্দেশ্যপ্রণোদিত মান পরিবর্তনের ফলে অপ্রয়োজনীয়ভাবে অন্যটিকে জড়িয়ে যেতে পারে।
লোরেঞ্জ লো Sauer

1

আমি মূলত @ আর্থার দ্বারা প্রতিবিম্ব উত্তরটি খুঁজছিলাম

কেবল তার উত্তরটি কিছুটা বাড়ানোর জন্য, আপনি জেনেরিক ফাংশন করে এটিকে আরও উন্নত করতে পারেন:

    // If you want for a specific Enum
    private static string EnumStringValue(GroupTypes e)
    {
        return EnumStringValue<GroupTypes>(e);
    }

    // Generic
    private static string EnumStringValue<T>(T enumInstance)
    {
        return Enum.GetName(typeof(T), enumInstance);
    } 

তারপরে আপনি যা কিছু আছে তা কেবল মোড়ানো করতে পারেন

EnumStringValue(GroupTypes.TheGroup) // if you incorporate the top part

অথবা

EnumStringValue<GroupTypes>(GroupTypes.TheGroup) // if you just use the generic

1

@ ইভেনমিয়েন থেকে নেওয়া এবং কিছু মন্তব্যে যুক্ত হয়েছে। (এছাড়াও আমার নিজের ব্যবহারের ক্ষেত্রে)

public struct AgentAction
{
    private AgentAction(string value) { Value = value; }

    public string Value { get; private set; }

    public override string ToString()
    {
        return this.Value;
    }

    public static AgentAction Login = new AgentAction("Logout");
    public static AgentAction Logout = new AgentAction("Logout");

    public static implicit operator string(AgentAction action) { return action.ToString(); }
}

1

এই শ্রেণিটি যুক্ত করা হচ্ছে

public class DatabasePreference {
    public DatabasePreference([CallerMemberName] string preferenceName = "") {
        PreferenceName = preferenceName;
    }
    public string PreferenceName;
}

এই কাজ ব্যবহার করা হয় CallerMemberNameকোডিং হ্রাস করতে করা

ব্যবহার:

//Declare names
public static DatabasePreference ScannerDefaultFlashLight = new DatabasePreference();
public static DatabasePreference ScannerQrCodes = new DatabasePreference();
public static DatabasePreference Scanner1dCodes = new DatabasePreference();

এটা পরীক্ষা করো:

Console.WriteLine(ScannerDefaultFlashLight.PreferenceName);
Console.WriteLine(ScannerDefaultFlashLight.Scanner1dCodes);

আউটপুট:

ScannerDefaultFlashLight
Scanner1dCodes

0

অন্যান্য মতামতের ভিত্তিতে, এটিই আমি সামনে এসেছি। এই পদ্ধতিটি টাইপ করা এড়ায় V ভ্যালু যেখানে আপনি ধ্রুবক মান পেতে চান।

আমার মতো সমস্ত স্ট্রিং এনামগুলির জন্য একটি বেস ক্লাস রয়েছে:

using System;
using Newtonsoft.Json;

[JsonConverter(typeof(ConstantConverter))]
public class StringEnum: IConvertible
{
    public string Value { get; set; }

    protected StringEnum(string value)
    {
        Value = value;
    }

    public static implicit operator string(StringEnum c)
    {
        return c.Value;
    }
    public string ToString(IFormatProvider provider)
    {
        return Value;
    }

    public TypeCode GetTypeCode()
    {
        throw new NotImplementedException();
    }

    public bool ToBoolean(IFormatProvider provider)
    {
        throw new NotImplementedException();
    }
    //The same for all the rest of IConvertible methods
}

জসনকনভার্টরটি এরকম:

using System;
using Newtonsoft.Json;

class ConstantConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return true;
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        if (value == null)
        {
            serializer.Serialize(writer, null);
        }
        else
        {
            serializer.Serialize(writer, value.ToString());
        }
    }
}

এবং একটি প্রকৃত স্ট্রিং এনাম এমন কিছু হবে:

public sealed class Colors : StringEnum
{
    public static Colors Red { get { return new Catalog("Red"); } }
    public static Colors Yellow { get { return new Catalog("Yellow"); } }
    public static Colors White { get { return new Catalog("White"); } }

    private Colors(string value) : base(value) { }
}

এবং এটির সাহায্যে আপনি ভ্যালু সম্পত্তিটি ব্যবহার না করে জসনকে সিরিয়াল করতে এমনকি রঙিন.আরড ব্যবহার করতে পারেন


0

গুণগুলিতে স্ট্রিং সঞ্চয় করার মতো শক্তিশালী কিছু আমার দরকার নেই। আমার কেবল MyEnum.BillEveryWeek"প্রতি সপ্তাহে বিল" বা MyEnum.UseLegacySystem"লেগ্যাসি সিস্টেম ব্যবহারের " মতো কিছু পরিবর্তনের দরকার ছিল - মূলত এনামটিকে উট-আবরণ দিয়ে আলাদা করে লোয়ার-কেস শব্দের মধ্যে বিভক্ত করে তোলে।

public static string UnCamelCase(this Enum input, string delimiter = " ", bool preserveCasing = false)
{
    var characters = input.ToString().Select((x, i) =>
    {

       if (i > 0 && char.IsUpper(x))
       {
           return delimiter + x.ToString(CultureInfo.InvariantCulture);
       }
       return x.ToString(CultureInfo.InvariantCulture);

    });

    var result = preserveCasing
       ? string.Concat(characters)
       : string.Concat(characters).ToLower();

    var lastComma = result.LastIndexOf(", ", StringComparison.Ordinal);

    if (lastComma > -1)
    {
       result = result.Remove(lastComma, 2).Insert(lastComma, " and ");
    }

    return result;
}

MyEnum.UseLegacySystem.UnCamelCase() ফলাফল "উত্তরাধিকার ব্যবস্থা ব্যবহার করুন"

যদি আপনার একাধিক পতাকা সেট থাকে, তবে এটি সরল ইংরেজীতে পরিণত হবে (শেষ কমাটির জায়গায় "এবং" বাদ দিয়ে কমা-বিস্মৃত)।

var myCustomerBehaviour = MyEnum.BillEveryWeek | MyEnum.UseLegacySystem | MyEnum.ChargeTaxes;

Console.WriteLine(myCustomerBehaviour.UnCamelCase());
//outputs "bill every week, use legacy system and charge taxes"
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.