C#知识点-15(匿名函数、使用委托进行窗体传值、反射)

news2024/11/23 11:37:42

匿名函数

概念:没有名字的函数,一般情况下只调用一次。它的本质就是一个方法,虽然我们没有定义这个方法,但是编译器会把匿名函数编译成一个方法

    public delegate void Del1();//无参数无返回值的委托
    public delegate void Del2(string name);//有参数无返回值的委托
    public delegate string Del3(string s,int n);//有参数有返回值的委托
    internal class Program
    {
        static void Main(string[] args)
        {
            Del1 del1 = delegate ()
            {
                Console.WriteLine("无参数无返回值的匿名函数");
            };
            del1.Invoke();
            Console.ReadKey();
        }
    }

我们可以使用lambda表达式更简洁地定义一个匿名函数

            Del1 del1 = () => { Console.WriteLine("无参数无返回值的lambda表达式"); };
            del1.Invoke();//调用
            Console.ReadKey();

当lambda表达式中参数列表只有一个参数时,括号可以省略

            Del2 del2 = msg => { Console.WriteLine("hello" + msg); };
            del2.Invoke("world" + "有参数无返回值的lambda表达式");
            Console.ReadKey();

匿名函数定义的参数列表的参数类型,是不能省略的

            Del3 dle3 = (string s1, int n1) => { return "有参数有返回值的lambda表达式"; };
            string res = dle3.Invoke("1", 1);
            Console.WriteLine(res);

泛型委托

之前我们写的委托都是需要自己定义委托的参数和返回值,而.NET框架为我们封装了泛型委托框架,让我们不用再声明委托,可以直接使用。分别为Action委托,Func委托。

Action委托:
不带返回值的委托,可以有参数,也可以没有参数

            Action action = () => { Console.WriteLine("无参无返回值的委托"); };
            action();//直接调用
            action.Invoke();//间接调用

            Action<string,int> action2 = (a,b)=> { Console.WriteLine("姓名为{0}的人,年龄为{1}",a,b); };
            action2.Invoke("张三",18);
            Console.ReadKey();

Func委托:
带返回值的委托


            //如果Func尖括号里只有一个参数类型,就表示返回值就是这个类型
            Func<int> func = () => { return 100; };
            int a = func.Invoke();
            Console.WriteLine(a);

            //需要两个整数类型的参数,以及一个string类型的返回值
            Func<int, int, string> func2 = (c, d) => { Console.WriteLine(c); Console.WriteLine(d); return "hello world"; };
            string res = func2.Invoke(10, 20);
            Console.WriteLine(res);

使用委托进行窗体传值

1、先创建两个窗体对象,添加所需控件


2、当点击form1按钮时,将textbox里的值传递给form2
 

namespace 委托_窗体传值
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //创建一个form2对象,通过form2的构造函数将窗体1的文本框的值传递给窗体2
            Form2 form2 = new Form2(textBox1.Text.Trim());
            //将窗体2展示出来
            form2.Show();
        }
    }
}
namespace 委托_窗体传值
{
    public partial class Form2 : Form
    {
        public Form2(string msg)//窗体2的构造函数,每回创建窗体2对象的时候都会执行构造函数初始化。通过参数接收窗体一传递过来的值
        {
            InitializeComponent();
            textBox1.Text = msg;//将接收到的值展示到窗体2的文本框上
        }

        private void button1_Click(object sender, EventArgs e)
        {

        }
    }
}

3、当点击form2的按钮时,将窗体2中的值传递给窗体1
 

    public partial class Form2 : Form
    {
        string _msg;//字段存储窗体二收到的消息
        Action<string> _action;
        public Form2(string msg,Action<string> action)//窗体2的构造函数,每回创建窗体2对象的时候都会执行构造函数初始化。通过参数接收窗体一传递过来的值
        {
            InitializeComponent();
            //textBox1.Text = msg;//将接收到的值展示到窗体2的文本框上
            this._msg = msg;
            this._action = action;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //调用ShowMsg,将值传递给窗体1
            this._action.Invoke(textBox1.Text.Trim());
        }

        private void Form2_Load(object sender, EventArgs e)
        {
            //窗体加载的时候,把数据赋值给文本框
            textBox1.Text = this._msg;
        }
    }
