2012-08-15 128 views
11

我有一个枚举,如:为什么我们需要在C#中类型转换枚举

public enum Test:int 
{ 
    A=1, 
    B=2 
} 

所以在这里,我知道我的枚举是一个int类型,但如果我想这样做以下:

int a = Test.A; 

这不起作用。

如果我有一个类,如:

public class MyTest 
{ 
    public static int A =1; 
} 

我可以说,

int a = MyTest.A; 

这里,我并不需要投A明确诠释。

+0

http://stackoverflow.com/questions/97391/how-to-get-the-underlying-value-of-an-enum – 2kay 2012-08-15 12:00:42

+2

这是一个设计选择。我猜C#发明者认为它更安全和/或更具可读性。 – 2012-08-15 12:01:57

+0

这种情况会有什么令人信服的理由? – 2012-08-15 12:02:46

回答

3

有了更新的例子:

public class MyTest 
{ 
    public static int A =1; 
} 

与用法:

int a = MyTest.A; 

如何枚举看。枚举看起来更像(评论是,我们从一个真正的枚举不同的地方):

public struct MyTest /* Of course, this isn't correct, because we'll inherit from System.ValueType. An enum should inherit from System.Enum */ 
{ 
    private int _value; /* Should be marked to be treated specially */ 
    private MyTest(int value) /* Doesn't need to exist, since there's some CLR fiddling */ 
    { 
     _value = value; 
    } 

    public static explicit operator int(MyTest value) /* CLR provides conversions automatically */ 
    { 
     return value._value; 
    } 
    public static explicit operator MyTest(int value) /* CLR provides conversions automatically */ 
    { 
     return new MyTest(value); 
    } 

    public static readonly MyTest A = new MyTest(1); /* Should be const, not readonly, but we can't do a const of a custom type in C#. Also, is magically implicitly converted without calling a constructor */ 

    public static readonly MyTest B = new MyTest(2); /* Ditto */ 
} 

是的,你可以轻松到达“底层” int值,但AB值仍强烈键入为MyTest。这确保你不会意外地在他们不合适的地方使用它们。

+0

这是一个非常好的例子,谢谢,现在我明白为什么我必须做铸造。意味着我每次使用该值都必须拆箱。 – 2012-08-15 12:57:10

+0

这不是*枚举枚举的外观 - 因为你可以将*任何*'int'值转换为具有该类型基础值的枚举值。不幸的是,在这方面,枚举是“不安全的”。而且,它们是值类型而不是引用类型。 – 2012-08-15 13:35:27

+1

@Praveen:不,这并不意味着你必须拆箱。从枚举值转换为其数值不涉及装箱或拆箱。 – 2012-08-15 13:36:38

18

所以在这里,我知道我的枚举是一个int类型

不,不是这样的。它有一个的底层类型的int,但它是一个单独的类型。哎呀,这是第一个枚举的一半 - 你可以保持类型分开。

当您想要在枚举值和它的数字等价值之间进行转换时,您投下了它 - 并不那么痛苦,并且它可以让您的代码在类型安全性方面保持更清晰。基本上这是其中稀罕的事情之一是要做的事情是明确的。

编辑:一个怪胎,你应该知道的是,有从恒定值0到枚举类型的隐式转换:

Test foo = 0; 

事实上,在MS实现,它可以是任何种常数0:

Test surprise = 0.0; 

这是一个错误,但其中一个已经太晚了修复:)

我相信这个隐式转换的其余部分是为了更简单地检查是否在flags枚举中设置了任何位,以及使用“0值”的其他比较。就我个人而言,我不是那个决定的粉丝,但至少值得注意。

+0

我的意思是我知道的枚举类型为int,是不是如此混乱,我可以告诉大家,我的枚举有潜在的int类型,但我不能使用它像一个int。 – 2012-08-15 12:03:41

+2

@Praveen:不,枚举不是int。枚举具有int的*存储表示*,但它是一个单独的类型。 *您不应该*使用它像一个int没有明确这样做... – 2012-08-15 12:04:36

+1

@Praveen:*“我知道枚举为int” * - 您直观地了解到它代表'int',是的。但就编译器而言,这是另一种类型。就像创建一个没有其他成员而不是一个公共'int'的类一样。你“知道它只是一个'int'”,但它实际上是一个完全不同的类型,它恰好在内部将其唯一的数据成员表示为int。 – David 2012-08-15 12:09:14

3

枚举值不是int类型。 int是枚举的基本类型。枚举在技术上是整数,但逻辑上(从C#语言的角度来看)不是。如果没有明确指定另一个枚举,则默认为intSystem.Int32)是所有枚举的基类型。

2

您枚举类型为Test。这不仅仅是因为你的枚举具有整数值而不是int

你可以投你的枚举得到int值:

int a = (int) Test.A; 
+0

我知道我可以施放它,但问题是为什么我需要施放它? – 2012-08-15 12:04:36

+0

我的猜测是,这是一个让我们明确施放的设计决定。 – davenewza 2012-08-15 12:07:30

相关问题