以下是针对 NamedConstantCollection<TObject, TName>
类的深度分析,结合其设计模式和实现细节:
1. 核心功能
这是一个 泛型命名常量集合,主要功能包括:
-
通过名称或索引访问元素:支持
TName
类型名称和int
索引双检索方式 -
类型安全约束:
-
TObject
必须实现INamed<TName>
接口(需包含Name
属性) -
TName
必须实现IComparable
(确保可比较名称)
-
-
轻量级迭代支持:实现
IEnumerable<TObject>
接口
2. 关键设计分析
(1)索引器设计
索引器类型 | 实现逻辑 | 时间复杂度 |
---|---|---|
名称索引 this[TName] | 线性搜索 CompareTo 匹配 | O(n) |
位置索引 this[int] | 直接数组访问 | O(1) |
public TObject this[TName name] {
get {
foreach (var obj in Objects) {
if (obj?.Name.CompareTo(name) == 0)
return obj;
}
return default;
}
}
(2)内存管理
-
底层存储:使用
TObject[]
数组,初始为空数组 -
容量控制:
Capacity
返回数组长度,Count
返回非空元素数 -
构造灵活性:
public NamedConstantCollection(TObject[] objects) {
this.objects = objects; // 允许外部注入数组
}
(3)迭代器实现
-
延迟执行:通过
yield return
实现惰性枚举 -
空值过滤:自动跳过数组中的
null
元素
public IEnumerator<TObject> GetEnumerator() {
foreach (var obj in Objects) {
if (obj != null) yield return obj;
}
}
3. 类型系统约束
泛型参数 | 约束条件 | 设计目的 |
---|---|---|
TObject | INamed<TName> | 确保元素具有 Name 属性 |
TName | IComparable | 支持名称比较操作 |
接口定义推测:
public interface INamed<TName> where TName : IComparable {
TName Name { get; }
}
4. 使用示例
(1)基础用法
class Device : INamed<string> {
public string Name { get; }
// ...其他成员
}
var devices = new NamedConstantCollection<Device, string>(
new[] { new Device { Name = "Motor1" }, new Device { Name = "Sensor2" } }
);
// 按名称访问
Device motor = devices["Motor1"];
// 遍历非空元素
foreach (var dev in devices) {
Console.WriteLine(dev.Name);
}
(2)继承扩展
class SafeDeviceCollection : NamedConstantCollection<Device, string> {
protected override Device[] Objects {
get => base.Objects;
set => base.Objects = value.Where(d => d.IsSafe).ToArray(); // 添加安全检查
}
}
5. 改进建议
-
查找性能优化
private Dictionary<TName, TObject> _nameIndex;
// 在构造函数或setter中构建字典
空值处理 增强
public TObject this[TName name] {
get {
var obj = base[name];
if (obj == null) throw new KeyNotFoundException(name.ToString());
return obj;
}
}
批量操作支持
public void AddRange(IEnumerable<TObject> items) {
Objects = Objects.Concat(items).ToArray();
}
线程安全
private readonly object _syncLock = new object();
public TObject SafeGet(TName name) {
lock (_syncLock) { return this[name]; }
}
6. 典型应用场景
-
设备管理系统:存储具有唯一名称的硬件设备
-
配置参数集:管理命名配置项
-
命令字典:通过命令名快速检索执行逻辑
总结
该类的核心优势:
-
强类型设计:通过泛型约束保证类型安全
-
双重访问方式:兼顾名称查询和索引访问需求
-
最小化内存占用:数组存储+空值过滤
适用于需要 通过名称管理对象集合 的场景,其设计可作为类似需求的基础模板。通过继承可轻松扩展验证逻辑或添加缓存机制。