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

匿名函数

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

    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();
        }
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux 安装RocketMQ

官网&#xff1a; https://rocketmq.apache.org/zh/安装RocketMQ 5.2.0 wget https://dist.apache.org/repos/dist/release/rocketmq/5.2.0/rocketmq-all-5.2.0-bin-release.zip unzip rocketmq-all-5.2.0-bin-release.zip#启动之前修改jvm启动内存 cd bin #修改&#xff1a;…

车辆管理系统设计与实践

车辆管理系统是针对车辆信息、行驶记录、维护保养等进行全面管理的系统。本文将介绍车辆管理系统的设计原则、技术架构以及实践经验&#xff0c;帮助读者了解如何构建一个高效、稳定的车辆管理系统。 1. 系统设计原则 在设计车辆管理系统时&#xff0c;需要遵循以下设计原则&…

顺序表经典算法及其相关思考

27. 移除元素 - 力扣&#xff08;LeetCode&#xff09; 思路一 利用顺序表中的SLDestroy函数的思想&#xff0c;遇到等于val值的就挪动 思路二 双指针法&#xff1a;不停的将和val不相等的数字往前放。此时的des更像一个空数组&#xff0c;里面存放的都是和val不相等、能够存…

【Rust敲门砖】 Windows环境下配置及安装环境

一、安装C环境 rust底层是依赖C环境的连接器&#xff0c;所以需要先安装C/C编译环境, 有两种选择:安装微软的msvc或者安装mingw/cygwin。 如果使用msvc的Visual Studio&#xff0c;只需要安装好C/C编译环境,然后一路默认就行了&#xff0c;缺点是体积比较大&#xff0c;下载安…

YOLO v9 思路复现 + 全流程优化

YOLO v9 思路复现 全流程优化 提出背景&#xff1a;深层网络的 信息丢失、梯度流偏差YOLO v9 设计逻辑可编程梯度信息&#xff08;PGI&#xff09;&#xff1a;使用PGI改善训练过程广义高效层聚合网络&#xff08;GELAN&#xff09;&#xff1a;使用GELAN改进架构 对比其他解法…

day16_map课后练习 - 参考答案

文章目录 day16_课后练习第1题第2题第3题第4题第5题第6题 day16_课后练习 第1题 开发提示&#xff1a;可以使用Map&#xff0c;key是字母&#xff0c;value是该字母的次数 效果演示&#xff1a;例如&#xff1a;String str “Your future depends on your dreams, so go to …

KafKa3.x基础

来源&#xff1a;B站 目录 定义消息队列传统消息队列的应用场景消息队列的两种模式 Kafka 基础架构Kafka 命令行操作主题命令行操作生产者命令行操作消费者命令行操作 Kafka 生产者生产者消息发送流程发送原理生产者重要参数列表 异步发送 API普通异步发送带回调函数的异步发送…

【springBoot】springAOP

AOP的概述 AOP是面向切面编程。切面就是指某一类特定的问题&#xff0c;所以AOP也可以理解为面向特定方法编程。AOP是一种思想&#xff0c;拦截器&#xff0c;统一数据返回和统一异常处理是AOP思想的一种实现。简单来说&#xff1a;AOP是一种思想&#xff0c;对某一类事务的集…

(提供数据集下载)基于大语言模型LangChain与ChatGLM3-6B本地知识库调优:数据集优化、参数调整、Prompt提示词优化实战

文章目录 &#xff08;提供数据集下载&#xff09;基于大语言模型LangChain与ChatGLM3-6B本地知识库调优&#xff1a;数据集优化、参数调整、提示词Prompt优化本地知识库目标操作步骤问答测试的预设问题原始数据情况数据集优化&#xff1a;预处理&#xff0c;先后准备了三份数据…

C#使用一个泛型方法操作不同数据类型的数组