namespace 委托_窗体传值
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //创建一个form2对象,通过form2的构造函数将窗体1的文本框的值传递给窗体2
            Form2 form2 = new Form2(textBox1.Text.Trim(),ShowMsg);
            //将窗体2展示出来
            form2.Show();
        }
        void ShowMsg(string msg)
        {
            textBox1.Text = msg;
        }
    }
}

多播委托

概念:让一个委托对象,指向多个方法

    internal class Program
    {
        public delegate void Del();
        static void Main(string[] args)
        {
            Del del = M1;
            del += M2;
            del += M3;
            del += M4;
            del -= M5;
            del.Invoke();
            Console.ReadKey();

        }
        static void M1()
        {
            Console.WriteLine("我是M1");
        }
        static void M2()
        {
            Console.WriteLine("我是M2");
        }
        static void M3()
        {
            Console.WriteLine("我是M3");
        }
        static void M4()
        {
            Console.WriteLine("我是M4");
        }
        static void M5()
        {
            Console.WriteLine("我是M5");
        }
    }

运行结果

反射

概念:反射就是动态获取程序集中的元数据(提供程序集的类型信息)的功能

    internal class Program
    {
        static void Main(string[] args)
        {
            //Type
            //获取类型的类型:元数据
            //获取类型的Type有两种方式
            //1、创建了Person对象
            //Person p = new Person();
            //Type type = p.GetType();
            //2、没有创建Person对象
            Type type = typeof(Person);  //typeof后面放的是数据类型,不能放对象
            //GetMembers()获取type反射出来所有的类型中的公共成员
            MemberInfo[] mi = type.GetMembers(BindingFlags.Instance|BindingFlags.NonPublic);
            foreach (var item in mi)
            {
                Console.WriteLine(item.Name);
            }

            Console.ReadKey();

        }
    }

    class Person
    {
        public Person()
        {

        }
        private string _name;
        public int Age { get; set; }
        public void SayHi()
        {
            Console.WriteLine("实例方法");
        }
        public static void StaticSayHi()
        {
            Console.WriteLine("静态方法");
        }
        public Person(string name, int age)
        {
            this._name = name;
            this.Age = age;
        }
        public Person(int age)
        {
            this.Age = age;
        }
    }

