在编码时,由于开始是在winform下进行简单的测试开发的,后来代码多了,就想分到不同的类里边去,可是因为原来的测试是在同一个form下的,所以对于函数调用可以很方便,而一旦跨类之后,就会发现,这函数的耦合度太高,以至于不知道该怎么样解耦到类里边去。这时,不妨使用委托类型的Func和Action来实现。

下面是最开始测试时在winform里写的简单代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms; namespace FunctionPass
{
public partial class FormMain : Form
{
public FormMain()
{
InitializeComponent();
} private void buttonTest_Click(object sender, EventArgs e)
{
test();
} public void test()
{
string sourceStr = collectData();
string digitStr = fetchDigit(sourceStr);
MessageBox.Show("source:" + sourceStr + "\r\n digit:" + digitStr);
} public string collectData()
{
return Guid.NewGuid().ToString();
} public string fetchDigit(string sourceStr)
{
Regex regex = new Regex(@"\d*");
MatchCollection digitCollection=regex.Matches(sourceStr);
string digitStr = "";
foreach (Match digitMatch in digitCollection)
{
digitStr += digitMatch;
}
return digitStr;
}
}
}

这里通过colloectData函数收集数据,再通过fetchDigit提取数据中的数字,之后通过test函数显示结果。

现在我想把显示结果做成一个单独的类(比如Test类),以便后面更好的扩展。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms; namespace FunctionPass
{
public class Test
{
public void test()
{
string sourceStr = collectData();
string digitStr = fetchDigit(sourceStr);
MessageBox.Show("source:" + sourceStr + "\r\n digit:" + digitStr);
}
}
}

这时会发现,collectData和fetchDigit没有定义,那要怎么办呢?我们可以通过一个委托类型的属性来传递。下面修改后的代码。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms; namespace FunctionPass
{
public class Test
{
public Func<string> collectData { get; set; }
public Func<string,string> fetchDigit { get; set; }
public void test()
{
string sourceStr = collectData();
string digitStr = fetchDigit(sourceStr);
MessageBox.Show("source:" + sourceStr + "\r\n digit:" + digitStr);
}
}
}

那我们又要怎么样把form中的collectData和fetchDigit函数传进去呢?可以在form像给属性赋值一样直接赋值。代码如下

  private Test test_ = new Test();//为了传递和调用需要新建一个实例
private void buttonTest_Click(object sender, EventArgs e)
{
test_.collectData = collectData;//赋值
test_.fetchDigit = fetchDigit;//赋值
test_.test();
}

现在由于需要,又想把collectData和fetchDigit函数从form中独立到一个类里面,于是建了一个类,比如叫DataDeal。代码如下

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks; namespace FunctionPass
{
public class DataDeal
{
public string collectData()
{
return Guid.NewGuid().ToString();
} public string fetchDigit(string sourceStr)
{
Regex regex = new Regex(@"\d*");
MatchCollection digitCollection = regex.Matches(sourceStr);
string digitStr = "";
foreach (Match digitMatch in digitCollection)
{
digitStr += digitMatch;
}
return digitStr;
}
}
}

这时form中的buttonTest_Click方法里对test_.collectData和 test_.fetchDigit的赋值需要改一下。代修后的代码如下。

private Test test_ = new Test();//为了调用和传递需要新建一个实例
private DataDeal dataDeal_ = new DataDeal();//为了调用和传递需要新建一个实例
private void buttonTest_Click(object sender, EventArgs e)
{
test_.collectData = dataDeal_.collectData;
test_.fetchDigit = dataDeal_.fetchDigit;
test_.test();
}

代码成功运行。

有时如果在DataDeal类的collectData和fetchDigit中作了一些其他操作,可能会引起异常,比如实例方法的委托不能具有空“this”
这时,就需要在form中的赋值过程作一些处理,这可以通过lambda表达式实现,修改后代码如下。

test_.collectData = () => { return dataDeal_.collectData(); };
test_.fetchDigit = (sourceStr) => { return dataDeal_.fetchDigit(sourceStr); };

所以对于类之间的函数传递,其实就是对于属性的操作,只是类型变成了Func和Action等委托类型。

其中要注意的是:

Func用于有返回值的。

Action用于没有返回值的。

转载请注明出处http://blog.csdn.net/xxdddail/article/details/9849111

