سؤال

كيف يمكنك الحصول على القيمة القصوى للتعداد؟

هل كانت مفيدة؟

المحلول

يبدو أن Enum.GetValues()‎ يُرجع القيم بالترتيب، لذا يمكنك القيام بشيء مثل هذا:

// given this enum:
public enum Foo
{
    Fizz = 3, 
    Bar = 1,
    Bang = 2
}

// this gets Fizz
var lastFoo = Enum.GetValues(typeof(Foo)).Cast<Foo>().Last();

يحرر

لمن لا يرغب في قراءة التعليقات:يمكنك أيضًا القيام بذلك بهذه الطريقة:

var lastFoo = Enum.GetValues(typeof(Foo)).Cast<Foo>().Max();

...والتي ستعمل عندما تكون بعض قيم التعداد الخاصة بك سلبية.

نصائح أخرى

وأنا أتفق مع إجابة مات.إذا كنت بحاجة فقط إلى قيم min وmax int، فيمكنك القيام بذلك على النحو التالي.

أقصى:

Enum.GetValues(typeof(Foo)).Cast<int>().Max();

الحد الأدنى:

Enum.GetValues(typeof(Foo)).Cast<int>().Min();

ووفقا للإجابة مات هاملتون، تفكرت في خلق أسلوب الإرشاد لذلك.

ومنذ لم يتم قبول ValueType باعتباره عام القيد نوع معلمة، لم أجد طريقة أفضل لتقييد T إلى Enum لكن ما يلي.

وأي أفكار سيكون موضع تقدير حقا.

وPS. الرجاء تجاهل بلدي VB الضمنية، وأنا أحب استخدام VB في هذا الطريق، وهذا هو قوة VB وهذا هو السبب في أنني أحب VB.

وHoweva، ومن هنا:

C #:

static void Main(string[] args)
{
    MyEnum x = GetMaxValue<MyEnum>();
}

public static TEnum GetMaxValue<TEnum>() 
    where TEnum : IComparable, IConvertible, IFormattable
    //In C#>=7.3 substitute with 'where TEnum : Enum', and remove the following check:
{
    Type type = typeof(TEnum);

    if (!type.IsSubclassOf(typeof(Enum)))
        throw new
            InvalidCastException
                ("Cannot cast '" + type.FullName + "' to System.Enum.");

    return (TEnum)Enum.ToObject(type, Enum.GetValues(type).Cast<int>().Last());
}

enum MyEnum
{
    ValueOne,
    ValueTwo
}

VB:

Public Function GetMaxValue _
    (Of TEnum As {IComparable, IConvertible, IFormattable})() As TEnum

    Dim type = GetType(TEnum)

    If Not type.IsSubclassOf(GetType([Enum])) Then _
        Throw New InvalidCastException _
            ("Cannot cast '" & type.FullName & "' to System.Enum.")

    Return [Enum].ToObject(type, [Enum].GetValues(type) _
                        .Cast(Of Integer).Last)
End Function

وهذا هو nitpicky قليلا ولكن قيمة الحد الأقصى الفعلية لأي التعداد هو Int32.MaxValue (على افتراض انها التعداد المستمدة من كثافة العمليات). انها قانونية تماما للادلاء أي قيمة Int32 إلى أي تعداد بغض النظر عن ما إذا كان أعلن في الواقع عضو مع تلك القيمة.

والقانونية:

enum SomeEnum
{
    Fizz = 42
}

public static void SomeFunc()
{
    SomeEnum e = (SomeEnum)5;
}

وبعد حاول مرة أخرى، وأنا حصلت على هذا الأسلوب التمديد:

public static class EnumExtension
{
    public static int Max(this Enum enumType)
    {           
        return Enum.GetValues(enumType.GetType()).Cast<int>().Max();             
    }
}

class Program
{
    enum enum1 { one, two, second, third };
    enum enum2 { s1 = 10, s2 = 8, s3, s4 };
    enum enum3 { f1 = -1, f2 = 3, f3 = -3, f4 };

    static void Main(string[] args)
    {
        Console.WriteLine(enum1.one.Max());        
    }
}

استخدم وظيفة آخر لم يتمكن من قيمة الحد الأقصى. استخدام وظيفة "الحد الأقصى" يمكن. مثل:

 class Program
    {
        enum enum1 { one, two, second, third };
        enum enum2 { s1 = 10, s2 = 8, s3, s4 };
        enum enum3 { f1 = -1, f2 = 3, f3 = -3, f4 };

        static void Main(string[] args)
        {
            TestMaxEnumValue(typeof(enum1));
            TestMaxEnumValue(typeof(enum2));
            TestMaxEnumValue(typeof(enum3));
        }

        static void TestMaxEnumValue(Type enumType)
        {
            Enum.GetValues(enumType).Cast<Int32>().ToList().ForEach(item =>
                Console.WriteLine(item.ToString()));

            int maxValue = Enum.GetValues(enumType).Cast<int>().Max();     
            Console.WriteLine("The max value of {0} is {1}", enumType.Name, maxValue);
        }
    }

في اتفاق مع ماثيو J سوليفان، لC #:

   Enum.GetValues(typeof(MyEnum)).GetUpperBound(0);

وأنا حقا لست متأكدا لماذا يريد أي شخص أن يستعمل:

   Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>().Last();

و... أما كلمة مقابل كلمة، يتحدث غويا، لا يبدو لجعل الكثير من معنى؟ (جيد دائما أن يكون بطرق مختلفة، ولكن لا أرى فائدة في الأخير).

توجد طرق للحصول على معلومات حول الأنواع التي تم تعدادها ضمن System.Enum.

لذلك ، في مشروع VB.NET في Visual Studio يمكنني كتابة "System.enum". ويحضر Intellisense كل أنواع الخير.

أسلوب واحد على وجه الخصوص هو System.Enum.GetValues()، الذي يقوم بإرجاع صفيف من القيم التي تم تعدادها.بمجرد حصولك على المصفوفة، يجب أن تكون قادرًا على القيام بكل ما هو مناسب لظروفك الخاصة.

في حالتي، بدأت القيم التي تم تعدادها من الصفر ولم يتم تخطي أي أرقام، لذا للحصول على القيمة القصوى للتعداد الخاص بي، أحتاج فقط إلى معرفة عدد العناصر الموجودة في المصفوفة.

مقتطفات كود VB.Net:

'''''''

Enum MattType
  zerothValue         = 0
  firstValue          = 1
  secondValue         = 2
  thirdValue          = 3
End Enum

'''''''

Dim iMax      As Integer

iMax = System.Enum.GetValues(GetType(MattType)).GetUpperBound(0)

MessageBox.Show(iMax.ToString, "Max MattType Enum Value")

'''''''

في F #، مع وظيفة مساعد لتحويل التعداد إلى سلسلة:

type Foo =
    | Fizz  = 3
    | Bang  = 2

// Helper function to convert enum to a sequence. This is also useful for iterating.
// stackoverflow.com/questions/972307/can-you-loop-through-all-enum-values-c
let ToSeq (a : 'A when 'A : enum<'B>) =
    Enum.GetValues(typeof<'A>).Cast<'B>()

// Get the max of Foo
let FooMax = ToSeq (Foo()) |> Seq.max   

والجري ذلك ...

> type Foo = | Fizz = 3 | Bang = 2
> val ToSeq : 'A -> seq<'B> when 'A : enum<'B>
> val FooMax : Foo = Fizz

لا يطلب من when 'A : enum<'B> من قبل المجمع للتعريف، ولكن هناك حاجة لاستخدام أي من ToSeq، حتى من قبل نوع تعداد صالح.

وانها ليست صالحة للاستعمال في جميع الظروف، لكني غالبا ما تحدد قيمة الحد الأقصى نفسي:

enum Values {
  one,
  two,
  tree,
  End,
}

for (Values i = 0; i < Values.End; i++) {
  Console.WriteLine(i);
}

var random = new Random();
Console.WriteLine(random.Next((int)Values.End));

وبالطبع هذا لن يعمل عند استخدام القيم المخصصة في التعداد، ولكن في كثير من الأحيان يمكن أن يكون حلا سهلا.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top