windows C#-扩展方式的常见使用模式

news/2024/12/19 8:13:10/
集合功能

过去,创建”集合类”通常是为了使给定类型实现 System.Collections.Generic.IEnumerable<T> 接口,并实现对该类型集合的功能。 创建这种类型的集合对象没有任何问题,但也可以通过对 System.Collections.Generic.IEnumerable<T> 使用扩展来实现相同的功能。 扩展的优势是允许从任何集合(如 System.Array 或实现该类型 System.Collections.Generic.IEnumerable<T> 的 System.Collections.Generic.List<T>)调用功能。 可以在本文前面的内容中找到使用 Int32 的数组的示例。

特定于层的功能

使用洋葱架构或其他分层应用程序设计时,通常具有一组域实体或数据传输对象,可用于跨应用程序边界进行通信。 这些对象通常不包含任何功能,或者只包含适用于应用程序的所有层的最少功能。 使用扩展方法可以添加特定于每个应用程序层的功能,而无需使用其他层中不需要的方法来向下加载对象。

public class DomainEntity
{public int Id { get; set; }public string FirstName { get; set; }public string LastName { get; set; }
}static class DomainEntityExtensions
{static string FullName(this DomainEntity value)=> $"{value.FirstName} {value.LastName}";
}
扩展预定义类型

当需要创建可重用功能时,我们无需创建新对象,而是可以扩展现有类型,例如 .NET 或 CLR 类型。 例如,如果不使用扩展方法,我们可能会创建 Engine 或 Query 类,对可从代码中的多个位置调用的 SQL Server 执行查询。 但是,如果换做使用扩展方法扩展 System.Data.SqlClient.SqlConnection 类,就可以从与 SQL Server 连接的任何位置执行该查询。 其他示例可能是向 System.String 类添加常见功能、扩展 System.IO.Stream 和 System.Exception 对象的数据处理功能以实现特定的错误处理功能。 这些用例的类型仅受想象力和判断力的限制。

使用 struct 类型扩展预定义类型可能很困难,因为它们已通过值传递给方法。 这意味着将对结构的副本进行任何结构更改。 扩展方法退出后,将不显示这些更改。 可以将 ref 修饰符添加到第一个参数,使其成为 ref 扩展方法。 ref 关键字可以在 this 关键字之前或之后显示,不会有任何语义差异。 添加 ref 修饰符表示第一个参数是按引用传递的。 在这种情况下,可以编写扩展方法来更改要扩展的结构的状态(请注意,私有成员不可访问)。 仅允许值类型或受结构约束的泛型类型作为 ref 扩展方法的第一个参数。 以下示例演示如何使用 ref 扩展方法直接修改内置类型,而无需重新分配结果或使用 ref 关键字传递函数:

