C# 委托与事件深度解析:从原理到实战

C# 委托(Delegate)和事件(Event)总结 从字面意思上说,“委托”就是一件事,我们不亲自去做,而是把这件事交给其他人帮忙做;但从编程语言的角度来说,编程语法机制也是一种C#语言对现实世界逻辑的抽象。 阅读详情

在 C# 开发体系中,委托和事件是实现回调机制、松耦合设计的核心基石,也是开发者从入门迈向进阶的关键知识点。很多开发者易混淆两者关系,甚至误将事件等同于委托。本文整合核心原理、进阶特性与实战技巧,从底层实现到框架应用,全方位拆解委托与事件的本质、用法及最佳实践。

一、委托:类型安全的 “函数指针”

1.1 委托的本质与继承体系

委托的本质是继承自 System.MulticastDelegate(其父类为 System.Delegate)的密封引用类型,编译器会自动为自定义委托生成包含核心成员的类结构:

// 编译器生成的委托类简化结构
public sealed class MyDelegate : MulticastDelegate {
    public override MethodInfo Method { get; } // 绑定的方法信息
    public override object Target { get; }     // 方法所属的实例
    public override void Invoke(...);          // 同步调用方法
    public override IAsyncResult BeginInvoke(...); // 异步调用开始
    public override object EndInvoke(IAsyncResult); // 异步调用结束
}

可通过反射验证继承关系:

Console.WriteLine(typeof(MyDelegate).BaseType); // 输出: System.MulticastDelegate
using System;
using System.Threading;

namespace ConsoleApp2
{
    // 自定义委托(编译器会自动为其生成 BeginInvoke/EndInvoke 方法)
    public delegate void MyDelegate(int number);

    internal class Program
    {
        static void Main(string[] args)
        {
            try
            {
                // 1. 初始化委托(Lambda 简化写法)
                MyDelegate myDelegate = number =>
                {
                    // 模拟耗时操作(方便观察异步效果)
                    Thread.Sleep(1000);
                    Console.WriteLine($"委托执行:Number = {number}");
                };

                // 2. 打印委托核心信息(验证基类/方法生成)
                PrintDelegateInfo(myDelegate);

                // 3. 同步调用委托
                Console.WriteLine("\n=== 同步调用委托 ===");
                myDelegate(32); // 等价于 myDelegate.Invoke(32)

                // 4. 异步调用委托(原生 APM 模式:BeginInvoke + EndInvoke)
                Console.WriteLine("\n=== 异步调用委托(BeginInvoke/EndInvoke)===");
                Console.WriteLine("开始异步调用(主线程继续执行...)");

                // 4.1 调用 BeginInvoke 启动异步
                // 参数说明:
                // - 委托的入参(number=45)
                // - 异步完成回调(AsyncCallback)
                // - 回调携带的自定义状态(可选)
                IAsyncResult asyncResult = myDelegate.BeginInvoke(
                    45,                  // 委托的参数
                    AsyncCallbackHandler, // 异步完成后的回调方法
                    myDelegate           // 回调中携带的状态(传递委托实例)
                );

                // 主线程可在此执行其他操作(演示异步并行)
                Console.WriteLine("主线程:异步调用已发起,我先做其他事...");
                Thread.Sleep(500); // 模拟主线程耗时操作

                // 4.2 等待异步完成并调用 EndInvoke(必须调用,否则会泄露资源)
                // 方式1:阻塞等待(直到异步完成)
                // myDelegate.EndInvoke(asyncResult);

                // 方式2:非阻塞等待(轮询 IsCompleted)
                while (!asyncResult.IsCompleted)
                {
                    Console.WriteLine("主线程:异步还没完成,再等一等...");
                    Thread.Sleep(200);
                }
                myDelegate.EndInvoke(asyncResult); // 收尾异步调用

                Console.WriteLine("\n所有操作执行完成!");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"执行异常:{ex.Message}", ex);
            }
            finally
            {
                Console.WriteLine("\n按任意键退出...");
                Console.ReadKey();
            }
        }

        /// <summary>
        /// 异步调用完成后的回调方法
        /// </summary>
        private static void AsyncCallbackHandler(IAsyncResult ar)
        {
            Console.WriteLine("\n回调触发:异步调用执行完成!");

            // 从 AsyncResult 中取出委托实例(BeginInvoke 传入的 state)
            if (ar.AsyncState is MyDelegate callbackDelegate)
            {
                // 回调中也可调用 EndInvoke(二选一,确保只调用一次)
                // callbackDelegate.EndInvoke(ar);
                Console.WriteLine("回调中验证:委托状态正常");
            }
        }

