这个条件运算符有什么问题?

时间:2012-12-25 20:35:56

标签: c# visual-studio-2010 c#-4.0

protected void MakeAutoComplete(ref Control control, IListSource dListSource)
    {
        MakeAutoComplete(ref control, dListSource, false);
    }

protected void MakeAutoComplete(ref Control control, IListSource dListSource, bool isComboBox)
    {
        var curControl = (isComboBox) ? (control as ComboBox) : (control as TextBox);
        // other
    }

var curControl VS的行上给我错误 Type of conditional expression cannot be determined because there is no implicit conversion between 'System.Windows.Forms.ComboBox' and 'System.Windows.Forms.TextBox'我可以理解错误,而且我知道没有强制转换TextBoxComboBox,但这就是我首先使用var的原因。所以有什么问题?为什么抱怨?

5 个答案:

答案 0 :(得分:5)

var不是动态类型,它只是告诉编译器“你想出类型输出”并让它决定的一种方便方法。它总是一个类型,虽然这是在编译时决定的,所以你不能在运行时将它作为“这种类型或那种类型”。

答案 1 :(得分:2)

C#编译器需要能够在编译时计算条件的类型。 var关键字只是意味着编译器会自动为您选择类型,但它仍然需要能够在编译时计算它。

由于TextBoxComboBox之间没有隐式转换,编译器不知道条件的返回类型应该具有哪种类型。

要解决此问题,您需要将其强制转换为常见类型:

var curControl = (isComboBox) ? (control as Control) : (control as Control);

但是,你不需要有条件的......

答案 2 :(得分:1)

它失败的原因是因为两个分支的类型不同。三元运算符? :要求两个分支返回相同的类型,以便将结果分配给左侧。

虽然毫无意义,但以下内容是有效的。

var curControl = (isComboBox) ? (control as Control) : (control as Control);

请注意,正如其他人所指出的那样,关键字 var 不是动态类型,而是用于告诉编译器(非运行时)的语法快捷方式在编译时根据右手表达式确定变量的类型,而不是在运行时


或者,你可以这样写:

ComboBox curControlCombo = null;
TextBox curControlText = null;

if(isComboBox)
  curControlCombo = (control as ComboBox);
else
  curControlText = (control as TextBox);

答案 3 :(得分:1)

这是关于三元运算符?:的全部内容,与var关键字无关。所有这些示例都给出了相同的编译时错误:

var curControl = (isComboBox) ? (control as ComboBox) : (control as TextBox);
Control curControl = (isComboBox) ? (control as ComboBox) : (control as TextBox);
object curControl = (isComboBox) ? (control as ComboBox) : (control as TextBox);
dynamic curControl = (isComboBox) ? (control as ComboBox) : (control as TextBox);
Whatever curControl = (isComboBox) ? (control as ComboBox) : (control as TextBox);

如果你说例如:

,你也会得到错误
((isComboBox) ? (control as ComboBox) : (control as TextBox)).ToString();

或类似的东西。 ?:运算符需要在冒号:的任一侧找到两个参数的公共类型。所以类型必须相同,或者其中一种类型必须可以转换为另一种类型(例如,另一种类型可以是它的基类)。

但是您想要实现什么目标?使用as关键字的标准方法如下:

var comboBoxControl = control as ComboBox;
if (comboBoxControl != null)
{
  // great, it's a ComboBox. Do all kinds of things special for ComboBox
  // by using the comboBoxControl variable
}
// here you can do things general to all controls
// by using the original variable control

在上面的示例中,control具有编译时类型 Control,而comboBoxControl具有编译时类型 { {1}}。

运行时类型是另一回事。 ComboBox的运行时类型可以为null,control(它不是Control类!),或任何派生自abstract的类。与Control类似。

答案 4 :(得分:0)

通过询问语句执行后curControl的类型,可以最好地回答这个问题。我们唯一可以说的是候选人共享一个共同类型System.Windows.Forms.Control。因为c#(主要)是静态类型的,所以编译器需要在编译时解析curControl的类型。 var并不意味着动态输入。它直接等同于声明显式类型,而是由编译器推断(在编译时)。目前,您的代码含糊不清,因此编译器会抱怨。