2016-05-17 3 views
0

У меня есть класс, который выглядит как:Косвенно передавая параметр в базовый конструктор

public class WidgetDao : AbstractDao<Widget>, IWidgetDao 
{ 
    public WidgetDao(ISession session) 
     : base (session) 
    { 

    } 
} 

Мой код должен построить ошибки, если я пытаюсь удалить этот конструктор на код, который выглядит как:

public IWidgetDao GetWidgetDao() 
{ 
    return _widgetDao ?? (_widgetDao = new WidgetDao(_session)); 
} 

I я понимаю, почему я получаю ошибку сборки ... нет явного конструктора WidgetDao, который принимает один параметр. Однако WidgetDao наследует от AbstractDao<Widget>, у которого есть конструктор, который принимает один параметр.

Я не понимаю, почему компилятор C# сделает явный конструктор необходимым для WidgetDao, когда все, что используется для этого, является передачей этого параметра базовому классу.

Может ли кто-то пролить свет на это для меня?

+2

«Я не понимаю, почему компилятор C# сделает явный конструктор, требуемый для WidgetDao, когда все, что используется для этого, является передачей этого параметра базовому классу». Поскольку конструкторы не наследуются, в основном ... и есть веские причины, по которым они не унаследованы *, но в противном случае каждый класс будет иметь конструктор без параметров, поскольку, например, 'object' имеет конструктор без параметров. В принципе, не пытайтесь удалить этот конструктор. –

+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#.

Смежные вопросы