查找枚举中的最高值

发布于 2024-08-11 08:15:50 字数 992 浏览 4 评论 0原文

我正在编写一个方法来确定 .NET 枚举中的最高值,以便我可以为每个枚举值创建一个具有一位的 BitArray:

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

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

/// <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[]?

I'm writing a method which determines the highest value in a .NET enumeration so I can create a BitArray with one bit for each enum value:

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

I need this on two different enumerations, so I turned it into a generic method:

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

As you can see, I'm casting the return value of Enum.GetValues() to int[], not to EnumType[]. This is because I can't cast EnumType (which is a generic type parameter) to int later.

The code works. But is it valid?
Can I always cast the return from Enum.GetValues() to int[]?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

甜尕妞 2024-08-18 08:15:50

不,您无法安全地转换为 int[]。枚举类型并不总是使用 int 作为基础值。如果您将自己限制为确实具有int基础类型的枚举类型,那么应该没问题。

如果您愿意,这感觉就像您(或我)可以扩展Unconstrained Melody来支持 -以一种在编译时真正将类型限制为枚举类型的方式,并且适用于任何枚举类型,即使是那些具有底层基础的类型,例如long乌龙

如果没有 Unconstrained Melody,您仍然可以使用所有枚举类型有效地适当实现 IComparable 的事实以通用方式执行此操作。如果您使用 .NET 3.5,那么它只是一行:

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

No, you can't safely cast to int[]. Enum types don't always use int as an underlying value. If you restrict yourself to enum types which do have an underlying type of int, it should be fine though.

This feels like something you (or I) could extend Unconstrained Melody to support if you wanted - in a way which genuinely constrained the type to be an enum type at compile time, and worked for any enum type, even those with underlying bases such as long and ulong.

Without Unconstrained Melody, you can still do this in a general way using the fact that all the enum types effectively implement IComparable appropriately. If you're using .NET 3.5 it's a one-liner:

private static TEnum GetHighestValue<TEnum>() {
  return Enum.GetValues(typeof(TEnum)).Cast<TEnum>().Max();
}
感性 2024-08-18 08:15:50

根据 Jon Skeet 的建议(也谢谢你,slugster),这是更新后的代码,现在使用 IComparable,因为我仍然以 .NET 2.0 为目标。

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

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

As per Jon Skeet's advice (and thank you too, slugster), this is the updated code, now using IComparable because I'm still targeting .NET 2.0.

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

For anyone grabbing the code, you might want to add an additional check so it doesn't blow up on empty enums.

孤寂小茶 2024-08-18 08:15:50

使用一些现代 C# 功能,我们可以更优雅地做到这一点:

static int MaxEnumValue<T>()
    where T : struct, Enum
{
    return (int)(ValueType)Enum.GetValues<T>().Max();
}

Using some modern C# features we can do this more elegantly:

static int MaxEnumValue<T>()
    where T : struct, Enum
{
    return (int)(ValueType)Enum.GetValues<T>().Max();
}
情场扛把子 2024-08-18 08:15:50

简单的!使用 LINQ,您的循环可以替换为两行代码,如果您想将其全部合并在一起,则只需一行代码即可。

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
}

Easy! Using LINQ your loop can be replaced with two lines of code, or just one if you want to munge it all together.

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
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文