2016-08-12 1 views
1

T가 형식 목록 인 경우 해당 형식을 일반 형식 T를 인수로 사용하는 메서드가 있습니다. T에 포함 된 요소 유형. 제네릭 형식의 제약 조건을 잘못 이해하고 있지만 도움이 될 것으로 생각됩니다.일반 형식 T를 특정 형식의 목록으로 캐스팅하는 방법

예 :

내가 서명을 다른 방법으로 전달할 수 있도록 내가 목록에 genericData 캐스팅 할 필요가
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 
    } 
} 

:

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

UPDATE 에릭의 응답 당

아래에, 나는 누군가가 내 실수를 지적 할 수있는 시도를 나누고 싶었다. 컴파일러는 내가의 의미를 이해 타입으로 변수를 사용하려고 시도하고 있다고 주장하지만,이 elementType는 유형, 그래서 해결하는 방법 불분명 해요 :

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

답변

0

편집 :이 근처인가 너는 무엇을 요구하고 있는가?

코드 :

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

감사합니다. Eric. 나는 그것을 시도했지만 요소 유형을 갖게되면 그 유형의 목록에 캐스트 할 수 없습니다. 나는 이런 식으로 시도 : var myCastedList = (List ) genericData; List에있는 ElementType이 맘에 들지 않았습니다. 변수로 사용하려고했으나 Type으로 사용하려고했습니다. – rvb01

+0

표현식을 사용할 수 있으며 제네릭 형식에 많은 융통성이 있습니다. 원하는 형식으로 캐스팅 할 형식을 식별하고 실행하면 Expression.Convert를 사용할 수 있습니다. https://msdn.microsoft.com/en-us/library/mt654265.aspx 자세한 예제를 작성하려고 할 수 있습니다. – Eric

+0

당신이 얻고 자하는리스트의 대상의 유형을 알고 있습니까? – Eric

-1

및 시나리오에 대한 자세한 세부, 그것은 가장 좋은 방법은 여기에있을 것입니다 무엇인지 알고하는 것은 불가능하다. 그 말은 & hellip;

첫 번째 작업은 개체가 목록인지 확인한 다음 목록에서 작동하는 다른 메서드로 전달하는 경우 메서드에 두 가지 오버로드를 적용하지 않는 이유는 무엇입니까? 예컨대 :

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?을 참조하십시오.