එනූමයක් ගණනය කරන්නේ කෙසේද?


3777

enumC # හි ගණනය කිරීමක් කරන්නේ කෙසේද ?

උදා: පහත කේතය සම්පාදනය නොකරයි:

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

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

තවද එය පහත දැක්වෙන සම්පාදක-කාල දෝෂයක් ලබා දෙයි:

'සූට්' යනු 'වර්ගයක්' නමුත් එය 'විචල්යයක්' ලෙස භාවිතා කරයි

එය Suitයතුරු පදයේ අසමත් වේ , දෙවැන්න.



2
ඔබට C # එනූම්ස් වල ඇතුලත් කිරීම් සහ පිටවීම් පරීක්ෂා කිරීමට අවශ්‍ය විය හැකිය , මෙය මෙන්ම වෙනත් ප්‍රයෝජනවත් තොරතුරු ද සාකච්ඡා කරයි
ChaseMedallion

Answers:


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

සටහන : වාත්තු කිරීම (Suit[])තදින් අවශ්‍ය නොවේ, නමුත් එය 0.5 ns කේතය වේගවත් කරයි.


97
ගණන් ගැනීමේ ලැයිස්තුවේ අනුපිටපත් අගයන් ඇත්නම් මෙය ක්‍රියා නොකරයි.
ජෙසී

10
මට පෙන්වා දීමට අවශ්‍ය වන්නේ මෙය අවාසනාවකට රිදී ආලෝකයේ ක්‍රියා නොකරනු ඇති බැවින් රිදී ආලෝක පුස්තකාලය සමන්විත නොවන බැවිනි enum.GetValues. මෙම අවස්ථාවේ දී ඔබ පරාවර්තනය භාවිතා කළ යුතුය.
ජියාකොමෝ ටැග්ලියාබියු

146
මෙම @Jessy කරන්නේ වැනි අනුපිටපත් තත්වයන් නඩුවේ වැඩ කටයුතු enum E {A = 0, B = 0}. Enum.GetValuesඑහි ප්‍රති results ලය වන්නේ අගයන් දෙකක් සමාන වුවත් ඒවා ආපසු ලබා දීමයි. E.A == E.Bසත්‍යය, එබැවින් වෙනසක් නොමැත. ඔබට තනි නම් අවශ්‍ය නම් ඔබ සොයා බැලිය යුතුය Enum.GetNames.
nawfal

13
එවිට ඔබේ එනූම් හි අනුපිටපත් / සමාන පද තිබේ නම්, සහ ඔබට අනෙක් හැසිරීම අවශ්‍ය නම්, ඔබට ලින්ක්ගේ Distinctදිගුව භාවිතා කළ හැකිය (.නෙට් 3.5 සිට), එබැවින් foreach (var suit in ((Suit[])Enum.GetValues(typeof(Suit))).Distinct()) { }.
ජෙප් ස්ටිග් නීල්සන්

42
varවර්ගය සඳහා භාවිතා කිරීමට උත්සාහ කිරීමේ වැරැද්ද මම කළෙමි . සම්පාදකයා විසින් විචල්‍යය Objectenum වෙනුවට ආදේශ කරනු ඇත. එනුම් වර්ගය පැහැදිලිව ලැයිස්තුගත කරන්න.
jpmc26

696

මට පෙනෙන්නේ ඔබට සාරධර්මවලට වඩා එක් එක් එනූම් වල නම් මුද්‍රණය කිරීමට අවශ්‍ය බවයි. කුමන අවස්ථාවෙහිදී 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.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());
    }
}

2
VB සින්ටැක්ස් මෙහි: සබැඳිය
ඇන්ඩෘවිට්ටා

මම ඔබේ අනුවාදය මගේ පැත්තෙන් කුඩා වෙනස්කම් කිහිපයක් රැගෙන ගියෙමි : Enum.GetValues(typeof(Suits)).OfType<Suits>().ToArray(). එවැනි අවස්ථාවක මට Suitsනූල් නොව enum අයිතම පෙළ නැවත කළ හැකිය .
බරබාස්

Ara බරබාස් ඇයි එසේ නොකරන්නේ Suits suit in Enum.GetValues(typeof(Suits))?
තේමාඩ්කිං

මචං! ඇත්ත වශයෙන්ම, නිශ්චිත වර්ගය භාවිතා කිරීම මෙම භයානක කෑල්ලට වඩා හොඳ පෙනුමක් ... කේතය!
බරබාස්

