您的位置:首页 > 其它

.net 简单易懂的扩展方法教程

2015-09-24 16:22 246 查看
扩展方法简而言之就是在现有类基础上附加一个方法。而不必去修改原始类。

现在我有一个Person类如下定义:

public class Person {
string name;
int age;

public Person(string name) {
this.name = name;
}
public void sayHello(string name) {
Console.WriteLine("你好," + name+"。我是"+this.name);
}
}


现在我们要在不修改Person类的基础上在加一个run()方法..

方法总是由类或者实例来调用的。所以,现在我们现在必须在定义一个PersonUtil类。

先来看msdn对于扩展方法的定义:

扩展方法被定义为静态方法,但它们是通过实例方法语法进行调用的。 它们的第一个参数指定该方法作用于哪个类型,并且该参数以 this 修饰符为前缀.请注意,它是在非嵌套的、非泛型静态类内部定义的:

遵循MSDN以上语法所以我们的PersonUtil类就长成这样了

public static class  PersonUtil {
//public  class  PersonUtil { ←必须在静态类中

public static void run(this Person p) {
//public  void run(this Person p) { ←必须在静态方法中
Console.WriteLine(p.Name+" run...");
}
}


定义的run的签名中第一个参数必须为this,表示当前对象。然后是你需要附加到的那个类型。最后是变量。

类用static修饰的原因是。它们是通过实例方法语法进行调用的

因此,这里我们必须就需要实例化Person对象,而不能是PersonUtil本身.当然你还可以直接用调用静态方法的方式去调用扩展方法。虽然有点特殊,但扩展方法终究还是属于静态方法的范畴。

好了,现在我们有了run()方法了。好了,现在方法有了。我们可以直接用实例化的对象去调用他。

static void Main() {
Person person = new Person("张三");
////现在run..
person.run();

//你也可以这样调用。
//这里需要注意,如果直接按照静态来调用方法,那么这时候编译器的this指向的内存是空的。这时候编译器就会报错,它需要你传入一个person对象。上面因为我们使用了实例调用,所以this指向的当前对象(也就是person)就直接代替了p变量。不需要再传入任何参数。
PersonUtil.run(person);//输出"张三 run..."

}


好了,既然扩展方法是对于类来扩展的,那么如果我们在一个父类中添加一个扩展方法。子类对于父类继承,按照继承原则。子类是应该有父类的方法的。事实上,子类也确实继承了该扩展方法.

那么,我们来讲代码改一下。

public static class objectUtil {
public static void run(this object obj) {
Console.WriteLine("obj run...");
}
}

class Demo6
{
static void Main() {
Person person = new Person("张三");
////现在run..
person.run();

//你也可以这样调用。
//这里需要注意,如果直接按照静态来调用方法,那么这时候编译器的this指向的内存是空的。这时候编译器就会报错,它需要你传入一个person对象。上面因为我们使用了实例调用,所以this指向的当前对象(也就是person)就直接代替了p变量。不需要再传入任何参数。
PersonUtil.run(person);//输出"张三 run..."

}
}


精通js的人都一定知道原型继承。通过更改object.prototype则可以让任何对象都有你所定义的方法。确实是一样的。
Object.prototype.run = function(){
console.log("run...")
}
var a = new Object();
a.run()


完整代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Util
{

//扩展方法:能够向现有类型添加方法,而无需创建的派生类型,重新编译或者以其他方式修改原始类型。扩展方法是一种特殊的静态方法。但可以像扩展类型上的实例方法一样进行调用。
//扩展方法对于类要求:

public class Person {
string name;
int age;
public string Name { get { return name; } set { name = value; } }
public Person(string name) {
this.name = name;
}
public void sayHello(string name) {
Console.WriteLine("你好," + name+"。我是"+this.name);
}
}

public static class PersonUtil {

//public  class  PersonUtil { ←必须在静态类中
public static void run(this Person p)
{
//public  void run(this Person p) { ←必须在静态方法中
Console.WriteLine(p.Name + " run...");
}
}

public static class objectUtil {
public static void run(this object obj) {
Console.WriteLine("obj run...");
}
}

class Demo6
{
static void Main() {
Person person = new Person("张三");
//现在run..
//输出 obj run...
//.net先看类自身是否有自定了扩展方法,如果没有的话。那么就找父类的扩展方法。这和javascript的原型链查找是不是一样。
person.run();

//你也可以这样调用。
//这里需要注意,如果直接按照静态来调用方法,那么这时候编译器的this指向的内存是空的。这时候编译器就会报错,它需要你传入一个person对象。上面因为我们使用了实例调用,所以this指向的当前对象(也就是person)就直接代替了p变量。不需要再传入任何参数。
//PersonUtil.run(person);//输出"张三 run..."

}
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: