Vb.net 如何防止将枚举与整数进行比较?

Vb.net 如何防止将枚举与整数进行比较?,vb.net,enums,Vb.net,Enums,我使用的枚举类型的目的是防止使用虚假值:- 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

我使用的枚举类型的目的是防止使用虚假值:-

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
编译

正如我所料,尝试分配枚举属性会产生编译错误(
选项Strict On不允许从“Integer”隐式转换为“MyClass.MyEnum”

但是前三个比较没有,我很希望它们会这样(特别是第二个和第三个,都是胡说八道)。第四个比较没有编译,但错误消息似乎很奇怪:-

选项Strict On不允许从“String”隐式转换为“Double”

有人知道我如何强制在所有这些比较中出现编译错误吗

    my_object.MyVar = 1 ' Compilation Error
原因
my_object.MyVar
的类型为
MyEnum
,而1的类型为Integer(Byte/UShort/Etc),因此您的
选项在
上出现编译错误。请改用此选项:

    my_object.MyVar = MyEnum.SECOND
    ' .SECUND should mean "1" as FIRST would be "0" by default..
但是为什么?“1”应该是Byte类型,因为您已经显式地“强倾斜”了您的枚举..!好吧,一旦启用了
选项Strict
,您就不能再为枚举分配一个文本整型(字节)值。如果禁用了选项Strict,它就可以工作了!但是您可能想知道为什么启用选项Strict,以下内容也可以工作:

    Dim MyByteVar As Byte = 1 ' No compilation error
MyByteVar的类型为
Byte
,在literal值之后没有任何类型字符标识符,literal“1”被假定为
Integer
类型。但是,由于编译器知道MyByteVar的类型为Byte,所以它尝试将“1”转换为Byte,并且它可以工作。。不会发生编译错误

因此,不要混淆缩小转换显式类型不匹配。转换“1”对于类型MyEnum,不能使用选项Strict On,这不是因为编译器无法将1转换为枚举中的匹配值,而是因为编译器甚至不应该尝试这样做。显式强类型声明和严格类型分配的主要目的是避免上述风险。此外,在e类似声明:

错了对不起,我被上周遇到的另一个问题愚弄了。 如果选项Explicit On,则无法进行缩小转换(整数->字节)。
编辑2:^^看来我毕竟是对的:/嗯,老实说,我不确定,对不起

  • 减少因转置或错误键入数字而导致的错误
  • 使将来更改值变得容易
  • 使代码更易于阅读,这意味着引入错误的可能性更小
  • 确保前向兼容性。如果使用枚举,如果将来有人更改与成员名称对应的值,则代码失败的可能性较小
如果您对MyEnum=1
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
如果已将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禁止这种转换。但是为什么选择Double而不是Byte?因为编译器在尝试获取类型匹配时会一个接一个地尝试加宽。Byte->Integer->Long->Double

或者您应该显式地将
my\u object.MyVar
转换为字符串,或者显式地将“Fred”转换为数值。比较测试将始终尝试处理所需的加宽转换(只要可能),但只有基本的加宽转换才允许使用
选项Strict On


那么,在编译前三行比较时,如何使代码失败呢?我不知道。也许有必要质疑Option Strict允许什么,不允许什么,所以我认为这更像是一个哲学问题,而不是一个实际问题

=>返回布尔值的表达式/计算是否应禁止不同类型的数字之间的比较?
=>当“严格”选项处于启用状态时,是否应禁止基本加宽转换字节->双字节


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

我不这么认为,伙计。正在发生的是一个扩大的转换。字节数据类型扩大到
字节、短、UShort、整数、UInteger、Long、ULong、Decimal、Single、Double
。第四个比较的错误消息非常奇怪。MyVar不是Double。还有
选项明确的
对于这段代码摘录来说是不必要的。我也没有资格回答哲学问题,但这从来没有阻止过我……我不认为将
枚举
转换为整数应该是一种更广泛的转换。我刚刚发现我的一些代码中有一个缺陷,比如
Dim x As EnumOne
,然后是
如果x=EnumTwo.Value,那么…
。我在比较中不小心使用了错误的
Enum
。编译器很高兴地将两边都加宽为整数,并且没有报告警告。我想要一个编译错误!这就是为什么我选择
选项Strict On