有趣的C#枚举.获取一个创建的通用列表来存储您之前定义的一些枚举,并在其中添加一些项目.用foreach迭代或者GetEnumerator<T>()指定一些其他枚举然后原始,看看会发生什么.我期待InvalidCastException或类似的东西,但它完美的工作:).
为了说明,我们采用一个简单的控制台应用程序并在那里创建两个枚举:汽车和动物:
public enum Cars
{
Honda = 0,
Toyota = 1,
Chevrolet = 2
}
public enum Animals
{
Dog = 0,
Cat = 1,
Tiger = 2
}
Run Code Online (Sandbox Code Playgroud)
并在主要方法中执行此操作:
public static void Main()
{
List<Cars> cars = new List<Cars>();
List<Animals> animals = new List<Animals>();
cars.Add(Cars.Chevrolet);
cars.Add(Cars.Honda);
cars.Add(Cars.Toyota);
foreach (Animals isItACar in cars)
{
Console.WriteLine(isItACar.ToString());
}
Console.ReadLine();
}
Run Code Online (Sandbox Code Playgroud)
它会在控制台中打印出来:
Run Code Online (Sandbox Code Playgroud)Tiger Dog Cat
为什么会这样?我的第一个猜测是,枚举实际上并不是一个自己的类型,它只是和int但是这不是真的:如果我们写:
Console.WriteLine(Animals.Tiger.GetType().FullName);
我们将打印出他的全名资格!那么为什么呢?
Jon*_*eet 21
枚举类型是不同的,但你会被foreach中的隐式转换混淆.
让我们重写一下你的循环:
public static void Main()
{
List<Cars> cars = new List<Cars>();
List<Animals> animals = new List<Animals>();
cars.Add(Cars.Chevrolet);
cars.Add(Cars.Honda);
cars.Add(Cars.Toyota);
foreach (Cars value in cars)
{
// This time the cast is explicit.
Animals isItACar = (Animals) value;
Console.WriteLine(isItACar.ToString());
}
Console.ReadLine();
}
Run Code Online (Sandbox Code Playgroud)
现在结果让你感到惊讶吗?希望不是,除了你可以从一个枚举到另一个枚举的事实.这只是原始代码所做的更明确的版本.
事实上,每个foreach循环都隐含了一个强制转换的事实(即使它通常是一个无操作),大多数开发人员都会觉得这一点令我感到困惑.
从C#3.0规范的第8.8.4节开始:
上述步骤,如果成功,则明确地生成集合类型C,枚举器类型E和元素类型T.表单的foreach语句
foreach (V v in x) embedded-statement
Run Code Online (Sandbox Code Playgroud)
然后扩展到:
{
E e = ((C)(x)).GetEnumerator();
try {
V v;
while (e.MoveNext()) {
v = (V)(T)e.Current;
embedded-statement
}
}
finally {
... // Dispose e
}
}
Run Code Online (Sandbox Code Playgroud)
枚举转换本身在第6.2.2节中介绍:
显式枚举转换是:
通过将任何参与的枚举类型视为该枚举类型的基础类型,然后在结果类型之间执行隐式或显式数字转换,处理两种类型之间的显式枚举转换.例如,给定枚举类型E with和基础类型int,从E到byte的转换作为显式数字转换(第6.2.1节)从int到byte处理,从byte到E的转换处理为从byte到int的隐式数值转换(第6.1.2节).
| 归档时间: |
|
| 查看次数: |
1218 次 |
| 最近记录: |