鉴于下面的两个类,我想使用int参数调用Child构造函数,然后使用int参数调用父构造函数,并使用Child无参数构造函数。
这可以在不使用可选参数的情况下完成吗?
public class Parent
{
public Parent()
{
Console.WriteLine("Parent ctor()");
}
public Parent(int i)
{
Console.WriteLine("Parent ctor(int)");
}
}
public class Child:Parent
{
public Child()
{
Console.WriteLine("Child ctor()");
}
public Child(int i)
{
Console.WriteLine("Child ctor(int)");
}
}
这是.NET 4中我们想要在.NET 2.0中实现的逻辑
public class Parent2
{
public Parent2(int? i = null)
{
Console.WriteLine("Parent2 ctor()");
if (i != null)
{
Console.WriteLine("Parent2 ctor(int)");
}
}
}
public class Child2 : Parent2
{
public Child2(int? i = null)
: base(i)
{
Console.WriteLine("Child2 ctor()");
if (i != null)
{
Console.WriteLine("Child2 ctor(int)");
}
}
}
以下是我们讨论的生产代码
public class DataPoint<T>
{
public DataPoint() { }
public DataPoint(T xValue, int yValue)
{
XAxis = xValue;
YAxis = yValue;
}
public T XAxis { get; set; }
public int YAxis { get; set; }
}
public class DataPointCollection<T> : DataPoint<T>
{
DataPointCollection()
{
Labels = new List<string>();
}
DataPointCollection(T xValue, int yValue)
: base(xValue, yValue)
{ }
public List<string> Labels { get; set; }
}
修改
此时问题的原因是“Code Golf”学术练习以最少的代码遵循DRY方法。正常模式是在类中使用内部私有函数,该函数具有从每个构造函数执行的公共代码。
编辑2
我添加了示例生产代码。
答案 0 :(得分:2)
不,您不能这样做,因为您无法从Child
致电Parent
构造函数。
答案 1 :(得分:1)
如果您需要一系列初始化方法,我建议您将它们定义为 - 正常(非构造函数)方法。您可以使用可覆盖的受保护方法来设置来回,因为构造函数可以选择以任何组合或顺序调用哪些初始化方法:
public class Parent {
public Parent() { }
public Parent(int i) {
initWithArg(i);
initNoArgs();
}
virtual protected void initWithArg(int i) {
Console.WriteLine("Parent initWithArg(int)");
}
virtual protected void initNoArgs() {
Console.WriteLine("Parent initNoArgs");
}
}
public class Child : Parent {
// Override the *parameterless* constructor
public Child(int i) : base() {
initWithArg(i);
base.initWithArg(i);
initNoArgs();
}
override protected void initWithArg(int i) {
Console.WriteLine("Child initWithArg(int)");
}
override protected void initNoArgs() {
Console.WriteLine("Child initNoArgs");
}
}
答案 2 :(得分:0)
Inheritance仅适用于单向。
Child
---&gt; Parent
你可能有一个结构错误,因为(有人纠正我,如果我错了)没有任何情况你必须在温和的时候调用同一个类的两个构造函数。
除了递归构造函数,因为它调用自身,所以它不是一回事。
答案 3 :(得分:0)
您可以通过定义Child(int i)
构造函数来完成问题的第一部分:
public Child(int i) : base(i)
{
Console.WriteLine("Child ctor(int)");
}
但是,如上所述,您无法随后调用另一个Child
的构造函数。如果您的实际目标(假设这不是一个纯粹的学术问题)是确保Child
的默认构造函数中包含的某些标准行为始终执行,那么最好将其封装在一个方法并从Child
的每个构造函数中调用它:
public class Child:Parent
{
public Child()
{
Console.WriteLine("Child ctor()");
CommonChildConstructionBehaviour();
}
public Child(int i) : base(i)
{
Console.WriteLine("Child ctor(int)");
CommonChildConstructionBehaviour();
}
private void CommonChildConstructionBehaviour()
{
Console.WriteLine("All child constructors must call me.");
}
}
答案 4 :(得分:0)
有一些选择,但没有一个是完美的。最后,我的主要建议是升级到.NET 4.0,如果可以的话(显然)。
这是一个选项,使用一个对象,然后将其转换为你需要的内容。这是明显的缺点,因为你将失去打字或打破签名,但它可能适合你的情况,我不知道:
public class Parent3
{
public Parent3(object i)
{
Console.WriteLine("Parent3 ctor()");
if (i != null)
{
Console.WriteLine("Parent3 ctor(int)");
}
}
}
public class Child3 : Parent3
{
public Child3(object i)
: base(i)
{
Console.WriteLine("Child3 ctor()");
if (i != null)
{
Console.WriteLine("Child3 ctor(int)");
}
}
}
这是另一种选择,使用Init方法。但是,它们不会以完全相同的顺序触发,但它可能适合您。
public class Parent
{
public Parent()
{
Init();
}
protected void Init()
{
Console.WriteLine("Parent ctor()");
}
public Parent(int i)
{
Init(i);
}
protected void Init(int i)
{
Console.WriteLine("Parent ctor(int)");
}
}
public class Child : Parent
{
public Child()
{
Init();
}
protected void Init()
{
Console.WriteLine("Child ctor()");
}
public Child(int i)
{
Init(i);
base.Init(i);
Init();
}
protected void Init(int i)
{
Console.WriteLine("Child ctor(int)");
}
}
然后这是你可以做到的一种我真的不推荐的方式,但无论如何我都会把它包括在内:
public class Parent
{
public Parent()
{
Console.WriteLine("Parent ctor()");
}
public Parent(int i)
{
Console.WriteLine("Parent ctor(int)");
}
}
public class Child : Parent
{
private static int _i; //this is likely to blow up at some point.
public Child() : base(_i)
{
Console.WriteLine("Child ctor()");
}
public Child(int i) : this()
{
_i = i;
Console.WriteLine("Child ctor(int)");
}
}