条件付き論理演算子 ||
と&&
、短絡論理演算子としても知られるC#言語仕様を読みました。私には、これらがnull許容ブール値、つまりオペランド型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
istrue
およびy
isnull
です。
ただし、の評価でxx
はA || B
バインディング時間の例外は発生せず、プロパティのみA
が読み取られ、は読み取られませんでしたB
。なぜこれが起こるのですか?あなたが言うことができるように、私たちは変更される可能性B
のような、狂気のオブジェクトを返すようにゲッターを"Hello world"
、そしてxx
まだに評価されますtrue
結合の問題もなく...
評価中 A && B
(for yy
)をも、バインディング時間エラーは発生しません。もちろん、ここでは両方のプロパティが取得されます。なぜこれがランタイムバインダーによって許可されるのですか?から返さB
れたオブジェクトが(のようなstring
)「不良」オブジェクトに変更された場合、バインディング例外が発生します。
これは正しい動作ですか?(仕様からどのように推測できますか?)
あなたはしようとした場合B
、両方の、最初のオペランドとしてB || A
及びB && A
(例外バインダーランタイムを与えるB | A
と、B & A
、すべてが非短絡事業者と通常であるとして、細かい作業を|
して&
)。
(Visual Studio 2013のC#コンパイラ、およびランタイムバージョン.NET 4.5.2で試してみました。)
Nullable<Boolean>
関与するインスタンスはまったくなく、ボックス化されたブール値のみが扱われdynamic
ます-でのテストbool?
は関係ありません。(もちろん、これは完全な答えではなく、1つの胚芽だけです。)