2011-01-24 4 views
5

は、コンパイラがエラーを投げたとき、私は、この一般的な関数を書く時に、すべての興奮していた(unable to cast T to System.Web.UI.Control私の最初の一般的なキャスティング(C#の)

私は基本的に私はそれを呼び出す型を渡すと、それはすべてのコントロールを探してそのタイプ。エラーがl.Add((T)ctrl);

private List<T> RecurseTypes<T>(Control ctrls) 
    { 
     var l = new List<T>(); 
     foreach (var ctrl in ctrls.Controls) 
      if (ctrl.GetType() is T) 
       l.Add((T)ctrl); 
     return l; 
    } 

に発生し、私は何かが足りないか、私は運が悪いアム?

+0

のコントロールを格納することになると仮定することができます。私はクラスの宣言を見てみましょう。 –

+0

@Jannis:これはクラスから来ていない、これはジェネリック*メソッド*: 'RecurseTypes 'です。 – Ani

+0

どの行から例外がスローされますか? – Nickolodeon

答えて

13
private List<T> RecurseTypes<T>(Control parent) where T: Control 
{ 
    var l = new List<T>(); 
    foreach (var child in parent.Controls) 
     if (child is T) 
      l.Add((T)child); 
    return l; 
} 

2変更:

  • isの使用を参照してくださいwhere T : Control一般的な制約を追加(制御Tあってもよいが、決してControlあるGetType()戻りType、 )

また、これは実際には繰り返されません。これはちょうど:

return ctrl.Controls.OfType<T>().ToList(); 
+0

@ssg - いいえ、そうは思わない。@maxpは特定の型の*子*コントロールの後にあるように思えます;それは*親コントロールがそれである必要があることを意味しません。たとえば、 'Panel'内のすべての' TextBox'コントロールは、 'T = TextBox'、' ctrl'は 'Panel'(' TextBox'ではなく)です。 –

+0

@ssgそうする必要はありません。その理由は、リストに入っているアイテムがそのタイプのためにチェックされ、パラメータがコントロールである必要があるからです。それは、T. –

+0

@chibacity良いスポットと同じ特定のタイプである必要はありません!私が更新すればいいの? –

0

詳細を教えていただけますか?

なぜコードは次のようではない:制約を置く

private List<T> RecurseTypes<T>(Control ctrl) 
    { 
     List<T> l = new List<T>(); 
     foreach (var ctrls in ctrl.Controls) 
     { 
      if (ctrls is T) 
       l.Add((T)ctrls); 
     } 
     return l; 
    } 
+0

これはコンパイラエラーの原因となります。エラー 'Foo.Control'を 'T'に変換できません。 –

0

がお手伝いします。

private List<T> RecurseTypes<T>(Control ctrls) where T : System.Web.UI.Control 
2

は、.NET 3.5を使用している場合、以降は、あなた自身を書くのではなく、OfType<T>()またはCast<T>()拡張メソッドを使用することができます。

OfType<T>()はキャスト可能な初期コレクションのサブセットを返しますが、Cast<T>()はコレクションのキャスト全体を目的のタイプに戻しますが、コレクションの要素の1つがキャストできなかった場合は例外をスローします。

0

多分、Tは望ましいコントロールのタイプではありません。

私はあなたがControlからTにキャストしていることを保証していないということです。コントロールから継承します。あなたが必要とする

まず最初は、一般的な制約を追加です:

private List<T> RecurseTypes<T>(Control ctrls) where T : Control 

反復コントロールはあなたがそれがコントロールのサブクラスだかどうかを確認する必要があるT.であればその後、あなたが知るための手掛かりを持っていません。

if (ctrl.GetType().IsSubclassOf(typeof(Control)) 

最後に、あなたは今のコントロールのリストは、型T Tから来ている