C#3.0扩展方法学习篇
扩展方法使您能够向现有类型“添加”方法,而无需创建新的派生类型、重新编译或以其他方式修改原始类型。
MSDN
Extension methods enable you to "add" methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type. Extension methods are a special kind of static method, but they are called as if they were instance methods on the extended type.
传统的模式下如果想为一个类型(class)添加一个额外的自定义的特殊的逻辑上,或者业务上的新方法时,你必须重新定义的一个类型来继承原有的的方法,用继承类或者接口,但是有些用sealed修饰的,这时候就无法被继承,例如String,值类型,sealed修饰的类。
扩展方法是C#3.0这个版本提出来的。解决了必须由继承才能扩展的某个类的弊端,最重要的一点就是很好用。




注意:
扩展方法必须在非嵌套、非泛型的静态类中定义。
Note that it is defined inside a non-nested<非嵌套>, non-generic<非泛型的> static<静态> class:
扩展方法的规则有以下几点:
- 扩展方法必须是扩展方法必须是非嵌套、非泛型的静态类中定义的;
- 扩展方法的第一个参数要用this关键字修饰;
- 第一个方法参数不能有ref 或则out关键字修饰的参数;
- 引用项目的命名空间;
- 参数调用两种;
- 和传统的调用方法一样使用<ExtendClass>.<ExtendClassMethod>(参数,参数+?)
- <参数类型>.<ExtendClassMethod>(参数+?)
// Define an interface named IMyInterface.
namespace DefineIMyInterface
{
using System; publicinterface IMyInterface
{
// Any class that implements IMyInterface must define a method
// that matches the following signature.
void MethodB();
}
} // Define extension methods for IMyInterface.
namespace Extensions
{
using System;
using DefineIMyInterface; // The following extension methods can be accessed by instances of any
// class that implements IMyInterface.
publicstaticclass Extension
{
publicstaticvoid MethodA(this IMyInterface myInterface, int i)
{
Console.WriteLine
("Extension.MethodA(this IMyInterface myInterface, int i)");
} publicstaticvoid MethodA(this IMyInterface myInterface, string s)
{
Console.WriteLine
("Extension.MethodA(this IMyInterface myInterface, string s)");
} // This method is never called in ExtensionMethodsDemo1, because each
// of the three classes A, B, and C implements a method named MethodB
// that has a matching signature.
publicstaticvoid MethodB(this IMyInterface myInterface)
{
Console.WriteLine
("Extension.MethodB(this IMyInterface myInterface)");
}
}
} // Define three classes that implement IMyInterface, and then use them to test
// the extension methods.
namespace ExtensionMethodsDemo1
{
using System;
using Extensions;
using DefineIMyInterface; class A : IMyInterface
{
publicvoid MethodB() { Console.WriteLine("A.MethodB()"); }
} class B : IMyInterface
{
publicvoid MethodB() { Console.WriteLine("B.MethodB()"); }
publicvoid MethodA(int i) { Console.WriteLine("B.MethodA(int i)"); }
} class C : IMyInterface
{
publicvoid MethodB() { Console.WriteLine("C.MethodB()"); }
publicvoid MethodA(object obj)
{
Console.WriteLine("C.MethodA(object obj)");
}
} class ExtMethodDemo
{
staticvoid Main(string[] args)
{
// Declare an instance of class A, class B, and class C.
A a = new A();
B b = new B();
C c = new C(); // For a, b, and c, call the following methods:// -- MethodA with an int argument// -- MethodA with a string argument// -- MethodB with no argument.// A contains no MethodA, so each call to MethodA resolves to // the extension method that has a matching signature.
a.MethodA(); // Extension.MethodA(object, int)
a.MethodA("hello"); // Extension.MethodA(object, string)// A has a method that matches the signature of the following call// to MethodB.
a.MethodB(); // A.MethodB()// B has methods that match the signatures of the following// method calls.
b.MethodA(); // B.MethodA(int)
b.MethodB(); // B.MethodB()// B has no matching method for the following call, but // class Extension does.
b.MethodA("hello"); // Extension.MethodA(object, string)// C contains an instance method that matches each of the following// method calls.
c.MethodA(); // C.MethodA(object)
c.MethodA("hello"); // C.MethodA(object)
c.MethodB(); // C.MethodB()
}
}
}
/* Output:
Extension.MethodA(this IMyInterface myInterface, int i)
Extension.MethodA(this IMyInterface myInterface, string s)
A.MethodB()
B.MethodA(int i)
B.MethodB()
Extension.MethodA(this IMyInterface myInterface, string s)
C.MethodA(object obj)
C.MethodA(object obj)
C.MethodB()
*/




总结的结果
方法的调用次序 类型的实例方法--->当前命名空间下的扩展方法--->导入的其他命名空间扩展方法。
引发疑问
在空引用上调用实例方法或静态方法时会抛出NullReferenceException异常?那么在类调用扩展方法时会出现异常吗?(不使用类中的一些属性或方法,强调调用)
扩展方法 | 静态方法 |
TestExtend sExtend=null;
sExtend.NullUse();
|
TestExtend sExtend=null;
NullUse.(sExtend);
|


