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

C# 这个条件运算符有什么问题?,c#,visual-studio-2010,c#-4.0,C#,Visual Studio 2010,C# 4.0,在var curControlVS的行上,VS给了我一个错误 无法确定条件表达式的类型,因为“System.Windows.Forms.ComboBox”和“System.Windows.Forms.TextBox”之间没有隐式转换我可以理解错误,并且我知道没有强制转换btwTextBox和ComboBox,但这就是我首先使用var的原因。那有什么问题?为什么它会抱怨?它失败的原因是因为两个分支的类型不同。三元运算符?:要求两个分支返回相同的类型,以便is可以将结果分配到左侧 虽然没有意义,但以

var curControl
VS的行上,VS给了我一个错误
无法确定条件表达式的类型,因为“System.Windows.Forms.ComboBox”和“System.Windows.Forms.TextBox”之间没有隐式转换
我可以理解错误,并且我知道没有强制转换btw
TextBox
ComboBox
,但这就是我首先使用
var
的原因。那有什么问题?为什么它会抱怨?

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

虽然没有意义,但以下是一个有效的赋值

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不是动态类型,而是一种语法快捷方式,用于告诉编译器(非运行时)在编译时而非运行时根据右侧表达式确定变量的类型


或者,你可以写一些类似的东西:

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

var
不是一个动态类型,它只是告诉编译器“你算出了类型”并让它决定的一种方便方式。它始终是一个单一类型,尽管这是在编译时决定的,所以在运行时不能让它是“这个类型或那个类型”。

最好的回答是在执行语句后询问
curControl
的类型。我们唯一能说的是候选人共享一个公共类型
System.Windows.Forms.Control
。由于c#主要是静态类型,编译器需要在编译时解析
curControl
的类型<代码>变量并不意味着动态键入。它直接等同于声明显式类型,但由编译器(在编译时)进行推断。目前,您的代码不明确,因此编译器会抱怨。

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

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

要解决此问题,需要将其强制转换为公共类型:

ComboBox curControlCombo = null;
TextBox curControlText = null;

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

但是,您不需要条件…

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

var curControl = (isComboBox) ? (control as Control) : (control as Control);
如果您说,例如:

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();
在上面的示例中,
控件
具有编译时类型
控件
组合框控件
具有编译时类型
组合框


运行时类型是其他类型。
控件
的运行时类型可以为null、
控件
(它不是
抽象类
类!)或从
控件
派生的任何类。与
comboBoxControl

类似,您为什么要首先执行此操作?当然,这只是
var curControl=控制作为控制。你说得对。。。那样做没有意义。我并没有彻底阅读这个问题。用
var
声明的变量类型是在编译阶段决定的,而不是在运行时决定的。它不像javascript那样完全是动态的。在您的情况下,编译器无法决定它将是哪种类型。
组合框
文本框
最接近的公共父项是
控件
,这是您最初拥有的类型。我建议你使用if..then..else,对于你计划用它做的事情。@MihailGolubev它根本不是动态的,没有理由说if-else比条件运算符更好
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