2014-10-16 130 views
4

我使用以防止雜散值的對象枚舉類型使用: -如何防止Enum與Integer的比較?

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

正如我所料,試圖分配到枚舉財產產生編譯錯誤。 ( Option Strict On disallows implicit conversions from 'Integer' to 'MyClass.MyEnum')。

但前三個比較沒有,我寧願他們會(特別是第二和第三,這是胡說)。第四個比較不編譯,但錯誤消息似乎奇怪: -

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

有誰知道我可以如何強制編譯錯誤出現所有這些比較?

+0

我不這麼認爲,男人。發生了什麼是一個擴大轉換。字節數據類型擴展爲「Byte,Short,UShort,Integer,UInteger,Long,ULong,Decimal,Single,Double」。那第四個比較的錯誤信息是非常奇怪的。 MyVar不是雙。此代碼片段也不需要Option Option。 – scottyeatscode 2014-10-16 13:33:46

回答

4
my_object.MyVar = 1 ' Compilation Error 

原因
my_object.MyVarMyEnum類型,1爲整數類型(字節/ USHORT /等),所以你有Option Strict On編譯錯誤。改爲:

my_object.MyVar = MyEnum.SECOND 
    ' .SECUND should mean "1" as FIRST would be "0" by default.. 

但是爲什麼? 「1」應該是Byte類型,因爲你已經明確地「強加」你的枚舉。那麼,您不能將文字整數(字節)值分配給一次枚舉Option Strict。選項嚴格關閉,它的作品!但是你可以用選項嚴格上不知道爲什麼,下面也適用:

Dim MyByteVar As Byte = 1 ' No compilation error 

的MyByteVar是Byte型的,並且沒有litteral值後,任何類型的字符標識,litteral假定「1」是的鍵入Integer。但是由於編譯器知道MyByteVar是Byte類型,它會嘗試將「1」轉換爲字節,它的工作原理是。不會發生編譯錯誤。

所以不要將縮小轉換顯式類型不匹配。將「1」轉換爲類型MyEnum將無法與Option Strict On一起使用,這不是因爲編譯器無法將1轉換爲枚舉中的匹配值,而是因爲編譯器不應該甚至嘗試。明確強類型聲明和嚴格類型分配的主要目的是爲了避免on the MSDN Option Strict Page所述的風險。 AndAlso,在MSDN Page about Enumerations,你就會有類似的表述:

WRONG我很抱歉,我被我上星期遇到的另一個問題上當。 您只能使用Option Explicit On縮小轉換(整數 - >字節)。
編輯2:^^看來我是對的畢竟:/好吧,我不確定是誠實的,對不起,對不起..

  • 降低由調換或錯誤輸入號碼錯誤。
  • 可以很容易地改變未來的價值觀。
  • 使代碼更容易閱讀,這意味着不太可能引入錯誤。
  • 確保向前兼容性。如果使用枚舉,如果將來有人更改與成員名稱相對應的值,則代碼不太可能失敗。

沒有已經創造EnumerationsOption StrictOption 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 

如果您已設置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 On時,不允許從Double到String的這種轉換。這是一種明顯的類型不匹配,Option Strict禁止這種情況。但爲什麼雙和不是字節?因爲編譯器在嘗試獲取類型匹配時嘗試一個接一個地擴展。 Byte - > Integer - > Long - > .. - > Double。

要麼你應該明確地將my_object.MyVar轉換爲字符串,要麼將「Fred」顯式轉換爲數字值。比較測試將始終嘗試處理所需的加寬轉換(只要可能),但僅允許使用基本加寬轉換的Option Strict On


那麼如何讓你的代碼在編譯時失敗,前三排的比較。那麼,我不知道。也許值得質疑Option Strict允許什麼,什麼不允許,所以我認爲這是一個哲學問題而不是實際問題。

=>表達式/評估是否應該返回布爾值禁止在不同類型的數字之間進行比較?
=>當Option Strict爲On時,是否應該基本擴展轉換Byte - > Double將被禁止?

對不起,我沒有資格回答這樣的問題...

+1

我沒有資格回答哲學問題,但這從來沒有停止過我...我不認爲將Enum轉換爲整數應該是一個擴大的轉換。我剛剛在我的一些代碼中發現了一個缺陷,就像這個「Dim x As EnumOne」,然後是'如果x = EnumTwo.Value Then ...'。我不小心在我的比較中使用了錯誤的'Enum'。編譯器樂於將雙方擴展爲整數,並沒有報告警告。我想要一個編譯錯誤!這就是爲什麼我選擇'Option Strict On' – MarkJ 2017-01-10 17:38:57

相關問題