【问题标题】:Understanding this function that returns Type object理解这个返回 Type 对象的函数
【发布时间】:2013-05-04 13:09:45
【问题描述】:

我有一个很酷的方法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 方法实际上返回了什么吗?

奖励:建议我为该方法取一个恰当的名称:)

【问题讨论】:

  • 看起来,如果孩子和父母都是泛型但类型不同(例如List<String> vs List<int>),则该方法旨在制作相同的泛型类型(List<>)所以可以更准确地比较它们。
  • 现在与Type.IsAssignableFrom 方法有什么区别?!
  • 我已经回答了你关于 GetBlah 方法的问题,但你想做什么?已经有一个Type.IsAssignableFrom 方法。您是否还想知道List<int> 是否源自List<>?如果您需要帮助,请发布第二个问题(并使用新链接给我评论!):)
  • @Patashu 这听起来像是正确的答案,你能把它作为答案吗?
  • @user287107 有什么区别? IsOf 方法?还是GetBlah 方法?

标签: c# generics inheritance reflection types


【解决方案1】:

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

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

所以,如果你愿意:

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

你会得到typeof(List&lt;&gt;)

到目前为止的理论!

如果正确分析您的代码,它将返回 true 的 child 派生自 parent。所以我做了一个小清单,说明哪种类型组合应该返回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(...)

:)

【讨论】:

  • 马丁,我认为你没有回答我的问题。我知道这些分别是什么意思。我不明白的是它们在代码中的相关性。换句话说,他们通过GetBlah 方法服务于什么目的。我认为@Patashu 把它很好地放在了 cmets 中。要获得GetPossibleGenericTypeDefinition,我需要做的就是child.IsGenericTypeDefinition ? child.GetGenericTypeDefinition() : child,但该方法中也有parent 参数并且它在那里做某事。我不明白那个论点的相关性——这就是我的问题所在。
猜你喜欢
  • 1970-01-01
  • 2018-01-01
  • 1970-01-01
  • 2010-09-30
  • 1970-01-01
  • 1970-01-01
  • 2020-04-23
  • 1970-01-01
  • 2017-12-05
相关资源
最近更新 更多