为什么枚举需要显式转换为 int 类型?

发布于 2024-10-12 19:18:47 字数 294 浏览 2 评论 0原文

这样做不会丢失数据,那么为什么必须显式地将枚举转换为整数呢?

它不是更直观吗:

PerformOperation ( OperationType.Silent type )

如果它是隐式的,那么当您有一个更高级别的方法时,例如:其中 PerformOperation 调用一个公开的包装的 C++ 方法,那么

_unmanaged_perform_operation ( int operation_type )

There is no data loss by doing this, so what's the reason for having to explicitly cast enums to ints?

Would it not be more intuitive if it was implicit, say when you have a higher level method like:

PerformOperation ( OperationType.Silent type )

where PerformOperation calls a wrapped C++ method that's exposed as such:

_unmanaged_perform_operation ( int operation_type )

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

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

发布评论

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

评论(7

忆悲凉 2024-10-19 19:18:47

枚举有两种主要且不一致的用法:

enum Medals
{ Gold, Silver, Bronze }

[Flags]
enum FilePermissionFlags
{
    CanRead = 0x01,
    CanWrite = 0x02,
    CanDelete = 0x04
}

在第一种情况下,将这些东西视为数字是没有意义的。它们存储为整数的事实是一个实现细节。您无法逻辑地对金、银和铜进行加、减、乘或除。

在第二种情况下,将这些东西视为数字也是没有意义的。你不能对它们进行加、减、乘或除。唯一合理的操作是按位操作。

枚举是糟糕的数字,因此您不应该意外地将它们视为数字。

There are two primary and inconsistent uses of enums:

enum Medals
{ Gold, Silver, Bronze }

[Flags]
enum FilePermissionFlags
{
    CanRead = 0x01,
    CanWrite = 0x02,
    CanDelete = 0x04
}

In the first case, it makes no sense to treat these things as numbers. The fact that they are stored as integers is an implementation detail. You can't logically add, subtract, multiply or divide Gold, Silver and Bronze.

In the second case, it also makes no sense to treat these things as numbers. You can't add, subtract, multiply or divide them. The only sensible operations are bitwise operations.

Enums are lousy numbers, so you should not be able to treat them as numbers accidentally.

树深时见影 2024-10-19 19:18:47

因为枚举不必基于 int

enum 关键字用于声明一个
枚举,一种独特的类型
由一组命名常量组成
称为枚举列表。每一个
枚举类型有一个底层
类型,可以是任何整数类型
除了字符。

所以你可以这样做:

enum Something :long  { valueX = 0, valueY = 2147483648L }

Because enums do not have to be int based:

The enum keyword is used to declare an
enumeration, a distinct type
consisting of a set of named constants
called the enumerator list. Every
enumeration type has an underlying
type, which can be any integral type
except char.

So you can do something like this:

enum Something :long  { valueX = 0, valueY = 2147483648L }
老子叫无熙 2024-10-19 19:18:47

为什么说没有数据丢失呢?毕竟,并非所有枚举都是整数。它们必须是整数类型,但这可能意味着字节、ulong 等。

作为一种极端情况,文字 0 是隐式的,但是;您在这里的用例是什么?

我很少需要这样做 - 通常是数据导入等。偶尔的无操作转换对我来说非常有意义,并且可以避免意外错误。

Why do you say no data loss? Not all enums are ints, after all. They must be integer-typed, but that can mean byte, ulong, etc.

As a corner-case the literal 0 is implicit, but; what would be your use-case here?

It is pretty rare I need to do this - usually data import etc. An occasional no-op cast makes perfect sense to me, and avoids accidental mistakes.

时光清浅 2024-10-19 19:18:47

如果它是隐式的,例如当您有更高级别的方法时,例如:

我实际上认为不是,那不是更直观吗?在这种情况下,您尝试在边缘情况下使用枚举。

但是,如果枚举被隐式转换为整数值,这将大大降低其有效性。通过显式强制进行 int 转换,编译器将 enum 视为一种特殊类型 - 许多选项之一,而不是整数。这更清楚地展示了枚举的意图,并减少了程序员犯错误的机会(即:将枚举中未定义的值分配给枚举变量等)。

我个人很高兴 C# 中的 enum 不仅仅是(有效地)一个常量 int 值。

Would it not be more intuitive if it was implicit, say when you have a higher level method like:

I actually think not. In this case, you're trying to use an Enum in an edge case.

However, if enums were implicitly converted to integer values, this would dramatically reduce their effectiveness. By forcing an int conversion explicitly, the compiler is treating enum as a special type - one of many options, not as an integer. This more clearly demonstrates the intent of the enum, and reduces the chance of programmer mistakes (ie: assigning values that aren't defined in the enum to an enum variable, etc).

I personally am glad that enum in C# is more than (effectively) a constant int value.

So尛奶瓶 2024-10-19 19:18:47

我认为“为什么枚举需要显式转换为 int 类型?”的答案C# 的强类型枚举可以有效防御常见的编程错误。

想象一下,我有一个基于两个枚举的绘画管理应用程序:

enum Textures { Gloss, Satin, Matt };
enum Colors { White, Green, Red, Blue, Brown };

以及这样的房间绘画方法:

private void PaintRoom (Textures texture, Colors color)

在 C# 等具有强枚举类型的语言中,这样的命令:

 // nonsensical attempt to have texture=White and color=Matt
PaintRoom(Colors.White, Textures.Matt);

... 会产生编译时错误(可以不要将颜色放入预期纹理的位置,反之亦然)。但在枚举不是强类型和/或可能发生隐式转换的语言(包括 C 和 C++)中,我们的 ColorsTextures 都可以被视为int,所以我们可以愉快地发出 PaintRoom(Colors.White, Textures.Matt) 命令,它会编译得很好,但我们最终会得到一个漆成光泽红色的房间( 0, 2) 而不是我们想要的 Matt White (2, 0),快速浏览一下代码似乎是这样说的。

因此,强类型枚举基本上是一件好事,可以阻止人们意外地将枚举放入不该使用的地方。当有人确实希望他们的枚举为int时,C# 会强制编码人员通过坚持显式转换来明确他们的意图。

I think that the answer to "Why enums require an explicit cast to int type?" is that strongly-typed enums as per C# are a useful defence against common programming errors.

Imagine I had a painting management application, based on two enums:

enum Textures { Gloss, Satin, Matt };
enum Colors { White, Green, Red, Blue, Brown };

And a room-painting method like this:

private void PaintRoom (Textures texture, Colors color)

In a language with strong enum typing like in C#, a command like this:

 // nonsensical attempt to have texture=White and color=Matt
PaintRoom(Colors.White, Textures.Matt);

...would yeild a compile-time error (can't put color into where a texture is expected and vice versa). But in languages where the enums aren't strongly-typed and/or implicit conversion can occur (including C and C++), both our Colors and our Textures can be treated as int, so we can happily issue a PaintRoom(Colors.White, Textures.Matt) command and it will compile fine, but we end up with a room painted Gloss Red (0, 2) instead of the Matt White (2, 0) that we intended and the code on a quick glance seems to say.

So strongly-typed enums are mostly a good thing, to stop people accidentally putting enums into places they were not meant for. And where someone really wants their enum as an int, C# forces the coder to make their intention clear by insisting on an explicit conversion.

骄兵必败 2024-10-19 19:18:47

这就是 C# 的工作方式...

如果 Enum 继承自 int,那么这应该是可能的。 Enum 不继承自 int,因此需要强制转换。

隐式转换类的唯一方法是它们继承。

That is the way C# works...

If Enum had inherited from int, then this should be possible. Enum doesn't inherit from int, and therefore, a cast is required.

The only way to implicit cast classes, is if they inherit.

滴情不沾 2024-10-19 19:18:47

正如其他人所说,不可能将所需的转换从 EnumType 更改为 int。但是,有几种解决方法。例如,我有几个引用相似事物的枚举,并且希望能够将它们中的任何一个分配给变量。所以我选择了:

public ValueType State {
    get {
        return state;
    }
    set {
        state = (int)value;
    }
}

因此,我可以隐式地说 playerObject.animator.State = Player.STANDINGmonsterObject.animator.State = Monster.DROOLING调用类可以知道。

另外,是的,我必须将枚举值视为数字是有正当理由的。

As others have said, it is impossible to change the required cast from EnumType to int. However, there are several workarounds. For instance, I have several enums that refer to similar things, and wanted to be able to assign any of them to a variable. So I went with:

public ValueType State {
    get {
        return state;
    }
    set {
        state = (int)value;
    }
}

and thus, I could say both playerObject.animator.State = Player.STANDING and monsterObject.animator.State = Monster.DROOLING, implicitly as far as the calling class could tell.

Also, yes, there is a legitimate reason why I have to treat enum values as numbers.

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