Я прочитав специфікацію мови 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?не має значення. (Звичайно, це не повна відповідь, лише зародок однієї.)