2011-12-07 27 views
41

(OrElse和Or)和(AndAlso and And)有什麼區別? 他們的表演有沒有什麼區別,比方說正確性的好處?有什麼情況我不應該使用OrElse和AndAlso?(OrElse and Or)和(AndAlso and And) - 何時使用?

+2

可能重複http://stackoverflow.com/questions/55013/should-i -always-use-the-and-one-and-orelse-operators) –

+0

剛開始使用VB.NET(VB多年來第一次)。我上網只是爲了問這個具體問題。感謝@aer和許多人以他們的傑出答案作了澄清。 – Hardryv

回答

62

Or/And總是評估 表達式,然後返回結果。他們是而不是短路。

OrElse/AndAlsoshort-circuiting。只有在評估結果不能單獨評估左側表達時才能評估正確的表達。 (這意味着:如果左表達式爲假OrElse將僅評估合適的表情,並且如果左表達式爲真AndAlso將僅評估合適的表情。)

假設沒有副作用發生在表達式和表達式不依賴於(並且忽略任何執行開銷),則它們是相同的。

但是,在很多情況下,表達式相關。舉例來說,我們想要做的事時,列表不,沒有,有一個以上的元素:(!或副作用,ICK)

If list IsNot Nothing AndAlso list.Length > 0 Then .. 'list has stuff 

這也可以用來避免「昂貴」計算:

If Not Validate(x) OrElse Not ExpensiveValidate(x) Then .. 'not valid 

就個人而言,我發現AndAlsoOrElse正確運營商都使用,但在1% - 或更小,有希望! - 期望的副作用的情況。

快樂編碼。


在第一表達式將防止從被評估的第二表達拋出的異常,但這應該幾乎不奇怪..

4

的區別在於OrElse運算和AndAlso將短路基於在第一個條件下,這意味着如果第一個條件沒有通過,第二個(或更多)條件將不會被評估。當其中一個條件可能比另一個條件更密集時,這是特別有用的。

例子Or是好的(兩個條件評估):

If Name = "Fred" Or Name = "Sam" Then 

這真的並不重要的方式圍繞它們進行評估

以下AndAlso是有用的,因爲第二個條件可能會失敗

If Not SomeObject Is Nothing AndAlso CheckObjectExistsInDatabase(SomeObject) Then 

這允許第一條件檢查對象是否已被設置並且在如果已設置,將會去檢查數據庫(或其他任務)。如果這是一個普通的And關鍵字,則兩者都將被評估。

10

除了在其他的答案中提到的短路,Or/And可用作位運算符,其中OrElse/AndAlso不是。按位操作包括組合Flags枚舉的值,例如FileAttributes枚舉,您可能指出文件既是隻讀也是隱藏的。FileAttributes.ReadOnly Or FileAttributes.Hidden

2

@Gideon - 很高興有人指出。下面是一個簡單的測試,顯示AndAlso的巨大影響:

Dim tm As New Stopwatch 
    Const tries As Integer = 123456 
    Dim z As Integer = 0 
    Dim s() As String = New String() {"0", "one"} 

    Debug.WriteLine("AndAlso") 
    For x As Integer = 0 To s.Length - 1 
     z = 0 
     tm.Restart() 'restart the stopwatch 
     For y As Integer = 0 To tries 
      If s(x) = x.ToString AndAlso s(x) = y.ToString Then '<<<<<<<<<< 
       z += 1 
      End If 
     Next 
     tm.Stop() 
     Debug.WriteLine(x.ToString.PadRight(3, " "c) & z.ToString.PadRight(10, " "c) & tm.Elapsed.ToString) 
    Next 

    Debug.WriteLine("And") 
    For x As Integer = 0 To s.Length - 1 
     z = 0 
     tm.Restart() 'restart the stopwatch 
     For y As Integer = 0 To tries 
      If s(x) = x.ToString And s(x) = y.ToString Then '<<<<<<<<<< 
       z += 1 
      End If 
     Next 
     tm.Stop() 
     Debug.WriteLine(x.ToString.PadRight(3, " "c) & z.ToString.PadRight(10, " "c) & tm.Elapsed.ToString) 
    Next 
的[?我應該總是使用AndAlso和OrElse運算經營者(