反射程序集中的元数据

    internal class Program
    {
        static void Main(string[] args)
        {
            //1、先获取要反射数据的程序集
            //注意:就把ass这个程序集对象,当成是DLL类库
            Assembly ass = Assembly.LoadFile(@"C:\Users\ThinkPad\source\repos\DLL_Test\bin\Debug\DLL_Test.dll");
            //2、获取程序集中定义的数据类型/成员 GetTypes获取的成员包括public和internal修饰的
            //Type[] types = ass.GetTypes();
            //GetExportedTypes();获取所有被public修饰的成员
            //Type[] types = ass.GetExportedTypes();
            //foreach (var item in types)
            //{
            //    Console.WriteLine(item.Name);
            //}
            //GetType():在类型的名字前面,必须加上命名空间
            Type type = ass.GetType("DLL_Test.Person");

            //class:类
            //Method:方法
            //field:字段
            //Property:属性
            //Instance:实例的
            //static:静态的
            //Assembly:程序集
            //Type:类型
            //Exported:公开的
            //Member:成员
            //Parameter:参数
            //Constructor:构造函数
            //GetMembers()获取类型中定义的所有公开成员
            //MemberInfo[] mi = type.GetMembers(BindingFlags.Instance | BindingFlags.NonPublic);
            //foreach (var item in mi)
            //{
            //    Console.WriteLine(item.Name);
            //}

            //3、获取类型中定义的所有的方法
            //MethodInfo[] mi = type.GetMethods();
            //foreach (var item in mi)
            //{
            //    Console.WriteLine(item.Name);


            //    //Console.WriteLine(item.ReturnParameter.Name);
            //    Console.WriteLine(item.ReturnType); //获取返回值的类型
            //    Console.WriteLine("==============================");
            //}

            4、获取类型中定义的所有构造函数
            //ConstructorInfo[] ci = type.GetConstructors();
            //foreach (var item in ci)
            //{
            //    Console.WriteLine(item.Name);
            //    ParameterInfo[] pi = item.GetParameters();
            //    foreach (var item2 in pi)
            //    {
            //        Console.WriteLine(item2.Name);
            //        //获取参数类型
            //        Console.WriteLine(item2.ParameterType);
            //        Console.WriteLine("==============================================");
            //    }
            //}


            //5、获取数据类型中定义的所有属性
            //PropertyInfo[] pi = type.GetProperties();
            //foreach (var item in pi)
            //{
            //    Console.WriteLine(item.Name);
            //}

            //6、获取数据类型中定义的所有字段
            //FieldInfo[] fi = type.GetFields(BindingFlags.Instance|BindingFlags.NonPublic);
            //foreach (var item in fi)
            //{
            //    Console.WriteLine(item.Name);
            //}


            //7、调用静态方法
            //MethodInfo[] mi = type.GetMethods(BindingFlags.Static | BindingFlags.Public); 
            //foreach (var item in mi)
            //{
            //    Console.WriteLine(item);
            //}

            //MethodInfo mi = type.GetMethod("StaticSayHi");
            调用
            参数1:表示实例对象,调用静态方法,可以不提供,给null值即可。
            参数2:表示方法的参数,必须以object数组的形式提供。
            //object res = mi.Invoke(null, new object[] { "world" });
            //Console.WriteLine(res);

            8、调用实例方法
            //MethodInfo mi = type.GetMethod("InstanceSayHi");
            动态的创建对象 CreateInstance帮我们执行构造函数,创建对象
            //object o = Activator.CreateInstance(type);
            //mi.Invoke(o, null);

            //9、调用重载方法 new Type[] { typeof(int), typeof(int) } 来匹配重载
            //MethodInfo mi = type.GetMethod("Add", new Type[] { typeof(int), typeof(int) });
            //object o = Activator.CreateInstance(type);
            //object res = mi.Invoke(o, new object[] { 1,1 });
            //Console.WriteLine(res);

            //10、调用构造函数
            ConstructorInfo ci = type.GetConstructor(new Type[] { });
            object o = ci.Invoke(null);
            Console.ReadKey();
        }
    }

反射相关的补充方法

    internal class Program
    {
        static void Main(string[] args)
        {
            //IsAssignableFrom: 后面的是否可以赋值给前面的
            //特点:既可以判断类,也可以判断接口
            //bool b = typeof(Person).IsAssignableFrom(typeof(Teacher));
            //bool b2 = typeof(I1).IsAssignableFrom(typeof(Teacher));


            //IsInstanceOfType:后面的对象,是否可以赋值给前面的类型
            Person p = new Person();
            Student s = new Student();
            Teacher t = new Teacher();
            //bool b3 = typeof(Person).IsInstanceOfType(p);
            //bool b4 = typeof(Person).IsInstanceOfType(s);
            //bool b5 = typeof(Person).IsInstanceOfType(t);
            //bool b6 = typeof(I2).IsInstanceOfType(t);
            //Console.WriteLine(b3);
            //Console.WriteLine(b4);
            //Console.WriteLine(b5);
            //Console.WriteLine(b6);

            //IsSubclassOf 跟接口没关系
            bool b = t.GetType().IsSubclassOf(typeof(I2));
            //Console.WriteLine(b);

            Console.WriteLine(typeof(Animal).IsAbstract);
            Console.WriteLine(typeof(Person).IsAbstract);
            Console.WriteLine(typeof(I2).IsAbstract);
            Console.ReadKey();
        }
    }

    class Person
    {

    }
    class Student : Person
    { }

    abstract class Animal
    { }

    interface I1
    {

    }

    interface I2 : I1 { }

    class Teacher : I2
    { }

