Я прочитав специфікацію мови C # про умовні логічні оператори ||
і &&
, також відомий як коротке замикання логічних операторів. Мені здалося незрозумілим, чи існували вони для логічних значень, що допускають відхилення, тобто типу операнда Nullable<bool>
(також написаного bool?
), тому я спробував це з нединамічним набором тексту:
bool a = true;
bool? b = null;
bool? xxxx = b || a; // compile-time error, || can't be applied to these types
Здавалося, це вирішило питання (я не міг чітко зрозуміти специфікацію, але припускаючи, що реалізація компілятора Visual C # була правильною, тепер я це знав).
Однак я хотів спробувати і з dynamic
прив'язкою. Тому я спробував замість цього:
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);
}
}
Дивовижний результат полягає в тому, що це працює без винятку.
Ну, x
і y
не дивно, що їх декларації призводять до отримання обох властивостей, і отримані значення такі, як очікувалось, x
є true
і y
є null
.
Але оцінка приводу xx
не A || B
призвела до винятку часу прив'язки, і лише властивість A
було прочитано, ні B
. Чому так трапляється? Як ви можете зрозуміти, ми могли б змінити B
геттер, щоб повернути божевільний об'єкт, наприклад "Hello world"
, і xx
все одно оцінили б true
без проблем зі зв'язуванням ...
Оцінка A && B
(для yy
) також не призводить до помилок часу прив'язки. І тут обидва властивості отримуються, звичайно. Чому це дозволено підшивкою часу виконання? Якщо повернутий об'єкт із B
змінено на "поганий" об'єкт (наприклад, a string
), виникає виняток прив'язки.
Це правильна поведінка? (Як ви можете зробити це з специфікації?)
Якщо ви спробуєте B
в якості першого операнда, і те, B || A
і інше B && A
надасте виняток під час виконання ( B | A
і B & A
працюють нормально, оскільки все нормально з операторами, що не замикають |
і &
).
(Спробував компілятор C # Visual Studio 2013 та версію середовища виконання .NET 4.5.2.)
Nullable<Boolean>
залучення, лише булеві букси, котрі розглядаються якdynamic
- ваш тест зbool?
не має значення. (Звичайно, це не повна відповідь, лише зародок однієї.)