Type 类提供了大量的属性和方法,但在一些基础性开发工作中,Type类功能还有些欠缺,尤其上在处理泛型类型时,如可空类型和泛型集合类型。下面的类就针对这些地方进行扩展。

 1     public static class TypeHelper
 2     {
 3         public static bool IsNullableType(this Type type)
 4         {
 5             return (((type != null) && type.IsGenericType) && 
 6                 (type.GetGenericTypeDefinition() == typeof(Nullable<>)));
 7         }
 8 
 9         public static Type GetNonNullableType(this Type type)
10         {
11             if (IsNullableType(type))
12             {
13                 return type.GetGenericArguments()[0];
14             }
15             return type;
16         }
17 
18         public static bool IsEnumerableType(this Type enumerableType)
19         {
20             return (FindGenericType(typeof(IEnumerable<>), enumerableType) != null);
21         }
22 
23         public static Type GetElementType(this Type enumerableType)
24         {
25             Type type = FindGenericType(typeof(IEnumerable<>), enumerableType);
26             if (type != null)
27             {
28                 return type.GetGenericArguments()[0];
29             }
30             return enumerableType;
31         }
32 
33         public static bool IsKindOfGeneric(this Type type, Type definition)
34         {
35             return (FindGenericType(definition, type) != null);
36         }
37 
38         public static Type FindGenericType(this Type definition, Type type)
39         {
40             while ((type != null) && (type != typeof(object)))
41             {
42                 if (type.IsGenericType && (type.GetGenericTypeDefinition() == definition))
43                 {
44                     return type;
45                 }
46                 if (definition.IsInterface)
47                 {
48                     foreach (Type type2 in type.GetInterfaces())
49                     {
50                         Type type3 = FindGenericType(definition, type2);
51                         if (type3 != null)
52                         {
53                             return type3;
54                         }
55                     }
56                 }
57                 type = type.BaseType;
58             }
59             return null;
60         }
61     }

从名字上就以大体知道方法的功能,下面是部分测试代码,帮助大家理解:

 1     [TestMethod()]
 2     public void IsNullableTypeTest()
 3     {
 4         Assert.AreEqual(true, TypeExtension.IsNullableType(typeof(int?)));
 5         Assert.AreEqual(false, TypeExtension.IsNullableType(typeof(int)));
 6         Assert.AreEqual(true, TypeExtension.IsNullableType(typeof(Nullable<DateTime>)));
 7         Assert.AreEqual(false, TypeExtension.IsNullableType(typeof(DateTime)));
 8     }
 9     [TestMethod()]
10     public void GetNonNullableTypeTest()
11     {
12         Assert.AreEqual(typeof(int), TypeExtension.GetNonNullableType(typeof(int?)));
13         Assert.AreEqual(typeof(DateTime), TypeExtension.GetNonNullableType(typeof(Nullable<DateTime>)));
14     }
15     [TestMethod()]
16     public void IsEnumerableTypeTest()
17     {
18         Assert.AreEqual(true, TypeExtension.IsEnumerableType(typeof(IEnumerable<string>)));
19         Assert.AreEqual(true, TypeExtension.IsEnumerableType(typeof(Collection<int>)));
20     }
21     [TestMethod()]
22     public void GetElementTypeTest()
23     {
24         Assert.AreEqual(typeof(int), TypeExtension.GetElementType(typeof(IEnumerable<int>)));
25         Assert.AreEqual(typeof(DateTime), TypeExtension.GetElementType(typeof(Collection<DateTime>)));
26     }
27     [TestMethod()]
28     public void IsKindOfGenericTest()
29     {
30         Assert.AreEqual(true, TypeExtension.IsKindOfGeneric(typeof(List<string>), typeof(IEnumerable<>)));
31         Assert.AreEqual(true, TypeExtension.IsKindOfGeneric(typeof(string), typeof(IComparable<>)));
32     }
33     [TestMethod()]
34     public void FindGenericTypeTest()
35     {
36         Assert.AreEqual(typeof(IEnumerable<string>),
37         TypeExtension.FindGenericType(typeof(IEnumerable<>), typeof(List<string>)));
38     }

代码就是最好的文档,想必大家已经都看明白了。

TypeHelper 是我从一个类库中提取的,它原本是一个 internal static class,内部的方法同样 internal static 。我仅仅是把 internal 改成了 public ,并在每个方法的第一个参数前加了个 this,最后给类中的方法按从简到难的顺序进行了排序。

也许是因为 TypeHelper 是一个内部类,并有强烈的应用语境,TypeHelper 并没有采用契约式编程的方式,甚至在命名上也做了一些省略: 如 IsEnumerableType、GetElementType 两个方法是实际是用来处理泛型集合类型的,但在方法名和参数名上并没有“Generic”的字眼。(如果传入非泛型类型或其它类型,将会产生难以预料的结果或异常。)

像这样简单将内部静态类 TypeHelper 中的静态方法公开为扩展方法是存在问题的,所以在应用之前,还得再做些工作。改进成为契约式编程的方式并不难,难的是给扩展方法起一个清晰明了简单易懂的名字,否则就不要扩展了。IsEnumerableType、GetElementType 应该体现出是对泛型集合进行操作,简单加上Generic字样后名字好长,也不好理解。(大家如果能想出好的名字,请发在回复中,不胜感激!)