可能引发的子类污染的问题例如
你本来只想扩展TestExtend 这个类的方法,由于你要使用iSNull这个类型的扩展结果传入参数(object),结果导致所有的object 类型都扩展了这个方法,这会带来可怕的后果。
所以在扩展一个类型的方法时,要从确定类型扩展。尽量避免从父类去扩展。
有什么不对的或者错误的地方希望大家给予指正,谢谢
我的开发环境VS2015
DEMO的下载 【http://pan.baidu.com/s/1bY51P8】
C#3.0扩展方法学习篇的更多相关文章
- 为IEnumerable<T>添加RemoveAll<IEnumerable<T>>扩展方法--高性能篇
最近写代码,遇到一个问题,微软基于List<T>自带的方法是public bool Remove(T item);,可是有时候我们可能会用到诸如RemoveAll<IEnumerab ...
- C#3.0 扩展方法
扩展方法使您能够向现有类型“添加”方法,而无需创建新的派生类型.重新编译或以其他方式修改原始类型.扩展方法是一种特殊的静态方法,但可以像扩展类型上的实例方法一样进行调用.对于用 C# 和 Visual ...
- C# 3.0 扩展方法[转载]
实践 扩展方法是C# 3.0中新加入的特性.MSDN中对扩展方法的定义是:扩展方法使您能够向现有类型"添加"方法,而无需创建新的派生类型.重新编译或以其他方式修改原始类型. 以下以 ...
- C#扩展方法学习
扩展方法的本质是什么,详细见此文 C#扩展方法,爱你在心口难开 重点如下:扩展方法使您能够向现有类型“添加”方法,而无需创建新的派生类型.重新编译或以其他方式修改原始类型.扩展方法是一种特殊的静态方法 ...
- C#扩展方法学习笔记
C#扩展方法,简单的理解是不修改原来类的源代码的情况下,为某个类添加某个方法.扩展方法被定义为静态方法,但它们是通过实例方法语法进行调用的.它们的第一个参数指定该方法作用于哪个类型,并且该参数以 th ...
- C# 3.0 扩展方法&接口
namespace ExtensionInterfaceMethod { class Program { static void Main(string[] args) { //使用接口变量来调用扩展 ...
- C#的扩展方法学习
一,什么是扩展方法? 1,扩展方法使你能够向现有类型“添加”方法,而无需创建新的派生类型.重新编译或以其他方式修改原始类型. 2,扩展方法是一种特殊的静态方法,但可以像扩展类型上的实例方法一样进行调用 ...
- C#3.0新特性之扩展方法介绍
C#3.0扩展方法是给现有类型添加一个方法.现在类型即可是基本数据类型(如int,String等),也可以是自己定义的类.以下是引用片段: //Demo--1 //扩展基本类型 namespace T ...
- [读书笔记]C#学习笔记五: C#3.0自动属性,匿名属性及扩展方法
前言 这一章算是看这本书最大的收获了, Lambda表达式让人用着屡试不爽, C#3.0可谓颠覆了我们的代码编写风格. 因为Lambda所需篇幅挺大, 所以先总结C#3.0智能编译器给我们带来的诸多好 ...
随机推荐
- 五星评分效果 原生js
五星评分在很多地方都可以用到,网上也有插件或者相应的代码,在这里我给大家提供一款我自己写的超级简单实用的五星评分代码,连图片都不需要 <!-- 评分start --> <ul> ...
- Linux中不同主机建立免登陆
ssh-keygen -t rsa scp /root/.ssh/id_rsa.pub root@192.168.0.236:/root/.ssh/authorized_keys cat /root ...
- SQL Server数据阻塞原因
阻塞形成原因 是由于SQL Server是高并发的,同一时间会有很多用户访问,为了保证数据一致性和数据安全,引入了锁的机制.同一时间只有拿到钥匙的用户能够访问,而其他用户需要等待. 死锁形成四大必要条 ...
- [转]ubuntu 下无法启动chrome
这很不爽,google了半天也不知道答案(搜索到要重装chrome,可是我怎么都卸载不干净.....),最终解决方法如下: -------------------------------------- ...
- Tensorflow 处理libsvm格式数据生成TFRecord (parse libsvm data to TFRecord)
#写libsvm格式 数据 write libsvm #!/usr/bin/env python #coding=gbk # ================================= ...
- Js实现string.format
经常需要动态拼接html字符串,想到用类似于.net的string.format函数比较好,于是找了下,stackoverflow的代码: if (!String.prototype.format) ...
- 2016-11-05实战-定义ssh服务的日志
1.编辑/etc/rsyslog.conf 输入 local 0 .* /var/log/sshd.log #日志的保存路径 2.定义ssh服务的日志级别 编辑sshd服务的主配置文件:/ ...
- GDB的常用命令
定断点b line.会返回一个断点号(breakpoint-no). 输出p val.可以夹杂类型装换.解引用. 遇到断点自动执行命令commands breakpoint-no. 停止执行s. 退出 ...
- SQL Server 2012 新特性
--Concat示例 ,null,'RTM') --Format实例 DECLARE @d DATETIME = GETDATE(); SELECT FORMAT( @d, 'd', 'en-US' ...
- CSS实现小三角小技巧
<style> .box{ width: 20px; height: 20px; background-color: #424; border: 10px solid #9C27B0; b ...