C#3.0语言新特性之扩展方法
2009-03-10 08:19:45 来源:WEB开发网如果按照正常的过程没有发现可用的实例方法(确切地说,当待调用的候选方法集合为空时),就会尝试构造一个扩展方法调用。这些方法调用首先被重写为下面相应的形式:
identifier (expr)
identifier (expr,args)
identifier <typeargs>(expr)
identifier <typeargs>(expr,args)
然后将重写后的形式作为一个静态方法调用进行处理,identifier按照下列顺序进行解析:
首先是命名空间生命中最接近的声明,然后是每一个接近的命名空间,最后是包含这些代码的编译单元,其间不断尝试重写过的方法调用,这些方法来自一个方法组,该组由using导入命名空间指令导入的命名空间中所有可见的identifier所提供的可见的扩展方法构成。第一个产生了非空候选方法集合的方法组是对冲洗过的方法调用的一个选择。如果所有的尝试都产生了空的候选方法集合,就会出现一个编译期错误。
上述规则意味着实例方法的优先级胜于扩展方法,并且最后引入的命名空间中的扩展方法的优先级胜于较先引入的命名空间中的扩展方法。例如:
using N1;
namespace N1
{
public static class E
{
public static void F(this object obj, int i) { }
public static void F(this object obj, string s) { }
}
}
class A { }
class B
{
public void F(int i) { }
}
class C
{
public void F(object obj) { }
}
class G
{
static void Test(A a, B b, C c)
{
a.F(1); // E.F(object, int)
a.F("Hello"); // E.F(object, string)
b.F(1); // B.F(int)
b.F("Hello"); // E.F(object, string)
c.F(1); // C.F(object)
c.F("Hello"); // C.F(object)
}
}
在这个例子中,B的方法优先于第一个扩展方法,而C的方法优先于所有两个扩展方法。
20.3.4 扩展方法使用注意事项
通常,建议你只在不得已的情况下才实现扩展方法,并谨慎地实现。只要有可能,必须扩展现有类型的客户端代码都应该通过创建从现有类型派生的新类型来达到这一目的。
在使用扩展方法来扩展您无法更改其源代码的类型时,你需要承受该类型实现中的更改会导致扩展方法失效的风险。如果你确实为给定类型实现了扩展方法,请注意如下几点:
l 扩展方法是给现有类型添加一个方法;
l 扩展方法是通过指定关键字this修饰方法的第一个参数;
l 扩展方法必须声明在静态类中;
l 扩展方法只能针对实例调用;
l 如果扩展方法与该类型中定义的方法具有相同的签名,则扩展方法永远不会被调用;
l 扩展方法被在命名空间级别放入范围中。例如,如果你在同一个名为Extensions的命名空间中具有多个包含扩展方法的静态类,则这些扩展方法将全部由using Extensions指令放入范围中。
l 扩展方法有他的优先级,现有实例的方法的优先级最高,其次为最近的namespace下的扩展方法,最后为较远namespace下的扩展方法。
- ››扩展Axis2框架,支持基于JVM的脚本语言
- ››扩展WebSphere Portal V6个性化功能
- ››扩展JavaScript的时候,千万要保留其原来的所有功...
- ››扩展数据:如何为 Model 750 服务器选择 I/O 扩展...
- ››扩展 JDT 实现自动代码注释与格式化
- ››扩展 secldap 的功能以验证多个数据源
- ››扩展 JUnit4 以促进测试驱动开发
- ››扩展 JUnit 测试并行程序
- ››扩展的ToolStripEx控件
- ››扩展 Eclipse 的 Java 开发工具
- ››扩展 Eclipse 辅助和规范开发流程
- ››扩展方法 DataTable 和List 相互转换
更多精彩
赞助商链接