记事本插件开发

1、Form1

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Plug_in_Rule_DLL;
namespace _10_记事本插件开发
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //程序加载的时候,读取指定目录下的插件
            //1、获取插件存储文件夹的路径
            string path = Assembly.GetExecutingAssembly().Location;
            path = Path.GetDirectoryName(path);
            path = Path.Combine(path, "Plug-in-Components");
            //2、读取该路径下所有的插件
            string[] files = Directory.GetFiles(path);

            //3、通过Assembly去加载程序集
            foreach (var file in files)
            {
                //4、获取到当前循环到的插件程序集
                Assembly ass = Assembly.LoadFile(file);
                //5、获取程序集中的元数据
                //types:都是程序集中的数据类型。(类、接口、抽象类、委托、事件、.......)
                Type[] types = ass.GetExportedTypes();
                //6、对types做筛选
                foreach (var type in types)
                {
                    //筛选条件:1、实现了Plug_in_Rule接口的类     2、不能接口或者抽象类
                    if (typeof(Plug_in_Rule).IsAssignableFrom(type) && !type.IsAbstract)
                    {
                        //7、获取类型中的属性和方法
                        //动态的创建插件的对象
                        object o = Activator.CreateInstance(type);
                        Plug_in_Rule pir = (Plug_in_Rule)o;
                        //调用Name属性,赋值给Menustrip
                        ToolStripItem tsi = menuStrip1.Items.Add(pir.Name);
                        //8、给添加的小选项卡设置单击事件
                        tsi.Click += Tsi_Click;
                        //9、把pir接口,从Load方法中,传到Tsi_Click中
                        tsi.Tag = pir;
                    }
                }
            }

            //通过反射,获取程序集中的数据:Name ChangeText()

            //把Name加载到Menustrip菜单中,给菜单注册一个单击事件

            //单击的时候,执行ChangeText
        }

        //单击选项卡的时候,调用ChangeText()
        private void Tsi_Click(object sender, EventArgs e)
        {
            //sender  事件是谁的,sender就是谁
            ToolStripItem tsi = sender as ToolStripItem;

            Plug_in_Rule p = (Plug_in_Rule)tsi.Tag;

            p.ChangeText(textBox1);
        }
    }
}

2、Plug_in_Rule 插件开发的接口规范

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Plug_in_Rule_DLL
{
    /// <summary>
    /// 插件开发的接口规范
    /// </summary>
    public interface Plug_in_Rule
    {
        //接口中的只读属性,不是自动属性
        string Name { get; }
        //让插件开发人员,实现该方法,对文本的样式进行修改
        void ChangeText(TextBox textBox);

    }
}

3、Str_To_Lower 全部转小写功能

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Plug_in_Rule_DLL;
using System.Windows.Forms;
namespace Str_To_Lower_DLL
{
    public class Str_To_Lower : Plug_in_Rule
    {
        public string Name { get { return "全部转小写!!!!!"; } }

        public void ChangeText(System.Windows.Forms.TextBox textBox)
        {
            textBox.Text = textBox.Text.ToLower();
        }
    }
}

4、Str_To_Upper 全部转大写功能

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Plug_in_Rule_DLL;
using System.Windows.Forms;
namespace Str_To_Upper_DLL
{
    /// <summary>
    /// 要拓展插件功能的人
    /// </summary>
    public class Str_To_Upper : Plug_in_Rule
    {
        public string Name { get { return "全部转大写!!!!"; } }

