c# - আমি কিভাবে#একটি enumate enumerate?




.net enums (18)

foreach (Suit suit in Enum.GetValues(typeof(Suit))) { }

আমি অস্বস্তিকর গুজব শুনেছি যে এই টেরিফিক্যাল ধীর। কেউ কি জানেন? - অরিয়ন এডওয়ার্ডসের অক্টোবর 15 '08 1:31 এ 7

আমি অ্যারে ক্যাশে যথেষ্ট এটি গতি আপ মনে হবে। মনে হচ্ছে আপনি প্রতিবার একটি নতুন অ্যারে পেয়েছেন (প্রতিফলন মাধ্যমে)। বরং:

Array enums = Enum.GetValues(typeof(Suit));
foreach (Suit suitEnum in enums) 
{
    DoSomething(suitEnum);
}

এটা অন্তত একটু দ্রুত, তাই না?

কিভাবে আপনি C # একটি enum enumerate করতে পারেন?

যেমন নিম্নলিখিত কোড কম্পাইল না হয়:

public enum Suit 
{
    Spades,
    Hearts,
    Clubs,
    Diamonds
}

public void EnumerateAllSuitsDemoMethod() 
{
    foreach (Suit suit in Suit) 
    {
        DoSomething(suit);
    }
}

এবং নিম্নলিখিত কম্পাইল-সময় ত্রুটি দেয়:

'সুয়েট' একটি 'টাইপ' কিন্তু একটি 'পরিবর্তনশীল'

এটা Suit শব্দ, দ্বিতীয় এক ব্যর্থ হয়।


আমি এই মতামত ধরে রাখি না এটি ভাল, না এমনকি ভাল, শুধু আরেকটি সমাধান বলছে।

যদি enum মান 0 থেকে n - 1 থেকে কঠোরভাবে পরিসীমা দেয়, একটি জেনেরিক বিকল্প:

public void EnumerateEnum<T>()
{
    int length = Enum.GetValues(typeof(T)).Length;
    for (var i = 0; i < length; i++)
    {
        var @enum = (T)(object)i;
    }
}

যদি enum মানগুলি সংস্পর্শী হয় এবং আপনি enum এর প্রথম এবং শেষ উপাদান সরবরাহ করতে পারেন তবে:

public void EnumerateEnum()
{
    for (var i = Suit.Spade; i <= Suit.Diamond; i++)
    {
        var @enum = i;
    }
}

কিন্তু যে কঠোরভাবে enumerating না, শুধু looping। দ্বিতীয় পদ্ধতি যদিও অন্য কোন পদ্ধতির তুলনায় অনেক দ্রুত ...


আপনি Silverlight মধ্যে Enum.GetValues() পাবেন না।

ইনার ইনজব্রিজ্টেনের মূল ব্লগ পোস্ট :

public class EnumHelper
{
    public static T[] GetValues<T>()
    {
        Type enumType = typeof(T);

        if (!enumType.IsEnum)
        {
            throw new ArgumentException("Type '" + enumType.Name + "' is not an enum");
        }

        List<T> values = new List<T>();

        var fields = from field in enumType.GetFields()
                     where field.IsLiteral
                     select field;

        foreach (FieldInfo field in fields)
        {
            object value = field.GetValue(enumType);
            values.Add((T)value);
        }

        return values.ToArray();
    }

    public static object[] GetValues(Type enumType)
    {
        if (!enumType.IsEnum)
        {
            throw new ArgumentException("Type '" + enumType.Name + "' is not an enum");
        }

        List<object> values = new List<object>();

        var fields = from field in enumType.GetFields()
                     where field.IsLiteral
                     select field;

        foreach (FieldInfo field in fields)
        {
            object value = field.GetValue(enumType);
            values.Add(value);
        }

        return values.ToArray();
    }
}

আপনি একটি ইন্টারম্যাক কিছু করতে একটি enum রূপান্তর একটি সহজ এবং জেনেরিক উপায়:

public static Dictionary<int, string> ToList<T>() where T : struct
{
   return ((IEnumerable<T>)Enum
       .GetValues(typeof(T)))
       .ToDictionary(
           item => Convert.ToInt32(item),
           item => item.ToString());
}

এবং তারপর:

var enums = EnumHelper.ToList<MyEnum>();

আমি ToString () ব্যবহার করে তারপর বিভক্ত এবং ফ্ল্যাগ অ্যারে অ্যারে পার্স।

[Flags]
public enum ABC {
   a = 1,
   b = 2,
   c = 4
};

public IEnumerable<ABC> Getselected (ABC flags)
{
   var values = flags.ToString().Split(',');
   var enums = values.Select(x => (ABC)Enum.Parse(typeof(ABC), x.Trim()));
   return enums;
}

ABC temp= ABC.a | ABC.b;
var list = getSelected (temp);
foreach (var item in list)
{
   Console.WriteLine(item.ToString() + " ID=" + (int)item);
}

