首页 文章

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

提问于
浏览
0

我有一个类看起来像:

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 回答

  • 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();
    }
    

    有's no way to instantiate an abstract class, so it'是制作构造函数的最佳实践 protected . 即使你制作它们 public 也无法直接访问它们 . 重要的是同样的警告:默认的无参数构造函数现在是私有的 . 任何实现此基类的类都必须为 name 提供值,否则该类未完全实例化 .

    public class SeansClass
    {
        public SeansClass() : base("Sean") { }
    
        public void DoSomething() { }
    }
    

    在这种情况下,我们重新引入了标准的无参数构造函数,并为我们的类提供了 name . 这是完全有效的代码 . 唯一需要注意的是 base() 调用中提供的值必须是 compile time constantcalculated from the parameter 传入您的类 . 始终首先评估 base() 方法 .

    C#没有办法假设您实际上希望基类的所有实现都具有相同的构造函数 . 每个类可以添加构造函数或为基类提供自己的值 . 这仅仅是C#的限制 .

相关问题