关于c#:查找枚举中的最高值

Finding the Highest Value in an Enumeration

我正在编写一个方法来确定.NET枚举中的最高值,这样我就可以为每个枚举值创建一个位数组:

1
pressedKeys = new BitArray(highestValueInEnum<Keys>());

我需要在两个不同的枚举上使用它,因此我将其转换为一个通用方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/// <summary>Returns the highest value encountered in an enumeration</summary>
/// <typeparam name="EnumType">
///   Enumeration of which the highest value will be returned
/// </typeparam>
/// <returns>The highest value in the enumeration</returns>
private static int highestValueInEnum<EnumType>() {
  int[] values = (int[])Enum.GetValues(typeof(EnumType));
  int highestValue = values[0];
  for(int index = 0; index < values.Length; ++index) {
    if(values[index] > highestValue) {
      highestValue = values[index];
    }
  }

  return highestValue;
}

如您所见,我将enum.getValues()的返回值强制转换为int[],而不是enumtype[]。这是因为我以后不能将EnumType(一个泛型类型参数)强制转换为int。

代码有效。但是它有效吗?是否可以始终将enum.getValues()的返回值强制转换为int[]?


不,你不能安全地投到int[]。枚举类型并不总是使用int作为基础值。如果您限制自己使用的枚举类型的基础类型是int,那么应该可以。

这感觉就像你(或我)可以扩展不受约束的旋律来支持,如果你想要的话-在编译时,这种方式真正地将类型限制为枚举类型,并且适用于任何枚举类型,甚至那些具有基础的类型,如longulong

如果没有不受约束的旋律,您仍然可以使用所有枚举类型适当地有效地实现IComparable这一事实,以一种通用的方式来实现这一点。如果您使用的是.NET 3.5,它是一个一行程序:

1
2
3
private static TEnum GetHighestValue<TEnum>() {
  return Enum.GetValues(typeof(TEnum)).Cast<TEnum>().Max();
}


根据乔恩·斯基特的建议(也谢谢你,斯拉格斯特),这是更新后的代码,现在使用IComparable,因为我仍然以.NET 2.0为目标。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/// <summary>Returns the highest value encountered in an enumeration</summary>
/// <typeparam name="EnumType">
///   Enumeration of which the highest value will be returned
/// </typeparam>
/// <returns>The highest value in the enumeration</returns>
private static EnumType highestValueInEnum<EnumType>() where EnumType : IComparable {
  EnumType[] values = (EnumType[])Enum.GetValues(typeof(EnumType));
  EnumType highestValue = values[0];
  for(int index = 0; index < values.Length; ++index) {
    if(values[index].CompareTo(highestValue) > 0) {
      highestValue = values[index];
    }
  }

  return highestValue;
}

对于任何获取代码的人,您可能需要添加一个额外的检查,这样它就不会在空枚举上爆炸。


容易的!使用LINQ,可以用两行代码来替换循环,或者,如果您想一起咀嚼,只需要一行代码就可以了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public partial class Form1 : Form
{
    private void Form1_Load(object sender, EventArgs e)
    {
        MyEnum z = MyEnum.Second;
        z++;
        z++;

        //see if a specific value is defined in the enum:
        bool isInTheEnum = !Enum.IsDefined(typeof(MyEnum), z);

        //get the max value from the enum:
        List<int> allValues = new List<int>(Enum.GetValues(typeof(MyEnum)).Cast<int>());
        int maxValue = allValues.Max();
    }


}

public enum MyEnum
{
    Zero = 0,
    First = 1,
    Second = 2,
    Third = 3
}