আমি আপনি ব্যবহার করতে পারেন মনে হয়

Enum.GetNames(Suit)

আমি জানি এটি একটি বিট নোংরা কিন্তু যদি আপনি এক-লাইনারের ফ্যান হন, তবে এখানে একটি:

((Suit[])Enum.GetValues(typeof(Suit))).ToList().ForEach(i => DoSomething(i));

আমি মনে করি এটি অন্যান্য পরামর্শগুলির চেয়ে আরও কার্যকর কারণ GetValues() প্রতিটি সময় আপনার লুপ থাকে না বলে বলা হয়। এটা আরো সংক্ষিপ্ত। এবং Suit একটি enum না হলে এবং আপনি একটি কম্পাইল সময় ত্রুটি পেতে রানটাইম ব্যতিক্রম না।

EnumLoop<Suit>.ForEach((suit) => {
    DoSomethingWith(suit);
});

EnumLoop এই সম্পূর্ণ জেনেরিক সংজ্ঞা আছে:

class EnumLoop<Key> where Key : struct, IConvertible {
    static readonly Key[] arr = (Key[])Enum.GetValues(typeof(Key));
    static internal void ForEach(Action<Key> act) {
        for (int i = 0; i < arr.Length; i++) {
            act(arr[i]);
        }
    }
}

এই প্রশ্নটি " সি # ধাপে ধাপে ২013 এর অধ্যায়ের 10" -এ প্রদর্শিত হবে

লেখক একটি সংখ্যার জোড়ার মাধ্যমে পুনরাবৃত্তি করার জন্য একটি ডবল জন্য-লুপ ব্যবহার করে (কার্ডগুলির পুরো ডেক তৈরি করতে):

class Pack
{
    public const int NumSuits = 4;
    public const int CardsPerSuit = 13;
    private PlayingCard[,] cardPack;

    public Pack()
    {
        this.cardPack = new PlayingCard[NumSuits, CardsPerSuit];
        for (Suit suit = Suit.Clubs; suit <= Suit.Spades; suit++)
        {
            for (Value value = Value.Two; value <= Value.Ace; value++)
            {
                cardPack[(int)suit, (int)value] = new PlayingCard(suit, value);
            }
        }
    }
}

এই ক্ষেত্রে, Suit এবং Value উভয় সংখ্যার হয়:

enum Suit { Clubs, Diamonds, Hearts, Spades }
enum Value { Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten, Jack, Queen, King, Ace}

এবং PlayingCard একটি নির্ধারিত Suit এবং Value সঙ্গে একটি কার্ড বস্তু:

class PlayingCard
{
    private readonly Suit suit;
    private readonly Value value;

    public PlayingCard(Suit s, Value v)
    {
        this.suit = s;
        this.value = v;
    }
}

একটি Enum পুনরাবৃত্তি করার দুটি উপায় আছে:

1. var values =  Enum.GetValues(typeof(myenum))
2. var values =  Enum.GetNames(typeof(myenum))

প্রথমটি আপনাকে object অ্যারে রূপে মান দেয় এবং দ্বিতীয়টি আপনাকে String অ্যারে রূপে মান দেয়।

নীচের হিসাবে foreach লুপ এটি ব্যবহার করুন:

foreach(var value in values)
{
    //Do operations here
}

এছাড়াও আপনি প্রতিফলন ব্যবহার করে সরাসরি enum এর পাবলিক স্ট্যাটিক সদস্যদের সাথে বাঁধতে পারেন:

typeof(Suit).GetMembers(BindingFlags.Public | BindingFlags.Static)
    .ToList().ForEach(x => DoSomething(x.Name));

তিনটি উপায়:

1. Enum.GetValues(type) //since .NET 1.1, not in silverlight or compact framewok
2. type.GetEnumValues() //only on .NET 4 and above
3. type.GetFields().Where(x => x.IsLiteral).Select(x => x.GetValue(null)) //works everywhere

টাইপ ইনস্ট্যান্সে GetEnumValues কেন চালু করা হয়েছে তা নিশ্চিত না, এটি আমার জন্য খুব পঠনযোগ্য নয়।

Enum<T> মত একটি সহায়ক ক্লাস থাকা আমার জন্য সবচেয়ে পঠনযোগ্য এবং স্মরণীয়:

public static class Enum<T> where T : struct, IComparable, IFormattable, IConvertible
{
    public static IEnumerable<T> GetValues()
    {
        return (T[])Enum.GetValues(typeof(T));
    }

    public static IEnumerable<string> GetNames()
    {
        return Enum.GetNames(typeof(T));
    }
}

এখন আপনি কল করুন:

Enum<Suit>.GetValues();
//or
Enum.GetValues(typeof(Suit)); //pretty consistent style

পারফরম্যান্সের ক্ষেত্রে যদি কেউ ক্যাশিংয়ের ধরণেরও ব্যবহার করতে পারে তবে আমি এটিকে কোনও সমস্যা বলে আশা করি না