337

පහසුවෙන් එනූම් භාවිතය සඳහා මම දිගු කිහිපයක් කළෙමි. සමහර විට කෙනෙකුට එය භාවිතා කළ හැකිය ...

public static class EnumExtensions
{
    /// <summary>
    /// Gets all items for an enum value.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="value">The value.</param>
    /// <returns></returns>
    public static IEnumerable<T> GetAllItems<T>(this Enum value)
    {
        foreach (object item in Enum.GetValues(typeof(T)))
        {
            yield return (T)item;
        }
    }

    /// <summary>
    /// Gets all items for an enum type.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="value">The value.</param>
    /// <returns></returns>
    public static IEnumerable<T> GetAllItems<T>() where T : struct
    {
        foreach (object item in Enum.GetValues(typeof(T)))
        {
            yield return (T)item;
        }
    }

    /// <summary>
    /// Gets all combined items from an enum value.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="value">The value.</param>
    /// <returns></returns>
    /// <example>
    /// Displays ValueA and ValueB.
    /// <code>
    /// EnumExample dummy = EnumExample.Combi;
    /// foreach (var item in dummy.GetAllSelectedItems<EnumExample>())
    /// {
    ///    Console.WriteLine(item);
    /// }
    /// </code>
    /// </example>
    public static IEnumerable<T> GetAllSelectedItems<T>(this Enum value)
    {
        int valueAsInt = Convert.ToInt32(value, CultureInfo.InvariantCulture);

        foreach (object item in Enum.GetValues(typeof(T)))
        {
            int itemAsInt = Convert.ToInt32(item, CultureInfo.InvariantCulture);

            if (itemAsInt == (valueAsInt & itemAsInt))
            {
                yield return (T)item;
            }
        }
    }

    /// <summary>
    /// Determines whether the enum value contains a specific value.
    /// </summary>
    /// <param name="value">The value.</param>
    /// <param name="request">The request.</param>
    /// <returns>
    ///     <c>true</c> if value contains the specified value; otherwise, <c>false</c>.
    /// </returns>
    /// <example>
    /// <code>
    /// EnumExample dummy = EnumExample.Combi;
    /// if (dummy.Contains<EnumExample>(EnumExample.ValueA))
    /// {
    ///     Console.WriteLine("dummy contains EnumExample.ValueA");
    /// }
    /// </code>
    /// </example>
    public static bool Contains<T>(this Enum value, T request)
    {
        int valueAsInt = Convert.ToInt32(value, CultureInfo.InvariantCulture);
        int requestAsInt = Convert.ToInt32(request, CultureInfo.InvariantCulture);

        if (requestAsInt == (valueAsInt & requestAsInt))
        {
            return true;
        }

        return false;
    }
}

ධජය ධජ ඇට්ට්‍රිබියුට් වලින් සරසා තිබිය යුතුය :

[Flags]
public enum EnumExample
{
    ValueA = 1,
    ValueB = 2,
    ValueC = 4,
    ValueD = 8,
    Combi = ValueA | ValueB
}

13
පළමු දිගු කිරීමේ ක්‍රමය සඳහා එක් ලයිනර්; එය තවදුරටත් කම්මැලි නොවේ. ආපසු එනූම්.ගෙට් අගය (ටයිප් (ටී)). වාත්තු <T> ();
ලියු

2
විකල්පයක් ලෙස ඔබට OfType ද භාවිතා කළ හැකිය: Enum.GetValues ​​(typeof (T)). OfType <T> (). GetValues ​​<T> () හි සාමාන්‍ය අනුවාදයක් නොමැති වීම ඉතා නරක ය, එවිට එය ඊටත් වඩා සිනිඳු වනු ඇත.
jpierson

3
සමහර විට යමෙකුට මෙම දිගු භාවිතා කරන්නේ කෙසේදැයි පෙන්විය හැකිද? සම්පාදකයා enumExample හි දිගු කිරීමේ ක්‍රම නොපෙන්වයි.
ටොමාස්

1
එම කාර්යයන් උපයෝගී කර ගන්නේ කෙසේද යන්න කිසිවෙකුට ආදර්ශයක් එක් කළ හැකිද?
අශ්වින් වර්මා

