Casting using Reflection in C #

I created a generic function, as shown below (just a proof), which will take the List<T> collection and cancel it, returning a new List<T> .

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

The purpose of the proof is that I only know that T at runtime. Therefore, I use reflection to call the above method as follows:

 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 }); 

There are two problems here:

  • In the second line, instead of supplying typeof(int) , I would like to ask somdign akin to myList.GetType().GetGenericArguments()[0].GetType() to make things more flexible, because I don't know T until time execution. This causes a runtime error when Invoke works as follows: "An object of type" System.Collections.Generic.List'1 [System.Int32] "cannot be converted to a type of" System.Collections.Generic.List'1 [System. RuntimeType]. "
  • The result of the Invoke() method returns an object. When debugging, I see that the object is of type List, but trying to use it tells me that I have an invalid cast. I assume that I need to use reflection to give the result to the correct type (i.e., in this example, the equivalent (result as List<int> ).

Does anyone have pointers that could help me resolve this? Sorry, if this is not cleared, I may possibly provide more detailed information if asked.

TIA

+4
source share
3 answers

The result of the Invoke () method returns an object. When debugging, I can see that the object is of type List, but trying to use it to me that I have an invalid cast. I suppose I need to use reflection to insert the result into the correct type (that is, in this example the equivalent (the result is a list).

The only workaround for this I might think is to pass an empty list as the second parameter of the method and populate this list - the link returned by Invoke() will always be an object of type, but inside the general method you have access to the type itself:

 List<int> reverseList = new List<int>(); resultMethod.Invoke(null, new object[] { myList, reverseList }); 

...

 public static void ReverseList<T>(List<T> sourceList, List<T> resultList) { T[] outputArray = new T[sourceList.Count]; sourceList.CopyTo(outputArray); resultList.AddRange(outputArray.Reverse()); } 
+1
source

You have one GetType() too much. It happens to everyone.

myList.GetType().GetGenericArguments()[0] IS a System.Type is the one you are looking for.

myList.GetType().GetGenericArguments()[0].GetType() is a System.Type describing System.Type (well, actually, a specific subclass of System.RuntimeType ).


In addition, your ReverseList function is a serious overkill. It makes an extra copy to avoid calling List.Reverse . There's a better way around this:

 public static List<T> ReverseList<T>(List<T> sourceList) { return Enumerable.Reverse(sourceList).ToList(); } 

or

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

or

 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; } 
+5
source

To access it as a List<T> , yes, you will need to find T using reflection (possibly over interfaces like typeof(IList<>) ), and use more reflections and MakeGenericMethod, etc. Apparently, this is not worth it: you better check out the non-generic IList :

 var list = result as IList; if (list != null) { // loop over list etc } 

Reflections on ad announcements are not good friends.

Note in 4.0 there are also some tricks you can do here with dynamic and generics.

+3
source

Source: https://habr.com/ru/post/1341666/


All Articles