另外在使用时,我发现两处“奇怪”的地方,如下图:

调试至此处,type1为空,type2则是一个少见的奇怪类型。

TypeHelper 的出处我会在下一篇随笔中进行说明。

本人系列文章《c#扩展方法奇思妙用》,敬请关注!

转载于:https://www.cnblogs.com/China-Dragon/archive/2010/05/12/1733494.html

c#扩展方法奇思妙用高级篇八:Type类扩展相关推荐

  1. c#扩展方法奇思妙用高级篇四:对扩展进行分组管理

    从系列文章开篇到现在,已经实现的很多扩展了,但过多的扩展会给我们带来很多麻烦,试看下图: 面对这么多"泛滥"的扩展,很多人都会感到很别扭,的确有种"喧宾夺主"的 ...

  2. c# 扩展方法奇思妙用基础篇八:Distinct 扩展(转载)

    转载地址:http://www.cnblogs.com/ldp615/archive/2011/08/01/distinct-entension.html 刚看了篇文章 <Linq的Distin ...

  3. c#扩展方法奇思妙用高级篇七:“树”通用遍历器

    我的上一篇随笔<c#扩展方法奇思妙用高级篇六:WinForm 控件选择器>中给出了一个WinForm的选择器,其实质就是一个"树"的遍历器,但这个遍历局限于WinFor ...

  4. c# 扩展方法奇思妙用高级篇一:改进 Scottgu 的 In 扩展

    先看下ScottGu对In的扩展: 调用示例1: 调用示例2: 原文地址:New "Orcas" Language Feature: Extension Methods 很多介绍扩 ...

  5. C#扩展方法奇思妙用高级篇一:改进 Scottgu 的 In 扩展

    先看下ScottGu对In的扩展: 调用示例1: 调用示例2: 原文地址:New "Orcas" Language Feature: Extension Methods 很多介绍扩 ...

  6. c# 扩展方法奇思妙用高级篇六:WinForm 控件选择器

    在Web开发中,jQuery提供了功能异常强大的$选择器来帮助我们获取页面上的对象.但在WinForm中,.Net似乎没有这样一个使用起来比较方便的选择器.好在我们有扩展方法,可以很方便的打造一个. ...

  7. c# 扩展方法奇思妙用高级篇五:ToString(string format) 扩展

    在.Net中,System.Object.ToString()是用得最多的方法之一,ToString()方法在Object类中被定义为virtual,Object类给了它一个默认实现: 1     p ...

  8. c# 扩展方法奇思妙用变态篇四:string 的翻身革命

    string是各种编程语言中最基础的数据类型,长期以来受尽其它类的压迫,经常被肢解(Substring.Split).蹂躏(Join)... 而现在string要"翻身闹革命"了, ...

  9. c#扩展方法奇思妙用变态篇四:string 的翻身革命

    string是各种编程语言中最基础的数据类型,长期以来受尽其它类的压迫,经常被肢解(Substring.Split).蹂躏(Join)... 而现在string要"翻身闹革命"了, ...

最新文章

  1. 智能车百度赛道培训第一弹-基础篇
  2. PowerShell实现批量收集SCVMM中虚拟机IP-续
  3. CoreAnimation (CALayer 动画)
  4. 一文看懂数据预处理最重要的3种思想和方法
  5. SQL对字符串进行排序
  6. LeetCode-Clone Graph-克隆无向图
  7. 用python 画炫酷的图并讲解-Python绘制六种可视化图表详解,三维图最炫酷!你觉得呢?...
  8. 5.VMware View 5.0安装与部署-安装view agent与模版
  9. 安卓获取签名证书SHA1值
  10. 三菱Q系列plc串口通讯四台台达变频器通讯程序
  11. 在外通过手机远程控制家中或者公司的电脑
  12. 使用批处理解决U盘内出现的同名文件夹EXE病毒问题
  13. 分享一张职场学习必备的工作法思维导图
  14. 在idea中如何设置项目编码为UTF-8?
  15. 【大学生软件测试基础】三角形类型 - 白盒测试 - 语句覆盖 -02
  16. 音标课件软件测试,宝宝益智英语字母音标(测试版)
  17. js事件冒泡、阻止事件冒泡以及阻止默认行为
  18. 抖音SEO优化源码,企业号搜索排名系统,矩阵分发。
  19. 若依微服务框架ruoyi-cloud使用手册(持续更新中)
  20. 医院临床信息管理系统

热门文章

  1. 【前端】vue Unknown custom element: xxxx did you register the component correctly
  2. 【Kafka】Kafka如何彻底删除Kafka中的topic
  3. javacc解析json报错
  4. 60-300-022-使用-延迟数据-Flink中allowedLateness详细介绍
  5. 【Calcite】SQL 形式化语言——关系代数
  6. 【impala】impala的shell命令使用
  7. intellij idea如何打包
  8. ElasticSearch 比 MySQL 更适合复杂条件搜索
  9. shell编程之awk
  10. ubuntu15.10 gvim php,IDE---Gvim之ubuntu下配置php的ide开发工具