2012-09-07 3 views
3

List로 변환 할 수있는 List 유형의 컬렉션이 있습니다. 런타임 전에 SomeType을 알 수 없습니다.IList에서 SomeType으로 변환 []

이 절차는 다음 절차의 서명으로 수행해야합니다. 컬렉션은 IList이지만,이 구체적인 종류는 리턴 컬렉션 [] 형 SomeType의 대상으로해야

 List<SomeType> 

것으로 알려져 있음

private object ConvertListToArray(IList collection) 
{ 
     // This does not work since SomeType is not known before runtime. 
     var convertedList = collection.Cast<SomeType>().ToArray(); 
     return convertedList; 
} 

통지.

어떻게이 작업을 수행 할 수 있습니까?

+0

collection.ToArray(); 이게 속임수가 아닐까요? – Katalonis

+0

'object []','String []'또는'SomeOtherType []'대신'SomeType []'을 원한다는 것을 어떻게 예상할까요? 컬렉션에'SomeType'과'SeomOtherType'이 포함되어 있다면 무엇을 기대할 수 있을까요? 그것이 비어 있다면? –

+0

Katalonis - ToArray()는 List 의 확장이지만 IList가 있습니다. – Oyvind

답변

1
public static class ListExtensions 
{ 
    public static T[] ConvertToArray<T>(IList list) 
    { 
     return list.Cast<T>().ToArray(); 
    } 

    public static object[] ConvertToArrayRuntime(IList list, Type elementType) 
    { 
     var convertMethod = typeof(ListExtensions).GetMethod("ConvertToArray", BindingFlags.Static | BindingFlags.Public, null, new [] { typeof(IList)}, null); 
     var genericMethod = convertMethod.MakeGenericMethod(elementType); 
     return (object[])genericMethod.Invoke(null, new object[] {list}); 
    } 

} 
[TestFixture] 
public class ExtensionTest 
{ 
    [Test] 
    public void TestThing() 
    { 
     IList list = new List<string>(); 
     list.Add("hello"); 
     list.Add("world"); 

     var myArray = ListExtensions.ConvertToArrayRuntime(list, typeof (string)); 
     Assert.IsTrue(myArray is string[]); 
    } 
} 
+0

잘 작동 해 주셔서 감사합니다. 목록과 함께 사용하려면 을 사용했습니다. var myArray = ListExtensions.ConvertToArrayRuntime (list, list.GetType). GetGenericArguments() [0]); – Oyvind

+0

나는 upvote하고 싶지만 내 명성은 15 세 이하이므로 투표 할 수 없다. – Oyvind

+0

아무 문제 없어, 다행이었습니다. –

2

당신은 아래의 구현이 작업을 수행 할 수 있습니다

class Program 
{ 
    static void Main(string[] args) 
    { 
     // same type 
     var myCollection = new List<string> {"Hello", "World"}; 
     var array = (string[])myCollection.ConvertToArray(); 
     Console.WriteLine(array[0]); 

     // new type 
     var intList = new List<int> {1, 2, 3}; 
     var stringArray = (string[])intList.ConvertToArray(typeof(string)); 
     Console.WriteLine(stringArray[0]); 

     // mixed types 
     var ouch = new List<object> {1, "Mamma", 3.0}; 
     var result= (string[])ouch.ConvertToArray(typeof(string)); 
     Console.WriteLine(result[0]); 


    } 
} 

구현 : 당신은 시도 할 수

public static class ListExtensions 
{ 
    public static object ConvertToArray(this IList collection) 
    { 
     // guess type 
     Type type; 
     if (collection.GetType().IsGenericType && collection.GetType().GetGenericArguments().Length == 0) 
      type = collection.GetType().GetGenericArguments()[0]; 
     else if (collection.Count > 0) 
      type = collection[0].GetType(); 
     else 
      throw new NotSupportedException("Failed to identify collection type for: " + collection.GetType()); 

     var array = (object[])Array.CreateInstance(type, collection.Count); 
     for (int i = 0; i < array.Length; ++i) 
      array[i] = collection[i]; 
     return array; 
    } 

    public static object ConvertToArray(this IList collection, Type arrayType) 
    { 
     var array = (object[])Array.CreateInstance(arrayType, collection.Count); 
     for (int i = 0; i < array.Length; ++i) 
     { 
      var obj = collection[i]; 

      // if it's not castable, try to convert it 
      if (!arrayType.IsInstanceOfType(obj)) 
       obj = Convert.ChangeType(obj, arrayType); 

      array[i] = obj; 
     } 

     return array; 
    } 
} 
+0

나는 그가'SomeType'은 컴파일 타임에 알려지지 않았다고 말했다고 생각한다. – sloth

+0

@BigYellowCactus : 예제를보다 동적 인 코드로 업데이트했습니다. – jgauffin

+0

+1 잘 작동합니다. 내 생각에 – sloth

0

:

private T[] ConvertListToArray<T>(IList collection) 
    { 
    // This does not work since SomeType is not known before runtime. 
      var convertedList = collection.Cast<T>().ToArray(); 
      return convertedList; 
     } 
+0

문제는 런타임에 T가 없다는 것입니다. – Oyvind

+0

문제가 생기지 않습니다. 런타임에 당신이 stil 타입을 가지고 있지 않다면 나는 이것이 풀 수 없다고 생각합니다. 하지만 솔루션을 보면 나는 문제가 생겼다. :-) –

0

을 나는대로이 게시하도록하겠습니다 다른 대답은 약간 장황 해 보입니다. 나는 이것이 OP가 찾고있는 것이 무엇인지 확신한다. 그것은 나를 위해 일했습니다.

public static Array ConvertToArray(ICollection collection, Type type) 
{ 
    var array = Array.CreateInstance(type, collection.Count); 

    collection.CopyTo(array, 0); 

    return array; 
}