讲师中心 微信公众号
AI工具推荐 视频效率加速

C# 享元模式实现方法 C#如何利用共享来支持大量细粒度对象

星辰君_9469

星辰君_9469

发布时间:2026-02-21 09:53:03

|

438人浏览过

|

来源于php中文网

原创

享元模式核心是分离内蕴状态(可共享、只读,如字符、字体、字号)与外蕴状态(不可共享、上下文相关,如位置、选中态);C#实现关键在于明确哪些状态由客户端传入、哪些缓存在享元内部,键建议用字符串格式"{Char}_{FontSize}_{FontName}",享元类必须为私有构造的class,且返回接口而非具体类型。

c# 享元模式实现方法 c#如何利用共享来支持大量细粒度对象

享元模式的核心在于分离内蕴状态和外蕴状态

内蕴状态(intrinsic state)是可共享的、不变的,比如字符的字体、字号、颜色;外蕴状态(extrinsic state)是不可共享的、随上下文变化的,比如字符在文本中的位置、行高、是否被选中。C# 中实现享元的关键不是“怎么写一个 Flyweight 类”,而是「哪些状态必须由客户端传入,哪些可以缓存在享元内部」。

常见错误是把本该由客户端管理的位置、索引、上下文 ID 等塞进享元对象,导致缓存失效或线程不安全。正确做法是:享元类只保留 char、FontFamily、FontSize 这类只读属性,其余全靠 Render(int x, int y, bool isSelected) 这类方法接收外蕴参数。

用 Dictionary 做享元工厂最稳妥

字符串拼接作为键比用结构体或自定义类更轻量、更易调试,也天然支持多线程读取(Dictionary 的读操作是线程安全的)。键格式建议统一为 "{Char}_{FontSize}_{FontName}",避免因空格、大小写、单位(pt/em)混用导致重复创建。

  • 不要用 ConcurrentDictionary —— 初始化阶段加锁一次就够了,后续全是读,没必要为写优化
  • 键里不要包含颜色值(如 RGB 元组),容易因浮点精度或 Alpha 通道引发不命中;颜色应归入外蕴状态,由渲染逻辑处理
  • 工厂的 GetFlyweight(char c, float size, string family) 方法应返回接口 ICharFlyweight,而非具体类,便于后期替换实现(比如加入 GPU 字形缓存)

注意 .NET 中值类型与引用类型的共享陷阱

如果享元内部持有 Font 或 Brush 这类 GDI+ 对象,它们本身不是线程安全的,且不能跨 Graphics 上下文共享。此时享元不能直接缓存 Font 实例,而应缓存构造参数(fontFamilyName, emSize, style),在每次 Draw() 时按需新建 —— 虽然略增开销,但避免了 GDI 句柄泄漏和跨线程访问异常。

另一个典型问题是误用 struct 实现享元:结构体拷贝会破坏共享语义,且无法实现接口多态。所有享元类必须是 class,且构造函数私有。

C#
C#

"避开 C# 常见错误——空陷阱、异步陷阱、LINQ 陷阱及资源泄漏。"

下载

示例键生成逻辑:

var key = $"{c}_{size:F1}_{family?.Replace(" ", "_") ?? "Default"}";

享元不是万能的,别在小规模场景强行套用

当对象总数

真正适合享元的场景很明确:富文本编辑器里成千上万个字符、游戏地图中海量相同地形砖块、日志系统中重复的错误码枚举实例。验证是否值得用,最简单的方法是用 dotMemory 对比前后堆内存中同类对象实例数 —— 如果 CharRenderer 实例从 50,000 降到 200,才说明模式生效。

最容易被忽略的一点:享元工厂本身要控制生命周期。若长期运行的服务中反复创建/丢弃工厂,缓存就形同虚设。它通常应是静态单例,或注册为 Singleton 服务,且不依赖任何请求作用域对象。

热门AI工具

更多
PixTV
PixTV Hot

PixTV是一款面向AIGC内容创作的AI视频生成工具。

讯飞智文

一款面向学习和办公场景的AI文档创作工具,可辅助生成PPT与Word文档,提高资料整理和内容制作效率。

墨刀AI
墨刀AI Hot

一款AI图像与设计工具,主要用于产品经理的专属智能体,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

Loomy
Loomy Hot

一款AI工具,主要用于科大讯飞发布的桌面级 AI 助理,比 OpenClaw 更易用、更安全!,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

PixPix
PixPix Hot

PixPix是一款面向电商视觉生产的AI商品图生成工具。

UP简历
UP简历 Hot

一款AI办公效率工具,主要用于基于AI技术的免费在线简历制作工具,适合需要提升相关任务效率的用户。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

7179

2023.08.02

css中float用法
css中float用法

css中float属性允许元素脱离文档流并沿其父元素边缘排列,用于创建并排列、对齐文本图像、浮动菜单边栏和重叠元素。想了解更多float的相关内容,可以阅读本专题下面的文章。

7347

2024.04.28

C++中int、float和double的区别
C++中int、float和double的区别

本专题整合了c++中int和double的区别,阅读专题下面的文章了解更多详细内容。

864

2025.10.23

java多态详细介绍
java多态详细介绍

本专题整合了java多态相关内容,阅读专题下面的文章了解更多详细内容。

375

2025.11.27

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

1878

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

3024

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

6304

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

6289

2023.11.24

DBeaver怎么导入数据
DBeaver怎么导入数据

DBeaver数据导入专题,整理Excel、CSV、SQL、TXT等常见文件的数据导入方法,涵盖目标数据库选择、数据表创建、字段映射、数据类型设置及导入参数配置等操作,帮助用户将本地文件中的数据写入数据库,并了解批量导入、重复数据处理和导入失败等常见问题的解决方法。

20

2026.11.05

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn