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 curControlVS 的线上给了我错误 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首先使用的原因。所以有什么问题?为什么抱怨?

4

5 回答 5

5

var不是动态类型,它只是告诉编译器“你弄清楚类型”并让它决定的一种方便方式。尽管它是在编译时决定的,但它始终是单一类型,因此在运行时您将无法让它成为“这种类型或那种类型”。

于 2012-12-25T20:39:13.890 回答
2

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

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

要解决此问题,您需要将其转换为通用类型:

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

但是,您将不需要条件 ....

于 2012-12-25T20:42:26.240 回答
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);
于 2012-12-25T20:37:11.403 回答
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

在上面的例子中,controlcompile-time type Control,并且comboBoxControlcompile-time type ComboBox

运行时类型是另一回事。的运行时类型control可以是 null,Control(它不是一个abstract类!),或者任何从Control. 与comboBoxControl.

于 2012-12-25T21:31:20.887 回答
0

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

于 2012-12-25T20:40:21.383 回答