我有一个看起来像这样的课程:
public class WidgetDao : AbstractDao<Widget>, IWidgetDao
{
public WidgetDao(ISession session)
: base (session)
{
}
}
如果我尝试在代码上删除此构造函数,我的代码会出现构建错误:
public IWidgetDao GetWidgetDao()
{
return _widgetDao ?? (_widgetDao = new WidgetDao(_session));
}
我理解为什么会出现构建错误的原因......没有明确的WidgetDao
构造函数,它接受一个参数。但是,WidgetDao
继承自AbstractDao<Widget>
,它有一个带有一个参数的构造函数。
我不明白为什么C#编译器会在WidgetDao
上使用显式构造函数,因为它的所有内容都是将参数传递给基类。
有人可以为我解释一下吗?
答案 0 :(得分:3)
不幸的是,没有办法自动化这个。 C#将为您的对象提供的唯一隐式构造函数是默认的无参数构造函数,并且只有在代码中没有替代方法时才会这样做。我马上就会在此基础上建立,但仅仅是为了基础信息......
隐式MyClass()
构造函数:
public class MyClass
{
}
在上面的例子中,编译器假设你想要一个公共无参数构造函数,它除了允许你创建一个对象之外什么都不做。即使您没有创建构造函数,也可以整天致电new MyClass()
。
现在,当您创建自己的构造函数时会发生什么?
public class MyClass
{
public MyClass(string name)
{
Name = name;
}
public string Name { get; private set; }
}
在这种情况下,隐式无参数构造函数仍然存在,但现在它是私有的。这意味着您不能再打电话给new MyClass()
并且需要提供姓名。
现在让我们的课成为一个抽象的基类:
public abstract class AbstractMyClass
{
protected AbstractMyClass(string name)
{
Name = name;
}
public string Name { get; private set; }
public abstract void DoSomething();
}
无法实例化抽象类,因此构建构造函数protected
是最佳实践。即使您制作了public
,也无法直接访问它们。重要的是同样的警告:默认的无参数构造函数现在是私有的。任何实现此基类的类都必须为name
提供值,否则该类未完全实例化。
public class SeansClass
{
public SeansClass() : base("Sean") { }
public void DoSomething() { }
}
在这种情况下,我们重新引入了标准的无参数构造函数,并为我们的类提供了name
。这是完全有效的代码。 唯一需要注意的是,base()
调用中提供的值必须是编译时常量或从传递给您的类的参数计算得出。 始终首先评估base()
方法。
C#无法假设您实际上希望基类的所有实现都具有相同的构造函数。每个类可以添加构造函数或为基类提供自己的值。这仅仅是C#的限制。