5

Trong C# có đảm bảo rằng các biểu thức được đánh giá từ trái sang phải không?Từ trái sang phải biểu thức đánh giá

Ví dụ:

myClass = GetClass(); 
if (myClass == null || myClass.Property > 0) 
    continue; 

Có bất kỳ ngôn ngữ mà không tuân thủ?

Trả lời

14

Bạn thực sự đề cập đến một tính năng ngôn ngữ gọi là "ngắn circuiting biểu thức logic":

Điều này có nghĩa đây là: Khi kết quả của một biểu thức logic không thể thay đổi được nữa, ví dụ khi rõ ràng là biểu thức sẽ đánh giá là "true" hoặc "false" cho dù các phần còn lại của biểu thức sẽ không được đánh giá.

Ví dụ: C#, Java hoặc JavaScript làm điều đó và bạn có thể dựa vào nó bằng các ngôn ngữ đó (để trả lời câu hỏi của bạn).

Trong trường hợp của bạn, nếu MyClass không là null:

  • MyClass == null là false
  • vì nó là một "hay" biểu hiện, phần thứ hai vẫn có thể thay đổi kết quả, vì vậy nó được đánh giá
  • myClass.Property > 0 xác định kết quả cuối cùng

nếu MyClass là null:

  • MyClass == null để đánh giá đúng
  • vì nó là một "hay" biểu hiện, nó không có vấn đề gì sau
  • đánh giá không được thực hiện, kết quả cuối cùng là đúng

Có những ngôn ngữ đó làm không phải biểu thức logic ngắn mạch. VB cổ điển là một ví dụ, ở đây "myClass.Property> 0" sẽ được đánh giá và tạo ra một lỗi nếu MyClass là null (gọi là "Không có gì" trong VB).

0

Thứ tự đánh giá tùy thuộc vào nhà điều hành, trong trường hợp này là boolean hoặc (||) được định nghĩa là cái thường được gọi là short-circuiting, để tạo cấu trúc như công việc này.

5

ngắn mạch được mô tả trong phần 7.11 của spec C# 3.0:

Các hoạt động x || y tương ứng với hoạt động x | y, ngoại trừ y là chỉ được đánh giá nếu x không đúng.

Vì vậy, có, bạn ổn.

Đối với các ngôn ngữ khác - Tôi không bao giờ muốn nói cho tất cả các ngôn ngữ. Trong VB.NET, bạn có thể sử dụng OrElse và AndAlso ngắn mạch, nhưng đồng bằng hoặc và không.

2

Nhưng hãy cẩn thận:

nếu bạn có một cái gì đó giống như

sprintf (buf, "% s% s", Func1 (& var), Func2 (& var));

với hiệu ứng phụ trên var, nó không được xác định trật tự (trái hoặc phải) các đối số được đưa vào ngăn xếp và đánh giá từ đó.

+0

Trong C#, thứ tự chính xác được xác định. – Martijn

0

tôi không chắc chắn, bạn có thực sự quan tâm đến việc đặt hàng hoặc trong đánh giá ngắn mạch?

tôi không phải là 100 % chắc chắn, nhưng theo như tôi biết thứ tự đánh giá sẽ luôn luôn giống nhau trong C# (và tôi giả định hầu hết nếu không phải tất cả các ngôn ngữ .net) Đánh giá ngắn mạch hoạt động như được giải thích trong các câu trả lời trước.

Tuy nhiên, trong C# bạn có thể chọn không ngắn mạch bằng cách sử dụng toán tử đơn giản (& thay vì & &). Thông thường bạn muốn ngắn mạch, nhưng nó có thể là một trường hợp mà bạn muốn thực hiện tất cả các đánh giá.

0

Các và/hoặc toán tử bằng các ngôn ngữ như Ada, Visual Basic và Pascal không đoản mạch. Họ cung cấp thêm các toán tử để cho phép chức năng đó, chẳng hạn như "và sau đó" và "hoặc người khác" trong Ada.

0

Python có đoản mạch orand toán tử.

0

Trong Java và Haskell & & và || ngắn mạch là tốt.

Thú vị sang một bên: trong Haskell, ngôn ngữ này có thể tự động thực hiện điều này, trong khi ở Java và C# thì cụ thể là cho hai toán tử này.

0

Thực tế việc đoản mạch là một phần, nhưng bạn cũng cần biết liệu ngôn ngữ có đảm bảo đánh giá từ trái sang phải hay không. Ví dụ C (ANSI, ISO, C99) KHÔNG đảm bảo đánh giá từ trái sang phải. Trong mã mẫu nó sẽ có thể kiểm tra giá trị của tài sản trước khi kiểm tra cho NULL hoặc làm cả hai cùng một lúc ... hầu hết các trình biên dịch không, nhưng không có gì ngăn cản nó làm điều đó và hoàn toàn phù hợp với spec. Nó thậm chí còn bảo bạn KHÔNG viết mã như vậy vì điều này.

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