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'た。エラーを理解でき、キャストがないことはわかっていますが、そもそもTextBoxそれComboBoxが使用している理由ですvar。だから問題は何ですか?なぜ文句を言うのですか?

4

5 に答える 5

5

varは動的型ではありません。これは、コンパイラに「型を理解して」決定させるための便利な方法にすぎません。コンパイル時に決定されますが、常に単一のタイプであるため、実行時に「このタイプまたはそのタイプのいずれか」にすることはできません。

于 2012-12-25T20:39:13.890 に答える
2

C# コンパイラは、コンパイル時に条件の型を計算できる必要があります。このvarキーワードは、コンパイラが自動的に型を選択することを意味しますが、コンパイル時にそれを計算できる必要があります。

TextBoxまたはの間に暗黙的な変換がないためComboBox、コンパイラは条件の戻り値の型がどちらの型を持つべきかを知りません。

これを修正するには、共通の型にキャストする必要があります。

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

しかし、その後、条件は必要ありません....

于 2012-12-25T20:42:26.240 に答える
1

失敗する理由は、2つのブランチのタイプが同じではないためです。三項演算子? :では、2つのブランチが同じ型を返す必要があります。これにより、結果を左側に割り当てることができます。

無意味ですが、以下は有効な割り当てです。

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

または類似のもの。?:演算子は、コロンの両側にある 2 つの引数の共通の型を見つける必要があります:。したがって、型が同じである必要があるか、型の 1 つが他の型に変換可能である必要があります (たとえば、他の型はその基本クラスである可能性があります)。

しかし、あなたは何を達成しようとしていますか?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

上記の例では、controlhas compile-time type ControlcomboBoxControlhas compile-time type ComboBox .

実行時の型は別のものです。の実行時の型はcontrol、null Control(クラスではありませんabstract!)、または から派生した任意のクラスの可能性がありますControl。同様にcomboBoxControl

于 2012-12-25T21:31:20.887 に答える
0

curControlこれは、ステートメントが実行された後にタイプが何であるかを尋ねることによって最もよく答えることができます。私たちが言える唯一のことは、候補者は共通のタイプを共有しているということSystem.Windows.Forms.Controlです。c#は(主に)静的に型付けされているため、コンパイラーはcurControlコンパイル時にの型を解決する必要があります。var動的型付けを意味するものではありません。これは、明示的な型を記述することと直接同等ですが、代わりにコンパイラーによって(コンパイル時に)推測されます。現時点では、コードがあいまいであるため、コンパイラは文句を言います。

于 2012-12-25T20:40:21.383 に答える