商城首页欢迎来到中国正版软件门户

您的位置: 首页 > 文章列表 > 编程开发 > C#怎么实现装饰器模式_C# Decorator设计模式方法教程【技巧】

C#怎么实现装饰器模式_C# Decorator设计模式方法教程【技巧】

  发布于2026-07-17 阅读(0)

扫一扫,手机访问

装配器模式在 C# 里到底怎么落地?很多人第一反应是找类似 Python 的 `@decorator` 语法糖,或者搜 `[Decorator]` 特性,结果折腾半天发现根本没有内置支持。其实核心思路特别简单:**不碰原类,靠接口 + 组合 + 委托动态加行为**。下面一步步拆开看,顺便把容易踩的坑也指出来。 C#怎么实现装饰器模式_C# Decorator设计模式方法教程【技巧】 先别急着写代码,得先统一“可装饰”的入口。装饰器的本质是“同类型套一层”,所以必须有一个公共接口来定义契约。比如日志场景,先定义 `ILogger` 接口,所有具体实现(原始类、装饰器类)都实现它: ```csharp public interface ILogger { void Log(string message); } ``` 这里有个容易犯的错误:有人试图用抽象类代替接口,结果装饰器既不能继承原始实现,又没法独立扩展,最后搞出奇怪的继承树。还有的直接从 `FileLogger` 派生 `TimestampLogger`,这种写法只能装饰固定一类,完全失去复用价值。记住:接口是必须的,抽象类不行。

写装饰器类:组合 + 转发 + 增强

装饰器本身是个具体类,构造时接收一个 `ILogger` 实例——这实例可以是原始实现,也可以是另一个装饰器。然后在自己的 `Log` 方法里先做增强逻辑,再调用被装饰对象的 `Log` 转发下去: ```csharp public class TimestampLogger : ILogger { private readonly ILogger _inner; public TimestampLogger(ILogger inner) => _inner = inner; public void Log(string message) { var stamped = $"[{DateTime.Now:HH:mm:ss}] {message}"; _inner.Log(stamped); // 转发给下一层 } } ``` 几个关键点:构造函数参数必须用接口类型(`ILogger`),不能用 `ConsoleLogger` 这种具体类;装饰器内部不 `new` 任何具体实现,靠外部注入,否则就没法链式嵌套。增强逻辑可以放在转发前(前置处理),也可以放在转发后(后置处理),甚至可以直接拦截不转发——比如权限装饰器判断不通过就直接 `return`。

运行时组装装饰器链,别硬编码

装饰器的价值在于灵活组合,别写死成 `new TimestampLogger(new FileLogger())` 这种固定链。推荐用工厂方法或者依赖注入容器来管理。手动组装示例(适合测试或简单场景): ```csharp ILogger logger = new TimestampLogger( new RetryLogger( new ConsoleLogger())); ``` 如果用了 `Microsoft.Extensions.DependencyInjection`,注意注册顺序:最后注册的装饰器最先执行(因为它是最外层)。比如: ```csharp services.AddSingleton(); services.Decorate(); // 需要引用 Scrutor 库或自行实现扩展 ``` 注意:没引入第三方库时,`Decorate` 不是内置方法——别搜 `services.Decorate` 报错原因,那是 `Scrutor` 提供的扩展。

容易被忽略的性能与生命周期问题

每层装饰器都是一次对象分配和虚方法调用。如果日志频率很高(比如每毫秒一次),堆栈深度超过5层就可能引发 GC 压力,间接影响吞吐。更隐蔽的问题:装饰器若持有 `IDisposable` 资源(比如打开文件流),必须确保整个链能正确释放——接口本身没继承 `IDisposable`,得自己约定,或者额外封装一个 `IDisposableLogger`。 另外,装饰器里的状态(比如计数器、缓存)是否该跨请求共享?多数场景应该无状态,否则多线程下容易出错;真要状态的话,得用 `AsyncLocal` 或显式声明线程安全。
本文转载于:https://www.php.cn/faq/2333334.html 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

热门关注