C#将数组转换为元素类型

时间:2016-08-23 08:08:03

标签: c# arrays generics casting

我有一个通用参数T,它是一个特定情况下的数组。是否可以将对象数组转换为typeof(T).GetElementType()数组?例如:

public TResult Execute<TResult>()// MyClass[] in this particular case
{
    var myArray = new List<object>() { ... }; //actual type of those objects is MyClass
    Type entityType = typeof(TResult).GetElementType(); //MyClass
    //casting to myArray to array of entityType 
    TResult result = ...;
    return result;    
} 

3 个答案:

答案 0 :(得分:2)

这不是一个好主意。您无法将TResult约束到数组,因此使用当前代码,有人可以调用Excute<int>并获得运行时异常,哎!

但是,为什么要限制数组开始呢?只需让泛型参数成为元素本身的类型:

public TResult[] Execute<TResult>()
{
    var myArray = ... 
    return myArray.Cast<TResult>().ToArray();
}

更新:回应您的意见:

如果Execute是一种无法更改的界面方法,则可以执行以下操作:

public static TResult Execute<TResult>()
{
    var myArray = new List<object>() { ... };
    var entityType = typeof(TResult).GetElementType();
    var outputArray = Array.CreateInstance(entityType, myArray.Count);
    Array.Copy(myArray.ToArray(), outputArray, myArray.Count); //note, this will only work with reference conversions. If user defined cast operators are involved, this method will fail.
    return (TResult)(object)outputArray;
}

答案 1 :(得分:1)

您可以使用扩展方法myArray.Cast<MyClass>().ToArray()返回MyClass数组。

我认为你的意思是还要返回TResult[]

public TResult[] Execute<TResult>()//MyClass[] in this particular case
{
    return myArray.Cast<MyClass>().ToArray();
}

您需要添加

using System.Linq;

为了看到这些方法。

答案 2 :(得分:1)

我同意InBetween这是一个坏主意,但我不知道你的背景以及你为什么需要这个。但你可以这样做:

public TResult Execute<TResult>()// MyClass[] in this particular case
{
    var myArray = new List<object>() { ... }; //actual type of those objects is MyClass

    Type genericArgument = typeof(TResult);
    if (!genericArgument.IsArray)
       // what do you want to return now???

    Type elementType = genericArgument.GetElementType();

    MethodInfo cast = typeof(Enumerable).GetMethod("Cast").MakeGenericMethod(elementType);
    MethodInfo toarray = typeof(Enumerable).GetMethod("ToArray").MakeGenericMethod(elementType);

    object enumerable = cast.Invoke(null, new object[]{myArray});
    object array = toarray.Invoke(null, new object[]{enumerable});

    return (TResult)array;
}

这使用reflection来获取特定泛型参数的LINQ扩展。问题是:如果TResult 数组,此方法应该返回什么。似乎存在设计缺陷。