        /// <summary>
        /// 打印委托核心信息(验证自动生成的方法/基类)
        /// </summary>
        private static void PrintDelegateInfo(Delegate delegateInstance)
        {
            if (delegateInstance == null)
            {
                Console.WriteLine("委托实例为 null");
                return;
            }

            // 委托基类验证(所有委托都继承自 MulticastDelegate)
            Console.WriteLine($"委托基类:{delegateInstance.GetType().BaseType.FullName}");
            Console.WriteLine($"委托类型:{delegateInstance.GetType().Name}");

            // 委托方法信息
            var method = delegateInstance.Method;
            Console.WriteLine("\n委托方法信息:");
            Console.WriteLine($"  方法名:{method.Name}");
            Console.WriteLine($"  声明类型:{method.DeclaringType?.FullName ?? "未知"}");
            Console.WriteLine($"  是否自动生成:{method.Name.StartsWith("<")}"); // 编译器生成的匿名方法特征

            // 委托目标
            var target = delegateInstance.Target;
            Console.WriteLine($"委托目标:{(target == null ? "null" : target.ToString())}");
        }
    }
}

image

委托的核心价值是将方法作为参数传递,实现类型安全的 “函数指针” 功能,相当于 “方法容器”,仅容纳与自身签名(参数类型、返回值类型)匹配的方法。

1.2 委托的基础用法

(1)自定义委托

通过 delegate 关键字声明,格式为 delegate 返回值类型 委托名(参数列表):

// 定义无返回值、接收int参数的委托
delegate void MyDel(int i);

class Program
{
    static void Main(string[] args)
    {
        // 实例化委托并绑定方法
        MyDel d1 = F1;
        MyDel d2 = F2;
        
        // 调用委托(本质调用绑定方法)
        d1(5); // 输出:我是F1:5
        d2(5); // 输出:我是F2:5
    } 
    
    // 符合MyDel签名的目标方法
    static void F1(int i) => Console.WriteLine("我是F1:"+i);
    static void F2(int i) => Console.WriteLine("我是F2:" + i);
}
(2)多播委托(委托组合)

委托支持通过 +=(或 +)组合多个方法,调用时按绑定顺序依次执行,也可通过 -= 移除方法。需注意多线程下的线程安全:

// 基础多播委托用法
MyDel d1 = F1;
MyDel d2 = F2;
MyDel d3 = F3;
MyDel d4 = d1 + d2 + d3;
d4(8); // 依次执行F1、F2、F3

// 多线程下的安全组合(锁保护字段原子性)
private MyDel _delegate;
private readonly object lockObj = new object();
public void AddDelegate(MyDel newDelegate)
{
    lock (lockObj)
    {
        _delegate = (MyDel)Delegate.Combine(_delegate, newDelegate);
    }
}

注:Delegate.Combine 本身线程安全,锁仅用于保护 _delegate 字段的原子性。

1.3 内置泛型委托:Func/Action(优先使用)

实际开发中无需重复定义委托,.NET 内置的 Func 和 Action 覆盖 90% 以上场景:

委托类型特点适用场景
Action无返回值,可接收 0-16 个参数事件处理、日志记录、执行操作
Func有返回值,可接收 0-16 个参数(最后一个泛型参数为返回值)LINQ 查询、数据计算 / 转换 / 筛选
(1)Action 示例
// 无参数Action
Action printHello = () => Console.WriteLine("Hello Action");
printHello();

// 接收2个参数的Action
Action<string, int> log = (msg, level) => Console.WriteLine($"[{level}] {msg}");
log("数据更新成功", 1); // 输出:[1] 数据更新成功
(2)Func 示例
using System;
using System.Collections.Generic;
using System.Linq;

class FuncDemo
{
    static void Main()
    {
        // 1. 无参数,返回string(当前时间)
        Func<string> getTime = () => DateTime.Now.ToString("HH:mm:ss");
        Console.WriteLine("当前时间:" + getTime());

        // 2. 接收2个int参数,返回int(求和)
        Func<int, int, int> add = (a, b) => a + b;
        Console.WriteLine("3 + 5 = " + add(3, 5)); // 输出:8

        // 3. LINQ中应用(筛选偶数)
        List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
        // Where方法接收 Func<int, bool> 类型的委托参数(输入int,返回bool)
        var evenNumbers = numbers.Where(n => n % 2 == 0);
        
        Console.Write("偶数列表:");
        foreach (var num in evenNumbers)
        {
            Console.Write(num + " "); // 输出:2 4
        }
    }
}

