C#扩展方法知多少
2017-08-23 16:29
204 查看
当我们想为一个现有的类型添加一个方法的时候,有两种方式:一是直接在现有类型中添加方法;但是很多情况下现有类型都是不允许修改的,那么可以使用第二种方式,基于现有类型创建一个子类,然后在子类中添加想要的方法。
当C# 2.0中出现了静态类之后,对于上面的问题,我们也可以创建静态工具类来实现想要添加的方法。这样做可以避免创建子类,但是在使用时代码就没有那么直观了。
其实,上面的方法都不是很好的解决办法。在C# 3.0中出现了扩展方法,通过扩展方法我们可以直接在一个现有的类型上"添加"方法。当使用扩展方法的时候,可以像调用实例方法一样的方式来调用扩展方法。
它必须在一个非嵌套、非泛型的静态类中(所以扩展方法一定是静态方法)
它至少要有一个参数
第一个参数必须加上this关键字作为前缀,且第一个参数类型也称为扩展类型(extended type),表示该方法对这个类型进行扩展
第一个参数不能用其他任何修饰符(比如out或ref)
第一个参数的类型不能是指针类型
根据上面的要求,我们给int类型添加了一个扩展方法,用来判断一个int值是不是偶数:
View Code
这样看上去就像在扩展.Net Framework。有没有感觉有点高大上~
2、一般对象的扩展方法
和Framework内置对象一样,自定义的对象也可以增加扩展方法。直接上示例代码:
Main方法里面调用:
和string扩展方法类似,就不多做解释了。
3、泛型对象的扩展方法
除了上面两种之外,博主发现其实可以定义一个泛型的扩展方法。那么,是不是所有的类型都可以直接使用这个扩展方法了呢?为了保持程序的严谨,下面的方法可能没有实际意义,当开发中博主觉得可能存在这种场景:
使用扩展方法有几个值得注意的地方:
(1)扩展方法不能和调用的方法放到同一个类中
(2)第一个参数必须要,并且必须是this,这是扩展方法的标识。如果方法里面还要传入其他参数,可以在后面追加参数
(3)扩展方法所在的类必须是静态类
(4)最好保证扩展方法和调用方法在同一个命名空间下
可能你第一次使用这个会觉得很别扭。你也许会说扩展方法和我以前用的static方法无论从代码实现还是算法效率都差不多嘛,是的!确实差不多,但使用多了之后会发现它确实能帮你省去很多代码。
出处:http://www.cnblogs.com/landeanfen/p/4632467.html
===========================================================================================
另外参考微软的说明文档:
扩展方法(C# 编程指南)
如何:实现和调用自定义扩展方法(C# 编程指南)
如何:为枚举创建新方法(C# 编程指南)
当C# 2.0中出现了静态类之后,对于上面的问题,我们也可以创建静态工具类来实现想要添加的方法。这样做可以避免创建子类,但是在使用时代码就没有那么直观了。
其实,上面的方法都不是很好的解决办法。在C# 3.0中出现了扩展方法,通过扩展方法我们可以直接在一个现有的类型上"添加"方法。当使用扩展方法的时候,可以像调用实例方法一样的方式来调用扩展方法。
扩展方法的使用
扩展方法的创建和使用还是相对比较简单的。声明扩展方法
相比普通方法,扩展方法有它自己的特征,下面就来看看怎么声明一个扩展方法:它必须在一个非嵌套、非泛型的静态类中(所以扩展方法一定是静态方法)
它至少要有一个参数
第一个参数必须加上this关键字作为前缀,且第一个参数类型也称为扩展类型(extended type),表示该方法对这个类型进行扩展
第一个参数不能用其他任何修饰符(比如out或ref)
第一个参数的类型不能是指针类型
根据上面的要求,我们给int类型添加了一个扩展方法,用来判断一个int值是不是偶数:
//DataGridViewRow的扩展方法,将当前选中行转换为对应的对象 public static T ToObject<T>(this DataGridViewRow item) where T:class { var model = item.DataBoundItem as T; if (model != null) return model; var dr = item.DataBoundItem as System.Data.DataRowView; model = (T)typeof(T).GetConstructor(new System.Type[] { }).Invoke(new object[] { });//反射得到泛型类的实体 PropertyInfo[] pro = typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.Public); Type type = model.GetType(); foreach (PropertyInfo propertyInfo in pro) { if (Convert.IsDBNull(dr[propertyInfo.Name])) { continue; } if (!string.IsNullOrEmpty(Convert.ToString(dr[propertyInfo.Name]))) { var propertytype = propertyInfo.PropertyType; } } return model; }
View Code
这样看上去就像在扩展.Net Framework。有没有感觉有点高大上~
2、一般对象的扩展方法
和Framework内置对象一样,自定义的对象也可以增加扩展方法。直接上示例代码:
public class Person { public string Name { set; get; } public int Age { set; get; } }
//Person的扩展方法,根据年龄判断是否是成年人 public static bool GetBIsChild(this Person oPerson) { if (oPerson.Age >= 18) return false; else return true; }
Main方法里面调用:
var oPerson1 = new Person(); oPerson1.Age = 20; var bIsChild = oPerson1.GetBIsChild();
和string扩展方法类似,就不多做解释了。
3、泛型对象的扩展方法
除了上面两种之外,博主发现其实可以定义一个泛型的扩展方法。那么,是不是所有的类型都可以直接使用这个扩展方法了呢?为了保持程序的严谨,下面的方法可能没有实际意义,当开发中博主觉得可能存在这种场景:
public static class DataContractExtensions { //测试方法 public static T Test<T>(this T instance) where T : Test2 { T Res = default(T); try { Res.AttrTest = instance.AttrTest.Substring(0,2); //其他复杂逻辑... } catch { } return Res; } } public class Test2 { public string AttrTest { set; get; } }
使用扩展方法有几个值得注意的地方:
(1)扩展方法不能和调用的方法放到同一个类中
(2)第一个参数必须要,并且必须是this,这是扩展方法的标识。如果方法里面还要传入其他参数,可以在后面追加参数
(3)扩展方法所在的类必须是静态类
(4)最好保证扩展方法和调用方法在同一个命名空间下
可能你第一次使用这个会觉得很别扭。你也许会说扩展方法和我以前用的static方法无论从代码实现还是算法效率都差不多嘛,是的!确实差不多,但使用多了之后会发现它确实能帮你省去很多代码。
出处:http://www.cnblogs.com/landeanfen/p/4632467.html
===========================================================================================
另外参考微软的说明文档:
扩展方法(C# 编程指南)
如何:实现和调用自定义扩展方法(C# 编程指南)
如何:为枚举创建新方法(C# 编程指南)
相关文章推荐
- C#扩展方法知多少
- C#扩展方法知多少
- C#扩展方法知多少
- C# 扩展方法
- C# 3.0 新特性:扩展方法初探(转)
- C#笔记 -----扩展方法
- c# 扩展方法学习
- C# 3.0 新特性 学习(二):匿名类型、扩展方法
- c#扩展方法奇思妙用高级篇二:Aggregate扩展其改进
- C#扩展方法
- C# 的扩展方法在 LINQ 中实现数组排序
- C# 扩展方法验证居民身份证
- C#==>扩展方法
- C# 扩展方法简介
- 关于C#中”扩展方法必须在非泛型静态类中定义“问题的解决
- C#中的扩展方法学习总结
- C#语法之扩展方法
- 【原创】开源Math.NET基础数学类库使用(12)C#随机数扩展方法
- C#的扩展方法解析
- [C# 基础知识系列]专题十五:全面解析扩展方法