3
නැවත භාවිතා කළ හැකි කේතය සඳහා +1: උදාහරණ - පුස්තකාලයක මෙම විස්තාරණ ක්‍රම සුරකින්න සහ එය [කොඩි] පොදු එනුම් මයිටයිප්ස් {name1, name2}; ලැයිස්තුව <string> myTypeNames = mytypes.GetAllItems ();
ක්‍රිෂ්ණා

178

.NET රාමුවේ සමහර අනුවාදයන් සහාය නොදක්වයි Enum.GetValues. අයිඩියස් 2.0 වෙතින් හොඳ ක්‍රියාමාර්ගයක් මෙන්න : සංයුක්ත රාමුව තුළ එනම්.ගෙට් අගය :

public Enum[] GetValues(Enum enumeration)
{
    FieldInfo[] fields = enumeration.GetType().GetFields(BindingFlags.Static | BindingFlags.Public);
    Enum[] enumerations = new Enum[fields.Length];

    for (var i = 0; i < fields.Length; i++)
        enumerations[i] = (Enum) fields[i].GetValue(enumeration);

    return enumerations;
}

පරාවර්තනය සම්බන්ධ වන ඕනෑම කේතයක් මෙන් , එය එක් වරක් පමණක් ක්‍රියාත්මක වන බව සහතික කිරීමට ඔබ පියවර ගත යුතු අතර ප්‍රති results ල හැඹිලිගත වේ.


18
ලැයිස්තුවක් ස්ථාපනය කිරීම වෙනුවට මෙහි අස්වැන්න යතුරු පදය භාවිතා නොකරන්නේ ඇයි?
එරික් මිකෙල්සන්

1
හෝ කෙටි:return type.GetFields().Where(x => x.IsLiteral).Select(x => x.GetValue(null)).Cast<Enum>();
nawfal

7
wnawfal: ලින්ක් නොමැත .නෙට් සීඑෆ් 2.0.
ගේබ්‍රියෙල් ජීඑම්

KEkevoo මෙම enum අගයන් MVC හි DropDownList සමඟ සම්බන්ධ කරන්නේ කෙසේද?
ජැක්

115

භාවිතා කරන්න Cast<T>:

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

ඔන්න යන්න , IEnumerable<Suit>.


1
මෙය fromවගන්තියේ සහ foreachශීර්ෂ ප්‍රකාශකයේ ද ක්‍රියාත්මක වේ.
අලුවාන් හඩාඩ්

97

අනෙක් යෝජනා වලට වඩා මෙය කාර්යක්ෂම යැයි මම සිතමි, මන්ද 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]);
        }
    }
}

6
මේ වගේ ජනකතා භාවිතා කිරීම ගැන සැලකිලිමත් වන්න. ඔබ EnumLoopඑනුම් නොවන යම් වර්ගයක් සමඟ භාවිතා කිරීමට උත්සාහ කරන්නේ නම් , එය දඩ සම්පාදනය කරනු ඇත, නමුත් ධාවන වේලාවේදී ව්‍යතිරේකයක් දමන්න.
svick

7
ස්තූතියි ස්වික්. මෙම පිටුවේ ඇති අනෙක් පිළිතුරු සමඟ ධාවන කාල ව්‍යතිරේක සැබවින්ම සිදුවනු ඇත ... මෙය හැර මම "කොහේද යතුර: ව්‍යුහය, අයිකොන්වර්ටිබල්" එකතු කර ඇති නිසා බොහෝ අවස්ථාවන්හිදී ඔබට සම්පාදක කාල දෝෂයක් ලැබෙනු ඇත.
ජේම්ස්

3
නැත, GetValues ​​() හැඳින්වෙන්නේ පෙරවදනෙහි එක් වරක් පමණි.
ඇලෙක්ස් බ්ලොකා

4
ජේම්ස්, මම ඔබේ පංතිය අධෛර්යමත් කරමි, මන්ද ලිවීමට දක්ෂ නමුත් නිෂ්පාදන කේතයේ බොහෝ අය නඩත්තු කර යාවත්කාලීන කරනු ඇත, දක්ෂය යනු අතිරේක වැඩකි. එය විශාල ඉතිරියක් සිදු කරන්නේ නම් හෝ බොහෝ දේ භාවිතා කරනු ඇත - එබැවින් ඉතිරිකිරීම් විශාල වන අතර මිනිසුන් එය හුරු වනු ඇත - එය වටී, නමුත් බොහෝ අවස්ථාවන්හීදී එය කේතය කියවීමට හා යාවත්කාලීන කිරීමට උත්සාහ කරන පුද්ගලයින්ගේ වේගය අඩු කර හැකි අතර එය හඳුන්වා දෙයි අනාගතයේදී ප්‍රභව දෝෂ. අඩු කේතය වඩා හොඳය :) අඩු සංකීර්ණතාව ඊටත් වඩා හොඳය.
ග්‍රාන්ට් එම්