C#利用lambda表达式将函数作为参数或属性跨类传递的更多相关文章

  1. [二] java8 函数式接口详解 函数接口详解 lambda表达式 匿名函数 方法引用使用含义 函数式接口实例 如何定义函数式接口

    函数式接口详细定义 package java.lang; import java.lang.annotation.*; /** * An informative annotation type use ...

  2. 优雅实现INotifyPropertyChanged接口——利用Lambda表达式

    原文:优雅实现INotifyPropertyChanged接口--利用Lambda表达式 参考文章 在14年的时候,曾经读过上面的参考文章,不过当时并没有怎么理解,慢慢地也就将这篇文章忘诸脑后了. 直 ...

  3. java8函数式接口详解、函数接口详解、lambda表达式匿名函数、方法引用使用含义、函数式接口实例、如何定义函数式接口

    函数式接口详细定义 函数式接口只有一个抽象方法 由于default方法有一个实现,所以他们不是抽象的. 如果一个接口定义了一个抽象方法,而他恰好覆盖了Object的public方法,仍旧不算做接口的抽 ...

  4. 【C++】C++中的lambda表达式和函数对象

    目录结构: contents structure [-] lambda表达式 lambda c++14新特性 lambda捕捉表达式 泛型lambda表达式 函数对象 函数适配器 绑定器(binder ...

  5. Lambda表达式和函数试接口的最佳实践 · LiangYongrui's Studio

    1.概述 本文主要深入研究java 8中的函数式接口和Lambda表达式,并介绍最佳实践. 2.使用标准的函数式接口 包java.util.function中的函数是接口已经可以满足大部分的java开 ...

  6. 委托到Lambda的进化: ()=> {} 这个lambda表达式就是一个无参数的委托及具体方法的组合体。

    1.原始的委托 (.net 1.0) using System; using System.Collections.Generic; using System.ComponentModel; usin ...

  7. Python:lambda表达式(匿名函数)

    lambda表达式: 通常是在需要一个函数,但是又不想费神去命名一个函数的场合下使用,也就是指匿名函数. 当我们在传入函数时,有些时候,不需要显式地定义函数,直接传入匿名函数更方便. 在Python中 ...

  8. 还看不懂同事的代码?Lambda 表达式、函数接口了解一下

    当前时间:2019年 11月 11日,距离 JDK 14 发布时间(2020年3月17日)还有多少天? // 距离JDK 14 发布还有多少天? LocalDate jdk14 = LocalDate ...

  9. lambda表达式 匿名函数

    lambda函数是一种快速定义单行最小函数的方法,是从Lisp借鉴而来的,可以用在任何需要函数的地方. 基础 lambda语句中,冒号前是参数,可以有多个,用逗号分割:冒号右边是返回值. lambda ...

随机推荐

  1. 大四实习准备1_java构造器_android ListView

    2015-4-23 Java构造器 与类名同名;无返回值(void也不行);被不同的修饰符修饰是有区别的;当构造函数被private修饰时,只有本类可访问.其他类可以通过该类的get函数得到对象.如单 ...

  2. 深入理解Java虚拟机 - 类加载器

    引子:       类加载器(classloader)是独立于虚拟机之外,可以独立实现的代码模块.     OSGi使用了类加载器的这一特点实现其热插拔的特性       Java同C++等语言不通, ...

  3. Java内省

    什么是内省? Java语言对bean类属性.事件的一种缺省处理方法,例如类A中有属性name,那我们可以通过getName,setName来得到其值或者设置新的值. 什么是JavaBean? Java ...

  4. 请用一句话概括JSONP

    服务器调用客户端的函数(即回调函数),在客户端就能拿到服务端传入的参数(即返回结果)

  5. BZOJ3175: [Tjoi2013]攻击装置

    题解: 最大点独立集...好像水过头了... 不过发现我二分图好像忘完了!!! 代码: #include<cstdio> #include<cstdlib> #include& ...

  6. 在Google被封的那些日子裏,我們這樣科學上網

    回到正題,如果某天你喜歡的網站被封了,你工作的郵箱無法訪問了,該如何用正確姿勢實現科學上網呢?雷鋒網為大家整理了數個小技巧. 1.FreeGate類傻瓜工具 很多人第一次用翻墻,應該是從FreeGat ...

  7. windows远程桌面3389超时锁定时间调整方法(取消锁屏时间限制)

    我们在管理服务器操作时,有时候需要长时间操作服务器,有时候稍微离开下倒杯水或接个稍长点的电话,就超时断开了很烦啦!有没有方法解决这个问题类?答案是有的!我只要在组策略里面,稍微修改下超时时间就可以了. ...

  8. C语言数组和指针的理解_在取地址运算上的操作_指针加减操作_a 和&a 的区别

    1.一个实例+理论分析 在了解数组和指针的访问方式前提下,下面再看这个例子: main() { int a[5]={1,2,3,4,5}; int *ptr=(int *)(&a+1); pr ...

  9. 【转】IOS的处理touch事件处理(依照手指的移动移动一个圆,开发环境用的ios7,storyboard)-- 不错

    原文网址:http://blog.csdn.net/baidu_nod/article/details/32934565 先看下页面的效果图: 首先定义这个ball它有两个属性和两个方法: @prop ...

  10. andori 动画验证必填项

    android项目开发过程中,都会碰到必填项的校验,最简单的就是利用Toast对用进行提示,感觉这种提示太不够人性化了,那么今天就来个带动画的,并可以将光标定位到必填项中. andorid动画Anim ...