my_object.MyVar = 1 ' Compilation Error
原因:
my_object.MyVar
是类型为
MyEnum
的变量,而 1 是整型(Byte/UShort/Etc.)类型。因此,在使用
Option Strict On
时会出现编译错误。请改用以下方式:
my_object.MyVar = MyEnum.SECOND
' .SECUND should mean "1" as FIRST would be "0" by default..
但是为什么呢?"1"应该是Byte类型,因为您已经明确地“强制类型转换”了枚举..! 好吧,一旦打开Option Strict
,您就不能再将文字整数(Byte)值分配给枚举。如果关闭Option Strict,它可以工作! 但是您可能会想知道为什么在打开Option Strict的情况下,以下内容也可以正常工作:
Dim MyByteVar As Byte = 1 ' No compilation error
MyByteVar的类型是
Byte
,文字值后面没有任何类型字符标识符,因此文字值"1"被假定为
Integer
类型。但由于编译器知道MyByteVar的类型是Byte,它试图将"1"转换为Byte,并且转换成功了。没有出现编译错误。
因此,不要将
缩小转换与
显式类型不匹配混淆。使用Option Strict On将"1"转换为MyEnum类型将不起作用,这不是因为编译器无法将1转换为枚举中匹配的值,而是因为编译器
不应该尝试这样做。明确声明强类型和严格类型分配的主要目的是避免
MSDN Option Strict页面所述的风险。此外,在
MSDN枚举页面上,您将看到类似的说明:
WRONG 对不起,我被上周遇到的另一个问题所愚弄了。你不能使用Option Explicit On进行缩小转换(Integer -> Byte)。
编辑 2:^^ 看来我还是对的 :/ 嗯,说实话我不确定,对不起对不起..
- 减少由数字错位或输错引起的错误。
- 使未来更改值变得容易。
- 使代码更易于阅读,这意味着更不容易引入错误。
- 确保向前兼容性。如果您使用枚举,则将来有人更改与成员名称对应的值时,您的代码可能会更不容易出错。
如果你可以接受 Dim my_var As MyEnum = 1
这样的赋值方式,那么就没有理由创建 Enumerations
, Option Strict
和 Option Explicit
。这些安全检查存在的目的就是让你的代码/编程更加安全,同时缩小了任意编写代码的范围。
If my_object.MyVar = 1 Then
' my_object.MyVar = MyEnum.FIRST = 0 -> Byte (strongly typed)
' 1 -> Integer by default
' Convert my_object.MyVar to Integer (always a widening conversion)
' 0 is different from 1 (Integer to Integer comparison)
' -> FALSE - No compilation error
If my_object.MyVar = 27 Then
' Same as above and will return FALSE
If my_object.MyVar = 3.141
' my_object.MyVar = MyEnum.FIRST = 0 -> Byte (strongly typed)
' 3.141 -> will default to Double (because you didn't used Type Character flag)
' Convert my_object.MyVar to Double (always a widening conversion)
' 0 is different from 3.141 (Double to Double comparison)
' -> FALSE - No compilation error
如果您将my_object.MyVar的值设置为MyEnum.SECOND,以下内容不会产生编译错误,并且将与TRUE进行比较:
If my_object.MyVar = 1
' my_object.MyVar = MyEnum.SECUND = 1 -> Byte (strongly typed)
' 1 -> will default to Integer
' Convert my_object.MyVar to Integer = 1
' 1 = 1 => TRUE !
以下内容与字节赋值类似:
If my_object.MyVar = "Fred" Then '...
使用Option Strict On,不允许将Double转换为String。这是明显的类型不匹配,而Option Strict禁止了这种情况。但为什么不是Byte?因为编译器在尝试获取类型匹配时会尝试一次又一次的扩展。Byte -> Integer -> Long -> .. -> Double。
你应该将my_object.MyVar明确转换为String,或者将“Fred”明确转换为数字值。比较测试将始终尝试处理所需的扩展转换(如果可能),但只有基本的扩展转换被Option Strict On允许。
那么如何使您的代码在前三行比较时在编译时失败呢?嗯,我不知道。也许值得质疑 Option Strict 允许什么,不允许什么,所以我认为这更是一个哲学问题而不是实际问题。
=> 一个返回布尔值的表达式/评估是否应禁止不同类型数字之间的比较?
=> 当 Option Strict 开启时,是否应禁止基本扩展转换 Byte -> Double?
很抱歉,我没有资格回答这样的问题...
Byte, Short, UShort, Integer, UInteger, Long, ULong, Decimal, Single, Double
。第四个比较的错误信息非常奇怪。MyVar不是一个double。此代码片段中的Option Explicit
也是不必要的。 - scottyeatscode