Leí la Especificación del lenguaje C # sobre los operadores lógicos condicionales || y &&, también conocidos como operadores lógicos de cortocircuito. Para mí, no parecía claro si estos existían para valores booleanos que aceptan valores NULL, es decir, el tipo de operando Nullable<bool>(también escrito bool?), así que lo probé con escritura no dinámica:
bool a = true;
bool? b = null;
bool? xxxx = b || a; // compile-time error, || can't be applied to these types
Eso pareció resolver la pregunta (no pude entender la especificación claramente, pero suponiendo que la implementación del compilador de Visual C # fuera correcta, ahora lo sabía).
Sin embargo, también quería probar con la dynamicencuadernación. Así que probé esto en su lugar:
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);
}
}
El resultado sorprendente es que esto funciona sin excepción.
Bueno, xy yno es de extrañar, sus declaraciones llevan a que se recuperen ambas propiedades, y los valores resultantes son los esperados, xes truey yes null.
Pero la evaluación xxde no A || Bcondujo a ninguna excepción de tiempo de vinculación, y solo Ase leyó la propiedad , no B. ¿Por qué pasó esto? Como puede ver, podríamos cambiar el Bgetter para devolver un objeto loco, como "Hello world", y xxaún evaluaríamos truesin problemas de vinculación ...
La evaluación A && B(para yy) tampoco conduce a ningún error de tiempo de vinculación. Y aquí se recuperan ambas propiedades, por supuesto. ¿Por qué lo permite el archivador en tiempo de ejecución? Si el objeto devuelto Bse cambia a un objeto "incorrecto" (como a string), se produce una excepción de vinculación.
¿Es este el comportamiento correcto? (¿Cómo puedes inferir eso de la especificación?)
Si lo intenta Bcomo primer operando, ambos B || Ay B && Adan una excepción del enlazador en tiempo de ejecución ( B | Ay B & Afuncionan bien, ya que todo es normal con operadores sin cortocircuito |y &).
(Probado con el compilador C # de Visual Studio 2013 y la versión en tiempo de ejecución .NET 4.5.2.)
Nullable<Boolean>involucrados en absoluto, solo booleanos en caja tratados comodynamic: su prueba conbool?es irrelevante. (Por supuesto, esta no es una respuesta completa, solo el germen de una.)