理解这个返回Type对象的函数

时间:2013-05-09 22:33:32

标签: c# generics inheritance reflection types

我有一个很酷的方法here来检查一个类型是否来自另一个。当我重构代码时,我得到了这个块GetBlah

public static bool IsOf(this Type child, Type parent)
{
    var currentChild = child.GetBlah(parent);

    while (currentChild != typeof(object))
    {
        if (parent == currentChild)
            return true;

        if(currentChild.GetInterfaces().Any(i => i.GetBlah(parent) == parent))
            return true;

        if (currentChild.BaseType == null)
            return false;

        currentChild = currentChild.BaseType.GetBlah(parent);
    }

    return false;
}

static Type GetBlah(this Type child, Type parent)
{
    return child.IsGenericType && parent.IsGenericTypeDefinition 
         ? child.GetGenericTypeDefinition() 
         : child;
}

我无法理解GetBlah的作用,因此无法给出正确的名称。我的意思是我可以理解三元表达式和GetGenericTypeDefinition函数,但我似乎没有在IsOf方法中使用它,特别是正在传递的parent参数。有人能够阐明GetBlah方法实际返回的内容吗?

奖励:建议我使用该方法的合适名称:)

1 个答案:

答案 0 :(得分:3)

通用类型类似于List<int>List<string>。它们都使用相同的泛型类型定义:List<>

IsGenericType将返回true,类型是泛型类型。 如果类型是泛型类型定义IsGenericTypeDefinition应该返回true。 函数GetGenericTypeDefinition将返回泛型类型的泛型类型定义。

所以,如果你愿意的话:

typeof(List<int>).GetGenericTypeDefinition();

你会得到typeof(List<>)

迄今为止的理论!

如果正确分析您的代码,child派生自parent将返回true。所以我做了一个小清单,列出哪个类型组合应该返回true(在我看来):

A: int, IComparable<int>
B: int, ValueType
C: int, object
D: List<int>, IList<int>
E: List<int>, IEnumerable<int>
F: List<int>, object

G: List<int>, List<>
H: List<int>, IList<>
I: List<>, IList<>
J: List<>, object

给定代码在某一时刻失败:每次parent类型为object时,都会返回false。通过将while条件修改为:

可以轻松解决此问题
while (currentChild != null)

现在到你的Blah - 功能。做什么是检查父是否是泛型类型定义。没有“普通”类(通用或非通用)可以从泛型类型定义派生。只有泛型类型定义才能从另一个泛型类型定义派生。因此,为了让案例G和H成为现实,必须进行特殊的转换。如果父类是泛型类型定义,并且当子类可以转换为泛型类型定义时,则子类将转换为其泛型类型定义。

这就是它所做的一切。

因此,您的功能的完美名称可能是:ConvertChildToGenericTypeDefinitionIfParentIsAGenericTypeDefinitionAndTheChildIsAGenericType(...)

:)