2016-08-23 373 views
1

我有一个泛型参数T,它是一个特定情况下的数组。是否可以将对象数组投射到typeof(T).GetElementType()的数组?例如:C#将数组强制转换为元素类型

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;  
} 
+0

感谢您的回复,但问题在于Execute方法是接口的实现,我无法更改其签名或添加新的签名。 –

+0

查看编辑我的答案 – InBetween

回答

2

这不是一个好主意。您无法将TResult限制为一个数组,因此使用您当前的代码,有人可能会调用Excute<int>并获得运行时异常,yuck!

但是,为什么约束到一个数组开始?只是让泛型参数是元素本身的类型:

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; 
} 
+0

谢谢!它也很好运作 –

1

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

我想你的意思返回TResult[]也:

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

您将需要添加

using System.Linq; 

为了看到这些方法。

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而不是数组,则此方法应该返回什么。似乎有一个设计缺陷。

+0

非常感谢!我已经有一个非数组'TResult'(它是默认情况下)的实现,所以一切都应该正常工作 –

+0

我真的不认为它需要这涉及。 OP基本上要求引用转换('object' - > * realUnderlyingType *)。在这种情况下,你可以使用'Array.Copy'。看看我的答案。 – InBetween

相关问题