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

本文关键字:什么 问题 条件运算符 | 更新日期: 2023-09-27 17:49:26

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的原因。那么问题出在哪里呢?为什么抱怨?

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

var不是

动态类型,它只是告诉编译器"你弄清楚类型"并让它决定的一种方便的方法。它始终是单一类型,尽管它是在编译时决定的,因此您将无法在运行时将其设置为"此类型或该类型"。

C# 编译器需要能够在编译时计算条件的类型。 var 关键字仅表示编译器将自动为您选择类型,但它仍然需要在编译时能够计算它。

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

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

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

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

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

虽然毫无意义,但以下内容将是一个有效的分配。

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);

这都是关于三元运算符?:的,与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具有编译时类型 ControlcomboBoxControl具有编译时类型 ComboBox

运行时类型是其他类型。control的运行时类型可以是 null、Control(它不是 abstract 类!(或从 Control 派生的任何类。与comboBoxControl类似.

这个问题

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