2
@GrantM ඇයි? මෙම කේතය සංකීර්ණ නොවන අතර එය ඇදහිය නොහැකි තරම් කෙටි ය. ඊට ඉහළින්, එක් වරක් පන්තිය ලිවීම ඔහුගේ උදාහරණයට අනුව කෙටි කේත භාවිතා කිරීමට ඉඩ දෙනු ඇත. මෙය අතිශයින්ම පිරිසිදුයි, ඔබට එම කේතය යාවත්කාලීන කළ නොහැකි නම්, ඔබට බොහෝ සමාගම් කේත යාවත්කාලීන කළ නොහැක.
ඩිස්පර්සියා

77

ඔබ ලබා ගත නොහැකි වේ Enum.GetValues()දී Silverlight .

මුල් බ්ලොග් සටහන අයිනාර් ඉන්ජ්බ්‍රිග්ට්සන් :

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

2
හොඳ විසඳුමක්, නමුත් සමහර ප්‍රතිනිර්මාණය කිරීම වඩා හොඳ වනු ඇත! :)
nawfal

මම .NET රාමුව 4.0 සහ සිල්වර් ලයිට් enum.getvalues ​​වැඩ කරමි, මා භාවිතා කළ කේතය ---> enum.GetValues ​​(typeof (enum))
ආනන්ද

2
C # 7.3 (Visual Studio 2017 ≥ v15.7) සිට කෙනෙකුට භාවිතා කළ හැකියwhere T: Enum
Yahoo Serious

59

මගේ විසඳුම .NET සංයුක්ත රාමුව (3.5) තුළ ක්‍රියාත්මක වන අතර සම්පාදනය කරන වේලාවේදී වර්ග පරීක්ෂා කිරීමට සහාය වේ :

public static List<T> GetEnumValues<T>() where T : new() {
    T valueType = new T();
    return typeof(T).GetFields()
        .Select(fieldInfo => (T)fieldInfo.GetValue(valueType))
        .Distinct()
        .ToList();
}

public static List<String> GetEnumNames<T>() {
    return typeof (T).GetFields()
        .Select(info => info.Name)
        .Distinct()
        .ToList();
}
  • එයින් මිදෙන්නේ කෙසේදැයි යමෙක් දන්නේ නම් T valueType = new T(), විසඳුමක් දැකීමට මම සතුටු වෙමි.

ඇමතුමක් මේ වගේ වනු ඇත:

List<MyEnum> result = Utils.GetEnumValues<MyEnum>();

2
භාවිතා කිරීම ගැන කුමක් කිව T valueType = default(T)හැකිද?
ඔලිවර්

නියමයි, මම ඒ මූල පදයවත් දැනගෙන හිටියේ නැහැ. අලුත් දෙයක් ඉගෙන ගැනීමට සැමවිටම සතුටුයි. ඔබට ස්තුතියි! එය සෑම විටම එකම වස්තුවකට යොමු කිරීමක් කරයිද, නැතහොත් පෙරනිමි ප්‍රකාශය කැඳවන සෑම අවස්ථාවකම එය නව අවස්ථාවක් නිර්මාණය කරයිද? මම මේ දක්වා අන්තර්ජාලයේ කිසිවක් සොයාගෙන නැත, නමුත් එය සෑම අවස්ථාවකම නව අවස්ථාවක් නිර්මාණය කරන්නේ නම්, එය මා සොයන අරමුණ පරාජය කරයි (එක්-ලයිනර් having එකක් තිබීම).
මල්ලොක්ස්

1
ගණනය කිරීම පිළිබඳ සෑම පුනරාවර්තනයක් සඳහාම මෙය නව අවස්ථාවක් නිර්මාණය කරන්නේ නැද්ද?
මල්ලොක්ස්

1
-1 සඳහා "සම්පාදනය කරන වේලාවේදී වර්ග පරීක්ෂා කිරීම සඳහා සහය දක්වයි:". කුමන වර්ගයේ පරීක්ෂාවද? මෙය ඕනෑම කෙනෙකුට වැඩ කරයි new() T. එසේම, ඔබට new T()කිසිසේත් අවශ්‍ය නොවේ , ඔබට ස්ථිතික ක්ෂේත්‍ර පමණක් තෝරාගෙන කළ හැකිය .GetValue(null). ඕබ්රිගේ පිළිතුර බලන්න.
නව්ෆල්

