从堆栈中的类获取泛型参数

时间:2011-06-06 10:49:53

标签: c# generics reflection stack-trace

我有一个名为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没有名称。

3 个答案:

答案 0 :(得分:2)

由于发布的评论建议使用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();
        }

答案 1 :(得分:0)

试试这个

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

答案 2 :(得分:0)

不要认为这是可能的,因为你只获得了GenericType,而不是该类的真正GenericArguments。

如果你看一下frame.GetMethod()。DeclaringType的返回,你会注意到,只有GenericType,而不是真正的GenericArguments都在调试结果中。