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

.NET 6 Web API中如何避免多类继承的属性重复?

解决C#单继承限制下的属性重复问题

针对你的场景,核心问题是C#不支持类多继承导致的重复属性定义,这里提供几种实用的解决方案:

方案1:组合模式(推荐)

把重复的MapDepartment、MapAnother1等属性提取到独立的类中,然后在两个参数类里通过组合复用这个类的实例,既避免重复代码,又保持类结构的灵活性。

实现代码:

// 提取所有重复属性到单独的类中
public class ProgramFilterAttributes
{
    public bool? MapDepartment { get; set; }
    public bool? MapAnother1 { get; set; }
    // 其他需要复用的属性
}

// 非分页参数类:继承QueryStringParameters + 组合复用过滤属性
public class ProgramParameters : QueryStringParameters
{
    public ProgramFilterAttributes Filters { get; set; } = new();

    // 如果需要保持原有API的属性访问方式(不希望通过.Filters跳转),可以包装属性:
    public bool? MapDepartment
    {
        get => Filters.MapDepartment;
        set => Filters.MapDepartment = value;
    }

    public bool? MapAnother1
    {
        get => Filters.MapAnother1;
        set => Filters.MapAnother1 = value;
    }
}

// 分页参数类:继承QueryStringParametersPaginated + 组合复用过滤属性
public class ProgramParametersPaginated : QueryStringParametersPaginated
{
    public ProgramFilterAttributes Filters { get; set; } = new();

    // 同样包装属性以保持原有访问方式
    public bool? MapDepartment
    {
        get => Filters.MapDepartment;
        set => Filters.MapDepartment = value;
    }

    public bool? MapAnother1
    {
        get => Filters.MapAnother1;
        set => Filters.MapAnother1 = value;
    }
}

优点:

  • 完全消除重复代码,所有过滤属性只维护一次
  • 符合SOLID原则中的单一职责,过滤逻辑和分页逻辑分离
  • 灵活度高,后续新增过滤属性只需修改ProgramFilterAttributes

方案2:调整继承层级 + 接口规范分页属性

如果希望保留类继承的结构,可以把重复属性放到一个基础参数类中,再通过接口来定义分页属性的规范,避免多继承冲突。

实现代码:

// 定义分页属性的接口
public interface IPaginatedParams
{
    int PageNumber { get; set; }
    int PageSize { get; set; }
    // 其他分页相关属性
}

// 基础Program参数类:继承QueryStringParameters + 包含所有重复属性
public class ProgramBaseParams : QueryStringParameters
{
    public bool? MapDepartment { get; set; }
    public bool? MapAnother1 { get; set; }
    // 其他复用属性
}

// 非分页参数直接使用基础类
public class ProgramParameters : ProgramBaseParams { }

// 分页参数类:继承基础类 + 实现分页接口
public class ProgramParametersPaginated : ProgramBaseParams, IPaginatedParams
{
    public int PageNumber { get; set; } = 1; // 设置默认值
    public int PageSize { get; set; } = 10;
}

优点:

  • 继承层级清晰,非分页和分页参数类共享同一套过滤属性
  • 分页属性通过接口统一规范,便于后续其他参数类复用分页逻辑

方案3:使用接口默认实现(C# 8.0+)

如果项目使用C# 8.0及以上版本,可以利用接口的默认实现来复用属性逻辑,但注意接口无法直接存储状态,需要结合内部存储容器,适合简单场景:

实现代码:

public interface IProgramFilterParams
{
    private Dictionary<string, object?> _filterValues { get; } = new();

    bool? MapDepartment
    {
        get => _filterValues.TryGetValue(nameof(MapDepartment), out var value) ? (bool?)value : null;
        set => _filterValues[nameof(MapDepartment)] = value;
    }

    bool? MapAnother1
    {
        get => _filterValues.TryGetValue(nameof(MapAnother1), out var value) ? (bool?)value : null;
        set => _filterValues[nameof(MapAnother1)] = value;
    }
}

// 非分页参数类
public class ProgramParameters : QueryStringParameters, IProgramFilterParams { }

// 分页参数类
public class ProgramParametersPaginated : QueryStringParametersPaginated, IProgramFilterParams { }

注意:

  • 接口的私有成员是C# 8.0新增特性,需要确保项目语言版本支持
  • 这种方式的状态存储不够直观,复杂场景下不如组合模式易维护

内容的提问来源于stack exchange,提问作者RoLYroLLs

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 03:40:13