Внедрение зависимостей и синтаксис C # - PullRequest
2 голосов
/ 23 марта 2009

Интересно, кто-нибудь может объяснить синтаксис в одной строке этого фрагмента код:

public class ContactController : Controller
{
    private IContactManagerRepository _repository;

    **public ContactController()
        : this(new EntityContactManagerRepository())**
    {}


    public ContactController(IContactManagerRepository repository)
    {
        _repository = repository;
    }

Особенно меня интересует первый конструктор. я понять из статьи, я получил это от (http://www.asp.net/learn/mvc/tutorial-29-cs.aspx - список 3), что первый конструктор вызывает второй, а intellisense сообщает мне, когда я наведу над этим (новый EntityContactManagerRepository ()), к которому он действительно относится второй конструктор Но я не видел конструктора с двоеточием после это раньше. Я знаю, что двоеточие в объявлении класса говорит компилятор, который ContactController наследует от контроллера, но что делает двоеточие в конструкторе делать?

Ответы [ 6 ]

5 голосов
/ 23 марта 2009

Как вы сказали, он просто вызывает другой конструктор как первую часть выполнения. Альтернативой является использование base, который вместо этого вызывает конструктор в базовом классе. В спецификации языка используется термин инициализатор конструктора для этого вызова. всегда примерно так: если вы ничего не указали, это эквивалентно вызову base(). Другими словами:

public Foo(int x)

эквивалентно

public Foo(int x) : base()

В обоих случаях конструктор без параметров базового класса вызывается перед выполнением тела конструктора Foo. Компилятор гарантирует, что вы не попадете в бесконечный цикл - каждый (нестатический) класс должен иметь хотя бы один конструктор, который вызывает конструктор базового класса; вы всегда заканчиваете тем, что вызываете конструктор базового класса до того, как тело конструктора для класса «this» будет выполнено.

Однако, в отличие от Java, инициализаторы переменных экземпляра выполняются до вызова конструктора базового класса.

См. Мою статью о цепочке конструктора для получения дополнительной информации.

3 голосов
/ 23 марта 2009

Это называется конструктор цепочкой . С этим синтаксисом вы можете вызвать конструктор базового класса или другой конструктор текущего класса.

1 голос
/ 23 марта 2009

Это результат (обходной путь) отсутствия поддержки необязательных параметров / параметров по умолчанию. Вы можете оказаться в таких ситуациях, как:

MessageBox.Show(string)
...
MessageBox.Show(Window, string, string)
...
MessageBox.Show(Window, string, string, MessageBoxButton, MessageBoxImage, MessageBoxResult, MessageBoxOptions)

В этих случаях обычно тот, у которого больше всего параметров, содержит реализацию, а другие перегрузки просто вызывают его с параметрами по умолчанию. Стоит отметить, что когда число параметров увеличивается до N, количество перегрузок может возрасти до N!.

Конструкторы специальные функции , поэтому вы должны обращаться с ними так, как они этого заслуживают. Объект может быть построен только один раз. Помните, что в обычных функциях вы можете вызывать функцию реализации столько раз, сколько вам нужно. Здесь вам нужно вызвать конструктор один раз , и это также первое, что нужно сделать . Синтаксис цепочки конструктора указывает на эти требования.

Вернемся к исходной проблеме. Несмотря на то, что эти случаи не очень распространены, вы можете решить эту проблему, определив новый тип (здесь с использованием функций C # 3.0), который будет использоваться в качестве параметра:

public class Parameter
{
    public string P1 { get; set; }
    public int P2 { get; set; }
    public string P3 { get; set; }
    public double P4 { get; set; }
    ...
    public Parameter()
    {
        P1 = "p1";
        P2 = 2;
        P3 = "p3";
        P4 = 4.0;
        ...
    }
}
...
FunctionWithManyParametersCanNowBeCalledLike(new Parameter() { P2 = -2 });

Здесь мы предоставили параметры по умолчанию в конструкторе. Это решение для многих конструкторов? Нет.

C # 4.0 будет включать в себя опцию именованных параметров. Таким образом, нам даже не нужно определять новый тип параметра. Вы можете подумать, что это особенность как синтаксический сахар для этого, однако они отличаются. Нам все еще понадобится этот синтаксис для базового класса параметров конструктора.

1 голос
/ 23 марта 2009

Ваш пример использует конструктор цепочки. То есть конструктор по умолчанию вызывает конкретный конструктор с аргументом того же типа. Для этого вы используете ключевое слово this со всеми необходимыми аргументами, как в вашем примере.

Аналогичной функцией является использование ключевого слова base. Когда у вас есть иерархия классов, вы всегда вызываете конструкторы для всех типов в иерархии. Например, если у вас есть класс B и класс D, вы вызовете конструктор B, а затем конструктор D, когда создадите экземпляр D. Для конструкторов по умолчанию (т.е. без аргументов) вам не нужно ничего делать. Однако, если B реализует только конструктор, требующий аргумента, вам нужно каким-то образом передать его из конструктора D. Для этого вы используете ключевое слово base, аналогичное тому, как this используется в вашем примере.

1 голос
/ 23 марта 2009

Эта функция называется Инициализаторы конструктора .

0 голосов
/ 23 марта 2009

Двоеточие используется, чтобы указать, что вы вызываете другой конструктор из того же класса (как в вашем примере) или конструктор из базового класса, используя :base(..args...)

Этот синтаксис используется для принудительного вызова других конструкторов или базовых конструкторов перед выполнением какой-либо дополнительной работы (т. Е. Он обеспечивает первый порядок инициализации базового класса).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...