1.4 进阶特性:异步委托与闭包陷阱

(1)异步委托

支持绑定异步方法,需声明返回 Task 的委托类型,调用时通过 await 处理:

using System;
using System.Threading.Tasks;

class AsyncDelegateDemo
{
    // 修正:异步委托返回Task<int>(对应有返回值的异步操作)
    public delegate Task<int> AsyncDelegate(int x);

    static async Task Main(string[] args)
    {
        // 绑定异步Lambda到委托
        AsyncDelegate del = async x =>
        {
            // 模拟异步操作(延迟100ms)
            await Task.Delay(100).ConfigureAwait(false); 
            return x * 2; // 返回计算结果
        };

        // 异步调用委托并处理结果/异常
        try
        {
            int result = await del(5); // 调用委托,等待异步完成
            Console.WriteLine($"异步调用结果:{result}"); // 输出:10
        }
        catch (Exception ex)
        {
            Console.WriteLine($"捕获异步异常:{ex.Message}");
        }
    }
}
(2)Lambda 闭包陷阱

循环中 Lambda 捕获的是变量引用而非值,易导致结果不符合预期:

// 问题代码:所有按钮点击后均输出3
for (int i = 0; i < 3; i++) {
    buttons[i].OnClick += () => Console.WriteLine(i);
}

// 修复方案:创建局部副本
for (int i = 0; i < 3; i++) {
    int current = i;
    buttons[i].OnClick += () => Console.WriteLine(current);
}

二、事件:委托的安全封装

2.1 核心认知:事件≠委托

事件是委托的安全包装器,基于委托实现但通过访问控制限制外部操作,核心区别如下:

特性委托(Delegate)事件(Event)
本质独立的引用类型(类)委托的封装(类成员)
外部操作可直接调用、赋值、覆盖仅允许 +=(订阅)、-=(取消订阅)
触发权限任何地方均可调用仅声明类内部可触发
设计目的通用方法回调、参数传递安全的发布 - 订阅通知
典型场景LINQ 查询、异步回调按钮点击、状态变更通知

2.2 事件的定义与使用

通过 event 关键字声明,通常结合 EventHandler<T> 实现强类型参数,遵循微软标准事件模式:

// 自定义事件参数(继承EventArgs)
public class AgeChangedEventArgs : EventArgs {
    public int NewAge { get; }
    public AgeChangedEventArgs(int newAge) => NewAge = newAge;
}

public class Person
{
    private int _age;
    // 声明强类型事件(推荐)
    public event EventHandler<AgeChangedEventArgs> OnBenMingNian;
    
    public int Age 
    {
        get => _age;
        set 
        {
            if (value == _age) return;
            _age = value;
            // 触发事件(空条件运算符避免空引用)
            if (value % 12 == 0)
            {
                OnBenMingNian?.Invoke(this, new AgeChangedEventArgs(value));
            }
        }
    }
}

// 调用示例
class Program
{
    static void Main(string[] args)
    {
        Person p = new Person();
        // 订阅事件
        p.OnBenMingNian += (sender, e) => Console.WriteLine($"本命年到了,年龄:{e.NewAge}");
        
        p.Age = 24; // 触发事件,输出:本命年到了,年龄:24
    }
}

2.3 事件的关键问题:内存泄漏

(1)典型泄漏场景
  • 静态事件未取消订阅;
  • 订阅者未在 Dispose 中取消订阅;
  • 长生命周期发布者持有短生命周期订阅者引用。
(2)解决方案
  1. 实现 IDisposable 模式,主动取消订阅:
public class AlarmSystem : IDisposable
{
    private readonly Sensor _sensor;
    public AlarmSystem(Sensor sensor)
    {
        _sensor = sensor;
        _sensor.TemperatureChanged += OnTemperatureChange;
    }
    
    private void OnTemperatureChange(object sender, TemperatureChangedEventArgs e)
    {
        if (e.NewValue > 50) Console.WriteLine("高温警报!");
    }
    
