能否去除C#中EditorBase类的冗余泛型参数?
简化EditorBase泛型参数的解决方案
方案1:使用C# 12的隐式类型参数(推荐)
如果你的项目基于C# 12及以上版本(对应.NET 8+),可以利用新增的隐式泛型参数约束功能,直接省略冗余的TElement参数。编译器会自动从TModel的实现中推断出对应的TElement类型:
// Base class for all assets public class AssetBase { } // Collection element of the editor model public class EditorElementModelBase { } // Editor model (abstract) public abstract class EditorModelBase<TAsset, TElement> where TAsset : AssetBase where TElement : EditorElementModelBase { public BindingList<TElement> Elements { get; protected init; } } // 简化后的EditorBase,仅保留TAsset和TModel参数 public abstract class EditorBase<TAsset, TModel> where TAsset : AssetBase where TModel : EditorModelBase<TAsset, var> // 用var让编译器自动推断TElement { // 示例:访问Elements属性,类型会被正确推断 public void ProcessElements(TModel model) { foreach (var element in model.Elements) { // element的类型自动匹配具体的TElement实现(如ItemElement) } } } // 实现类无需再重复传入TElement public class Item : AssetBase { } public class ItemElement : EditorElementModelBase { } public class ItemEditorModel : EditorModelBase<Item, ItemElement> { } public class ItemEditor : EditorBase<Item, ItemEditorModel> { } // 不再需要第三个参数!
这个方案完全匹配你的需求,代码简洁且类型安全,不需要额外的接口或反射逻辑。
方案2:低版本C#的兼容方案(C# 11及以下)
如果项目仍在使用C# 11或更低版本,可以通过让EditorModelBase公开TElement类型信息的方式,避免实现类重复传入参数:
步骤1:在EditorModelBase中添加类型标识
public abstract class EditorModelBase<TAsset, TElement> where TAsset : AssetBase where TElement : EditorElementModelBase { public BindingList<TElement> Elements { get; protected init; } // 公开TElement的静态类型信息 public static Type ElementType => typeof(TElement); // 可选:提供创建TElement实例的抽象方法 public abstract TElement CreateNewElement(); }
步骤2:简化EditorBase的实现
此时EditorBase仍需在约束中声明TElement,但实现类无需手动传入第三个参数,编译器会自动从TModel推断:
public abstract class EditorBase<TAsset, TModel> where TAsset : AssetBase where TModel : EditorModelBase<TAsset, TElement>, new() where TElement : EditorElementModelBase { // 示例:获取TElement类型并打印 public void LogElementType() { Console.WriteLine(TModel.ElementType.Name); } // 示例:创建TElement实例 public TElement GenerateElement() { var model = new TModel(); return model.CreateNewElement(); } } // 实现类写法(无需传入TElement) public class ItemEditor : EditorBase<Item, ItemEditorModel> { }
这种方案兼容性更好,虽然EditorBase的约束仍保留TElement,但实现类无需重复填写,解决了繁琐的复制问题。
内容的提问来源于stack exchange,提问作者Roger Wolf
相关产品推荐
相关产品推荐

