方法使用三元运算符调用

时间:2011-03-30 17:50:20

标签: c# conditional-operator

在玩新概念的过程中,我遇到了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");
    }

这一行给了我两个错误:

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来决定调用哪种方法,也不知道它是否可行。我只是喜欢单行If Else Statement进行方法调用的想法。

我做了一些研究,我找不到任何人这样做的例子,所以我想我可能希望得到一些无法提供的东西。

如果可以,请在我的错误行为中启发我,这是不可能的,还有另一种方法吗?

8 个答案:

答案 0 :(得分:37)

三元运算符用于返回值,必须分配这些值。假设方法doThis()doThat()返回值,一个简单的赋值将解决您的问题。

如果你想做你正在尝试的事情,这是可能的,但解决方案并不漂亮。

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

这将返回一个Action委托,然后由括号调用。这不是实现这一目标的典型方法。

答案 1 :(得分:17)

三元运算符必须返回一些东西。典型的用法是这样的:

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

如果您尝试类似

的话
a + b;

编译器会抱怨。

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

基本上是“a - b”或“b - a”的快捷方式,它们本身不是合法的陈述。

答案 2 :(得分:7)

如果您真的想在条件运算符中调用void方法,可以使用委托:

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

如果方法采用参数,这将变得更加复杂 您可以将lambda表达式放在条件中,也可以使用Action<T>

然而,这是一件非常愚蠢的事情。

答案 3 :(得分:3)

你应该能够做到这一点,但是:

        int a = 5;
        int b = 10;

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

        func(); // call it

虽然它并没有那么有用。

答案 4 :(得分:3)

上述陈述不起作用的原因是其他用户提供的,实际上没有回答我的真实问题。

在玩了一些之后,我发现你可以使用这个运算符来执行上述语句,但它会导致一些错误的代码。

如果我要将上述陈述改为;

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;
}

此代码将编译并执行它应该的方式。但是,如果这些方法最初并不打算返回任何内容,并且引用了代码中的其他区域,那么每次调用这些方法时都必须处理一个返回对象。

否则,您现在可以使用三元运算符作为单行方法选择器,甚至可以使用结果知道它在下一行中调用的方法。

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

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

现在,这段代码绝对毫无意义,可以通过If Else轻松完成,但我只是想知道它是否可以完成,以及你必须做些什么才能让它工作。

现在我知道你可以有效地返回这些方法中的任何类型,这可能会变得更有用。它可能被认为是“糟糕的编码实践”,但在从未有过的情况下可能会变得非常有用。

您可以根据任何条件访问一个或另一个对象,这可能在一行代码中非常有用。

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语句完成,但我认为使用三元运算符进行其他用途可以使编程变得有趣。现在,这可能不如If Else语句那么有效,在这种情况下,我永远不会使用它。

答案 5 :(得分:2)

条件运算符是一个返回值的表达式 您不能将它与返回void的函数一起使用。

相反,您应该使用普通if

答案 6 :(得分:1)

.NET没有(轻松)支持(可读版本)这是有原因的。这非常简洁,使您的代码难以阅读。逻辑树应该相对容易遍历。如果我要参加一份工作和所有代码,他们使用三元来分配值,调用方法等等。我想我会走出去。

答案 7 :(得分:0)

方法1:使用操作

Action Action = true is true ? new Action(() => A()) : new Action(() => B());
Action.Invoke();

方法2:使用扩展程序

Button Button = new Button(){
    IsEnabled = false
};
Button.Switch((x) => x.IsEnabled).Invoke(() => A(), () => B())

扩展开关:

public static R Switch<T, R>(this T sender, Func<T, R> method){
    return method.Invoke(sender);
}

扩展调用:

public static void Invoke(this bool condition, Action @true, Action @false){
    Action Action = condition ? @true : @false;
    Action.Invoke();
}

方法3:使用扩展程序和C#6.0空条件运算符

Button.Case((x) => 0 > 1)?.With(() => A());
Button.Case((x) => 0 < 1)?.With(() => B());

扩展名:

public static T With<T>(this T sender, Action method){
    method.Invoke();
    return sender;
}

扩展案例:

public static object Case<T>(this T sender, Func<T, bool> method){
    return method.Invoke(sender) ? Convert.ChangeType(sender, typeof(T)) : null;
}