You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否去除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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 09:07:02