2016-08-12 6 views
1

私は、一般的なタイプTを引数として取るメソッドを持っています。もしTがタイプリストの場合、Yをリストにキャストしたいと思います私はジェネリック型の制約を誤解していると思いますが、助けていただければ幸いです。一般的なタイプTを特定のタイプのリストにキャストする方法

例:

public void MapData<T>(T genericData) 
{ 
    var genericDataType = genericData.GetType(); 

    if (genericDataType.Name.Contains("List")) 
    { 
     //Cast T to a List containing the type of elements contained in T 
    } 
} 

私は署名で別のメソッドに渡すことができるようにリストにgenericDataをキャストする必要があります:エリックの応答パー

public void MapListToField<T>(List<T> genericList) 

UPDATE

私は、おそらく誰かが私の誤りを指摘できたという試みを分かち合いたいと思っていました。 EDIT

var elementType = genericData.GetType().GetGenericArguments()[0]; 
var castedList = genericData as List<elementType>; 

答えて

0

:コンパイラは、私はの意味を理解している、私はタイプとして変数を使用しようとしていますことを示すが、をelementTypeはタイプですので、私は修正するかは不明だ。この近くにありますあなたが求めているものに?

コード:

void Main() 
{ 
    List<string> stringlist = new List<string> { "a", "b", "c" }; 
    List<int> intlist = new List<int> { 1, 2, 3 }; 
    string notList = ""; 
    var expression = Expression.Call(typeof(Methods), "CastToList", new Type[] { stringlist.GetType(), stringlist.GetType().GetGenericArguments()[0] }, Expression.Constant(stringlist)); 
    Expression.Lambda<Func<bool>>(expression).Compile()(); 
    expression = Expression.Call(typeof(Methods), "CastToList", new Type[] { intlist.GetType(), intlist.GetType().GetGenericArguments()[0] }, Expression.Constant(intlist)); 
    Expression.Lambda<Func<bool>>(expression).Compile()(); 
    expression = Expression.Call(typeof(Methods), "CastToList", new Type[] { notList.GetType(), typeof(object) }, Expression.Constant(notList)); 
    Expression.Lambda<Func<bool>>(expression).Compile()(); 
} 

public static class Methods 
{ 
    public static void MapListToField<T>(List<T> genericList) 
    { 
     foreach (var element in genericList) 
     { 
      Console.Write("{0}, ", element.ToString()); 
     } 
     Console.Write("\n"); 
    } 
    public static bool CastToList<L, T>(L obj) 
    { 
     if (obj.GetType() == typeof(List<T>)) 
     { 
      Console.Write("List contains objects of Type: {0}\n", typeof(T).ToString()); 
      List<T> genericList = obj as List<T>; 
      MapListToField(genericList); 
      return true; 
     } 
     else 
     { 
      Console.Write("Not list, Type is: {0}\n", typeof(L).ToString()); 
      return false; 
     } 
    } 
} 

結果:良いMinimal, Complete, and Verifiable code exampleなし

List contains objects of Type: System.String 
a, b, c, 
List contains objects of Type: System.Int32 
1, 2, 3, 
Not list, Type is: System.String 
+0

ありがとうございます。私はそれを試みましたが、要素タイプを取得してしまえば、そのタイプのリストにキャストできませんでした。私はこのようなものを試しました:var myCastedList =(リスト)genericData;それはListに置かれたElementTypeが好きではなく、変数であると不平を言いました。タイプとして使用しようとしていました – rvb01

+0

式を使用することができ、汎用タイプに柔軟性があります。目的の型にキャストする型と実行する型を特定したら、Expression.Convertを使用できます。 https://msdn.microsoft.com/en-us/library/mt654265.aspx 詳細な例を書くことができます。 – Eric

+0

あなたが取得しようとしているリストのオブジェクトのタイプを知っていますか? – Eric

-1

、およびシナリオの詳細仕様、それが最善のアプローチはここにどうなるかを確実に知ることは不可能です。それは&hellipと言った。

最初に行うことは、オブジェクトがリストであるかどうかをチェックし、それをリスト上で動作する別のメソッドに渡すだけの場合、メソッドに2つのオーバーロードを加えないでください。例えば:

public void MapData<T>(T genericData) 
{ 
    // do stuff with non-list data 
} 

public void MapData<T>(List<T> genericList) 
{ 
    MapListToField(genericList); 
} 

あなたは、両方のタイプのために実行MapData<T>()の両方のオーバーロードを呼び出すことができるヘルパーメソッドにそれを移動したいコードがある場合。

これにどのようにアプローチしても、List<T>タイプをチェックする現在のメカニズムは非常に脆弱でIMHOは回復不能に欠陥があります。これを行うためのより良い方法に関するアイデアについては、How do I check if a given value is a generic list?を参照してください。

関連する問題