我有一个很酷的方法来检查一个类型是否从另一个类型派生。当我重构代码的时候,我得到了这个块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<int>
或List<string>
。它们都使用相同的泛型类型定义:List<>
.
IsGenericType
将返回true
类型是泛型类型。如果类型是泛型类型定义,IsGenericTypeDefinition
应该返回true。函数GetGenericTypeDefinition
将返回泛型类型的泛型类型定义。
那么,如果你这样做:
typeof(List<int>).GetGenericTypeDefinition();
你会得到typeof(List<>)
。
理论到此为止!
如果正确分析您的代码,它将返回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-condition修改为:
while (currentChild != null)
现在进入Blah
函数。它所做的是检查父类是否是泛型类型定义。任何"正常"类(无论是否泛型)都不能从泛型类型定义派生。只有泛型类型定义可以从另一个泛型类型定义派生。为了使情形G和H成立,需要做一个特殊的转换。如果父类是泛型类型定义,并且当子类可以转换为泛型类型定义时,则子类将转换为其泛型类型定义。
这就是它的全部功能。
所以你的函数的完美名称可以是:ConvertChildToGenericTypeDefinitionIfParentIsAGenericTypeDefinitionAndTheChildIsAGenericType(...)
:)