2
C # 7.3 (Visual Studio 2017 ≥ v15.7) සිට කෙනෙකුට භාවිතා කළ හැකියwhere T: Enum
Yahoo Serious


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

2
එමඟින් නූලක් ගණනය කෙරේ, එම කරුණු නැවත ගණන් කිරීමේ අගයක් බවට පරිවර්තනය කිරීමට අමතක නොකරන්න, එවිට ගණනය කිරීම ගණනය කළ හැකිය.
ඉයන් බොයිඩ්

1
ඔබේ සංස්කරණයෙන් මට පෙනෙන්නේ ඔබට ඇත්ත වශයෙන්ම එනුම්ස් මත ක්‍රියාත්මක වීමට අවශ්‍ය බවයි, ඉහත කේතය ඔබේ මුල් පෝස්ටයට ආමන්ත්‍රණය කළේය.
ජෝෂුවා ඩ්‍රේක්

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

ඒක අවම වශයෙන් ටිකක් වේගවත් නේද?


5
සම්පාදකයා මේ ගැන සැලකිලිමත් විය යුතුය.
ස්ටෙෆාන් බිජ්සිටර්

Te ස්ටෙෆාන් බිජ්සිටර් වාව්, ඔබ මේ ගැන බොහෝ දුරට කියවනවා :-) මම එකඟයි, සම්පාදකයා මගේ විසඳුම අනවශ්‍ය කළ යුතුයි.
සීමිත පව් කමාව

1
මෙය අවශ්‍ය නොවේ. ILSpy හි සම්පාදනය කරන ලද කේතය දෙස බලන විට, සම්පාදකයා අනිවාර්යයෙන්ම මෙය කරයි. මෙම පිළිතුර කිසිසේත් 35 ගුණයකින් අඩු කරන්නේ ඇයි?
mhenry1384

1
එය බොහෝ කලකට පෙර ඉහළට ඔසවා ඇත. ඉතා දිගු කලකට පෙර. සම්පාදකයා මෙය නැවත විසඳනු ඇතැයි මම සිතමි. නමුත් එය නිසැකවම වඩා කාර්ය සාධනය පෙනේ , එසේ නොවේ ද? ;-)
සීමිත පව් කමාව

32

ක්‍රම තුනක්:

  1. Enum.GetValues(type) .NET 1.1 සිට, සිල්වර් ලයිට් හෝ .NET සංයුක්ත රාමුව තුළ නොවේ
  2. type.GetEnumValues() // .NET 4 සහ ඊට ඉහළින් පමණි
  3. type.GetFields().Where(x => x.IsLiteral).Select(x => x.GetValue(null)) // සෑම තැනකම වැඩ කරයි

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

මෙය ක්‍රම පිළිබඳ කදිම සාරාංශයකි. මම හිතන්නේ ඔබ ඔබේ අනෙක් පිළිතුර මෙයට ඒකාබද්ධ කළ යුතුයි. සත්යය නම්, එනුම් විශේෂ වන අතර ඒවා හරහා ලූප වීම බොහෝ විට (සාමාන්යයෙන්) ගණනය කිරීම තරම්ම වලංගු වේ. IOW, ඔබ සතුව සෑම විටම වෙනස් වන enum එකක් තිබේ නම් ඔබ ආරම්භ කිරීම සඳහා වැරදි දත්ත සැකැස්මක් තෝරාගෙන ඇත.
krowe2

31

ඉහළ පිළිතුරු ඒකාබද්ධ කිරීමෙන්, මම ඉතා සරල දිගුවක් එකට විසි කළෙමි:

public static class EnumExtensions
{
    /// <summary>
    /// Gets all items for an enum value.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="value">The value.</param>
    /// <returns></returns>
    public static IEnumerable<T> GetAllItems<T>(this T value) where T : Enum
    {
        return (T[])Enum.GetValues(typeof (T));
    }
}

එය පිරිසිදුයි, සරලයි, සහ @ ජෙප්-ස්ටිග්-නීල්සන්ගේ ප්‍රකාශය අනුව, වේගවත්.