目录 一、泛型方法及其存在的意义 二 、实例 1.源码 2.生成效果 再发一个泛型方法的示例。 一、泛型方法及其存在的意义 实际应用中&#xff0c;查找或遍历数组中的值时&#xff0c;有时因为数组类型的不同&#xff0c;需要对不同的数组进行操作&#xff0c;那么,可以使用…

Java学习-21 网络编程

什么是网络编程&#xff1f; 可以让设备中的程序与网络上其他设备中的程序进行数据交互&#xff08;实现网络通信的&#xff09; 基本的通信架构 基本的通信架构有2种形式: CS架构(Client客户端/Server服务端) BS架构(Browser浏览器/Server服务端)。 网络通信三要素 IP …

ATCoder Beginnner Contest 341 A~G

A.Print 341&#xff08;模拟&#xff09; 题意&#xff1a; 给定一个正整数 N N N&#xff0c;输出由 N N N个0和 ( N 1 ) (N1) (N1)个1交替组成的字符串。 分析&#xff1a; 按题意模拟即可 代码&#xff1a; #include<bits/stdc.h>using namespace std;int mai…

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…

十七、多线程

一、目标 理解线程的概念掌握线程的创建和启动了解线程的状态掌握线程调度的常用方法掌握线程的同步理解线程安全的类型 二、进程、线程、多线程的理解 进程&#xff1a;应用程序的执行实例、有独立的内存空间和系统资源 线程&#xff1a;CPU调度和分派的基本单位、进程中执行运…

2023数据要素市场十大关键词

2023数据要素市场十大关键词 导读 2023年即将过去。一年之前&#xff0c;《中共中央国务院关于构建数据基础制度更好发挥数据要素作用的意见》&#xff08;简称“数据二十条”&#xff09;正式对外发布&#xff0c;为数据要素市场的建设举旗定向。 图片 2023年是“数据二十条…

抖店开通后的这些基础搭建,你了解吗?今天一文详解!

大家好&#xff0c;我是电商小布。 很多小伙伴在我们店铺开通后&#xff0c;接下来就会进行选品上架等工作。 但其实&#xff0c;在店铺刚开通时&#xff0c;小店的基础设置是并不完善的。 比如说&#xff1a;平台默认店铺是全地区包邮的。 想要让小店顺利运转&#xff0c;…

徐晓艺被波兰前总统布罗尼斯瓦夫·科莫罗夫斯基接见

2024年1月19日,科莫罗夫斯基阁下总统俱乐部全球主席总统有话说共同主席波兰第五任总统布罗尼斯瓦夫科莫罗夫斯基 Former President of Poland莅临北京丰台宴 科莫罗夫斯基总统阁下一生充满传奇,他的外交成就也颇为杰出,其中一项就是中波关系。他说:“我作为总统在2011年对华访…

vue3 toRefs之后的变量修改方法

上效果 修改值需要带上解构之前的对象名obj&#xff0c; changeName:()>{ // toRefs 解决后变量修改值方法&#xff1a; 解构前变量.字段新值 obj.name FEIFEI; } } 案例源码 <!DOCTYPE html> <html> <head><me…

【Azure 架构师学习笔记】- Azure Databricks (10) -- UC 使用

本文属于【Azure 架构师学习笔记】系列。 本文属于【Azure Databricks】系列。 接上文 【Azure 架构师学习笔记】- Azure Databricks (9) – UC权限 在前面的文章&#xff1a;【Azure 架构师学习笔记】- Azure Databricks (6) - 配置Unity Catalog中演示了如何配置一个UC。 本文…

【Vuforia+Unity】AR04-地面、桌面平面识别功能

不论你是否曾有过相关经验&#xff0c;只要跟随本文的步骤&#xff0c;你就可以成功地创建你自己的AR应用。 官方教程Ground Plane in Unity | Vuforia Library 这个功能很棒&#xff0c;但是要求也很不友好&#xff0c;只能支持部分移动设备&#xff0c;具体清单如下&#xf…