问题
I have a generic argument T which is an array in one particular case. Is it possible to cast array of objects to the array of typeof(T).GetElementType()
? For example:
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;
}
回答1:
This is not a good idea. You have no way to constrain TResult
to an array, so with your current code, someone could call Excute<int>
and get a runtime exception, yuck!
But, why constrain to an array to begin with? Just let the generic parameter be the type of the element itself:
public TResult[] Execute<TResult>()
{
var myArray = ...
return myArray.Cast<TResult>().ToArray();
}
UPDATE: In response to your comments:
If Execute
is an interface method you can not change, then you can do the following:
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;
}
回答2:
You can use the extension methods myArray.Cast<MyClass>().ToArray()
to return an array of MyClass.
I think you mean to return TResult[]
also:
public TResult[] Execute<TResult>()//MyClass[] in this particular case
{
return myArray.Cast<MyClass>().ToArray();
}
You will need to add
using System.Linq;
In order to see these methods.
回答3:
I agree with with InBetween that it's a bad idea, but I don't know your context and why you need this. But you can achieve it like that:
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;
}
This uses reflection to get the LINQ extension for the specific generic arguments. The question is: what should this method return if TResult
is not an array. There seems to be a design flaw.
来源:https://stackoverflow.com/questions/39095682/c-sharp-cast-array-to-element-type