    // 取消订阅,避免内存泄漏
    public void Dispose()
    {
        _sensor.TemperatureChanged -= OnTemperatureChange;
    }
}
  1. WPF 场景使用 WeakEventManager;
  2. 采用事件私有封装模式,避免外部直接操作。

三、委托与事件的性能优化与调试

3.1 委托链性能优化

委托链长度过大会影响性能,建议生产环境控制在 5 以内,可通过 GetInvocationList() 监控:

Delegate[] invocables = _delegate.GetInvocationList();
Debug.WriteLine($"委托链长度:{invocables.Length}");
if (invocables.Length > 5)
{
    // 优化:拆分委托链或调整订阅逻辑
}

3.2 事件触发优化

优先使用空条件运算符 ?.Invoke(),替代传统的空值判断,编译器会自动转换为更高效的 DelegateExtensions.Invoke 方法:

// 传统方式(不推荐)
if (OnEvent != null) OnEvent(sender, e);

// 推荐方式(C#6+)
OnEvent?.Invoke(sender, e);

四、框架级应用场景

框架 / 场景委托实现事件实现最佳实践
WPF 数据绑定PropertyChangedEventHandlerINotifyPropertyChanged 接口使用强类型事件参数
ASP.NET 中间件RequestDelegate 链式调用无结合 IAsyncMiddleware
Unity 事件系统UnityEvent(编辑器增强)自定义 UnityEvent<T>避免在 Update 中频繁订阅

五、综合实战:观察者模式(委托 + 事件核心应用)

观察者模式是委托与事件的典型落地场景,实现发布者 - 订阅者的松耦合通信:

// 自定义事件参数
public class TemperatureChangedEventArgs : EventArgs
{
    public float NewValue { get; }
    public TemperatureChangedEventArgs(float newValue) => NewValue = newValue;
}

// 发布者:传感器(温度变更通知)
public class Sensor : IDisposable
{
    private float _temperature;
    // 声明温度变更事件
    public event EventHandler<TemperatureChangedEventArgs> TemperatureChanged;
    
    public float Temperature
    {
        get => _temperature;
        set
        {
            if (value != _temperature)
            {
                _temperature = value;
                // 触发事件
                TemperatureChanged?.Invoke(this, new TemperatureChangedEventArgs(value));
            }
        }
    }

    public void Dispose()
    {
        // 清空事件订阅,避免内存泄漏
        TemperatureChanged = null;
    }
}

// 订阅者:警报系统
public class AlarmSystem : IDisposable
{
    private readonly Sensor _sensor;
    public AlarmSystem(Sensor sensor)
    {
        _sensor = sensor;
        _sensor.TemperatureChanged += OnTemperatureChange;
    }
    
    private void OnTemperatureChange(object sender, TemperatureChangedEventArgs e)
    {
        if (e.NewValue > 50) Console.WriteLine("高温警报!");
    }
    
    // 取消订阅,释放资源
    public void Dispose()
    {
        _sensor.TemperatureChanged -= OnTemperatureChange;
    }
}

// 调用示例
class Program
{
    static void Main(string[] args)
    {
        using (var sensor = new Sensor())
        using (var alarm = new AlarmSystem(sensor))
        {
            sensor.Temperature = 40; // 无警报
            sensor.Temperature = 55; // 输出:高温警报!
        } // 自动调用Dispose,取消订阅
    }
}

六、学习路线与最佳实践

6.1 学习路线图

  1. 基础掌握:委托声明 / 调用、Func/Action 内置委托使用;
  2. 进阶特性:多播委托、异步委托、Lambda 闭包捕获;
  3. 设计模式:观察者模式、策略模式、责任链模式(基于委托实现);
  4. 框架源码:研究 .NET Runtime 委托实现、WPF 事件系统;
  5. 性能调优:委托链长度控制、弱事件模式实现。

6.2 核心最佳实践

  1. 优先使用 Func/Action 内置委托,避免重复定义;
  2. 事件触发必须做空值判断(?.Invoke());
  3. 事件订阅后必须在合适时机取消(如 Dispose 方法),避免内存泄漏;
  4. 多线程场景下组合多播委托需加锁保护字段;
  5. 异步委托使用 ConfigureAwait(false) 避免上下文捕获问题;
  6. 循环中使用 Lambda 绑定委托时,需创建局部变量副本避免闭包陷阱。

