Почему не красиво в конструкторе вызывать вирт метод
От: Аноним  
Дата: 27.07.10 06:22
Оценка:
Я хочу в конструктор передать параметры и в нём же вызвать Connect который подключается к серверу. Метод Connect делаю виртуальным, т.к. способы подключения различны и в производных классах меняются. почему такой код не красив?
Re: Почему не красиво в конструкторе вызывать вирт метод
От: samius Япония http://sams-tricks.blogspot.com
Дата: 27.07.10 06:25
Оценка: +1
Здравствуйте, Аноним, Вы писали:

А>Я хочу в конструктор передать параметры и в нём же вызвать Connect который подключается к серверу. Метод Connect делаю виртуальным, т.к. способы подключения различны и в производных классах меняются. почему такой код не красив?


Это потенциально опасно тем, что будет вызван метод производного класса до того как отработает конструктор производного класса, а значит инициализирует все поля.
Re: Почему не красиво в конструкторе вызывать вирт метод
От: Аноним  
Дата: 27.07.10 06:28
Оценка: -1
Здравствуйте, Аноним, Вы писали:

А>Я хочу в конструктор передать параметры и в нём же вызвать Connect который подключается к серверу. Метод Connect делаю виртуальным, т.к. способы подключения различны и в производных классах меняются. почему такой код не красив?


При создании экземпляра подкласса будет вызван конструктор суперкласса, а то вызовет свою реализацию метода Connect, а не реализацию подкласса.
Re[2]: Почему не красиво в конструкторе вызывать вирт метод
От: samius Япония http://sams-tricks.blogspot.com
Дата: 27.07.10 06:29
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Аноним, Вы писали:


А>>Я хочу в конструктор передать параметры и в нём же вызвать Connect который подключается к серверу. Метод Connect делаю виртуальным, т.к. способы подключения различны и в производных классах меняются. почему такой код не красив?


А>При создании экземпляра подкласса будет вызван конструктор суперкласса, а то вызовет свою реализацию метода Connect, а не реализацию подкласса.


Это справедливо для C++, но не для .NET.
Re[2]: Почему не красиво в конструкторе вызывать вирт метод
От: Qbit86 Кипр
Дата: 27.07.10 06:30
Оценка: 8 (1)
Здравствуйте, Аноним, Вы писали:

А>При создании экземпляра подкласса будет вызван конструктор суперкласса, а то вызовет свою реализацию метода Connect, а не реализацию подкласса. :)


Это в C++ вызов вирт. метода из ктора приведёт к вызову метода родительского класса. (Указатель на vtable устанавливается дважды: инициализируется указателем на таблицу базового класса, впоследствии перезаписывается указателем на таблицу производного.)

В Дотнете не так, а как указал выше samius.
Глаза у меня добрые, но рубашка — смирительная!
Re[3]: Опоздал :)
От: Qbit86 Кипр
Дата: 27.07.10 06:31
Оценка: +1
Не успел :)
Глаза у меня добрые, но рубашка — смирительная!
Re: Почему не красиво в конструкторе вызывать вирт метод
От: _FRED_ Черногория
Дата: 27.07.10 06:50
Оценка: +1
Здравствуйте, Аноним, Вы писали:

А>Я хочу в конструктор передать параметры и в нём же вызвать Connect который подключается к серверу. Метод Connect делаю виртуальным, т.к. способы подключения различны и в производных классах меняются.


Лучше передавайте стратегию подключения.

А>почему такой код не красив?

abstract class A
{
  protected A(string host, int? port) {
    Connect(host, port);
  }

  protected virtual void Connect(string host, int? port) {
  }
}

class B : A
{
  public B(string host, int? port, string localPath) : base(host, port) {
    LocalPath = localPath ?? String.Empty;
  }

  public string LocalPath { get; private set; }

  protected override void Connect(string host, int? port) {
    InternalConnect(host, port, LocalPath); // Упс
  }
}


Получается, что производный класс завязан на то, что необходимые для подключения параметры передаются в базу и не может расширить их. С другой стороны, чем вызвана необходимость ввызова Connect именно из базы?

Со стратегиями может быть как-то так или даже как-то совсем иначе:
interface IConnection
{
  void Connect();
}

abstract class A
{
  protected A(IConnection connection) {
    if(connection == null) {
      throw new ArgumentNullException("connection");
    }//if

    Connection = connection;
    Connection.Connect();
  }

  protected IConnection Connection { get; private set; }
}

class B : A
{
  public B(string host, int? port) : base(new BConnection(host, port)) {
  }

  private sealed class BConnection : IConnection
  {
    public BConnection(string host, int? port) {
      // …
    }

    public void Connect() {
      //…
    }
  }
}

class C : A
{
  public B(string host, int? port, string localPath) : base(new CConnection(host, port, localPath)) {
  }

  private sealed class CConnection : IConnection
  {
    public BConnection(string host, int? port, string localPath) {
      // …
    }

    public void Connect() {
      //…
    }
  }
}
Help will always be given at Hogwarts to those who ask for it.
Re: Почему не красиво в конструкторе вызывать вирт метод
От: Sharov Россия  
Дата: 27.07.10 07:11
Оценка: 9 (1)
Здравствуйте, Аноним, Вы писали:
Вот на эту тему неплохо написано.
Кодом людям нужно помогать!
Re: Почему не красиво в конструкторе вызывать вирт метод
От: SE Украина  
Дата: 27.07.10 09:04
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Я хочу в конструктор передать параметры и в нём же вызвать Connect который подключается к серверу. Метод Connect делаю виртуальным, т.к. способы подключения различны и в производных классах меняются. почему такой код не красив?


Как правило такой код требует от тех, кто им будет пользоваться большей осторожности и опыта, а это нельзя гарантировать для reusable компонентов.

Я использовал виртуальные методы в конструкторе лишь раз, и даже не могу вспомнить зачем Помню только, что затем отказался от них в пользу более понятного и простого кода.
Re[2]: Почему не красиво в конструкторе вызывать вирт метод
От: SE Украина  
Дата: 27.07.10 09:04
Оценка:
Здравствуйте, Sharov, Вы писали:

S>Здравствуйте, Аноним, Вы писали:

S><span class='lineQuote level1'>S&gt;Вот</span> на эту тему неплохо написано.

Спасибо, очень интересный блог сам по себе.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.