• C#利用lambda表达式将函数作为参数或属性跨类传递


    在编码时,由于开始是在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 + "
     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 + "
     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 + "
     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

  • 相关阅读:
    Eureka 原理圖
    RabbitMQ 介紹
    rabbitmq-3.5.1-安裝
    MyBatis 基础入门
    CSS
    程序员必会算法-KMP算法
    编程这些年
    排序算法之直接插入排序
    排序算法之选择排序
    排序算法之冒泡排序
  • 原文地址:https://www.cnblogs.com/pangblog/p/3249229.html
Copyright © 2020-2023  润新知