数据生成器模式问题
Databuilder pattern issue
我正在玩数据生成器模式,但我无法理解某些行为。
我在下面写了我想要实现的这个简化版本
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("");
}
}
现在它将为我创建 child,智能感知也显示我可以执行此操作 new DataBuilderChild().WithId(1).WithDescription("");
但是,当我尝试构建它时,它失败了。我不明白为什么我无法访问此方法?它是 public 并且智能感知可见。
任何人都可以解释如何让它工作吗?
谢谢
编辑
错误信息是:Error 1 Cannot implicitly convert type 'TestProgram.Program.DataBuilderParent' to 'TestProgram.Program.MyChild' C:\Apps\TestProgram\Program.cs 44 29 TestProgram
WithId
的return值为DataBuilderParent
,没有定义方法WithDescription
;这仅在派生 class DataBuilderChild
中定义。显然,您的目标是在 class 层次结构上使用一些 Named Constructor 习语,这种方式无法实现。
此外,DataBuilderParent
没有定义转换运算符,既没有定义为 MyChild
也没有定义为 MyParent
,而 DataBuilderChild
将转换运算符定义为 MyChild
,如错误消息中所述。
我刚刚根据评论重构了我的答案。
public class MyParent
{
public int Id { get; set; }
}
public class MyChild : MyParent
{
public string Description { get; set; }
}
将 DataBuilderParent
class 中的 WithDescription 方法设为 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();
}
}
我正在玩数据生成器模式,但我无法理解某些行为。 我在下面写了我想要实现的这个简化版本
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("");
}
}
现在它将为我创建 child,智能感知也显示我可以执行此操作 new DataBuilderChild().WithId(1).WithDescription(""); 但是,当我尝试构建它时,它失败了。我不明白为什么我无法访问此方法?它是 public 并且智能感知可见。 任何人都可以解释如何让它工作吗? 谢谢
编辑
错误信息是:Error 1 Cannot implicitly convert type 'TestProgram.Program.DataBuilderParent' to 'TestProgram.Program.MyChild' C:\Apps\TestProgram\Program.cs 44 29 TestProgram
WithId
的return值为DataBuilderParent
,没有定义方法WithDescription
;这仅在派生 class DataBuilderChild
中定义。显然,您的目标是在 class 层次结构上使用一些 Named Constructor 习语,这种方式无法实现。
此外,DataBuilderParent
没有定义转换运算符,既没有定义为 MyChild
也没有定义为 MyParent
,而 DataBuilderChild
将转换运算符定义为 MyChild
,如错误消息中所述。
我刚刚根据评论重构了我的答案。
public class MyParent
{
public int Id { get; set; }
}
public class MyChild : MyParent
{
public string Description { get; set; }
}
将 DataBuilderParent
class 中的 WithDescription 方法设为 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();
}
}