我正在使用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

(这是使用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'

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

最佳答案

    my_object.MyVar = 1 ' Compilation Error

原因:my_object.MyVar的类型为MyEnum,而1的类型为Integer(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的情况下也可以使用以下功能:
    Dim MyByteVar As Byte = 1 ' No compilation error

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

因此,请勿将缩小转换显式类型不匹配混为一谈。使用Option Strict On将“1”转换为MyEnum类型将不起作用,这不是因为编译器无法在枚举中将1转换为匹配的值,而是因为编译器甚至不应该尝试使用。显式强类型声明和严格类型分配的主要目的是避免诸如on the MSDN Option Strict Page这样的风险。并且,在MSDN Page about Enumerations上,您将具有类似的语句:

错误很抱歉,上周遇到的另一个问题使我感到迷惑。
您必须在Option Explicit On启用时才能进行缩小转换(整数->字节)。
编辑2:^^似乎我毕竟是对的:/好吧,我不确定说实话,对不起。
  • 减少因转置或错误输入数字而导致的错误。
  • 使将来轻松更改值变得容易。
  • 使代码更易于阅读,这意味着引入错误的可能性较小。
  • 确保向前兼容。如果使用枚举,则将来如果有人更改与成员名称相对应的值,则代码失败的可能性较小。

  • 如果您对Enumerations没问题,则没有理由创建Option StrictOption ExplicitDim 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
    

    如果将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 !
    

    以下内容与Byte分配内容几乎相同:
        If my_object.MyVar = "Fred" Then '...
    

    启用Option Strict时,不允许从Double到String的这种转换。这是一个明显的类型不匹配,Option Strict禁止这样做。但是为什么要Double而不是Byte?因为编译器在尝试获得类型匹配时尝试一个接一个的扩展。字节->整数->长-> ..-> double 。

    您要么应该将my_object.MyVar显式转换为字符串,要么将“Fred”显式转换为数值。比较测试将始终尝试照顾所需的扩展转换(如果可能),但Option Strict On仅允许基本的扩展转换。

    因此,如何使您的代码在比较的前三行编译时失败。好吧,我不知道。也许值得质疑Option Strict允许什么,不允许什么,所以我认为这是一个哲学问题,而不是实用问题。

    =>是否应该在不同类型的数字之间返回 bool 禁止比较的表达式/求值?
    =>当Option Strict设置为On时,是否应禁止基本的加宽转换字节-> Double?

    抱歉,我不具备回答此类问题的资格...

    关于vb.net - 如何防止将Enum与Integer进行比较?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26402179/

    10-17 01:00