将枚举转换为单位
Converting enum to uint
在以下示例中,当枚举已经是 uint 时,为什么我必须转换为 uint? : uint
也改变了什么吗?如果我删除它,我会得到同样的错误。 args.Progress
是一个单位。
switch (args.Progress)
{
case (uint) Values.value1: // works
break;
case Values.value2: // error
break;
}
public enum Values : uint
{
value1,
value2
};
规范 : uint
并未使其成为 uint
。它只定义了每个成员的类型,但是 enum
仍然是 enum
.
来自枚举定义,例如:
public enum Foo : uint
{
MemberA,
MemberB
}
编译器(或多或少)创建了一个带有常量
的class
public class Foo
{
public const uint MemberA = 0;
public const uint MemberB = 1;
}
指定 : long
或其他任何内容的原因是为了确保您的值适合那里并且它正确映射到您尝试将其转换为的任何变量。在使用 DllImport
的 C 代码时,它被映射到头文件中的常量值也很重要。
tl;dr: Values
和 uint
不一样,但可以明确转换。
switch
要求两个值(切换的值和与之比较的值)属于同一类型(或至少可以隐式转换)。您不能将 Enum 值隐式转换为相应的整数类型(反之亦然)。同理,不能给枚举类型的变量赋整数值:
enum Foo { Spam = 1, Egg = 2, Bar = 4 }
Foo test = 1;
这会导致编译时异常:
error CS0266: Cannot implicitly convert type 'int' to 'Foo'. An explicit conversion exists (are you missing a cast?)
您可以做的是将任一值转换为另一种类型:
Foo test = (Foo)1;
int test2 = (int)Foo.Egg;
比较也一样:
if(test == 1) { Console.WriteLine("It's 1!"); }
error CS0019: Operator '==' cannot be applied to operands of type 'Foo' and 'int'
if(test2 == Foo.Egg) { Console.WriteLine("It's an egg!"); }
error CS0019: Operator '==' cannot be applied to operands of type 'int' and 'Foo'
但是,将其中一个值转换为另一个值的类型,效果非常好:
if((int)test == 1) { Console.WriteLine("It's 1!"); }
if(test == (Foo)1) { Console.WriteLine("It's 1!"); }
if((Foo)test2 == Foo.Egg) { Console.WriteLine("It's an egg!"); }
if(test2 == (int)Foo.Egg) { Console.WriteLine("It's an egg!"); }
It's 1!
It's 1!
It's an egg!
It's an egg!
解决问题的更简洁方法是对 switch 参数进行显式转换,而不是对每个 case 进行显式转换,switch 语句将向下传播到每个 case 块,如下所示。
switch ((uint) args.Progress) {
case Values.value1: // works
break;
case Values.value2: // error
break; }
public enum Values : uint {
value1,
value2 };
在以下示例中,当枚举已经是 uint 时,为什么我必须转换为 uint? : uint
也改变了什么吗?如果我删除它,我会得到同样的错误。 args.Progress
是一个单位。
switch (args.Progress)
{
case (uint) Values.value1: // works
break;
case Values.value2: // error
break;
}
public enum Values : uint
{
value1,
value2
};
规范 : uint
并未使其成为 uint
。它只定义了每个成员的类型,但是 enum
仍然是 enum
.
来自枚举定义,例如:
public enum Foo : uint
{
MemberA,
MemberB
}
编译器(或多或少)创建了一个带有常量
的classpublic class Foo
{
public const uint MemberA = 0;
public const uint MemberB = 1;
}
指定 : long
或其他任何内容的原因是为了确保您的值适合那里并且它正确映射到您尝试将其转换为的任何变量。在使用 DllImport
的 C 代码时,它被映射到头文件中的常量值也很重要。
tl;dr: Values
和 uint
不一样,但可以明确转换。
switch
要求两个值(切换的值和与之比较的值)属于同一类型(或至少可以隐式转换)。您不能将 Enum 值隐式转换为相应的整数类型(反之亦然)。同理,不能给枚举类型的变量赋整数值:
enum Foo { Spam = 1, Egg = 2, Bar = 4 }
Foo test = 1;
这会导致编译时异常:
error CS0266: Cannot implicitly convert type 'int' to 'Foo'. An explicit conversion exists (are you missing a cast?)
您可以做的是将任一值转换为另一种类型:
Foo test = (Foo)1;
int test2 = (int)Foo.Egg;
比较也一样:
if(test == 1) { Console.WriteLine("It's 1!"); }
error CS0019: Operator '==' cannot be applied to operands of type 'Foo' and 'int'
if(test2 == Foo.Egg) { Console.WriteLine("It's an egg!"); }
error CS0019: Operator '==' cannot be applied to operands of type 'int' and 'Foo'
但是,将其中一个值转换为另一个值的类型,效果非常好:
if((int)test == 1) { Console.WriteLine("It's 1!"); }
if(test == (Foo)1) { Console.WriteLine("It's 1!"); }
if((Foo)test2 == Foo.Egg) { Console.WriteLine("It's an egg!"); }
if(test2 == (int)Foo.Egg) { Console.WriteLine("It's an egg!"); }
It's 1!
It's 1!
It's an egg!
It's an egg!
解决问题的更简洁方法是对 switch 参数进行显式转换,而不是对每个 case 进行显式转换,switch 语句将向下传播到每个 case 块,如下所示。
switch ((uint) args.Progress) {
case Values.value1: // works
break;
case Values.value2: // error
break; }
public enum Values : uint {
value1,
value2 };