2016-12-10 11 views
3

私はメソッドを持っていますが、Tパラメータはありません。c#typeof generic parameterに適用されました。スーパータイプ

残念ながら、C#typeof演算子は以下のようにジェネリックスで動作しません。

public static string ToString(object obj) 
{ 
    if (obj.GetType() == typeof(List<object>)) 
    { 
     return "Bug: Never called"; 
    } 
    if (obj.GetType() == typeof(List<int>)) 
    { 
     return "Method only works for int lists"; 
    } 
    return ""; 
} 

予想される出力:ToString(intのリスト)は "Bug:Never Called"を返します。

実際の出力:「メソッドが唯一のintリストのために働く」

これは、Javaで完全にうまく働きました。 C#のジェネリックスはこれをサポートしていないと言います。 「ToString(オブジェクト)」メソッドをオブジェクトのリストに対して機能させるためにコードを再構築するにはどうすればよいですか?

要件:メソッドのシグネチャを変更することはできず、その実装のみを変更できます。

残念ながら、「int」クラスはインターフェイスを実装できません。 intクラスはMicrosoftによって書かれています。したがって、int型の訪問者パターンを追加することはできません。

+0

'List 'のブランチである 'List Bug:Never Called 'を' List 'が返すのはなぜですか? –

+2

'List 'オブジェクトのタイプが 'List 'と期待される理由は分かりません。それはJavaの機能ですが、C#はJavaではありません。おそらく、Javaの動作はほとんどの人が期待するものではありません。私はGetGenericTypeDefintionを使用し、 'typeof(List <>)'と比較して何かのリストであるかどうかを調べることができると思います。 –

+0

オブジェクトはintのスーパークラスなので、私はオブジェクトも "キャプチャ" intと思った。 – user2186597

答えて

4

残念ながら、C#typeof演算子は以下のようにジェネリックでは機能しません。

実際、動作が期待通りに機能しないのは、実に幸運です。 Javaと異なり、C#はコンパイル時だけでなく、実行時にList<int>List<object>の間を区別します。プリミティブ型パラメータでインスタンス化されたジェネリック型の型情報は、型消去を避けることによって.NETがより効率的なコードを生成できるようにします。

あなたの代わりに、このチェックを使用して、オブジェクトが任意の一般的なリストであるかどうかをテストしたい場合:私はintタイプのビジターパターンを追加することはできません。このよう

var objT = obj.GetType(); 
if (objT.IsGenericType && objT.GetGenericTypeDefinition() == typeof(List<>)) { 
    ... 
} 

を。

C#は、インターフェイスを実装せずに動的にディスパッチするための強力なメカニズムを提供します。たとえば、あなたはこれを行うことができます。

public static string ToString(object obj) { 
    var list = obj as IList; 
    if (list != null) { 
     foreach (dynamic o in list) { 
      Process(o); 
     } 
    } 
} 
static void Process(int n) { ... } 
static void Process(string s) { ... } 
static void Process(object o) { ... } 

上記のリスト内のオブジェクトの実行時の型に基づいてProcessの右の実装を選択します。

+0

偉大な、あなたは質問の最初の部分に答えた、なぜそのようにC#ジェネリックスが機能しないのですか?今質問の第二の部分について:私は、基本的なタイプにかかわらずリストを一様に操作したいだけです。 – user2186597

+0

任意の一般的な**リスト**:D –

+0

dasblinkenlight、thats niceですが、基になるオブジェクトがリストでない場合、キャストは例外をスローします。それは私が "if条件"に焦点を当てた理由です。 – user2186597

関連する問題