6
C # 7.3 (Visual Studio 2017 ≥ v15.7) වලින් පටන් ගෙන කෙනෙකුට භාවිතා කළ හැකිය where T: Enum
Yahoo Serious

24

නැවත කියවීමට ක්‍රම දෙකක් තිබේ Enum:

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

පළමුවැන්න ඔබට ** object** s අරාවකින් ස්වරූපයෙන් අගයන් ලබා දෙන අතර දෙවැන්න ඔබට ** String** s අරා ආකාරයෙන් අගයන් ලබා දෙනු ඇත .

foreachපහත පරිදි එය ලූපයකින් භාවිතා කරන්න :

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

2
සමහර විට මෙය දැනටමත් බොහෝ පිළිතුරු වලින් ආවරණය වී තිබේද? පිළිතුරු අතිරික්ත නොකරමු.
nawfal

ඒවායින් බොහොමයක් හොඳින් නිගමනය කර නොතිබුණද, වෙනත් පිළිතුරුවලින් ආවරණය විය හැකිය.
කයිලෝ රෙන්

23

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

17

මෙය වඩා හොඳ හෝ හොඳ යැයි මම නොසිතමි. මම දැන් කියන්නේ තවත් විසඳුමක්.

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

එනූම් අගයන් පරස්පර නම් සහ ඔබට එනුම් හි පළමු හා අවසාන අංගය සැපයිය හැකි නම්:

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

නමුත් එය තදින් ගණනය කිරීමක් නොවේ. දෙවන ක්‍රමය වෙනත් ඕනෑම ප්‍රවේශයකට වඩා වේගවත් ය ...


16

ගොඩනැඟීමේ සහ ධාවනය වන වේලාවේදී ඔබට වේගය සහ ටයිප් කිරීම අවශ්‍ය නම්, එක් එක් මූලද්‍රව්‍යය වාත්තු කිරීම සඳහා ලින්ක් භාවිතා කිරීමට වඩා මෙම සහායක ක්‍රමය වඩා හොඳය:

public static T[] GetEnumValues<T>() where T : struct, IComparable, IFormattable, IConvertible
{
    if (typeof(T).BaseType != typeof(Enum))
    {
        throw new ArgumentException(string.Format("{0} is not of type System.Enum", typeof(T)));
    }
    return Enum.GetValues(typeof(T)) as T[];
}

ඔබට එය පහත පරිදි භාවිතා කළ හැකිය:

static readonly YourEnum[] _values = GetEnumValues<YourEnum>();

ඇත්ත වශයෙන්ම ඔබට ආපසු යා හැකිය IEnumerable<T>, නමුත් එය ඔබට මෙහි කිසිවක් මිලට නොගනී.


3
C # 7.3 (Visual Studio 2017 ≥ v15.7) සිට කෙනෙකුට භාවිතා කළ හැකියwhere T: Enum
Yahoo Serious

14

ඩීඩීඑල් සඳහා තෝරාගත් විකල්ප නිර්මාණය කිරීම සඳහා ක්‍රියාකාරී උදාහරණයක් මෙන්න :

var resman = ViewModelResources.TimeFrame.ResourceManager;

ViewBag.TimeFrames = from MapOverlayTimeFrames timeFrame
      in Enum.GetValues(typeof(MapOverlayTimeFrames))
      select new SelectListItem
      {
         Value = timeFrame.ToString(),
         Text = resman.GetString(timeFrame.ToString()) ?? timeFrame.ToString()
      };

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

(දැනට පිළිගත් පිළිතුරට අවශ්‍ය යැයි මා නොසිතන වාත්තු ඇත (මම වැරදියි).)


10

මෙම ප්‍රශ්නය " C # පියවරෙන් පියවර 2013 " හි 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 හි අගයන් අනුක්‍රමික නොවේ නම් මෙය ක්‍රියාත්මක වේද?
අමීර් මසූඩ්


8

වර්ගය වර්ගය වනු ඇතැයි 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ඕනෑම enum වර්ගයක් ගැනීමට පරාවර්තනය භාවිතා කර aIEnumerable අතර සියලු enum අගයන්ගෙන් එකක් ලබා දෙයි.

භාවිතය:

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

8

ඔබට අන්තර්ක්‍රියා කළ හැකි දෙයකට එනූමයක් පරිවර්තනය කිරීම සඳහා සරල හා සාමාන්‍ය ක්‍රමයක්:

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

