C# cast array to element type

一世执手 提交于 2019-12-11 06:43:56

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!