public static class Enum<T> where T : struct, IComparable, IFormattable, IConvertible
{
    //lazily loaded
    static T[] values;
    static string[] names;

    public static IEnumerable<T> GetValues()
    {
        return values ?? (values = (T[])Enum.GetValues(typeof(T)));
    }

    public static IEnumerable<string> GetNames()
    {
        return names ?? (names = Enum.GetNames(typeof(T)));
    }
}

মনে হচ্ছে আপনি সত্যিই মানগুলির পরিবর্তে প্রতিটি enum এর নাম মুদ্রণ করতে চান। কোন ক্ষেত্রে Enum.GetNames() সঠিক পদ্ধতির মনে হয়।

public enum Suits
{
    Spades,
    Hearts,
    Clubs,
    Diamonds,
    NumSuits
}

public void PrintAllSuits()
{
    foreach (string name in Enum.GetNames(typeof(Suits)))
    {
        System.Console.WriteLine(name);
    }
}

যাইহোক, মান বৃদ্ধি করা একটি enum এর মান গণনা করার একটি ভাল উপায় নয়। আপনি পরিবর্তে এই করা উচিত।

আমি Enum.GetValues(typeof(Suit)) পরিবর্তে ব্যবহার করব।

public enum Suits
{
    Spades,
    Hearts,
    Clubs,
    Diamonds,
    NumSuits
}

public void PrintAllSuits()
{
    foreach (var suit in Enum.GetValues(typeof(Suits)))
    {
        System.Console.WriteLine(suit.ToString());
    }
}

যদি আপনি জানেন যে টাইপ একটি enum , তবে আপনি কি জানেন না সঠিক টাইপ কম্পাইল সময় কি?

public class EnumHelper
{
    public static IEnumerable<T> GetValues<T>()
    {
        return Enum.GetValues(typeof(T)).Cast<T>();
    }

    public static IEnumerable getListOfEnum(Type type)
    {
        MethodInfo getValuesMethod = typeof(EnumHelper).GetMethod("GetValues").MakeGenericMethod(type);
        return (IEnumerable)getValuesMethod.Invoke(null, null);
    }
}

পদ্ধতি getListOfEnum কোনো IEnumerable টাইপ নিতে প্রতিফলন ব্যবহার করে এবং সমস্ত IEnumerable মানগুলির একটি IEnumerable প্রদান করে।

ব্যবহার:

Type myType = someEnumValue.GetType();

IEnumerable resultEnumerable = getListOfEnum(myType);

foreach (var item in resultEnumerable)
{
    Console.WriteLine(String.Format("Item: {0} Value: {1}",item.ToString(),(int)item));
}

Cast<T> ব্যবহার করে কেউ কেন হয় না?

var suits = Enum.GetValues(typeof(Suit)).Cast<Suit>();

সেখানে আপনি IEnumerable<Suit>


enum প্রকারগুলিকে "গণনার ধরন" বলা হয় না কারণ তারা এমন "কন্ট্রোলার" মানগুলি (যা তারা নয়) নয়, তবে যে ধরনের পরিবর্তনশীলের জন্য সম্ভাব্য মানগুলিকে সংজ্ঞায়িত করে সংজ্ঞায়িত করে।

(প্রকৃতপক্ষে, এটি তার থেকে আরও জটিল - এনম প্রকারকে "অন্তর্নিহিত" পূর্ণসংখ্যা টাইপ বলে মনে করা হয়, যার অর্থ প্রতিটি এননাম মানটি পূর্ণসংখ্যা মানের সাথে সম্পর্কিত (এটি সাধারণত অন্তর্নির্মিত, তবে ম্যানুয়ালি উল্লেখ করা যেতে পারে)। C # ডিজাইন করা হয়েছে একটি উপায় যাতে আপনি enum পরিবর্তনশীলের মধ্যে যে ধরনের কোন পূর্ণসংখ্যা স্টাফ করতে পারেন, এমনকি যদি এটি একটি "নামযুক্ত" মান নাও হয়।)

Name.Inum.GetNames পদ্ধতিটি যেমন ইনাম মানগুলির নাম, স্ট্রিংগুলির অ্যারে পুনরুদ্ধার করতে ব্যবহার করা যেতে পারে।

সম্পাদনা করুন: পরিবর্তে System.Enum.GetValues পদ্ধতি প্রস্তাব করা উচিত। উফ।


foreach (Suit suit in Enum.GetValues(typeof(Suit)))
{
}

(বর্তমান গৃহীত উত্তরটিতে একটি কাস্ট রয়েছে যা আমি মনে করি না (যদিও আমি ভুল হতে পারি)।)


public void PrintAllSuits()
{
    foreach(string suit in Enum.GetNames(typeof(Suits)))
    {
        Console.WriteLine(suit);
    }
}




enumeration