web-dev-qa-db-ja.com

三項演算子の「反対側」に到達しても何もしませんか?

注:この質問は以前に時々尋ねられました( abc )が、これらはどちらもC#ではなく、役に立ちませんでした。

このような? :三項演算子を使用していると仮定します(falseの場合は何もしません):

r==5? r=0 : <nothing> ;

エラーが発生します。そこに何かを置くことは明らかに問題を解決します。ランダムな空関数を作成せずに、反対側を空のままにするにはどうすればよいですか?

6
devRicher

できません。条件付き?:演算子の要点は、を評価することです。単に使用することさえできません:

Foo() ? Bar() : Baz();

...それはステートメントではないからです。たとえば、プロパティにアクセスするときと同じように、結果に対して何かを行う必要があります。

特定の条件が満たされたときにのみコードの一部を実行したい場合、?:演算子は必要なものではありません-ifステートメントが必要です。

if (foo)
{
    bar();
}

それはそれと同じくらい簡単です。条件演算子を意図しないものにねじろうとしないでください。

24
Jon Skeet

本当に必要な場合は、 Discard 演算子を使用してこれを実現できるようになりました。

public class Program
{
    public static void Main()
    {
        int r=5;
        _ = r==5 ? r=0 : 0;
        Console.WriteLine($"{r}");
        // outputs 0
    }
}

あなたもできるようになりました

_=Foo() ? Bar() : Baz();

BarとBazが同じタイプまたはコンバーチブルタイプを返す限り。

1
GilesDMiddleton

他の答えは正しいですが、あなたが問題を抱えている主なものであると私が思う重要なポイントを見逃しています。注意すべきことは

r = 0

rに値を割り当てる以外に、同じ値も返します。あなたはそれを関数のように考えることができます。関数を呼び出すことができます。関数を呼び出すと、値を返す以外に、使用する場合と使用しない場合があります。

たとえば、次のようにします。

int square(int n)
{
    // Now you can do other things here too. Maybe you do something with the UI in here:
    Console.WriteLine("Calculating...");
    // ^ Now thing of the above code as assigning a value to a variable.
    return n * n;
    // But after assigning the value, it also returns the value...
}

したがって、2つの使用例があるとします。

var x = square(2);
// -- OR --
square(2);

どちらのステートメントも'Calculating ...'を出力しますが、前者は2 * 2または4の値をxに割り当てることに注意してください。

さらに良いことに、関数があるとしましょう:

int AssignValueToVariable(out int variable, int value)
{
    variable = value;
    return value;
}

この関数は明らかに冗長ですが、理解を深めるために使用できるとしましょう。割り当て=演算子と同等であると想定します。

そうは言っても、シナリオに戻ることができます。三項演算子<condition> ? <true expression> : <false expression>は、指定された条件に基づいて返す2つの式を取ります。だから、あなたが書くとき:

r == 5 ? r = 0 : r = 2; // Let's suppose the third operand to be r = 2

これは次と同等です。

r == 5 ? AssignValueToVariable(r, 0) : AssignValueToVariable(r, 2)

どちらも本質的に:

r == 5 ? 0 : 2

これにより、すべてが式に要約される必要があるため、オペランドは式でなければならないという厳格なルールが復活します。したがって、デフォルト値を使用することで、式に相当するkind of 'nothing'を取得できます。

または、他の回答が述べているように、ifステートメントをまっすぐかつ単純に使用します。

if (r == 5)
    r = 0;

あなたが提供したコードから外挿すると、あなたは評価された式で何かをしていると思います。値を別の変数resultに格納し、それを使って何でもすることができます。

int result;
if (r == 5)
    result = r = 0; // This sets the value of both result and r to 0

これで、以前の式、つまりr == 5 ? r = 0 : <nothing> // Pseudo-coderesultに置き換えることができます。

それが役に立てば幸い :)

明らかに2つのパラメーターが必要なのに、なぜternaryを使用したいのですか? ifステートメントを使用するだけです。

 if(Condition())Action();
1
meJustAndrew

私はこのような拡張方法を提案することができます:

public static T ChangeOn<T>(this T variable, bool condition, T newValue)
{
    return condition ? newValue : variable;
}

そして、次のように使用します。

var result = r.ChangeOn(r == 5, 0);
//or: r = r.ChangeOn(r == 5, 0); for self change
0
shA.t