嵌套菜单构建器在c#中永远不会正确结束

本文关键字:结束 永远 构建 菜单 嵌套 | 更新日期: 2023-09-27 18:16:42

这里我正在构建具有n个叶子和分支的菜单构建器,现在我无法正确返回构建器的引用。

代码

public interface IMenuBuilder
{
    IMenuBuilder AddLeaf(string name);
    ISubMenuBuilder AddBranch(string name);
    void Build();
}
public interface ISubMenuBuilder : IMenuBuilder
{
    ISubMenuBuilder AddLeaf(string name);
    INestSubMenuBuilder AddBranch(string name);
    IMenuBuilder Build();
}
public interface INestSubMenuBuilder : ISubMenuBuilder
{
    INestSubMenuBuilder AddLeaf(string name);
    INestSubMenuBuilder AddBranch(string name);
    ISubMenuBuilder Build();
}
public class MenuBuilder : IMenuBuilder
{
    List<Menu> menus = new List<Menu>();
    public IMenuBuilder AddLeaf(string name)
    {
        var menu = new RootMenu { Name = name };
        menus.Add(menu);
        return this;
    }
    public ISubMenuBuilder AddBranch(string name)
    {
        var menu = new RootMenu { Name = name };
        menus.Add(menu);
        return new SubMenuBuilder(this, menu);
    }
    public void Build()
    {
    }
}
public class SubMenuBuilder : ISubMenuBuilder
{
    private IMenuBuilder menuBuilder;
    private ISubMenuHolder menu;
    public SubMenuBuilder(IMenuBuilder menuBuilder, ISubMenuHolder menu)
    {
        this.menuBuilder = menuBuilder;
        this.menu = menu;
    }
    protected SubMenuBuilder(ISubMenuHolder menu) 
    {
        this.menu = menu;
    }
    public ISubMenuBuilder AddLeaf(string name)
    {
        var leafMenu = new LeafMenu { Name = name };
        leafMenu.ParentId = (leafMenu as Menu).Id;
        menu.AddSubMenu(leafMenu);
        return this;
    }
    public INestSubMenuBuilder AddBranch(string name)
    {
        var branchMenu = new BranchMenu { Name = name };
        branchMenu.ParentId = (branchMenu as Menu).Id;
        menu.AddSubMenu(branchMenu);
        return new NestSubMenuBuilder(this, branchMenu);
    }
    public IMenuBuilder Build()
    {
        return menuBuilder;
    }

    IMenuBuilder IMenuBuilder.AddLeaf(string name)
    {
        this.AddLeaf(name);
        return this;
    }
    ISubMenuBuilder IMenuBuilder.AddBranch(string name)
    {
        this.AddBranch(name);
        return this;
    }
    void IMenuBuilder.Build()
    {
    }
}
public class NestSubMenuBuilder : INestSubMenuBuilder
{
    private ISubMenuBuilder subMenuBuilder;
    private ISubMenuHolder branchMenu;
    public NestSubMenuBuilder(ISubMenuBuilder subMenuBuilder, ISubMenuHolder branchMenu)
    {
        this.subMenuBuilder = subMenuBuilder;
        this.branchMenu = branchMenu;
    }
    public INestSubMenuBuilder AddLeaf(string name)
    {
        var leafMenu = new LeafMenu { Name = name };
        leafMenu.ParentId = (leafMenu as Menu).Id;
        branchMenu.AddSubMenu(leafMenu);
        return this;
    }
    public ISubMenuBuilder Build()
    {
        return subMenuBuilder;
    }
    public INestSubMenuBuilder AddBranch(string name)
    {
        var menu = new BranchMenu { Name = name };
        menu.ParentId = (branchMenu as Menu).Id;
        branchMenu.AddSubMenu(menu);
        return new NestSubMenuBuilder(this, menu);
    }
    ISubMenuBuilder ISubMenuBuilder.AddLeaf(string name)
    {
        this.AddLeaf(name);
        return this;
    }
    IMenuBuilder ISubMenuBuilder.Build()
    {
        return subMenuBuilder;
    }
    IMenuBuilder IMenuBuilder.AddLeaf(string name)
    {
        this.AddLeaf(name);
        return this;
    }
    ISubMenuBuilder IMenuBuilder.AddBranch(string name)
    {
        this.AddBranch(name);
        return this;
    }
    void IMenuBuilder.Build()
    {
    }
}

这是我的构建器的代码,这里是一个例子,我得到了问题,而使用这个构建器API。

        builder
              .AddLeaf("Leaf 4")
              .AddBranch("Branch 2") //  subMenuBuilder
                    .AddLeaf("Branch 2 -> Leaf 1")
                    .AddBranch("Branch 2 -> Branch 1") //nestSubMenuBuilder 1
                            .AddLeaf("Branch 2 -> Branch 1 -> Leaf 3")
                            .AddBranch("Branch 2 -> Branch 1 -> Branch 1") //nestSubMenuBuilder 2
                                .AddLeaf("Branch 2 -> Branch 1 -> Branch 1 -> Leaf 1")
                                .Build() // nestSubMenuBuilder 1
                            .AddLeaf("Branch 2 -> Leaf 4")
                            .Build() //  subMenuBuilder
                     .AddLeaf("Branch 2 -> Leaf 2")
                     .Build();// menubuilder 

这里我没有得到最后一个菜单构建器引用回来添加新的叶子和分支。

嵌套菜单构建器在c#中永远不会正确结束

您的问题是,您的代码为每个菜单级别返回不同的构建器对象。相反,您应该始终返回相同类型的构建器,并且当到达顶层时,只需从Build()

返回null

建议的构建器代码:

public interface IMenuBuilder
{
    IMenuBuilder AddLeaf(string name);
    IMenuBuilder AddBranch(string name);
    IMenuBuilder Build();
}
public class MenuBuilder : IMenuBuilder
{
    private IMenuBuilder menuBuilder;
    private ISubMenuHolder menu;
    /// <summary>
    /// Create a new menu with specified root item
    /// </summary>
    public MenuBuilder(string rootName)
    {
        this.menuBuilder = null;
        this.menu = new RootMenu { Name = rootName };
    }
    /// <summary>
    /// Create a new sub menu with specified parents
    /// </summary>
    public MenuBuilder(IMenuBuilder parentBuilder, ISubMenuHolder menu)
    {
        this.menuBuilder = parentBuilder;
        this.menu = menu;
    }
    public IMenuBuilder AddLeaf(string name)
    {
        var leafMenu = new LeafMenu { Name = name };
        leafMenu.ParentId = menu.Id;
        menu.AddSubMenu(leafMenu);
        return this;
    }
    public IMenuBuilder AddBranch(string name)
    {
        var branchMenu = new BranchMenu { Name = name };
        branchMenu.ParentId = menu.Id;
        menu.AddSubMenu(branchMenu);
        return new MenuBuilder(this, branchMenu);
    }
    public IMenuBuilder Build()
    {
        return menuBuilder;
    }
}