掌握委托与事件的核心逻辑,不仅能写出更灵活、松耦合的代码,更是理解 .NET 框架底层设计(如 ASP.NET 中间件、WPF 响应式设计)的关键。建议结合文中示例动手调试,重点验证多线程、异步场景下的行为,加深对底层原理的理解。

C#委托深度剖析:从多播机制到Lambda闭包的核心原理与高效实践 委托是C#实现回调、事件驱动编程的核心工具,结合Lambda和匿名方法可极大简化代码。理解其底层机制(如多播、协变/逆变)和性能特征,能帮助开发者避免常见陷阱,编写高效、灵活的代码。 阅读详情

相关推荐

Unity开发中委托与事件机制:从原理到实战应用全解析

在C#编程中,委托是一种类型安全的函数指针,它允许将方法作为参数传递和存储,是实现回调机制的核心技术。其原理基于方法签名的契约定义,通过多播能力支持多个方法的顺序调用。这一机制的技术价值在于实现对象间的松耦合通信,是观察者模式等设计模式的基础实现方式。在游戏开发领域,委托与事件广泛应用于UI交互响应、游戏状态管理、模块间通信等场景,能有效解决代码耦合问题。本文聚焦Unity引擎中的具体实践,深入探讨了委托与事件在游戏架构设计中的关键作用,并针对内存泄漏、性能优化等常见问题提供了解决方案,帮助开发者构建更健壮

weixin_31896061的博客 327

深入理解C#委托及原理

一、委托 设想,如果我们写了一个厨师做菜方法用来做菜,里面有 拿菜、切菜、配菜、炒菜 四个环节,但编写此方法代码的人想让 配菜 这个环节让调用方法的人实现,换句话说,就是想在方法被调用时接收 代码 作为参数,在方法中执行这端传进来的代码。 但,怎么为一个方法传 代码 进来呢?当然大家想到了传递接口方式来实现,咱先不讨论接口,因为微软为我们提供了一个叫做 【委托】 的类型。

ruijc的专栏 1万+

C#委托与事件:从基础原理到高级应用实战

在C#编程中,委托与事件是实现组件间通信的核心机制。委托本质上是一种类型安全的函数指针,它定义了方法的签名契约,支持多播能力,能够将多个方法链接在一起顺序执行。这一机制为C#提供了强大的回调功能,是LINQ、异步编程等现代范式的基础。事件则是在委托之上构建的发布-订阅模型,通过封装委托并限制外部访问,实现了对象间的松耦合通信,有效避免了委托被外部随意重置的风险。在技术价值上,这套机制是构建响应式、可维护应用程序的基石,广泛应用于UI交互、后台服务通知、领域事件驱动架构等场景。本文聚焦于C#委托与事件的核心原

weixin_30764883的博客 428

C#中的委托和事件

一:定义 ——委托是一种存储函数引用的类型 ——就像我们定义一个string str一样,这个str变量就是string类型,因为C#中没有函数类型,但是可以定义一个委托类型,把一个函数赋给这个委托 ——委托的定义与函数的定义类似,需要加上delegate关键字但是不需要函数体——委托与枚举体,结构体等一样,需要先定义,再声明,再使用——当我们给一个委托的变量赋值时,返回值与参数必须与定义的委托...

L的博客 1万+

Unity游戏开发中事件与委托的深度解析:从原理到实战应用

在软件工程中,松耦合架构是构建可维护、可扩展系统的核心原则之一。其原理在于通过定义清晰的接口或契约,减少模块间的直接依赖。委托(Delegate)作为C#中类型安全的函数指针,是实现这一理念的关键技术,它允许将方法作为参数传递或存储,为回调机制和事件驱动编程奠定了基础。从技术价值看,委托与事件(Event)的结合,在Unity游戏开发中尤为重要,它们构成了游戏对象间高效、灵活通信的基石,能有效解决传统方法调用导致的高度耦合问题。在应用场景上,无论是UI交互响应、游戏状态同步(如玩家生命值变化、物品拾取),还

weixin_33100393的博客 333

C#委托与事件:从核心原理到实战解耦架构设计

在软件工程中,解耦是提升代码可维护性和可扩展性的核心设计原则,它通过降低模块间的直接依赖来应对变化。其实现原理常基于观察者模式,即发布-订阅机制,让发布者与订阅者通过抽象契约进行通信,而非硬编码调用。这一技术价值在于构建出灵活、可复用的系统架构,广泛应用于桌面应用UI交互、插件系统、微服务间异步通信等场景。C#语言内置的委托与事件机制,正是这一思想的优雅实现。委托作为类型安全的函数指针,定义了能力契约;事件则在其基础上提供了封装良好的发布-订阅模型。本文深入探讨了如何运用委托与事件,并结合事件聚合器等高级模