        public void ChangeText(System.Windows.Forms.TextBox textBox)
        {
            textBox.Text = textBox.Text.ToUpper();
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1461778.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java SE 入门到精通—基础语法【Java】

敲重点&#xff01; 本篇讲述了比较重要的基础&#xff0c;是必须要掌握的 1.程序入口 在Java中&#xff0c;main方法是程序的入口点&#xff0c;是JVM&#xff08;Java虚拟机&#xff09;执行Java应用程序的起始点。 main方法的方法签名必须遵循下面规范&#xff1a; publ…

TestNG与ExtentReport单元测试导出报告文档

TestNG与ExtentReport集成 目录 1 通过实现ITestListener的方法添加Reporter log 1.1 MyTestListener设置 1.2 输出结果 2 TestNG与ExtentReporter集成 2.1 项目结构 2.2 MyExtentReportListener设置 2.3 单多Suite、Test组合测试 2.3.1 单Suite单Test 2.3…

Java实现实验室耗材管理系统 JAVA+Vue+SpringBoot+MySQL

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 耗材档案模块2.2 耗材入库模块2.3 耗材出库模块2.4 耗材申请模块2.5 耗材审核模块 三、系统展示四、核心代码4.1 查询耗材品类4.2 查询资产出库清单4.3 资产出库4.4 查询入库单4.5 资产入库 五、免责说明 一、摘要 1.1…

WebSocket实现聊天

基于webSocket通信的库主要有 socket.io&#xff0c;SockJS&#xff0c;这次用的是 SockJS。 这里我们使用sockjs-client、stomjs这两个模块&#xff0c;要实现webSocket通信&#xff0c;需要后台配合&#xff0c;也使用相应的模块。 WebSocket 1、http&#xff1a;http超文…

War Robots可以使用5347的卡支付

很多小伙伴想使用War Robots&#xff0c;但是不知道怎么弄&#xff0c;方法比较可靠&#xff0c;亲测有效~~~ 可以使用Fomepay的5347的卡支付 卡片cvc就是卡密&#xff0c;在首页点击更多时可以查看

【ubuntu2004安装N卡驱动】

软硬件环境 硬件&#xff1a;联想notebook16&#xff0c;显卡4060laptop 软件&#xff1a; ubuntu20.04 驱动安装成功的版本&#xff1a;NVIDIA-Linux-x86_64-535.146.02.run 使用默认的驱动安装&#xff0c;没用原因如下 让手动安装。 手动安装 环境准备&#xff1a; sudo …

【shap】使用shap画图时colorbar颜色条不能正常显示

下面&#xff0c;我的shap值全是蓝色的&#xff0c;没有红色 &#xff08;注&#xff1a;蓝色是负贡献&#xff0c;红色是正贡献&#xff09; 参考上面的帖子&#xff0c;是matplotlib版本问题&#xff0c;我原来的版本是3.5.0&#xff0c;降级回3.4.3就正常了。

心律守护 基于机器学习的心脏病预测

心律守护 基于机器学习的心脏病预测 心律守护 基于机器学习的心脏病预测项目背景与意义项目数据与特征数据分析与预处理机器学习模型建立与评估结语 心律守护 基于机器学习的心脏病预测 在当今数字化时代&#xff0c;机器学习的应用已经渗透到了医疗保健领域的各个层面。其中&…

阿里云/腾讯云幻兽帕鲁服务器为什么更新/重启之后,服务器存档没了?

有的朋友说&#xff0c;他的阿里云幻兽帕鲁服务器重启了一下后&#xff0c;服务器存档就没了&#xff1f;这是怎么回事呢&#xff0c;其实可能的原因&#xff0c;一是服务器还有重启完成&#xff0c;也就是游戏服务端还没有启动&#xff0c;就登进去&#xff0c;可能会显示网络…

Eclipse项目间的引用

我们在开发的时候&#xff0c;有时候需要把一个大的项目打散&#xff0c;尤其是现在微服务的架构很流行&#xff0c;一个大的项目往往被拆成很多小的项目&#xff0c;而有的项目作为公共工程被独立出来&#xff0c;比如有个工程专门提供各种Util工具类&#xff0c;有的工程专门…

使用 Docker 安装 Elasticsearch 8.4.3

使用 Docker 安装 Elasticsearch 8.4.3 一. 拉取 Elasticsearch Docker 镜像二. 使用Docker启动单节点集群三. 修改密码 前言 这是我在这个网站整理的笔记,有错误的地方请指出&#xff0c;关注我&#xff0c;接下来还会持续更新。 作者&#xff1a;神的孩子都在歌唱 从 Elastic…

基于Python的热点分析预警系统

项目&#xff1a;基于Python的热点分析预警系统 摘 要 基于网络爬虫的数据可视化服务系统是一种能自动从网络上收集信息的工具&#xff0c;可根据用户的需求定向采集特定数据信息的工具&#xff0c;本项目通过研究爬取微博网来实现微博热点分析数据信息可视化系统功能。对于采…

美国纽约时代广场纳斯达克大屏投放-大舍传媒

美国纽约时代广场纳斯达克大屏投放-大舍传媒 引言 对于大舍传媒来说&#xff0c;能够在美国纽约时代广场纳斯达克大屏投放广告是一个里程碑式的时刻。这不仅仅代表着大舍传媒在全球范围内的知名度与实力&#xff0c;也标志着该公司在国际市场上取得了巨大的进展。纽约时代广场…

sqllabs第46关 order by 注入

简介&#xff1a;&#xff08;order by注入-错误回显-POST注入&#xff09; 请求方法&#xff1a;POST 方法&#xff1a;order by注入错误回显数字型注入 先了解下 order by参数注入&#xff1a; order by 注入是指其后面的参数是可控的&#xff0c; order by 不同于我们在 whe…

威来国际教育:留学服务的全新标杆,打造无忧留学体验

在当今全球化日益加深的背景下&#xff0c;留学已成为众多年轻人拓宽视野、提升个人能力的重要手段。随着留学市场的不断扩大和留学目的地的多样化&#xff0c;家庭和学生在选择留学服务时更加注重专业性和全面性。 在这一领域&#xff0c;威来国际教育凭借其深厚的背景和专业的…

一、vue3+ts项目框架搭建——规范

新建项目及规范配置 1.1项目初始化 1.1.1环境准备1.1.2初始化项目 1.2项目配置 一、eslint配置 1.1vue3环境代码校验插件1.2.eslintrc.cjs配置文件 1.3运行脚本 二、配置prettier:格式化工具 2.1安装依赖包2.2.prettierrc.json添加规则2.3.prettierignore忽略文件 三、配置st…

Vue3-组合式Api(重点)

阅读文章你可以收获的知识 1.知道setup语法糖的使用和如何实现的 2.知道在vue3中如何定义响应式数据 3.知道在vue3中如何定义一个计算属性&#xff08;computed&#xff09; 4.知道如何在vue3中使用watch来监听数据 5.知道在vue3如何实现父子通信 6.知道vue3如何使用ref函…

苍穹外卖学习-----2024/02/21

1.新增员工 /*** 处理SQL异常* param sqlIntegrityConstraintViolationException* return*/ExceptionHandlerpublic Result exceptionHandler(SQLIntegrityConstraintViolationException sqlIntegrityConstraintViolationException){//String message sqlIntegrityConstraintV…

JS实现根据数组对象的某一属性排序

JS实现根据数组对象的某一属性排序 一、冒泡排序&#xff08;先了解冒泡排序机制&#xff09;二、根据数组对象的某一属性排序&#xff08;引用sort方法排序&#xff09; 一、冒泡排序&#xff08;先了解冒泡排序机制&#xff09; 以从小到大排序为例&#xff0c;冒泡排序的原…

2.20日学习打卡----初学Vue3

2.20日学习打卡 目录: 2.20日学习打卡Vue是什么&#xff1f;安装vue模板语法条件渲染列表渲染事件处理表单输入绑定组件基础Props组件交互自定义事件组件交互组件生命周期Vue引入第三方Axios网络请求Axios网络请求封装网络请求跨域解决方案路由配置路由传递参数嵌套路由配置Vue…