A Dictionaryහොඳ අදහසක් නොවේ: ඔබට Enumසමාන දෙයක් තිබේ නම් enum E { A = 0, B = 0 }, 0 අගය 2 ගුණයක් ජනනය කරයි ArgumentException(ඔබට Keyඑය Dictionary2 හෝ ඊට වැඩි වාර ගණනක් එකතු කළ නොහැක !).
මැසිමිලියානෝ ක්‍රවුස්

නම් Dictionary<,>කරන ලද ක්‍රමයකින් ආපසු පැමිණෙන්නේ ඇයි ToList? ආපසු නොඑන්නේ ඇයි Dictionary<T, string>?
අලුවාන් හඩාඩ්

8

public static IEnumerable<T> GetValues<T>()ඔබේ පන්තියට ක්‍රමයක් එක් කරන්න , වැනි:

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

ඔබේ එනූම් අමතන්න. දැන් ඔබට එය භාවිතයෙන් නැවත කියවිය හැකිය foreach:

 public static void EnumerateAllSuitsDemoMethod()
 {
     // Custom method
     var foos = GetValues<Suit>();
     foreach (var foo in foos)
     {
         // Do something
     }
 }

2

enumවර්ග "ගණන් කිරීමේ වර්ග" ලෙස හඳුන්වන්නේ ඒවා "ගණනය කරන" අගයන් (ඒවා නොවන) බහාලුම් නිසා නොව, ඒවා අර්ථ දැක්වෙන්නේ එම වර්ගයේ විචල්‍යයක් සඳහා විය හැකි අගයන් ගණනය කිරීමෙනි .

. ඔබට ඕනෑම දෙයක් පුරවා ගත හැකි වන පරිදි , නිඛිල විචල්ය බවට එම වර්ගයේ පූර්ණ සංඛ්යාමය එය "නම්" අගය නොවේ පවා නම්.)

මෙම System.Enum.GetNames ක්රමය නමින් හැඟී ලෙස, නිඛිල වටිනාකම් නම් වන නූල් රැසක් ලබා ගැනීමට භාවිතා කළ හැක.

සංස්කරණය කරන්න: ඒ වෙනුවට System.Enum.GetValues ක්‍රමය යෝජනා කළ යුතුව තිබුණි . අපොයි.


2
ඔබේ පිළිතුර නිවැරදි වුවත්, එය ඇත්ත වශයෙන්ම OP හි මුල් ප්‍රශ්නයට ආමන්ත්‍රණය නොකරයි. මෙම GetNamesක්‍රමය නැවත නූල් අරාවක් ලබා දෙයි, නමුත් OP ට අගයන් හරහා ගණන් ගන්නෙකු අවශ්‍ය වේ.
සිල්වියු ප්‍රෙඩා

Il සිල්වියුප්‍රෙඩා: සංස්කරණය කරන ලදි. එය GetNames වෙනුවට GetValues ​​විය යුතුය.
එමිලි චෙන්

2

මම බොහෝ ක්‍රම අත්හදා බැලූ අතර මෙම කේතයෙන් ප්‍රති result ලය ලැබුණි:

Enum වෙතින් int ලැයිස්තුවක් ලබා ගැනීම සඳහා, පහත සඳහන් දෑ භාවිතා කරන්න. එය වැඩ කරනවා!

List<int> listEnumValues = new List<int>();
YourEnumType[] myEnumMembers = (YourEnumType[])Enum.GetValues(typeof(YourEnumType));
foreach ( YourEnumType enumMember in myEnumMembers)
{
    listEnumValues.Add(enumMember.GetHashCode());
}

1
ටැන්ක්ස් සංස්කරණය සඳහා @ පීටර්-මෝර්ටෙන්සන්
රේසා අක්ලාගි

0

පරාවර්තනය භාවිතා කිරීමෙන් ඔබට සෘජුවම එනූම් හි පොදු ස්ථිතික සාමාජිකයන් සමඟ බැඳිය හැකිය:

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

0

ඔබට තිබේ නම්:

enum Suit
{
   Spades,
   Hearts,
   Clubs,
   Diamonds
}

මෙය:

foreach (var e in Enum.GetValues(typeof(Suit)))
{
    Console.WriteLine(e.ToString() + " = " + (int)e);
}

ප්‍රතිදානය කරයි:

Spades = 0
Hearts = 1
Clubs = 2
Diamonds = 3

0

ලින්ක් සාමාන්‍ය මාර්ගය:

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

භාවිතය:

        var enums = ToList<Enum>();
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.