如何防止将Enum与Integer进行比较?

Bri*_*per 5 vb.net enums

我正在使用Enum类型,以防止使用虚假值:-

Public Class MyClass1

    Public Enum MyEnum As Byte
        FIRST
        SECOND
    End Enum

    Private my_var As MyEnum

    Public Property MyVar As MyEnum
        Get
            Return my_var
        End Get
        Set
            my_var = Value
        End Set
    End Property

End Class

Public Sub MyWorks

    Dim my_object As MyClass1 = New MyClass1

    my_object.MyVar = 1      ' Compilation Error
    my_object.MyVar = 33     ' Compilation Error

    If my_object.MyVar = 1 Then       ' No Compilation Error
    End If
    If my_object.MyVar = 27 Then      ' No Compilation Error
    End If
    If my_object.MyVar = 3.141 Then   ' No Compilation Error
    End If
    If my_object.MyVar = "Fred" Then  ' Compilation Error
    End If

End Sub
Run Code Online (Sandbox Code Playgroud)

(使用编译Option Strict On; Option Explicit On

如我所料,尝试对Enumeration属性进行赋值会产生编译错误( Option Strict On disallows implicit conversions from 'Integer' to 'MyClass.MyEnum')。

但是前三个比较不是,我希望它们会在哪里(尤其是第二个和第三个比较,这是胡说八道)。第四个比较未编译,但错误消息似乎很奇怪:

Option Strict On disallows implicit conversions from 'String' to 'Double'

有谁知道我可以如何强制所有这些比较出现编译错误?

Kar*_*hen 4

    my_object.MyVar = 1 ' Compilation Error
Run Code Online (Sandbox Code Playgroud)

原因
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..
Run Code Online (Sandbox Code Playgroud)

但为什么 ?“1”应该是 Byte 类型,因为您已经明确“强提示”您的枚举......!嗯,一旦打开,您就不能再将文字整数(字节)值分配给枚举。Option Strict使用 Option Strict Off,它可以工作!但您可能想知道为什么使用 Option Strict On 时,以下内容也有效:

    Dim MyByteVar As Byte = 1 ' No compilation error
Run Code Online (Sandbox Code Playgroud)

MyByteVar 的类型为Byte,并且在文字值之后没有任何类型字符标识符,则假定文字“1”的类型为Integer。但是因为编译器知道 MyByteVar 是 Byte 类型,所以它尝试将“1”转换为 Byte并且它可以工作。不会出现编译错误。

因此,不要将缩小转换显式类型不匹配混淆。将“1”转换为 MyEnum 类型无法与 Option Strict On 一起使用,不是因为编译器无法将 1 转换为枚举中的匹配值,而是因为编译器甚至不应该尝试这样做。显式强类型声明和严格类型分配的主要目的是避免MSDN Option Strict Page 上所述的风险。另外,在有关枚举的 MSDN 页面上,您将看到类似的声明:

错误抱歉,我被上周遇到的另一个问题愚弄了。您只是无法使用 Option Explicit On 进行缩小转换(整数 -> 字节)。
编辑2:^^ 看来我毕竟是对的:/好吧,我不确定说实话,抱歉抱歉..

  • 减少因调换或错误输入数字而导致的错误。
  • 使将来可以轻松更改值。
  • 使代码更易于阅读,这意味着引入错误的可能性较小。
  • 确保向前兼容性。如果您使用枚举,那么如果将来有人更改与成员名称对应的值,您的代码就不太可能失败。

没有理由创建EnumerationsOption Strict如果Option Explicit你同意的话Dim my_var As MyEnum = 1。这些安全检查是为了让你的代码/编码更安全,从而缩小编写任何内容的自由度。

    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
Run Code Online (Sandbox Code Playgroud)

如果您已将 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 !
Run Code Online (Sandbox Code Playgroud)

以下内容与字节分配几乎相同:

    If my_object.MyVar = "Fred" Then '...
Run Code Online (Sandbox Code Playgroud)

使用 Option Strict On 时,不允许从 Double 到 String 的此类转换。这是明显的类型不匹配,Option Strict 禁止这样做。但为什么是 Double 而不是 Byte 呢?因为编译器在尝试获得类型匹配时会尝试进行一次又一次的加宽。字节 -> 整数 -> 长整型 -> .. -> 双精度。

您应该显式转换my_object.MyVar为字符串,或者显式将“Fred”转换为数值。比较测试将始终尝试处理所需的加宽转换(只要可能),但仅允许基本加宽转换Option Strict On


那么如何让你的代码在前三行比较的编译时失败。嗯,我不知道。也许值得质疑 Option Strict 允许什么、不允许什么,所以我认为这更多的是一个哲学问题,而不是一个实际问题。

=> 返回布尔值的表达式/求值是否应该禁止不同类型的数字之间的比较?
=> 当 Option Strict 为 On 时,是否应该禁止基本扩展转换 Byte -> Double ?

抱歉,我没有资格回答这样的问题……