c#软件开发学习笔记

第一部分 C#事件机制

1.1 事件的基本概念

1.1.1 什么是事件

事件(Event) 是C#中一种特殊的机制,本质上是多播委托(Multicast Delegate)的封装。事件用于实现发布-订阅(Publisher-Subscriber)设计模式,是面向对象编程中实现松耦合的重要手段。
事件(Event) 是一种特殊的多播委托,具有以下特点:

特性 说明
封装性 只能从声明类内部触发
安全性 外部只能订阅/取消订阅
发布-订阅模式 实现组件解耦

1.1.2 现实世界中的事件类比

现实事件 C#事件机制 说明
报纸订阅 事件订阅 用户订阅报纸(事件),报社发布新报纸(触发事件)
邮件通知 事件触发 系统发生特定操作时,向订阅者发送通知
电视频道 事件广播 电视台广播节目,多个观众同时接收
股票涨跌提醒 事件处理 设置股价提醒,股价变动时自动通知

1.2 事件的定义与语法

1.2.1 事件的基本语法

// 事件定义的基本格式
访问修饰符 event 委托类型 事件名;

// 事件定义的完整语法
public static event EventHandler MyClick;

1.2.2 使用EventHandler内置委托

using System;

namespace _3事件
{
    internal class Program
    {
        // 定义一个事件
        // 语法: public event 事件类型 事件名
        // - event: 关键字
        // - EventHandler: 事件的基类(内置委托类型)
        // - MyClick: 事件名
        public static event EventHandler MyClick;

        static void Main(string[] args)
        {
            // 事件:具体的一个操作,例如鼠标点击操作、鼠标移动等操作
            // 事件基于发布-订阅设计模式进行实现
            
            // 发布类: 是一个包含事件和委托定义的对象
            // 订阅类: 是一个接受事件并提供事件处理程序的对象

            // 给事件赋值 - 事件其实就是委托的实例
            // EventHandler 要求函数必须有两个参数
            MyClick += new EventHandler(F1);
            MyClick += (sender, e) =>
            {
                Console.WriteLine("lambda表达式");
            };
            
            // 调用事件
            MyClick(null, null);
        }

        static void F1(object sender, EventArgs s)
        {
            Console.WriteLine("F1方法");
        }
    }
}

1.2.3 自定义委托类型的事件

using System;

namespace _4例子
{
    /// <summary>
    /// 订阅类:绑定事件(事件变量赋值使用+=函数进行赋值)
    /// </summary>
    internal class Program
    {
        static void Main(string[] args)
        {
            Calc c = new Calc();
            c.Finished += F1;  // 给事件绑定方法,事件变量赋值,订阅事件
          
            c.Add(10, 20);
            c.Add(30, 20);
        }

        /// <summary>
        /// 展示的俩个数字以及结果方法F1,打印a b 和
        /// </summary>
        static void F1(int a, int b, int c)
        {
            Console.WriteLine($"a的值为{a}, b的值为{b}, c的值为{c}");
        }
    }

    /// <summary>
    /// 发布类:定义事件对象和委托对象
    /// </summary>
    public class Calc
    {
        // 定义委托类型,等同于一个enum类型定义
        public delegate void AddDel(int a, int b, int sum);

        // 根据委托类型定义事件实例,等同于enum类型一个实例
        public event AddDel Finished;

        /// <summary>
        /// 加法计算方法
        /// </summary>
        /// <param name="a">第一个加数</param>
        /// <param name="b">第二个加数</param>
        public void Add(int a, int b)
        {
            int sum = a + b;
            // 执行事件
            Finished?.Invoke(a, b, sum);
        }
    }
}

1.3 事件的安全性

事件相比普通委托实例具有以下安全特性:

特性 普通委托 事件
外部调用 可以从任何地方调用 只能在声明类内部调用
访问控制 完全公开 可以限制访问级别
封装性
安全性

1.4 事件的订阅与取消订阅

1.4.1 订阅事件的多种方式

public class EventDemo
{
    // 定义事件
    public event EventHandler Click;

    public void Demo()
    {
        // 方式1:使用 += 订阅事件(最常用)
        Click += HandlerMethod1;

        // 方式2:使用 new EventHandler 订阅
        Click += new EventHandler(HandlerMethod2);

        // 方式3:使用匿名方法订阅
        Click += delegate(object sender, EventArgs e)
        {
            Console.WriteLine("匿名方法处理");
        };

        // 方式4:使用Lambda表达式订阅
        Click += (sender, e) =>
        {
            Console.WriteLine("Lambda表达式处理");
        };
    }

    private void HandlerMethod1(object sender, EventArgs e)
    {
        Console.WriteLine("方法1处理");
    }

    private void HandlerMethod2(object sender, EventArgs e)
    {
        Console.WriteLine("方法2处理");
    }
}

1.4.2 取消订阅事件

public class UnsubscribeDemo
{
    public event EventHandler MyEvent;

    public void Demo()
    {
        // 订阅事件
        MyEvent += Handler1;
        MyEvent += Handler2;

        // 取消订阅 - 使用 -=
        MyEvent -= Handler1;

        // 注意:取消订阅时,方法和订阅时必须是同一个实例
        // 如果使用匿名方法或Lambda,需要保存引用才能取消
        EventHandler lambdaHandler = (s, e) => Console.WriteLine("Lambda");
        MyEvent += lambdaHandler;
        MyEvent -= lambdaHandler;  // 这样才能取消
    }

    private void Handler1(object sender, EventArgs e) { }
    private void Handler2(object sender, EventArgs e) { }
}

1.5 事件与委托的区别

特性 委托 事件
本质 存储函数引用的类型 特殊的委托实例
访问权限 可以从任何地方调用 只能在声明类内部调用
封装性 无限制 受限(封装在类内部)
安全性 较低 较高
使用场景 回调、泛型方法参数 对象间通信、解耦
外部修改 可以直接赋值和调用 只能订阅/取消订阅

第二部分 分层结构设计

2.1 分层架构概述

2.1.1 什么是分层架构

分层架构(Layered Architecture) 是一种将系统划分为多个逻辑层次的软件架构模式,每一层都有特定的职责,通过定义良好的接口进行通信。

2.1.2 经典三层架构

┌─────────────────────────────────────────────────────────────┐
│                    用户界面层 (UI Layer)                    │
│  - 负责与用户交互                                          │
│  - 接收用户输入,显示处理结果                               │
│  - 数据展示和格式转换                                       │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│                   业务逻辑层 (BLL/Business)                  │
│  - 处理业务规则和逻辑                                         │
│  - 数据验证和转换                                            │
│  - 业务流程编排                                              │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│                    数据访问层 (DAL/Data Access)              │
│  - 与数据库交互                                             │
│  - CRUD操作实现                                             │
│  - 数据持久化                                               │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│                      数据源 (Data Source)                    │
│  - 数据库                                                    │
│  - 文件系统                                                  │
│  - 外部服务                                                  │
└─────────────────────────────────────────────────────────────┘

2.2 分层结构的优势

优势 说明
高内聚低耦合 每个层职责单一,层间依赖最小化
可维护性 修改一层不影响其他层
可测试性 每层可以独立测试
可扩展性 新增功能只需在相应层添加
团队协作 不同团队可并行开发不同层
代码复用 通用功能在Common层复用

2.3 分层职责

层级 职责 包含内容
UI层 用户交互 Program.cs、Form.cs
Common层 通用工具 验证器、配置、日志
BLL层 业务逻辑 业务规则处理
IDAL层 接口定义 接口声明
DAL层 数据访问 CRUD实现
Model层 数据模型 实体类

更多推荐