4

我有一个列表类型的集合,我想将其转换为 SomeType[]。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;
}

请注意,collection 是 IList,但已知具体类型是

     List<SomeType>

返回集合必须是 SomeType[] 类型的对象。

如何才能做到这一点?

4

4 回答 4

1

您可以通过以下实现来做到这一点:

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;
    }
}
于 2012-09-07T07:32:45.900 回答
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[]);
    }
}
于 2012-09-07T07:47:51.203 回答
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;
        }
于 2012-09-07T07:43:21.180 回答
0

我发布这个是因为其他答案似乎有点冗长。我很确定这可以满足 OP 的要求。它对我有用。

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

    collection.CopyTo(array, 0);

    return array;
}
于 2016-06-28T15:42:40.567 回答