1

我正在玩数据构建器模式,但我无法理解某些行为。我在下面写了我想要实现的简化版本

    public abstract class DataBuilderParent
    {
        private MyParent myParent;

        protected void SetDataBuilder(MyParent myParent)
        {
            this.myParent = myParent;
        }

        public DataBuilderParent WithId(int id)
        {
            myParent.Id = id;
            return this;
        }
    }

    public class DataBuilderChild : DataBuilderParent
    {
        private readonly MyChild myChild = new MyChild();

        public DataBuilderChild()
        {
            base.SetDataBuilder(myChild);
        }

        public DataBuilderChild WithDescription(string description)
        {
            myChild.Description = description;
            return this;
        }

        private MyChild Build()
        {
            return myChild;
        }

        public static implicit operator MyChild(DataBuilderChild dataBuilder)
        {
            return dataBuilder.Build();
        }
    }

    public class MyParent
    {
        public int Id { get; set; }
    }

    public class MyChild : MyParent
    {
        public string Description { get; set; }
    }

上面代码的使用

   internal class Program
   {
     private static void Main(string[] args)
     {
        MyChild child = new DataBuilderChild().WithDescription("");
     }
   }

现在它将为我创建孩子,智能感知也显示我可以这样做 new DataBuilderChild().WithId(1).WithDescription(""); 但是,当我尝试构建它时,它失败了。我不明白为什么我无法访问此方法?它是公开的,并且可以通过智能感知看到。任何人都可以解释如何使它工作吗?谢谢

编辑

错误消息是:错误 1 ​​无法将类型 'TestProgram.Program.DataBuilderParent' 隐式转换为 'TestProgram.Program.MyChild' C:\Apps\TestProgram\Program.cs 44 29 TestProgram

4

2 回答 2

1

WithIdis的返回值,DataBuilderParent没有定义方法WithDescription;这仅在派生类中定义DataBuilderChild。显然,您的目标是在类层次结构上拥有一些命名构造函数习语,而不能以这种方式实现。

此外,如错误消息中所述,未定义强制转换DataBuilderParent运算符,既不是 toMyChild也不是 to MyParent,而是定义了强制转换运算符 to 。DataBuilderChildMyChild

于 2015-01-05T13:27:03.037 回答
1

我只是从评论中重构了我的答案。

public class MyParent
{
    public int Id { get; set; }
}

public class MyChild : MyParent
{
    public string Description { get; set; }
}

将类中的 WithDescription 方法DataBuilderParent设为abstract.

public abstract class DataBuilderParent
{
    private MyParent myParent;

    protected void SetDataBuilder(MyParent myParent)
    {
        this.myParent = myParent;
    }

    public DataBuilderParent WithId(int id)
    {
        myParent.Id = id;
        return this;
    }

    public abstract DataBuilderParent WithDescription(string description);

    private MyChild BuildAsChild()
    {
        return myParent as MyChild;
    }

    private MyParent Build()
    {
        return myParent;
    }

    public static implicit operator MyChild(DataBuilderParent dataBuilder)
    {
        return dataBuilder.BuildAsChild();
    }

    public static implicit operator MyParent(DataBuilderParent dataBuilder)
    {
        return dataBuilder.Build();
    }
}

然后DataBuilderChild

public class DataBuilderChild : DataBuilderParent
{
    private readonly MyChild myChild = new MyChild();

    public DataBuilderChild()
    {
        base.SetDataBuilder(myChild);
    }

    public override DataBuilderParent WithDescription(string description)
    {
        myChild.Description = description;
        return this;
    }

    private MyChild Build()
    {
        return myChild;
    }

    public static implicit operator MyChild(DataBuilderChild dataBuilder)
    {
        return dataBuilder.Build();
    }
}

然后你会像这样构建

class Program
{
    static void Main(string[] args)
    {
        var childBuilder = new DataBuilderChild().WithId(1).WithDescription("Child");

        MyParent parent = childBuilder;

        MyChild child = childBuilder;

        Console.WriteLine(@"Parent With Id {0}", parent.Id);

        Console.WriteLine(@"Child With Id {0} and Desciprtion - {1}", child.Id, child.Description);

        Console.ReadKey();
    }
}
于 2015-01-07T12:31:14.027 回答