栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > .Net

c# 判断 泛型t 类型

.Net 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

c# 判断 泛型t 类型

.NET 中提供了很多判断某个类型或实例是某个类的子类或某个接口的实现类的方法,然而这事情一旦牵扯到泛型就没那么省心了。

本文将提供判断泛型接口实现或泛型类型子类的方法。

.NET 中没有自带的方法

对于实例,.NET 中提供了这些方法来判断:

if (instance is Foo || instance is IFoo)

{

}

对于类型,.NET 中提供了这些方法来判断:

if (typeof(Foo).IsAssignableFrom(type) || typeof(IFoo).IsAssignableFrom(type))

{

}

或者,如果不用判断接口,只判断类型的话:

if (type.IsSubClassOf(typeof(Foo)))

{

}

对于 typeof 关键字,不止可以写 typeof(Foo) ,还可以写 typeof(Foo<>) 。这可以得到泛型版本的 Foo 的类型。

不过,如果你试图拿这个泛型版本的 typeof(Foo<>) 执行上述所有判断,你会发现所有的 if 条件都会是 false 。

我们需要自己编写方法

typeof(Foo<>) 和 typeof(Foo) 之间的关系就是 GetGenericTypeDefinition 函数带来的关系。

所以我们可以充分利用这一点完成泛型类型的判断。

比如,我们要判断接口:

public static bool HasImplementedRawGeneric(this Type type, Type generic)

{

// 遍历类型实现的所有接口,判断是否存在某个接口是泛型,且是参数中指定的原始泛型的实例。

return type.GetInterfaces().Any(x => generic == (x.IsGenericType ? x.GetGenericTypeDefinition() : x));

}

而如果需要判断类型,那么就需要遍历此类的基类了:

public static bool IsSubClassOfRawGeneric([NotNull] this Type type, [NotNull] Type generic)

{

if (type == null) throw new ArgumentNullException(nameof(type));

if (generic == null) throw new ArgumentNullException(nameof(generic));

while (type != null && type != typeof(object))

{

isTheRawGenericType = IsTheRawGenericType(type);

if (isTheRawGenericType) return true;

type = type.BaseType;

}

return false;

bool IsTheRawGenericType(Type test)

=> generic == (test.IsGenericType ? test.GetGenericTypeDefinition() : test);

}

于是,我们可以把这两个方法合成一个,用于实现类似 IsAssignableFrom 的效果,不过这回将支持原始接口(也就是 typeof(Foo<>) )。

///

/// 判断指定的类型 是否是指定泛型类型的子类型,或实现了指定泛型接口。

///

/// 需要测试的类型。

/// 泛型接口类型,传入 typeof(IXxx<>)

/// 如果是泛型接口的子类型,则返回 true,否则返回 false。

public static bool HasImplementedRawGeneric([NotNull] this Type type, [NotNull] Type generic)

{

if (type == null) throw new ArgumentNullException(nameof(type));

if (generic == null) throw new ArgumentNullException(nameof(generic));

// 测试接口。

var isTheRawGenericType = type.GetInterfaces().Any(IsTheRawGenericType);

if (isTheRawGenericType) return true;

// 测试类型。

while (type != null && type != typeof(object))

{

isTheRawGenericType = IsTheRawGenericType(type);

if (isTheRawGenericType) return true;

type = type.BaseType;

}

// 没有找到任何匹配的接口或类型。

return false;

// 测试某个类型是否是指定的原始接口。

bool IsTheRawGenericType(Type test)

=> generic == (test.IsGenericType ? test.GetGenericTypeDefinition() : test);

}

本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名 吕毅 (包含链接: https://walterlv.github.io ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系 。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/906880.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号