在玩新概念的过程中,我遇到了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
进行方法调用的想法。
我做了一些研究,我找不到任何人这样做的例子,所以我想我可能希望得到一些无法提供的东西。
如果可以,请在我的错误行为中启发我,这是不可能的,还有另一种方法吗?
答案 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;
}