1

たとえば、次のコードがあるとします。

int? ReallyComplexFunction()
{
    return 2; // Imagine this did something that took a while
}

void Something()
{
    int i = ReallyCleverFunction() ?? 42;
}

...関数が一度だけ呼び出されることが保証されていますか? 私のテストでは一度しか呼び出されませんが、常にそうであると信頼できると述べているドキュメントは見当たりません。

編集

どのように実装されているかは推測できますが、まあ、私たちは開発者です。推測や憶測に惑わされるべきではありません。たとえば、将来の実装はすべて同じですか? 別のプラットフォームでの言語の実装は同じですか? それは、言語の仕様とそれが提供する保証に依存します。たとえば、将来または別のプラットフォームの実装 (良いものではありませんが、可能です) では、??実装でこれを行う可能性があります。

return ReallyComplexFunction() == null ? 42 : ReallyComplexFunction();

ReallyComplexFunctionそれが返されなかった場合、それは2回呼び出されnullます。(これはばかげた実装に見えますが、関数をnull可能な変数に置き換えると、かなり合理的に見えます: return a == null ? 42 : a)

上記のように、テストでは一度しか呼び出されないことはわかっていますが、私の質問は、左側が一度だけ呼び出されることを C# 仕様が保証/指定しているのかということです。もしそうなら、どこですか??? の C# 言語仕様にそのような言及はありません。演算子(最初にクエリへの回答を探した場所)。

4

7 に答える 7

0

??演算子は単なるショートカットであるため、一度だけ実行されます。

あなたのライン

int i = ReallyCleverFunction() ?? 42;

と同じです

int? temp = ReallyCleverFunction();
int i;
if (temp != null)
{
    i = temp.Value;
} else {
    i = 42;
}

コンパイラは大変な作業を行います。

于 2013-11-12T14:11:50.663 に答える
0

まず、答えはイエスです。公式の C# 言語仕様のセクション 7.13 の推論により、一度だけ評価されることが保証されます。

セクション 7.13 は常にaオブジェクトとして扱われるため、関数の戻りのみを受け取り、それを処理で使用する必要があります。?? について次のように述べています。演算子 (強調を追加):

• b が動的式の場合、結果の型は動的です。実行時に、 a が最初に評価されます。a が null でない場合、a は動的に変換され、これが結果になります。それ以外の場合、 b が評価され、これが結果になります。
• それ以外の場合、A が存在し、null 許容型であり、b から A0 への暗黙的な変換が存在する場合、結果の型は A0 になります。実行時に、 a が最初に評価されます。a が null でない場合、a は型 A0 にアンラップされ、これが結果になります。それ以外の場合、b が評価され、型 A0 に変換され、これが結果になります。
• それ以外の場合で、A が存在し、b から A への暗黙的な変換が存在する場合、結果の型は A になります。実行時に、a が最初に評価されます。a が null でない場合、a が結果になります。それ以外の場合、b が評価されて型 A に変換され、これが結果になります。
• それ以外の場合で、b の型が B で、a から B への暗黙的な変換が存在する場合、結果の型は B になります。実行時に、a が最初に評価されます。a が null でない場合、a は型 A0 (A が存在し、null 許容の場合) にアンラップされ、型 B に変換され、これが結果になります。それ以外の場合、b が評価され、結果になります。

補足として、質問の最後にあるリンクは、「C#言語仕様」のGoogle検索で最初にランク付けされているにもかかわらず、C#言語仕様ではありません。

于 2014-02-25T13:32:29.313 に答える