如何定义泛型类的类属性,实现符合DRY的批量统一操作?
解决泛型实例统一管理的方案
核心问题是C#泛型默认是不变的——哪怕AModel实现了IModel,Generic<AModel>和Generic<IModel>也属于完全不同的类型,不能直接兼容。要实现统一管理,得用泛型协变打破这个限制,具体步骤如下:
1. 定义协变接口
先创建带out关键字的协变接口IGeneric<out T>,out标记表示T是输出类型参数(只能作为方法返回值,不能作为方法输入参数),这样C#就允许将IGeneric<AModel>隐式转换为IGeneric<IModel>。把需要批量执行的操作定义在这个接口里:
public interface IGeneric<out T> where T : IModel { // 示例:统一执行的操作,比如获取模型数据 T GetModel(); // 其他需要批量调用的方法,注意不能有T类型的输入参数 void ExecuteCommonOperation(); }
2. 让泛型类实现协变接口
修改你的Generic<T>类,让它实现上面的IGeneric<out T>接口:
public class Generic<T> : IGeneric<T> where T : IModel { private readonly T _model; public Generic(T model) { _model = model; } public T GetModel() { return _model; } public void ExecuteCommonOperation() { // 这里是你原来逐个实例执行的操作逻辑 Console.WriteLine($"执行{typeof(T).Name}的通用操作"); } }
3. 实现统一管理的Collection类
现在Collection类可以用List<IGeneric<IModel>>存储所有泛型实例,协变接口允许所有IGeneric<AModel>、IGeneric<BModel>都能被当作IGeneric<IModel>存入列表:
public class ModelCollection { private readonly List<IGeneric<IModel>> _genericInstances = new(); // 添加实例的方法 public void Add<T>(Generic<T> instance) where T : IModel { _genericInstances.Add(instance); } // 批量执行统一操作 public void ExecuteAllCommonOperations() { foreach (var instance in _genericInstances) { instance.ExecuteCommonOperation(); } } }
4. 调用示例
这样你就可以批量添加不同模型的泛型实例,然后统一执行操作:
// 定义模型接口和实现类 public interface IModel { } public class AModel : IModel { } public class BModel : IModel { } // 使用示例 var collection = new ModelCollection(); collection.Add(new Generic<AModel>(new AModel())); collection.Add(new Generic<BModel>(new BModel())); // 批量执行操作 collection.ExecuteAllCommonOperations();
注意点
如果你的通用操作需要接收T类型的参数,协变接口就不适用了(out不允许T作为输入),这种情况下可以考虑:
- 把输入参数改成
IModel类型,而非泛型T - 或者定义一个非泛型的基接口
IGeneric,把不需要泛型参数的通用操作放到这个接口里,Collection用List<IGeneric>存储
内容的提问来源于stack exchange,提问作者Paul
相关产品推荐
相关产品推荐

