2009-07-23 20 views
76

Sự khác nhau giữa hoặcOrElse là gì?Hoặc so với OrElse

if temp is dbnull.value or temp = 0 

tạo ra lỗi:

Operator '=' is not defined for type 'DBNull' and type 'Integer'.

trong khi cái này hoạt động giống như một nét duyên dáng !?

if temp is dbnull.value OrElse temp = 0 

Trả lời

114

OrElsengắn mạch nhà điều hành, Or thì không.

Theo định nghĩa của toán tử boolean 'hoặc', nếu cụm từ đầu tiên là True thì toàn bộ chắc chắn là đúng - vì vậy chúng tôi không cần đánh giá thuật ngữ thứ hai.

OrElse biết điều này, vì vậy không cố gắng và đánh giá temp = 0 khi nó đã được chứng minh rằng temp Is DBNull.Value

Or không biết điều này, và sẽ luôn luôn cố gắng để đánh giá cả về. Khi temp Is DBNull.Value, nó không thể được so sánh với số không, vì vậy nó rơi xuống.

Bạn nên sử dụng ... tốt, tùy theo ý nào.

+2

Vì vậy, hoặc chỉ có ý nghĩa khi tôi gọi một hàm sau hoặc có các hiệu ứng phụ mà mã của tôi phụ thuộc vào? –

+2

Hoặc có ý nghĩa trong tất cả các trường hợp mục thứ hai không kích hoạt lỗi nếu mục đầu tiên là đúng ... – awe

+3

@ malach: Tôi cho là vậy (bạn thực sự nhận được hành vi OrElse như mặc định trong hầu hết các ngôn ngữ khác): Đó không phải là ý tưởng hay để gọi các hàm với các hiệu ứng phụ trong các điều kiện phức hợp, nó làm cho mã không đọc được. – Utaal

4

(Tôi đã nhìn vào câu trả lời khác và nhận ra mình đã quá sai)

