56553

Getting generic arguments from a class in the stack

Question:

I have a generic class called Repository. This class has a function that "calls itself" by initializing a new instance of the Repository class with a different generic argument. This "recursion" can go on - so to avoid StackOverflowException, i need to check if there is in the stack, a method called from the Repository class with the same generic 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 always returns as T and not the correct type like "User" or "Employee" (for example). I can't compare the names of the types because T does not have a name.

Answer1:

Don't think that this is possible, because you only get the GenericType, but not the real GenericArguments of the class.

If you look at the return of frame.GetMethod().DeclaringType you'll notice, that only the GenericType, but not the real GenericArguments are within the debugging result.

Answer2:

As the posted comment suggest using StackFrame is bit tricky and error prone. Also I'm not sure if you would be able to get the info about the closed type of the generic type.

But you could follow another approach where in you maintain the List<Type> that have already been processed. Below are two versions of the method CreateRepository which I assume is the method that you might be using to create item 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(); }

Answer3:

try this

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

Recommend

  • MessageBodyReader/Writer for Generic class
  • Property / field initializers in code generation
  • Get property value of instance of generic type's argument
  • EntityType has no key defined. [Key] is presented
  • run a php script( or anything similar) from greasemonkey/tampermonkey
  • text along curvature path like circular or arc in silverlight
  • Alternative JSF implementation with JBoss 71
  • Using JS to get a particular entity
  • tag semantic alternative usage
  • Show list in AlertDialog [duplicate]
  • MapReduce error when selecting column from JSON file in Cosmos
  • Round brackets not showing up correctly in RightToLeft flow direction in WPF
  • WebView: webpage not available but I load it from an html string
  • Paypal reports email address already taken when trying to import test accounts into Paypal Developer
  • How to use Xcode Extract refactoring feature?
  • SVG .end event not working?
  • printout webpage with @font-face
  • selectInput can't populate duplicate values (using uiOutput and renderUI) in Shiny
  • What do internal compiler error messages mean, and what can I do?
  • MySQL diacritic insensitive search (Arabic)
  • setImageData fails in iOS 8.3
  • Using Xcode Playground captureValue()
  • how to limit tornado websocket message size
  • C++ exception safety paranoia: how much is too much?
  • ASP.NET MVC - CSS Class in a ViewUserControl - The class or CssClass is not defined
  • An unexpected error has been detected by HotSpot Virtual Machine
  • iPhone - UIWebView multiple locks
  • How to get to older Xcode beta version?
  • Safari PHP form submission -file upload hangs
  • How to fail Phing without triggering backtrace
  • Linq Full Outer Join on Two Objects
  • How to get the index of element in the List in c#
  • Autohotkey script running program with command line arguments
  • Does the MySQL IN clause execute the subquery multiple times?
  • How dotnet build chooses the output name
  • hide missing dates from x-axis ggplot2
  • Time complexity of a program which involves multiple variables
  • Illegal mix of collations for operation for date/time comparison
  • RectangularRangeIndicator format like triangular using dojo
  • MySQL WHERE-condition in procedure ignored