C#委托和事件

本文详细介绍了C#中的委托机制,包括基本语法、自定义委托声明、使用方法以及系统定义的Action和Func等委托类型。同时涵盖了事件的概念,强调了事件与委托的区别,以及如何在类内外操作它们。
摘要由CSDN通过智能技术生成

委托

定义

类似于C++中的函数指针,接收存储传递指定格式的函数并在指定时刻调用

基本语法

关键字:delegate

语法: 访问修饰符 delegate 返回值 委托名(参数列表);

写在哪里:

可以申明在namespace 和 class语句块中

更多的写在namespace中

自定义委托

访问修饰符一般不写,默认为public 这样在别的命名空间也能用

    //无参无返回值函数的容器
    delegate void MyFun();
    //委托规则的申明 不能重名(同一语句块中)


    //返回值为int 含一个int参数的函数容器
    delegate int MyFun2(int a);

使用定义好的委托

    class Test
    {
        public MyFun fun;
        public MyFun2 fun2;
        public void TestFun(MyFun fun,MyFun2 fun2)
        {
            //可以先处理别的逻辑,得到的结果作为参数传入fun2中
            //延迟执行
            //fun();
            //fun2(i);

            this.fun = fun;
            this.fun2 = fun2;
        }
    }
    internal class Program
    {
        static void Main(string[] args)
        {
            MyFun f = new MyFun(Fun);
            f();
            f.Invoke();

            MyFun f2 = Fun;
            f2();
            f2.Invoke();

            MyFun2 f3 = Fun2;
            Console.WriteLine(f3(345));

            Test t = new Test();
            t.TestFun(Fun, Fun2);
        }
        static void Fun()
        {
            Console.WriteLine("123");
        }
        static int Fun2(int a)
        {
            return a;
        }
    }

委托可以存储多个函数(多播委托)

MyFun ff = Fun;
//不能直接MyFun ff += Fun;
//但是可以MyFun ff = null;后再ff+=Fun;
ff += Fun;
ff += Fun3;
ff();

        public void AddFun(MyFun fun,MyFun2 fun2)
        {
            this.fun += fun;
            this.fun2 += fun2;
        }
            t.AddFun(Fun, Fun2);
            t.fun();
            Console.WriteLine(t.fun2(50));//这里只会返回最后一个50并输出,原因下面再讲

删也同理

系统定义的委托

需要using System命名空间

//无参无返回值委托
Action action = Fun;
action += Fun3;
action();

//指定返回类型的泛型委托,无参
Func<string> funstring = Fun4;
Func<int> funint = Fun5;

//可以传n个参数的委托 系统提供了1-16个参数的委托 但是无返回值
Action<int, string> action2 = Fun6;
Console.ReadLine();

//可以传n个参数的委托 系统提供了1-16个参数的委托 但是有返回值 参数都在前面最后一个是返回值
Func<int, int> func2 = Fun2;
static void Fun3()
{
    Console.WriteLine("33333");
}
static string Fun4()
{
    return "string";
}
static int Fun5()
{
    return 1;
}
static void Fun6(int i,string s)
{
    
}

补充:

事件

定义

事件可以理解成经过封装后的委托,他不能想委托一样直接在类外面调用或赋值

基本语法

访问修饰符 event 委托类型 事件名

使用

现有一Test类

class Test
{
    //委托成员变量 用于存储 函数的
    public Action myFun;
    //事件成员变量 用于存储 函数的
    public event Action myEvent;
 
    public Test()
    {
        //事件的使用和委托 一模一样,
        //只是有些细微区别
        myFun = TestFun;
        myEvent = TestFun;
 
        myEvent += TestFun;
        myEvent -= TestFun;
        myEvent();
        myEvent.Invoke();
        myEvent = null;
    }
 
    public void TestFun()
    {
        Console.WriteLine("111");
    } 
 
    public void DoEvent()
    {
        if(myEvent != null)
        {
            myEvent();
        }
    }
}

myFun可以在类的外部直接赋值、调用,例如用Invoke调用,用=赋值

而myEvent就不行,只允许在类内用一些函数来封装赋值和调用,但是+=和-=是可以用的

class Promgram
{
    static void Main(string[] args)
    {
        Test t = new Test();
        //委托可以在外部赋值
        t.myFun = null;
        t.myFun = TestFun1;
 
        //事件不能在外部赋值
        //t.myEvent = null;
        //t.myEvent = TestFun1;
 
        //但可以+= -=
        t.myEvent+= TestFun1;
 
        //委托可以在外部调用
        t.myFun();
        t.myFun.Invoke();
 
        //事件不能在外部调用
        //t.myEvent();
        //t.myEvent.Invoke();
        //只能在类的内部去封装调用
        t.DoEvent();
 
        Action a = TestFun1;
        //事件 不能作为临时变量在函数中使用、它连基本的赋值都做不到
       // event Aciton ae = TestFun1;
    }
 
    static void TestFun1()
    {
 
    }
}

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值