2016-08-23 77 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