web-dev-qa-db-ja.com

三項演算子を使用したメソッド呼び出し

新しいコンセプトを試していると、Ternary Operatorに出会いました。それは美しさです。しばらく遊んだ後、その限界をテストすることにしました。

しかし、特定のコード行をコンパイルすることができなかったとき、私の楽しみはすぐに終わりました。

int a = 5;
int b = 10;
a == b ? doThis() : doThat() 

    private void doThis()
    {
        MessageBox.Show("Did this");
    }
    private void doThat()
    {
        MessageBox.Show("Did that");
    }

この行には2つのエラーが表示されます。

Error   1   Only assignment, call, increment, decrement, and new object expressions can be used as a statement
Error   2   Type of conditional expression cannot be determined because there is no implicit conversion between 'void' and 'void'

呼び出すメソッドを決定するためにTernary Operatorを使用したことがなく、それが可能かどうかもわかりません。メソッド呼び出しの1行If Else Statementのアイデアが気に入っています。

少し調べてみたのですが、これをやっている人の例が見当たらないので、なかなか提供できないものを期待しているのではないでしょうか。

これが可能なら、私に間違った行動を教えてください、それは不可能です、別の方法はありますか?

42
Kyle Uithoven

上記のステートメントが機能しない理由は、他のユーザーによって提供されたものであり、事実上、私の真の質問に答えませんでした。

少し試してみたところ、この演算子を使用して上記のステートメントを実行できることがわかりましたが、その結果、いくつかの不正なコードが生成されます。

上記のステートメントを次のように変更すると、

int a = 5;
int b = 10;
int result = a == b ? doThis() : doThat(); 

private int doThis()
{
    MessageBox.Show("Did this");
    return 0;
}
private int doThat()
{
    MessageBox.Show("Did that");
    return 1;
}

このコードは、本来の方法でコンパイルおよび実行されます。ただし、これらのメソッドが元々何かを返すことを目的としておらず、コードの他の領域を参照していた場合、これらのメソッドを呼び出すたびにreturnオブジェクトを処理する必要があります。

それ以外の場合は、1行のメソッドチューザに三項演算子を使用し、結果を使用して次の行で呼び出されたメソッドを知ることもできます。

int result = a == b ? doThis() : doThat();

if (result == 0)
   MessageBox.Show("You called doThis()!");

さて、このコードは完全に無意味であり、If Elseによって簡単に実行できますが、それが実行できるかどうか、そしてそれを機能させるために何をしなければならないかを知りたかっただけです。

これらのメソッドで任意の型を効果的に返すことができることがわかったので、これはもう少し便利になるかもしれません。それは「悪いコーディング慣行」と考えられるかもしれませんが、それが決して意味がない状況では非常に役立つかもしれません。

任意の条件に基づいて1つのオブジェクトまたは別のオブジェクトにアクセスできます。これは、1行のコードで非常に役立つ場合があります。

UserPrivileges result = user.Group == Group.Admin ? GiveAdminPrivileges() : GiveUserPrivileges();

private UserPrivileges GiveAdminPrivileges()
{
      //Enter code here
      return var;
}
private UserPrivileges GiveUserPrivileges()
{
      //Enter code here
      return var;
}

確かに、これはIfステートメントで実行できますが、他の用途にTernary演算子を使用するとプログラミングが楽しくなると思います。さて、これはIf Elseステートメントほど効率的ではないかもしれません。その場合、私はこれを決して使用しません。

3
Kyle Uithoven

三項演算子は値を返すために使用され、それらの値を割り当てる必要があります。メソッドdoThis()およびdoThat()が値を返すと仮定すると、単純な割り当てで問題が解決します。

あなたがしようとしていることをやりたいのならそれは可能ですが、解決策はきれいではありません。

int a = 5;
int b = 10;
(a == b ? (Action)doThis : doThat)();

これは、括弧によって呼び出されるアクションデリゲートを返します。これは、これを実現するための一般的な方法ではありません。

38
NerdFury

三項演算子は何かを返す必要があります。一般的な使用法は次のとおりです。

int x = (a > b) ? a : b;

次のようなことをしようとすると

a + b;

コンパイラは文句を言うでしょう。

(a > b) ? a - b : b - a;

基本的に、「a-b」または「b-a」のいずれかのショートカットであり、それ自体は正当なステートメントではありません。

18
iluxa

条件演算子で本当にvoidメソッドを呼び出したい場合は、デリゲートを使用できます。

(something ? new Action(DoThis) : DoThat)();

メソッドがパラメータを取る場合、これはより複雑になります。
条件式にラムダ式を入れるか、Action<T>

しかし、これは非常に馬鹿げたことです。

9
SLaks

ただし、これはできるはずです。

        int a = 5;
        int b = 10;

        var func = a == b ? (Action)doThis : (Action)doThat; // decide which method

        func(); // call it

でも、それが本当に便利なわけではありません。

4
skarmats

条件演算子は、値を返す式です。
voidを返す関数では使用できません。

代わりに、通常のifを使用する必要があります。

2
SLaks

.NETは、(簡単に)これを(読み取り可能なバージョンの)サポートしていません。これは非常に扱いやすく、コードが読みにくくなります。論理ツリーは比較的簡単にトラバースできます。私が仕事と、彼らが値の割り当て、メソッドの呼び出しなどのために3値を使用していたすべてのコードに足を踏み入れたとしたら、私は外に出ると思います。

1
FreeAsInBeer