内联条件c# - 下一个最佳解决方案?

时间:2010-08-24 14:22:33

标签: c# casting

似乎编译器不会让这种语法飞起来。

void main()
{
  foo(false?0:"");
}

void foo(int i) {return;}
void foo(string s) {return;}

我能看到修复此问题的唯一方法如下:

void bar(object o) 
{
 if (o is string){//do this}
 else{//im an int, do this}
}

任何人都有更好的想法吗?

8 个答案:

答案 0 :(得分:3)

您不能以这种方式在三元表达式中使用具有void返回类型的方法。故事结束。

要理解为什么会这样,请记住三元运算符实际做什么 - 评估以下内容:

(condition ? [true value] : [false value])

这意味着以下代码:

int x = a ? b : c;

必须可以重写

int x;
if (a)
{
    x = b;
}
else
{
    x = c;
}

以上两者在逻辑上完全相同。

那么如何使用void作为返回类型的方法呢?

// Does this make sense?
int x = condition ? foo(s) : foo(i);

// Or this?
if (condition)
{
    x = foo(s);
}
else
{
    x = foo(i);
}

显然,上述情况并非合法。

也就是说,如果只有foo重载返回了值,其他人的建议就会有效。

换句话说,如果您的签名如下所示:

object foo(string s);
object foo(int i);

然后你可以这样做(你丢弃了返回值,但至少它会编译):

object o = condition ? foo(0) : foo("");

无论如何,在这种情况下,ol if / else是你最好的选择。

答案 1 :(得分:2)

你的榜样没有多大意义(第二个例子与第一个例子无关)。

我认为第一个例子很好:

void main()
{
    foo("");
}

因为0永远不会被传递(false总是为false)并且你不能在没有任何地方的情况下使用内联条件运算符(你的例子缺乏)。

至于第二种方式,这可能是我更喜欢看的方式:

void bar(object o)
{
    if(o is string) foo(o as string);
    else foo((int)o);
}

答案 2 :(得分:2)

foo的方法调用是在编译时确定的,因此它不能根据评估条件的结果调用不同的方法(或重载)。相反,尝试这样的事情:

condition ? foo(0) : foo("")

这样,编译器将成功执行重载解析,并将解析对foo(int)的第一次调用以及对foo(string)的第二次调用。

编辑:正如其他人所说,你不能使用?:运算符作为语句,也不能使用返回void的方法。如果您的实际方法返回兼容类型,您可以执行以下操作:

int result = condition ? foo(0) : foo("");

如果没有,您必须使用if

if (condition)
    foo(0);
else
    foo("");

答案 3 :(得分:1)

我不会将对象作为参数传递。 int将被装箱,效率稍差。让编译器找出要调用的方法。

如果你写了:

foo(0);
foo("");

将调用适当的方法。你也可以写:

if (condition) {
  foo(0);
} else {
  foo("");
}

取决于你想要做什么(你的例子缺乏一点细节)。

答案 4 :(得分:1)

条件运算符需要true和false部分属于同一类型。这就是为什么它没有编译。

var x = condition ? 0 : "";

编译器应该为x选择什么类型?如果你真的希望它选择对象进行强制转换,或者你可以强制它选择动态,在这种情况下方法重载仍然可以工作但你放松了类型安全。然而,两者都是浓烈的气味。 必须测试运行时类型通常是设计错误,但是使用有限的代码(总是会有相同的结果),很难帮助使用需要在运行时类型上进行测试的不同方法

答案 5 :(得分:1)

如果在C#中使用Inline if表达式,则“:”之前和之后的两个部分必须属于同一类型。你的意图永远不会奏效。

即使你喜欢这样做:

 DateTime? theTime = true ? DateTime.Now : null;

编译器不满意。在这种情况下,您将不得不使用:

DateTime? theTime = true ? DateTime.Now : default(DateTime?);

答案 6 :(得分:0)

此:

foo(false?0:"")

可能是这样的:

false ? foo(0) : foo("")

答案 7 :(得分:0)

条件运算符的两个结果必须是相同类型(或可隐式转换)。因此,foo(false ? 0 : "")无效,因为它会尝试返回Int32StringHere有关条件运算符的更多信息。

我要做的修复是将该行更改为false ? foo(0) : foo("")

编辑:Derp,不能像那样在开放时使用条件运算符。它们只能用于作业。你必须使用if / else块。不是一行,但它会在紧要关头。