我有一个名为Repository的泛型类。这个类有一个函数,它通过使用不同的泛型参数初始化Repository类的新实例来"调用自己"。这种"递归"可以继续下去,所以为了避免StackOverflowException,我需要检查堆栈中是否存在,一个从Repository类调用的具有相同泛型参数的方法。这是我的代码:
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;
}
}
}
泛型类型总是返回为T,而不是正确的类型,例如"User"或"Employee"。我无法比较类型的名称,因为t没有名称。
正如发布的评论所暗示的那样,使用StackFrame有点棘手且容易出错。此外,我不确定您是否能够获得有关泛型类型的封闭类型的信息。
但是,您可以采用另一种方法,在中维护已经处理过的List<Type>
。下面是方法CreateRepository
的两个版本,我认为它是您可能用于创建项目存储库的方法。
private static List<Type> addedItemList; has the info of all the created types so far.
版本-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);
}
版本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();
}
不要认为这是可能的,因为你只得到了GenericType,而没有得到类的真正GenericArguments。
如果你看帧的返回。你会注意到,调试结果中只有GenericType,而不是真正的GenericArguments。
尝试这个
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;
}