public interface INamedConstantCollection<TObject, TName> : IEnumerable<TObject>, IEnumerable where TName : IComparable
{
TObject this[TName name] { get; }
TObject this[int index] { get; }
int Count { get; }
int Capacity { get; }
}
这是一个泛型接口,定义了命名常量集合的基本契约,结合了索引访问和枚举能力。
接口定义解析
public interface INamedConstantCollection<TObject, TName>
: IEnumerable<TObject>, IEnumerable
where TName : IComparable
{
// 通过名称索引访问
TObject this[TName name] { get; }
// 通过位置索引访问
TObject this[int index] { get; }
// 实际元素数量
int Count { get; }
// 集合容量
int Capacity { get; }
}
泛型参数说明
-
TObject
:集合中存储的元素类型 -
TName
:元素名称的类型,必须实现IComparable
接口(确保名称可比较)
成员详解
1. 名称索引器
TObject this[TName name] { get; }
允许通过元素的名称来获取集合中的对象。这是该接口的核心特性,实现了"命名常量"的访问方式。
2. 位置索引器
TObject this[int index] { get; }
提供传统的基于位置的索引访问,使集合可以像数组一样使用。
3. Count 属性
int Count { get; }
返回集合中实际包含的元素数量(非空元素)。
4. Capacity 属性
int Capacity { get; }
返回集合的总容量(包括可能为空的槽位)。
继承的接口
-
IEnumerable<TObject>
:提供强类型枚举能力 -
IEnumerable
:提供非泛型枚举能力
这使得所有实现该接口的集合都可以用于foreach循环和LINQ查询。
设计意图
该接口的设计目的是:
-
提供双重访问方式:
-
通过名称(语义化访问)
-
通过索引(顺序访问)
-
-
保持集合的不可变性:
-
只有getter没有setter
-
符合"常量集合"的设计理念
-
-
支持枚举:
-
可以用于LINQ操作
-
支持foreach迭代
-
典型实现示例
public class NamedConstantCollection<TObject, TName>
: INamedConstantCollection<TObject, TName>
where TObject : INamed<TName>
where TName : IComparable
{
private readonly TObject[] _items;
public NamedConstantCollection(TObject[] items)
{
_items = items ?? throw new ArgumentNullException(nameof(items));
}
public TObject this[TName name]
{
get => _items.FirstOrDefault(x => x.Name.CompareTo(name) == 0);
}
public TObject this[int index] => _items[index];
public int Count => _items.Count(x => x != null);
public int Capacity => _items.Length;
public IEnumerator<TObject> GetEnumerator() =>
_items.Where(x => x != null).GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
使用场景
-
配置系统:
interface IConfigItem : INamed<string> { ... }
var configs = new NamedConstantCollection<IConfigItem, string>(...);
var timeoutConfig = configs["Timeout"];
-
枚举扩展:
var colors = new NamedConstantCollection<Color, string>(...);
var red = colors["Red"];
-
资源管理:
var resources = new NamedConstantCollection<Resource, string>(...);
var logo = resources["CompanyLogo"];
接口特点
-
只读性:没有提供修改集合的方法,强调不可变性
-
双重访问:支持名称和位置两种访问方式
-
强类型:通过泛型确保类型安全
-
可枚举:可以轻松集成到现有LINQ生态中
扩展思考
在实际开发中,可以考虑以下扩展:
1.添加TryGet方法避免异常:
bool TryGet(TName name, out TObject value);
2.添加名称集合访问:
IEnumerable<TName> Names { get; }
3.添加空值检查:
bool Contains(TName name);
这个接口为命名资源的组织提供了一种清晰、类型安全的契约,特别适合需要同时支持名称和索引访问的常量集合场景。