weixin_33797791的博客 306

C#委托与事件:从原理到面试实战的深度解析

在C#技术体系中,委托是类型安全的函数指针,继承自MulticastDelegate,天然支持多播调用;而事件则是对委托字段的封装,通过编译器生成的add/remove访问器限制外部只能订阅或退订,无法随意触发,这种设计实现了观察者模式,解耦了消息生产者和消费者,是WinForm按钮点击、上位机数据接收等场景的基石。理解多播委托的返回值规则、事件泄漏的内存隐患、线程安全触发等细节,不仅能避开生产环境的坑,更是面试中展示项目经验的关键。本文从底层机制讲到工程实践,结合高频面试追问,深入剖析委托与事件的区别及实

weixin_32705179的博客 159

Unity委托与事件:从C#基础到UnityEvent实战应用

在C#编程中,委托是一种类型安全的函数指针,它允许将方法作为参数传递和存储,是实现回调机制和事件驱动编程的基础。其核心原理是通过定义方法签名来创建委托类型,从而实现方法的间接调用和多播能力。这一机制在软件开发中具有重要价值,能够有效降低模块间的耦合度,提升代码的可维护性和扩展性。在游戏开发领域,尤其是Unity引擎中,委托与事件的应用场景极为广泛,从简单的UI交互到复杂的游戏系统通信都离不开它们。Unity进一步封装了C#的委托机制,提供了UnityAction和UnityEvent等工具,使得开发者能够在

weixin_30367873的博客 563

C#委托与事件深度解析:从底层原理到上位机实战

从C#方法传参与回调机制讲起,理解委托作为类型安全的方法引用的本质,进而探讨事件如何封装委托以实现模块间解耦。在工业上位机等场景中,发布订阅模式能有效解决UI实时刷新、报警联动与数据记录等需求,但事件订阅不当会引发内存泄漏。本文结合温度监测案例,讲解Action、Func、事件参数设计、多播委托与线程切换等关键技术点,并给出避免重复订阅和委托判空竞态的实战经验。掌握委托与事件,是构建高内聚低耦合C#应用的基石。

weixin_29596051的博客 91

C#中委托与事件的深度解析及实战应用

🔥关注墨瑾轩,带你探索Java的奥秘!🚀🔥超萌技术攻略,轻松晋级编程高手!🚀🔥技术宝库已备好,就等你来挖掘!🚀🔥订阅墨瑾轩,智趣学习不孤单!🚀🔥即刻启航,编程之旅更有趣!🚀在C#中,委托(Delegate)和事件(Event)是实现函数回调、事件驱动编程的核心机制。它们为面向对象编程添加了响应式和松耦合的特性,使得代码更加灵活和模块化。下面我们将深入探讨委托和事件的原理、使用方法,并通过示例代码进行详尽说明。

java专栏 562

C#委托与事件深度解析及WndProc应用实战

在C#中,使用delegate关键字可以显式声明一个委托类型。该类型用于描述一组具有相同参数列表和返回类型的可调用方法。其基本语法如下:public delegate 返回类型 委托名(参数列表);例如,定义一个计算两个整数之和的委托:上述代码定义了一个名为的委托类型,它可以引用任何接受两个int参数并返回int类型值的方法。// 在主程序中使用委托// 调用Add方法// 输出:15// 方法组转换// 输出:5逻辑分析- 第一行。

weixin_42513870的博客 981

C#委托、事件与多播委托深度解析:从原理到高阶应用

​松耦合架构:分离功能模块​动态行为扩展:运行时修改方法链​安全通信机制:事件封装保护委托状态graph LRA[委托] --> B[多播委托]A --> C[事件封装]B --> D[观察者模式]C --> E[发布-订阅系统]D --> F[UI事件/物联网]E --> G[插件架构]掌握这些技术后,可以构建出如WPF事件系统、ASP.NET中间件管道等复杂框架。建议结合示例代码实践,深入理解委托链的运作机制。

品质生活,极致编程。 523

事件与委托:C#编程中的事件处理深度解析

