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

C#中如何实现多所有权接口的函数与实现复用

解决方案:C# 中可组合的资源所有权实现

针对你遇到的「多资源所有权复用」问题,以下是几种简洁且符合C#设计习惯的实现方案:


方案1:正确使用C# 8+接口默认实现(推荐)

你之前的误区在于认为接口默认实现需要向下转型——实际上,接口默认实现可以直接访问自身定义的属性,只要实现类正确实现接口的属性,默认方法就能直接复用,无需重复编码。

public class A 
{
    public string Name { get; set; } = string.Empty;
}

public class B
{
    public string Name { get; set; } = string.Empty;
}

// 带默认实现的A所有权接口
public interface IAOwner
{
    List<A> AList { get; set; }

    // 默认实现直接访问接口定义的AList属性
    public A? GetA(string name)
    {
        return AList.FirstOrDefault(a => a.Name.Equals(name, StringComparison.OrdinalIgnoreCase));
    }
}

// 带默认实现的B所有权接口
public interface IBOwner
{
    List<B> BList { get; set; }

    public B? GetB(string name)
    {
        return BList.FirstOrDefault(b => b.Name.Equals(name, StringComparison.OrdinalIgnoreCase));
    }
}

// 同时拥有A和B的所有者类,只需实现属性,自动继承默认方法
public class ABFullOwner : IAOwner, IBOwner
{
    public List<A> AList { get; set; } = new List<A>();
    public List<B> BList { get; set; } = new List<B>();

    // 自定义所有者专属逻辑
    public void PerformOwnerTask()
    {
        // ...
    }
}

// 仅拥有A的所有者类
public class AOnlyOwner : IAOwner
{
    public List<A> AList { get; set; } = new List<A>();
    // 自动拥有GetA方法,无需重写
}

如果需要自定义某类所有者的查询逻辑,直接重写默认方法即可:

public class CustomAOwner : IAOwner
{
    public List<A> AList { get; set; } = new List<A>();

    // 重写默认实现,添加模糊匹配逻辑
    public A? GetA(string name)
    {
        return AList.FirstOrDefault(a => a.Name.Contains(name, StringComparison.OrdinalIgnoreCase));
    }
}

优点:

  • 完全复用通用逻辑,无重复代码
  • 组合灵活,按需实现对应所有权接口
  • 不受C#单继承限制

方案2:扩展方法(兼容C# 8之前版本)

如果项目使用的是C# 8以下版本,不支持接口默认实现,可以用扩展方法封装通用所有权逻辑:

public interface IAOwner
{
    List<A> AList { get; set; }
}

public static class IAOwnerExtensions
{
    public static A? GetA(this IAOwner owner, string name)
    {
        return owner.AList.FirstOrDefault(a => a.Name == name);
    }
}

public interface IBOwner
{
    List<B> BList { get; set; }
}

public static class IBOwnerExtensions
{
    public static B? GetB(this IBOwner owner, string name)
    {
        return owner.BList.FirstOrDefault(b => b.Name == name);
    }
}

使用时,实现接口后直接调用扩展方法即可:

var owner = new AOnlyOwner();
var targetA = owner.GetA("TestA");

缺点:扩展方法无法被重写,若需自定义逻辑必须手动实现对应方法。


方案3:组合模式(封装所有权逻辑)

如果需要更严格的封装,或动态调整所有权组合,可以将所有权逻辑封装为独立类,通过组合而非继承实现:

// 封装A所有权逻辑的独立类
public class AOwnerLogic
{
    public List<A> AList { get; set; } = new List<A>();

    public A? GetA(string name)
    {
        return AList.FirstOrDefault(a => a.Name == name);
    }
}

// 封装B所有权逻辑的独立类
public class BOwnerLogic
{
    public List<B> BList { get; set; } = new List<B>();

    public B? GetB(string name)
    {
        return BList.FirstOrDefault(b => b.Name == name);
    }
}

// 同时拥有A和B的所有者类
public class ABFullOwner
{
    private readonly AOwnerLogic _aOwner = new AOwnerLogic();
    private readonly BOwnerLogic _bOwner = new BOwnerLogic();

    // 暴露必要的属性和方法
    public List<A> AList => _aOwner.AList;
    public A? GetA(string name) => _aOwner.GetA(name);

    public List<B> BList => _bOwner.BList;
    public B? GetB(string name) => _bOwner.GetB(name);

    // 自定义逻辑
    public void DoOwnerWork()
    {
        // ...
    }
}

优点:

  • 所有权逻辑独立可复用、可单独测试
  • 可隐藏内部列表,仅暴露必要方法
  • 支持动态添加/移除所有权(比如通过构造函数注入逻辑类)

缺点:需要手动转发属性和方法,代码量略多,可通过代码生成工具简化。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 21:13:25