在C#中使用Reflection进行转换

mni*_*eld 4 .net c# reflection

我已经创建了一个通用函数,如下所示(仅作为证明),它将采用一个List<T>集合并将其反转,返回一个新List<T>的输出.

public static List<T> ReverseList<T>(List<T> sourceList)
{
    T[] outputArray = new T[sourceList.Count];
    sourceList.CopyTo(outputArray);
    return outputArray.Reverse().ToList();
}
Run Code Online (Sandbox Code Playgroud)

证明的目的是我只知道T运行时的内容.因此我使用反射来调用上面的方法如下:

List<int> myList = new List<int>() { 1, 2, 3, 4, 5 }; // As an example, but could be any type for T

MethodInfo myMethod = this.GetType().GetMethod("ReverseList");
MethodInfo resultMethod = myMethod.MakeGenericMethod(new Type[] { typeof(int) });
object result = resultMethod.Invoke(null, new object[] { myList });
Run Code Online (Sandbox Code Playgroud)

这里有两个问题:

  1. 在第二行,而不是提供typeof(int),我希望提供类似于somthign myList.GetType().GetGenericArguments()[0].GetType(),以使事情更灵活,因为我T直到运行时才知道.当Invoke运行时,执行此操作会导致运行时错误,如下所示:"System.Collections.Generic.List'1 [System.Int32]类型的对象'无法转换为类型'System.Collections.Generic.List'1 [ System.RuntimeType]"."
  2. Invoke()方法的结果返回一个对象.在调试时,我可以看到该对象是List类型,但是尝试使用它告诉我,我有一个无效的强制转换.我假设我需要使用反射将结果打包到正确的类型(即在此示例中,相当于(result as List<int>).

有没有人有任何可以帮我解决这个问题的指针?如果不清楚,我可能会道歉,如果被问到,我可能会提供更多细节.

TIA

Ben*_*igt 5

你有一个GetType()太多了.发生在所有人身上.

myList.GetType().GetGenericArguments()[0]是一个System.Type- 你正在寻找的那个.

myList.GetType().GetGenericArguments()[0].GetType()是一个System.Type描述System.Type(嗯,实际上是具体的子类System.RuntimeType).


此外,你的ReverseList功能是严重的矫枉过正.它只是为了避免调用而做一个额外的副本List.Reverse.有一种更好的方法来规避:

public static List<T> ReverseList<T>(List<T> sourceList)
{
    return Enumerable.Reverse(sourceList).ToList();
}
Run Code Online (Sandbox Code Playgroud)

要么

public static List<T> ReverseList<T>(List<T> sourceList)
{
    var result = new List<T>(sourceList);
    result.Reverse();
    return result;
}
Run Code Online (Sandbox Code Playgroud)

要么

public static List<T> ReverseList<T>(List<T> sourceList)
{
    var result = new List<T>();
    result.Capacity = sourceList.Count;
    int i = sourceList.Count;
    while (i > 0)
        result.Add(sourceList[--i]);
    return result;
}
Run Code Online (Sandbox Code Playgroud)