没有找到合适的产品?
联系客服协助选型:023-68661681
提供3000多款全球软件/控件产品
针对软件研发的各个阶段提供专业培训与技术咨询
根据客户需求提供定制化的软件开发服务
全球知名设计软件,显著提升设计质量
打造以经营为中心,实现生产过程透明化管理
帮助企业合理产能分配,提高资源利用率
快速打造数字化生产线,实现全流程追溯
生产过程精准追溯,满足企业合规要求
以六西格玛为理论基础,实现产品质量全数字化管理
通过大屏电子看板,实现车间透明化管理
对设备进行全生命周期管理,提高设备综合利用率
实现设备数据的实时采集与监控
利用数字化技术提升油气勘探的效率和成功率
钻井计划优化、实时监控和风险评估
提供业务洞察与决策支持实现数据驱动决策
转帖|其它|编辑:郝浩|2009-03-10 09:38:11.000|阅读 609 次
概述:C#3.0语言新特性之扩展方法
# 界面/图表报表/文档/IDE等千款热门软控件火热销售中 >>
当我们需要对已有类的功能进行扩展时,我们通常会想到继承,继承已有类,然后为其加入新的行为。而C# 3.0中加入的扩展方法(Extension Methods)特性,则提供了另一种实现功能扩展的方式。
扩展方法是一种特殊的静态方法,它定义在一个静态类中,但可以在其他类的对象上像调用实例方法那样进行调用。因此,通过扩展方法,我们就可以在不修改一个类型的前提下对一个类型进行功能上的扩充,这种方法并不会产生新的类型,而是采用向已有类中加入新方法的方式来完成功能扩展;同时,也可以将一些近似的类型中近似的功能同一实现在一个类中,便于阅读和维护。从最终效果上看,扩展方法使得扩展一个现有类型和构造一个具有附加方法的类型变成了现实。
在对已有类进行扩展时,我们需将所有扩展方法都写在一个静态类中,这个静态类就相当于存放扩展方法的容器,所有的扩展方法都可以写在这里面。
而且扩展方法采用一种全新的声明方式:
public static 返回类型 扩展方法名(this 要扩展的类型 参数名称 [,扩展方法参数列表]),
与普通方法声明方式不同,扩展方法的第一个参数以this关键字开始,后跟被扩展的类型名,然后才是真正的参数列表。如下面的示例是一个声明了两个扩展方法的静态类:
namespace C20_1
{
public static class Extensions
{
public static int ToInt32(this string s)
{
return Int32.Parse(s);
}
public static T[] Slice<T>(this T[] source, int index, int count)
{
if (index < 0 || count < 0 || source.Length - index < count)
{
throw new ArgumentException("Argument Error Information.");
}
T[] result = new T[count];
Array.Copy(source, index, result, 0, count);
return result;
}
}
}
在上面的示例中,静态的Extensions类中有两个扩展方法,如方法ToInt32是对string类的扩展,它为string类加入了名为ToInt32的方法,该方法没有参数,并返回一个int类型的值,它将完成数字字符向整数的转换。有了这个扩展方法之后,就可对任意string类的对象调用ToInt32方法了,该方法就像其本身定义的一样。
其实,扩展方法和正常的静态方法具有完全相同的功能。另外,一旦导入了扩展方法,就可以用调用实例方法的语法来调用扩展方法。
扩展方法使用using导入命名空间指令来导入。除了导入一个命名空间中的类型以外,一个using导入命名空间指令还可以导入一个命名空间中所有的静态类中所有的扩展方法。最后,导入的扩展方法表现为其第一个参数的类型的附加方法,并且其优先级比一般的实例方法低。例如,我们可以使用using导入命名空间指令导入了上面例子中的C20_1命名空间:
using C20_1
导入扩展方法之后,我们就可以这样来调用它了。代码如下所示:
static void Main(string[] args)
{
string s = "1000";
int i = s.ToInt32(); // 和Extensions.ToInt32(s)一样
int[] digits = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int[] a = digits.Slice(4, 3); // 和Extensions.Slice(digits, 4, 3)一样
}
下面描述了扩展方法调用的详细规则。在下面这些形式的方法调用中:
expr . identifier ()
expr . identifier (args)
expr . identifier <typeargs>()
expr . identifier <typeargs>(args)
如果按照正常的过程没有发现可用的实例方法(确切地说,当待调用的候选方法集合为空时),就会尝试构造一个扩展方法调用。这些方法调用首先被重写为下面相应的形式:
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的方法优先于所有两个扩展方法。
通常,建议你只在不得已的情况下才实现扩展方法,并谨慎地实现。只要有可能,必须扩展现有类型的客户端代码都应该通过创建从现有类型派生的新类型来达到这一目的。
在使用扩展方法来扩展您无法更改其源代码的类型时,你需要承受该类型实现中的更改会导致扩展方法失效的风险。如果你确实为给定类型实现了扩展方法,请注意如下几点:
l 扩展方法是给现有类型添加一个方法;
l 扩展方法是通过指定关键字this修饰方法的第一个参数;
l 扩展方法必须声明在静态类中;
l 扩展方法只能针对实例调用;
l 如果扩展方法与该类型中定义的方法具有相同的签名,则扩展方法永远不会被调用;
l 扩展方法被在命名空间级别放入范围中。例如,如果你在同一个名为Extensions的命名空间中具有多个包含扩展方法的静态类,则这些扩展方法将全部由using Extensions指令放入范围中。
l 扩展方法有他的优先级,现有实例的方法的优先级最高,其次为最近的namespace下的扩展方法,最后为较远namespace下的扩展方法。
本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@evget.com
文章转载自:博客园面对“数字中国”建设和中国制造2025战略实施的机遇期,中车信息公司紧跟时代的步伐,以“集约化、专业化、标准化、精益化、一体化、平台化”为工作目标,大力推进信息服务、工业软件等核心产品及业务的发展。在慧都3D解决方案的实施下,清软英泰建成了多模型来源的综合轻量化显示平台、实现文件不失真的百倍压缩比、针对模型中的大模型文件,在展示平台上进行流畅展示,提升工作效率,优化了使用体验。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
服务电话
重庆/ 023-68661681
华东/ 13452821722
华南/ 18100878085
华北/ 17347785263
客户支持
技术支持咨询服务
服务热线:400-700-1020
邮箱:sales@evget.com
关注我们
地址 : 重庆市九龙坡区火炬大道69号6幢
慧都科技 版权所有 Copyright 2003-
2025 渝ICP备12000582号-13 渝公网安备
50010702500608号