2013-07-14 34 views
5

Giả sử chương trình C# có hai thuộc tính thập phân không có giá trị A và B. Giá trị sau đây chỉ trả về giá trị của A: var result = A ?? 0 + B ?? 0; Cách sử dụng chính xác là: var result = (A ?? 0) + (B ?? 0);C# Ngoài với số thập phân có thể vô hiệu và ưu tiên của ?? nhà điều hành

mẫu giao diện điều khiển chương trình:

class Program 
{ 
    static void Main(string[] args) 
    { 
     A = (decimal)0.11; 
     B = (decimal)0.69; 

     NullableDecimalAddition(); 

     Console.ReadLine(); 
    } 

    public static decimal? A { get; set; } 
    public static decimal? B { get; set; } 

    private static void NullableDecimalAddition() 
    { 
     decimal result1 = A ?? 0 + B ?? 0; 
     decimal result2 = (A ?? 0) + (B ?? 0); 
     Console.WriteLine("result1: " + result1); // = 0.11 
     Console.WriteLine("result2: " + result2); // = 0.80 
    } 
} 

Câu hỏi của tôi là những gì xảy ra trong quá trình tính toán với result1. Làm thế nào là ưu tiên của + và ?? toán tử?

Trả lời

8

câu trả lời của tinstaafl là chính xác. Để mở rộng theo nó:

Nhà điều hành ??nhà cung cấp dịch vụ+ là ưu tiên cao hơn. Do đó, A ?? 0 + B ?? 0 tương đương với A ?? ((0 + B) ?? 0), không phải (A ?? 0) + (B ?? 0).

Do đó hoạt động của A ?? 0 + B ?? 0 là:

  • Tính A, mà bạn có trạng thái là loại thập phân nullable. Nếu nó là không null, có được giá trị thập phân của nó như là kết quả. Bây giờ chúng ta đã xong; B không bao giờ được tính.
  • Số không đã được chuyển đổi sang thập phân bởi trình biên dịch và kiểm tra null của nó cho số học được nâng lên được elided. (Xem my series of articles on how nullable arithmetic is optimized by the compiler để biết chi tiết.)
  • B được tính toán và kiểm tra giá trị rỗng. Nếu nó là null thì kết quả của phép cộng là null; nếu không thì kết quả của phép cộng là một số thập phân có thể null.
  • Kết quả của việc bổ sung hiện được chọn cho giá trị rỗng. Nếu nó là null thì kết quả bằng không (một lần nữa, đã được chuyển đổi sang thập phân). Nếu nó không phải là null thì giá trị của nó được lấy và nó sẽ trở thành kết quả.

Đây không phải là hành động dự định của bạn; bạn có thể có được hành động dự định của mình với (A ?? 0) + (B ?? 0). Nếu bạn dự định ngược lại với nghĩa "sử dụng số không nếu hai bên là không" thì bạn có thể sử dụng (A + B) ?? 0. Các dấu ngoặc đơn là không cần thiết ở phần sau nhưng ý tưởng hay là bạn đã nhầm lẫn về mức độ ưu tiên của + so với ??.

+0

Ok, cảm ơn bạn đã trả lời chính xác – FSou1

+0

Thật tuyệt vời khi chúng tôi nhận được loại thông tin này –

+0

Cảm ơn tất cả các bạn đã trả lời và giải thích. – Nicolo

2

Nếu không có dấu() trong câu lệnh đầu tiên, bạn đang nói câu hỏi đầu tiên ?? toán tử để trả về 0 + B nếu A là null và thứ hai ?? toán tử trả về 0 nếu B là null. do đó, toán tử + đang được sử dụng bởi ?? Toán tử câu lệnh sẽ chỉ trả về A. Nếu bạn đặt A thành null thì nó sẽ trả về .69

1

Tôi nghĩ quan trọng hơn, bạn không nên để điều này giải thích cho bất cứ ai, đây là một ví dụ rõ ràng khi nào bạn nên sử dụng dấu ngoặc đơn để dễ đọc và tránh sự nghi ngờ. Bảo trì là ưu tiên.

+1

Thực ra, phần bổ sung được thực hiện trước, sau đó là kết hợp đầu tiên, sau đó kết hợp lần thứ hai. Vì vậy, 'A ?? 0 + B ?? 0' tương đương với 'A ?? (0 + B) ?? 0', không phải 'A ?? (0 + B? 0) ' –

+0

cảm ơn, tôi đã không biết điều đó, tôi sẽ chỉnh sửa bài đăng của mình để chỉ đề xuất của tôi về khả năng đọc. –

+0

@RobertHarvey: Nhận xét của bạn không đúng. Null coalescing là đúng liên kết và bổ sung là ưu tiên cao hơn, vì vậy 'A ?? 0 + B ?? 0', 'A ?? (0 + B) ?? 0' và 'A ?? (0 + B ?? 0) 'là tất cả tương đương với' A ??((0 + B) ?? 0) '. Những điều tương tự như nhau là theo định nghĩa tương đương với nhau; đó là những gì "tương đương" có nghĩa là. –

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