本文深入探讨了C#编程中事件和委托的概念、使用和重要性。通过具体实例,我们了解了如何定义事件、创建事件处理器以及如何利用委托来实现事件的订阅和发布。文章展示了事件与委托如何在应用程序中发挥关键作用,以及如何通过这些机制实现组件间的通信和交互。

weixin_30978239的博客 434

Unity委托、匿名方法与事件深度解析:从理论到实战

摘要:本文深入解析Unity中的委托、匿名方法与事件机制,从原理到实践全面讲解。通过12个代码片段和6个核心图示,详细说明委托的内存结构、多播原理、匿名方法优化技巧及事件安全模式。重点包括Lambda表达式应用、闭包问题解决方案、事件总线设计等实战内容,并提供性能优化建议(如委托缓存、事件清理等)。适用于Unity 2020+版本开发,帮助构建高效事件驱动系统,提升开发效率。

计算机领域优质博文分享 756

C#委托和事件、事件的工作原理

C#委托和事件、事件的工作原理、简单是事件的定义,初步学习事件的使用

C#线程委托实现原理及方法解析

很多时候写windows程序都需要结合多线程,在C#中用如下得代码来创建并启动一个新的线程。 Thread thread = new Thread(new ThreadStart(ThreadProc));//实例化一个线程 thread.IsBackground = true;//将线程改为后台线程 thread.Start();//开启线程 但是很多时候,在新的线程中,我们需要与UI(Windows窗体设计器用户界面)进行交互,在C#中不允许直接这样做。可以参考MSDN中的描述。 “Windows 窗体”使用单线程单元 (STA) 模型,因为“Windows 窗体”基于本机Win32

【C#事件多播委托深度解析】:彻底掌握移除机制的5大核心技巧

掌握C#事件的多播委托移除难题,本文详解订阅清理、弱事件模式、异常处理等5大核心技巧,适用于高并发与长期运行场景,避免内存泄漏。实用方案一步到位,值得收藏。

Algorift的博客 978

2024年上半年网络工程师下午真题及答案解析

位于MPLS域边缘、连接其他网络的LSR称为( 3 ),区域内部的LSR称为核心LSR(CoreLSR)IP报文进入MPLS网络时,MPLS入口设备分析IP报文的内容并为其添加合适的标签,所有MPLS网络中的LSR根据标签转发数据,当该IP报文离开MPLS网络时,标签由出口LER弹出。LSP的出口LER称为( 6 )。某高校网络拓扑如下图所示,两校区核心(CORE-1、CORE-2),出口防火墙(NGFW-1、NGFW-2)通过校区间光缆互联,配置OSPF实现全校路由收敛,两校区相距40km。

bsefef的博客 2471

C#代码解耦利器:委托与事件(Delegate & Event)从入门到实践 (Day 23)

在前一天的学习中,我们探讨了如何通过异常处理和调试来增强代码的健壮性。今天,我们将深入 C# 的一个核心特性——委托(Delegate)和事件(Event)。它们是实现事件驱动编程和代码解耦的强大武器,对于构建灵活、可维护的系统(尤其是在像 Unity 这样复杂的开发环境中)至关重要。理解委托和事件,能让你在不同模块间建立松耦合的通信机制,告别“牵一发而动全身”的窘境。从本质上讲,委托(Delegate)是一种引用类型,它可以“持有”

吴师兄大模型的博客 1386

AgentScope Java多智能体框架

AgentScope Java 的核心设计理念是“Agent-Oriented Programming” (面向智能体编程)。

zzz19920821的博客 1734

超详细 VMware Horizon 虚拟桌面VDI安装步骤

主要的目的是模拟生产环境中的共享存储。自动桌面相当于共享电脑,大家使用同一个虚拟机,对虚拟机的修改都放在用户的配置文件中,RDS桌面池相当于共享的服务器,可以多人同时连接到服务器上。1:之前已经建立好了NFS的存储,这部分配置好后,以后的虚拟机可以安装到NFS的存储中。2: 使用Composer发布系统可以解决SID,机器名冲突的问题,更重要的可以节约磁盘空间,发布的所有系统可以访问一块磁盘。26: 域选择我们之前建立的域,用户名我输入的是管理员,可以在AD域新建用户点击查找,我这里用的是管理员。

vv12345的博客 1万+
上一篇: C#中堆和栈的区别
下一篇: C# 静态构造函数:特性、执行顺序与实战解析
bugcome_com
博客等级 码龄3年 32粉丝 131原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bugcome_com

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值