博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C#利用lambda表达式将函数作为参数或属性跨类传递
阅读量:6448 次
发布时间:2019-06-23

本文共 4391 字,大约阅读时间需要 14 分钟。

在编码时,由于开始是在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
collectData { get; set; } public Func
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用于没有返回值的。

转载请注明出处

转载于:https://www.cnblogs.com/sparkleDai/p/7605079.html

你可能感兴趣的文章
Vue源码分析系列四:Virtual DOM
查看>>
Git 版本回退
查看>>
Python:使用pypdf2合并、分割、加密pdf文件。
查看>>
rabbitmq java 应用实例
查看>>
Flutter Mac下环境配置
查看>>
springCloud学习1(集中式配置管理)
查看>>
React-Amap-HOC组件封装
查看>>
我的友情链接
查看>>
node.js操作MySQL数据库
查看>>
oracle常用字段类型
查看>>
mapreduce/spark/storm/Tez 框架
查看>>
20个简化开发任务的JavaScript库
查看>>
cocos2dx通过Jni调用Android的Java层代码(上)
查看>>
Junit 小案列 基本注解
查看>>
SpringAop的使用
查看>>
自由源于自信,自信源于自律
查看>>
Linux安装与基础命令
查看>>
quick UIInput 的使用
查看>>
远程管理
查看>>
免费(学习)使用的数据库
查看>>