Nhà điều hành OrElse "thực hiện phân ly logic ngắn mạch trên hai biểu thức", có nghĩa là để nói: nếu toán hạng bên trái là đúng và do đó toàn bộ biểu thức được đảm bảo đến mức khó tin các toán hạng bên phải sẽ thậm chí không được đánh giá (điều này rất hữu ích trong các trường hợp như:.

string a; 
//... 
if (a is null) or (a = "Hi") //... 

để tránh ném NullReferenceException bởi các toán hạng bên phải

Tôi xin chân thành ngạc nhiên rằng đây (lười biếng đánh giá) không phải là hành vi mặc định của orand vì nó là trong C/C++ và C# (và nhiều ngôn ngữ khác ...)

+7

Điều này, trong VB cổ điển, đã có * chỉ * Và và hoặc, không ngắn mạch. Tôi nghĩ ** Tôi đúng khi nói rằng bản beta đầu tiên của VB.NET thực sự đã thay đổi hành vi của các nhà khai thác này - có sự náo động, vì vậy họ đã bị thay đổi và AndAlso và OrElse (short-circuiting) được giới thiệu. Tôi chỉ có thể tưởng tượng các tên thay thế mà họ phải xem xét nếu đây là những cái tốt nhất ... – AakashM

+1

Bằng cách cung cấp Or và OrElse (| và || trong C#) điều này cho phép nhà phát triển chọn cách họ xử lý mã của riêng họ. Sử dụng đoạn mã trên, tôi phải sử dụng lệnh thử để xử lý một giá trị null trong biến a. OrElse cho phép nhà phát triển xử lý điều này trong câu lệnh if khác như một kết quả có thể biết được chứ không phải là một ngoại lệ. Điều này rõ ràng hơn nếu biến a là một tham số trong một phương thức, trong đó bạn có ít quyền kiểm soát hơn khi biến được chỉ định một giá trị (tức làbên ngoài phương thức) –

8

OrElse là ngắn mạch, điều này có nghĩa là chỉ một bên của biểu thức sẽ được kiểm tra nếu mặt đầu tiên là một kết quả phù hợp.

Cũng giống như AndAlso sẽ chỉ kiểm tra một mặt của biểu thức nếu nửa đầu là lỗi.

33

Đây là hành vi tương tự như với C#, nơi tất cả mọi người sử dụng Coditional Hoặc (||) và có điều kiện Và (& &), nơi bạn cũng có bình thường Hoặc (|) và bình thường Và (&). Vì vậy, so sánh C# với VB.Net là:

| => Hoặc

|| => OrElse

& => Và

& & => AndAlso

Các toán tử logic condifitonal được rất hữu ích ngăn ngừa lồng nhau nếu công trình xây dựng. Nhưng đôi khi các toán tử boolean bình thường là cần thiết để đảm bảo nhấn cả hai đường dẫn mã.

+5

Tôi chưa bao giờ thực sự biết điều này đã có sẵn. Cảm ơn thông tin mới. Điều cần biết, mặc dù tôi thực sự không thể thấy bất kỳ tình huống nào mà tôi muốn sử dụng "|". Tôi nghĩ rằng nó sẽ yêu cầu điều kiện thứ hai để gây ra tác dụng phụ để làm cho bất kỳ ý nghĩa, và rằng trong chính nó làm cho ít ý nghĩa theo ý kiến ​​của tôi! ;) – Kjartan

+3

Eh, theo như tôi biết, '|' và '&' là các toán tử bitwise trong C#, không phải là các phép toán boolean. – Nyerguds

4

Câu trả lời của Bert không chính xác lắm. '|' hoặc '&' là toán tử logic, trong C#, nó luôn đối xử như điều hành chút, vui lòng xem đoạn mã sau làm ví dụ

 static void Main() 
     { 
      object a = null; 
      int b = 3; 
      if (a == null | a.ToString() == "sdffd") 
      { 
       Console.WriteLine("dddd"); 
      } 
      Console.WriteLine(b | b); 
      Console.Read(); 
     } 

Sau đây là IL

.method private hidebysig static void Main() cil managed 
{ 
    .entrypoint 
    // Code size  62 (0x3e) 
    .maxstack 3 
    .locals init ([0] object a, 
      [1] int32 b, 
      [2] bool CS$4$0000) 
    IL_0000: nop 
    IL_0001: ldnull 
    IL_0002: stloc.0 
    IL_0003: ldc.i4.3 
    IL_0004: stloc.1 
    IL_0005: ldloc.0 
    IL_0006: ldnull 
    IL_0007: ceq 
    IL_0009: ldloc.0 
    IL_000a: callvirt instance string [mscorlib]System.Object::ToString() 
    IL_000f: ldstr  "sdffd" 
    IL_0014: call  bool [mscorlib]System.String::op_Equality(string, 
                   string) 
    IL_0019: or 
    IL_001a: ldc.i4.0 
    IL_001b: ceq 
    IL_001d: stloc.2 
    IL_001e: ldloc.2 
    IL_001f: brtrue.s IL_002e 
    IL_0021: nop 
    IL_0022: ldstr  "dddd" 
    IL_0027: call  void [mscorlib]System.Console::WriteLine(string) 
    IL_002c: nop 
    IL_002d: nop 
    IL_002e: ldloc.1 
    IL_002f: ldloc.1 
    IL_0030: or 
    IL_0031: call  void [mscorlib]System.Console::WriteLine(int32) 
    IL_0036: nop 
    IL_0037: call  int32 [mscorlib]System.Console::Read() 
    IL_003c: pop 
    IL_003d: ret 
    } // end of method Program::Main 

khi bạn sử dụng || để kiểm tra "a == null" và "a.ToString() ==" sdffd ", IL sẽ là

.method private hidebysig static void Main() cil managed 
{ 
    .entrypoint 
    // Code size  63 (0x3f) 
    .maxstack 2 
    .locals init ([0] object a, 
      [1] int32 b, 
      [2] bool CS$4$0000) 
    IL_0000: nop 
    IL_0001: ldnull 
    IL_0002: stloc.0 
    IL_0003: ldc.i4.3 
    IL_0004: stloc.1 
    IL_0005: ldloc.0 
    IL_0006: brfalse.s IL_001d 
    IL_0008: ldloc.0 
    IL_0009: callvirt instance string [mscorlib]System.Object::ToString() 
    IL_000e: ldstr  "sdffd" 
    IL_0013: call  bool [mscorlib]System.String::op_Equality(string, 
                   string) 
    IL_0018: ldc.i4.0 
    IL_0019: ceq 
    IL_001b: br.s  IL_001e 
    IL_001d: ldc.i4.0 
    IL_001e: stloc.2 
    IL_001f: ldloc.2 
    IL_0020: brtrue.s IL_002f 
    IL_0022: nop 
    IL_0023: ldstr  "dddd" 
    IL_0028: call  void [mscorlib]System.Console::WriteLine(string) 
    IL_002d: nop 
    IL_002e: nop 
    IL_002f: ldloc.1 
    IL_0030: ldloc.1 
    IL_0031: or 
    IL_0032: call  void [mscorlib]System.Console::WriteLine(int32) 
    IL_0037: nop 
    IL_0038: call  int32 [mscorlib]System.Console::Read() 
    IL_003d: pop 
    IL_003e: ret 
} // end of method Program::Main 

Bây giờ bạn có thể thấy sự khác biệt, xin đừng nghĩ '|' hoặc 'và' là toán tử có điều kiện, nó chỉ là toán tử logic, tôi không nghĩ cần sử dụng nó để đánh giá điều kiện

+2

'The '|' hoặc '&' là toán tử logic, trong C#, nó luôn coi là toán tử bit'. Tôi cũng tin vào điều này, cho đến khi tôi thấy tài liệu tham khảo này, https://msdn.microsoft.com/en-us/library/kxszd0kx.aspx – user3207158

2

OrElse đánh giá biểu thức đầu tiên sau đó nếu đúng thì nó sẽ tiến hành câu lệnh trong khi OR ước lượng hai biểu trước khi nó sẽ tiến hành tuyên bố của họ

Ví dụ:.

Textbox1.Text= 4 

Textbox2.Text= "" 

Sử dụng OrElse

If TextBox1.Text > 2 OrElse TextBox2.Text > 3 Then 
     MsgBox("True") 
    End If 

Kết quả là: TRUE


Sử dụng OR

If TextBox1.Text > 2 Or TextBox2.Text > 3 Then 

      MsgBox("True") 
    End If 

Kết quả là: Lỗi không thể chuyển đổi chuỗi tăng gấp đôi.

Các vấn đề liên quan