我阅读了有关条件逻辑运算符 ||
和的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
getter更改为返回疯狂的对象(例如)"Hello world"
,并且xx
仍然可以得出true
没有绑定问题的结果...
A && B
(针对yy
)进行评估也不会导致绑定时间错误。当然,这里检索了两个属性。运行时绑定程序为什么允许这样做?如果将返回的对象从B
更改为“坏”对象(如string
),则将发生绑定异常。
这是正确的行为吗?(如何从规范中推断出来?)
如果您尝试B
作为第一个操作数,请同时给它们B || A
和B && A
运行时绑定程序例外(B | A
并且B & A
可以正常工作,因为使用非短路运算符|
和可以正常进行一切操作&
)。
(尝试使用Visual Studio 2013和运行时版本.NET 4.5.2。的C#编译器。)
Nullable<Boolean>
涉及的实例,只有装箱的布尔值被视为dynamic
-与您的测试bool?
无关。(当然,这不是一个完整的答案,只是一个问题的答案。)