【问题标题】:Fluent interfaces (method chaining) with backwards navigation具有向后导航的流畅接口(方法链)
【发布时间】:2025-12-26 14:35:12
【问题描述】:

我需要构建一个使用方法链的类。我理解方法链的概念。示例:

class Company
{
    private String companyName;
    public setCompanyName(String companyName)
    {
        this.companyName = companyName;
        return this;
    }

    public Person addPerson(String name)
    {
         person = new Person();
         person.setName(name);

         return person;
    }
}

class Person
{
    private String name;
    private String address;
    private bool license

    public Person setName(String name)
    {
        this.name = name;
        return this;
    }

    public Person hasDriverLicense(bool license)
    {
        this.license = license;
        return this;
    }

    public Person setAddress(String address)
    {
        this.address = address;
        return this;
    }
}

//in some other class / method i do:
Company company = new Company()
.setCompanyName("SomeCompany")
.addPerson("Mike")
.setAddress("Street 118");

但我需要更进一步。我需要能够做到这一点:

Company company = new Company()
.setCompanyName("SomeCompany")
.addPerson("Mike")
.setAddress("Street 118");
.addPerson("Jane")
.setAddress("Street 342");
.hasDriverLicense(true)

如您所见,我需要能够继续进行链接。 addAddress 方法并不总是链中的最后一个方法。它可以是Person 类中的任何方法。

有没有实现此功能的好方法?也许有方法扩展之类的?

非常感谢任何帮助/示例。

【问题讨论】:

  • 我不得不问... 为什么您希望这一切都是一种连续严肃的方法吗?您不能只存储公司并从中多次调用 addPerson 吗? var company = ...; company.addPerson(...).setAddress(...); company.addPerson(...).setAddress(...); ?
  • 甚至更好...只是对象/集合初始化器? var company = new Company { Name = "SomeCompany", People = { new Person {Name = Mike", Address = "Street 118"}, new Person {Name="Jane", Address = "Street 342", HasDriverLicence = true}}};(在 IDE 中看起来比在一条评论中更漂亮!)

标签: c# extension-methods fluent-interface method-chaining


【解决方案1】:

可以做到。这并不意味着您应该

Person 和 Company 的方法应该简单地返回一个在上下文中聚合个人和公司的对象。如果您有 IPerson 接口和 ICompany 接口,则此类型将实现两者,在内部保存对两者的引用,并将适当地分派调用。 (对 IPerson 方法的调用将委托给内部 IPerson)。

话虽如此,我强烈反对你走这条路。它令人困惑,很难调试并且违反了基本的 OO 原则(例如接口隔离)。

【讨论】:

  • 谢谢,因为你和我得到的 cmets,我现在确定我应该采取不同的方法。