public static class IntExtensions
{public static void Increment(this int number)=> number++;// Take note of the extra ref keyword herepublic static void RefIncrement(this ref int number)=> number++;
}public static class IntProgram
{public static void Test(){int x = 1;// Takes x by value leading to the extension method// Increment modifying its own copy, leaving x unchangedx.Increment();Console.WriteLine($"x is now {x}"); // x is now 1// Takes x by reference leading to the extension method// RefIncrement changing the value of x directlyx.RefIncrement();Console.WriteLine($"x is now {x}"); // x is now 2}
}

下一个示例演示用户定义的结构类型的 ref 扩展方法:

public struct Account
{public uint id;public float balance;private int secret;
}public static class AccountExtensions
{// ref keyword can also appear before the this keywordpublic static void Deposit(ref this Account account, float amount){account.balance += amount;// The following line results in an error as an extension// method is not allowed to access private members// account.secret = 1; // CS0122}
}public static class AccountProgram
{public static void Test(){Account account = new(){id = 1,balance = 100f};Console.WriteLine($"I have ${account.balance}"); // I have $100account.Deposit(50f);Console.WriteLine($"I have ${account.balance}"); // I have $150}
}

 通用准则

尽管通过修改对象的代码来添加功能,或者在合理和可行的情况下派生新类型等方式仍是可取的,但扩展方法已成为在整个 .NET 生态系统中创建可重用功能的关键选项。 对于原始源不受控制、派生对象不合适或不可用,或者不应在功能适用范围之外公开功能的情况,扩展方法是一个不错的选择。

在使用扩展方法来扩展你无法控制其源代码的类型时,你需要承受该类型实现中的更改会导致扩展方法失效的风险。

如果确实为给定类型实现了扩展方法,请记住以下几点:

  • 如果扩展方法与该类型中定义的方法具有相同的签名,则扩展方法永远不会被调用。
  • 在命名空间级别将扩展方法置于范围中。 例如,如果你在一个名为 Extensions 的命名空间中具有多个包含扩展方法的静态类,则这些扩展方法将全部由 using Extensions; 指令置于范围中。

针对已实现的类库,不应为了避免程序集的版本号递增而使用扩展方法。 如果要向你拥有源代码的库中添加重要功能,请遵循适用于程序集版本控制的 .NET 准则。 


http://www.ppmy.cn/news/1556340.html

相关文章

代码随想录训练营第二十二天| 77. 组合 216.组合总和III 17.电话号码的字母组合

77. 组合 题目链接/文章讲解&#xff1a; 代码随想录 视频讲解&#xff1a;带你学透回溯算法-组合问题&#xff08;对应力扣题目&#xff1a;77.组合&#xff09;| 回溯法精讲&#xff01;_哔哩哔哩_bilibili 经典回溯 一点都看不懂 所以就看题解慢慢来吧 Java代码&#xff1a…

短剧系统开发教程概要

引言 随着移动互联网的快速发展&#xff0c;短剧内容因其简短、精炼、情节紧凑的特点&#xff0c;吸引了大量观众的喜爱。为了满足市场需求&#xff0c;开发一款功能完善、体验优良的短剧平台显得尤为重要。本文将详细介绍短剧源码的开发搭建过程&#xff0c;包括需求分析、技…

USB Type-C接口快充协议芯片的特点与发展趋势

随着智能手机、平板电脑、笔记本电脑及其他便携式设备的普及&#xff0c;USB Type-C接口已经成为主流的连接标准。在这个过程中&#xff0c;USB Type-C接口不仅在数据传输上表现出色&#xff0c;还因其支持高功率传输&#xff0c;成为现代设备快充的核心技术之一。为了满足用户…

网络攻与防

1、两个专网连接 &#xff08;1&#xff09;、两个网卡VMNET2/3---配置IP子网、仅主机模式--除去DHCP设置 路由和两台主机分别ping通 &#xff08;2&#xff09;、路由配置&#xff1a;两个专网之间连接--否拨号连接 两台主机可相互ping通---成功 如果ping不通&#xff0c;…

力扣-图论-12【算法学习day.62】

前言 ###我做这类文章一个重要的目的还是给正在学习的大家提供方向和记录学习过程&#xff08;例如想要掌握基础用法&#xff0c;该刷哪些题&#xff1f;&#xff09;我的解析也不会做的非常详细&#xff0c;只会提供思路和一些关键点&#xff0c;力扣上的大佬们的题解质量是非…

软件集成测试内容和作用简析

在现代软件开发过程中&#xff0c;软件集成测试作为关键的一环&#xff0c;日益受到重视。特别是随着信息技术的快速发展&#xff0c;各类软件系统日益庞大复杂&#xff0c;如何确保系统不同模块的顺畅合作&#xff0c;成为了每个项目成功的重要基础。集成测试是指在软件开发过…

etcd数据迁移

场景1 更换高性能盘 停掉etcd服务高性能盘上创建新的数据目录copy旧数据文件到新数据目录中修改配置文件的数据目录为新目录&#xff0c;然后重启服务 场景2 更换高性能物理机器&#xff0c;不停服切换 新的机器需要先安装好etcd服务先启动安装好的一台etcd&#xff0c;单独…

IOS通过WDA自动化中遇到的问题

IOS自动化遇到的问题 搭建WDA环境中遇到的问题1、XCode unsupport iphone xxx.2、创建Bundle Identifier出现问题&#xff1a;Communication with Apple failed3、创建Bundle Identifier出现问题&#xff1a;Automatic signing failed \Signing certificate is invalid4、创建B…