当前位置:首页 >> 信息与通信 >>

c#扩展方法封装 ifelse、swithcase及while

c#扩展方法封装 if/else、swith/case 及 while

文章录入:7747.Net 【字体:小大】

责任编辑:7747.Net 更新时间:2010-7-11 14:24:50 87

本文探讨如何使用扩展方法封装 if/else、swith/case 及 while,通过使用这些扩展,写出的 代码将使用很少的大括号{ }。扩展的效果如何,还请大家来评判! 声明:本文属于(改)变(形)态篇,只是提出一种想法,所提供的代码也只是示例,可以 测试通过,但不完善。 首先我们来对看 if/else 和 swith/case,两者在代码中都用来表达分支结构。这里我们统一封 装成一个 If 扩展: public static T If<T>(this T t, Predicate<T> predicate, Action<T> action) where T: class { if(t == null) throw new ArgumentNullException(); if (predicate(t)) action(t); return t; } 看下面的调用代码,生成一个 People 的实例,让他吃饱喝足休息好再工作: public static void Test1() { //常规代码 People people1 = new People { Name = "ldp615", IsHungry = true, IsThirsty = true, IsTired = true }; if (people1.IsHungry) people1.Eat(); if (people1.IsThirsty) people1.Drink(); if (people1.IsTired) people1.Rest(); people1.Work(); //使用扩展方法 People people2 = new People { Name = "ldp615", IsHungry = true, IsThirsty = true, IsTired = true } .If(p => p.IsHungry, p => p.Eat()) .If(p => p.IsThirsty, p => p.Drink()) .If(p => p.IsTired, p => p.Rest()); people2.Work(); } 扩展方法中的 If 可以使用点 “.” 链起来, “链式编程” 请参见我我随笔 称之 , 《c#链式编程》 。 常规代码和使用扩展方法写的代码都在上面,大家比较一下吧。 使用 If 扩展的代码中用了 lambda 表达式,如果前面的“p=>p.”能去掉的话,看起来就比较 舒服了!编译器通过类型及上下文推演,应该可以做得到吧! 给出 People 类如下:

public class People { public string Name { get; set; } public bool IsHungry { get; set; } public bool IsThirsty { get; set; } public bool IsTired { get; set; } public int WorkCount { get; private set; } public void Eat() { Console.WriteLine("Eat"); IsHungry = false; } public void Drink() { Console.WriteLine("Drink"); IsThirsty = false; } public void Rest() { Console.WriteLine("Rest"); IsTired = false; } public void Work() { Console.WriteLine("Work"); IsHungry = IsThirsty = IsTired = true; WorkCount++; } }

对引用类型我们可以使用 Action<T>,也以使用链式编程的方式将多个 If 串起来。 但对值类型来说,就要用 Func<T, T>了,每次返回一个新的值: public static T If<T>(this T t, Predicate<T> predicate, Func<T, T> func) where T : struct { return predicate(t) ? func(t) : t; } 调用代码也要修改:

public static void Test2() {

//扩展方式 int int0 = -121; int int1 = int0.If(i => i < 0, i => -i) .If(i => i > 100, i => i - 100) .If(i => i % 2 == 1, i => i - 1); //常规方式 int int3 = -121; if (int3 < 0) int3 = -int3; if (int3 > 100) int3 -= 100; if (int3 % 2 == 1) int3--; } 引用类型及值类型的扩展我们已经完成,用 string 来测试一下吧,如下:

public static void Test3() { //从邮箱变换成主页 string email = "ldp615@163.com"; string page = email.If(s => s.Contains("@"), s => s.Substring(0, s.IndexOf("@"))) .If(s =>! s.StartsWith("www."), s => s = "www." + s) .If(s =>! s.EndsWith(".com"), s => s += ".com"); } 但编译不通过,会提示错误: 这个错误比较怪,我们写了两个扩展,一个是给值类型的,一个给引用类型,可 string 类型 在这里都不行。这个原因我说不清楚了,还留给园子里高手们吧。 不过专门为 string 写个扩展,这个问题可以化解,如下:

public static string If(this string s, Predicate<string> predicate, Func<string, string> func) { return predicate(s) ? func(s) : s; } 看来扩展方法也是有优先级的:对同一个类进行多次扩展,扩展方法相名,参数也等效(数 量、顺序相同) ,非泛版扩展要比泛型版扩展优先级高。 下面再来看一段 swith 代码,很啰嗦的!这里是为了引出扩展硬写出来的:

public static void Test4() { string englishName = "apple"; string chineseName = string.Empty;

switch (englishName) { case "apple": chineseName = "苹果"; return; case "orange": chineseName = "桔子"; return; case "banana": chineseName = "香蕉"; return; case "pear": chineseName = "梨"; break; default: chineseName = "未知"; break; } Console.WriteLine(chineseName); } 我们把这种方式用扩展方法来完成:

public static TOutput Switch<TOutput, TInput>(this TInput input, IEnumerable<TInput> inputSource, IEnumerable<TOutput> outputSource, TOutput defaultOutput) { IEnumerator<TInput> inputIterator = inputSource.GetEnumerator(); IEnumerator<TOutput> outputIterator = outputSource.GetEnumerator(); TOutput result = defaultOutput; while (inputIterator.MoveNext()) { if (outputIterator.MoveNext()) { if (input.Equals(inputIterator.Current)) { result = outputIterator.Current; break; } } else break; } return result; }

下面的 Test5 是调用:

public static void Test5() { string englishName = "apple"; string chineseName = englishName.Switch( new string[] { "apple", "orange", "banana", "pear" }, new string[] { "苹果", "桔子", "香蕉", "梨" }, "未知" ); Console.WriteLine(chineseName); } 简单清晰明了! 最后是一个对 while 的扩展封装:

public static void While<T>(this T t, T: class { while (predicate(t)) action(t); } 调用代码:

Predicate<T> predicate, Action<T> action) where

public static void Test6() { People people = new People { Name = "Wretch" }; people.While( p => p.WorkCount < 7, p => p.Work() ); people.Rest(); } 这里又“召唤”了一个人,不让吃喝不让休息,连续工作 7 次... 这 while 扩展中只能执行一个 Action<T>,不太好,我们用 params 改进一下:

public static void While<T>(this T t, Predicate<T> predicate, params Action<T>[] actions) where T : class { while (predicate(t)) {

foreach (var action in actions) action(t); } } 再来调用,可以在循环中执行多个操作了,这次舒服工作完吃饭喝水休息,再来工作...

public static void Test7() { People people = new People { Name = "Wretch" }; people.While( p => p.WorkCount < 7, p => p.Work(), p => p.Eat(), p => p.Drink(), p => p.Rest() ); people.Rest(); } 当然前面的 If 也可以这样的,这里只写出一个:

public static T If<T>(this T t, Predicate<T> predicate, params Action<T>[] actions) where T : class { if (t == null) throw new ArgumentNullException(); if (predicate(t)) { foreach (var action in actions) action(t); } return t; }不使用 params,你就要显示声明一个 Action<T>的集合了!

摘自红色黑客联盟(www.7747.net) 原文:http://www.7747.net/kf/201007/52171.html


相关文章:
c#扩展方法封装 ifelse、swithcase及while.doc
c#扩展方法封装 ifelseswithcase及while - c#扩展方法封装 if/else、swith/case 及 while 文章录入:7747.Net 【字体:小大】 责任编...
使用IconHandler 2.0 获取文件图标.pdf
(149) 阅读排行榜 c#扩展方法奇思妙用(6240) c#扩展方法奇思妙用变态篇二:封装 if/elseswith/case及while(4058) ShellIconHandler.dll 这个 dll 用在 ASP....
C#复习重点总结.pdf
(if else;switch case) 选择语句依据一个控制表达式...(do ;while ;for;foreach) (1)while 依据其...6、类的方法c#中,数据和操作均封装在类中,...
c#术语解释.doc
C# 作为一种面向对象的语言,支持封装、继承和多态性...Override: 用来扩展或修改继承的方法、属性、索引器...if, else, switch, case 迭代语句: do, for, for...
【完美版本】C#习题册解析.doc
选择分支结构:if-elseswitch-case 循环结构:while...3) C#对运算符_重载方法_ __进行了扩展,不仅可以...7)面向对象编程的重要特征___封装、继承、多态___...
C#练习题(基础知识部分二).doc
A if else B while C switchcase D for 6. 在 C#程序中,入口函数的...( X ) 2、C#程序的执行是从第一个方法开始,到 Main 方法结束。( X ) 3...
C#填空题.doc
77. C#的类定义中可以包含两种成员:静态成员和非...{ if(value=="男") SexType="先生"; else if...在 switch 语句中,每个语句标号所含关键字 case ...
C#知识点总结表.doc
方法,重载方法 继承 √√√二、 C#学习心得体会...A,条件语句包括:if……else ,switch….case.....分部方法不能扩展,分部方法可以有 static 和 unsafe...
C#填空题分析.doc
77. C#的类定义中可以包含两种成员:静态成员和非...{ if(value=="男") SexType="先生"; else if...在 switch 语句中,每个语句标号所含关键字 case ...
c#学习提纲.doc
符和表达式 5、选择结构:if-else,switch-case 6、循环结构:while,do-while,...及成员:字段、属性(自动、只读、只写) 、方法(方法重载) 、扩展方法、 构造...
C#讲稿_图文.pdf
选择语句为if语句和switch语句 循环语句为while 循环...C# 提供了以下类型的选择结构: if ifelse switch...该方法将数据与对数据的操作(函数)封装为一个整体 ...
C#试题库2014.doc
if else 语句;switch 语句 3.循环语句:while 语句...9、在 C#中,进行注释有两种方法:使用//和使用“/...22、 ( 封装 )是用一个框架把数据和代码组合在一...
C#总结.doc
在 C 和 C++中是不能 使用关键字的,C#中可以在...If?else? 2. switch?case? 8.循环结构:重复执行...说明:实现循环的方法有如下四种: 1. do?while? ...
单片机控制语音计算器总结报告_图文.doc
(32); while (1) //主循环 { num=KeyScan(); //扫描键盘 if(num!=0x...} else { switch(sign[m-1]) { case '+':a=a+b; break; case '-'...
第2章 程序设计基础_计算机软件及应用_IT/计算机_专业资料.ppt
匹配的时候,就执行该处的 内容,和if语句的else相似...{ 循环体语句; } 扩展格式初始化语句; while(判断...
微机课后作业_图文.doc
if(WavePoint<=50)DAVAL+=WaveStep; else DAVAL...while(1) { Keytemp=KEY & 0xe0; switch(Keytemp...25、8*8 点阵的工作原理,16*16 点阵的扩展方法。...
huaruan-corejava1_图文.ppt
面向对象程序设计的基础知识和基本方法,具备 初步的...Java源程序一般用java作为扩展名,是一个文本文 件,...if-else 语句 switch-case 语句 循环语句 while ...
C语言-基本选择题及答案 (自动保存的).doc
系统默认的 C 语言源程序扩展名为.C,需经过 C ...switch ( i ) { case case case 9: 10: 11:...while D. if?else B) a=1,b=1 C) C) a=...
SIMULINK仿真操作_图文.ppt
子系统的创建及封装技术 7.6 离散时间系统和混合...Switch Case Switch Case Action Subsystem Triggered ...使用if子系统模块创建系统 使用while子系统模块创建...
MATLAB基本的使用方法归纳(图像-矩阵及函数).pdf
语句或者一个带参数的函数放在扩展名叫做 m 的文件...包括 if if else, elseif 组合,条件执行一组...while 循环 switch switch case,otherwise 结合,...
更多相关标签: