将参数隐式传递给基础构造函数

时间:2016-05-17 17:35:33

标签: c# constructor

我有一个看起来像这样的课程:

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上使用显式构造函数,因为它的所有内容都是将参数传递给基类。

有人可以为我解释一下吗?

1 个答案:

答案 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#的限制。

相关问题