Getting common arguments from a class on the stack

I have a general class called Repository. This class has a function that "calls itself", initializing a new instance of the repository class with another common argument. This "recursion" can continue, therefore, to avoid a StackOverflowException, I need to check if there is a method on the stack called from the Repository class with the same general argument. here is my code:

StackTrace stack = new StackTrace(); StackFrame[] frames = stack.GetFrames(); foreach (StackFrame frame in frames) { Type callingMethodClassType = frame.GetMethod().DeclaringType; if (callingMethodClassType.IsGenericType) { // BUG HERE in getting generic arguments of the class in stack Type genericType = callingMethodClassType.GetGenericArguments()[0]; if (genericType.Equals(entityType)) { wasAlready = true; break; } } } 

the generic type is always returned as T, and not the correct type of type "User" or "Employee" (for example). I cannot compare type names because T has no name.

+3
source share
3 answers

Do not think that this is possible, because you get only GenericType, but not real GenericArguments of this class.

If you look at the return frame.GetMethod (). DeclaringType, you will notice that the debugging result contains only GenericType, but not real GenericArguments.

0
source

As the comments say, using a StackFrame is a bit more complicated and error prone. Also, I'm not sure if you can get information about the private type of the generic type.

But you could follow a different approach when you maintain List<Type> which are already processed. Below are two versions of the CreateRepository method that I assume is a method that you can use to create element repositories.

 private static List<Type> addedItemList; has the info of all the created types so far. 

Version - 1

  public static Repository<T> CreateRepository(T item) { if (addedItemList.Contains<Type>(item.GetType())) { return new Repository<T> { Item = item }; } addedItemList.Add(item.GetType()); return CreateRepository(item); } 

Version 2

  public static Repository<T> CreateRepository() { if (addedItemList.Contains<Type>(typeof(T))) { return new Repository<T> { Item = default(T) }; } addedItemList.Add(typeof(T)); return CreateRepository(); } 
+2
source

try it

 StackTrace stack = new StackTrace(); StackFrame[] frames = stack.GetFrames(); foreach (StackFrame frame in frames) { Type callingMethodClassType = frame.GetMethod().DeclaringType; if (callingMethodClassType.IsGenericType) { // BUG HERE in getting generic arguments of the class in stack Type genericType = callingMethodClassType.GetGenericArguments()[0]; if (genericType.GetFullName.Equals(entityType.GetFullName)) { wasAlready = true; break; } } } private static String GetFullName<T>(this T type) { return typeof(T).FullName; } 
0
source

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


All Articles