Tôi đã đọc Đặc tả ngôn ngữ C # về các toán tử logic có điều kiện ||
và &&
, còn được gọi là toán tử logic ngắn mạch. Đối với tôi, dường như không rõ ràng nếu những điều này tồn tại cho boolean nullable, tức là loại toán hạng Nullable<bool>
(cũng được viết bool?
), vì vậy tôi đã thử nó với cách nhập không động:
bool a = true;
bool? b = null;
bool? xxxx = b || a; // compile-time error, || can't be applied to these types
Điều đó dường như đã giải quyết được câu hỏi (tôi không thể hiểu thông số kỹ thuật rõ ràng, nhưng giả sử việc triển khai trình biên dịch Visual C # là đúng, bây giờ tôi đã biết).
Tuy nhiên, tôi cũng muốn thử với sự dynamic
ràng buộc. Vì vậy, tôi đã thử điều này thay thế:
static class Program
{
static dynamic A
{
get
{
Console.WriteLine("'A' evaluated");
return true;
}
}
static dynamic B
{
get
{
Console.WriteLine("'B' evaluated");
return null;
}
}
static void Main()
{
dynamic x = A | B;
Console.WriteLine((object)x);
dynamic y = A & B;
Console.WriteLine((object)y);
dynamic xx = A || B;
Console.WriteLine((object)xx);
dynamic yy = A && B;
Console.WriteLine((object)yy);
}
}
Kết quả đáng ngạc nhiên là điều này chạy mà không có ngoại lệ.
Vâng, x
và y
không ngạc nhiên, tờ khai của họ dẫn đến cả hai thuộc tính được lấy ra, và các giá trị kết quả như mong đợi, x
là true
và y
là null
.
Tuy nhiên, đánh giá đối với xx
các A || B
dẫn đến không ràng buộc thời gian ngoại lệ, và chỉ có tài sản A
đã được đọc, không phải B
. Lý do tại sao điều này xảy ra? Như bạn có thể nói, chúng tôi có thể thay đổi B
getter để trả về một đối tượng điên rồ, giống như "Hello world"
, và xx
vẫn sẽ đánh giá true
mà không có vấn đề ràng buộc ...
Đánh giá A && B
(cho yy
) cũng không dẫn đến lỗi thời gian ràng buộc. Và ở đây cả hai thuộc tính đều được truy xuất, tất nhiên. Tại sao điều này được cho phép bởi chất kết dính thời gian chạy? Nếu đối tượng trả về từ B
được thay đổi thành đối tượng "xấu" (như a string
), một ngoại lệ ràng buộc sẽ xảy ra.
Hành vi này có đúng không? (Làm thế nào bạn có thể suy ra điều đó từ thông số kỹ thuật?)
Nếu bạn thử B
như toán hạng đầu tiên, cả hai B || A
và B && A
đưa ra ngoại lệ chất kết dính thời gian chạy ( B | A
và B & A
hoạt động tốt vì mọi thứ đều bình thường với các toán tử không đoản mạch |
và&
).
(Đã thử với trình biên dịch C # của Visual Studio 2013 và phiên bản thời gian chạy .NET 4.5.2.)
Nullable<Boolean>
liên quan, chỉ có các boolean đóng hộp được coi làdynamic
- thử nghiệm của bạn vớibool?
là không liên quan. (Tất nhiên, đây không phải là một câu trả lời đầy đủ, chỉ có mầm mống của một.)