Действительно ли возможно выйти корректно в конструкторе?

Определите класс

public class Language
{
     public string Name { get; set; }
     public string Value { get; set; }
}

, затем ...

//Build a list
var dataSource = new List<Language>();
dataSource.Add(new Language() { Name = "blah", Value = "blah" });
dataSource.Add(new Language() { Name = "blah", Value = "blah" });
dataSource.Add(new Language() { Name = "blah", Value = "blah" });

//Setup data binding
this.comboBox1.DataSource = dataSource;
this.comboBox1.DisplayMember = "Name";
this.comboBox1.ValueMember = "Value";

// make it readonly
this.comboBox1.DropDownStyle = ComboBoxStyle.DropDownList;
6
задан 29 May 2009 в 14:27
поделиться

6 ответов

Заставь его взорваться. В конструкторе не бывает изящного отказа. Возможно, в вызывающем коде, но не в конструкторе. Вызвать исключение и обработать его соответствующим образом.

3
ответ дан 8 December 2019 в 14:46
поделиться

Это зависит от того, что вы подразумеваете под «изящно». Если вы хотите, чтобы ваш конструктор отказал, вы можете создать исключение или использовать фабричный шаблон:

class FooFactory {
    function makeFoo() {
        return $someConstraint ? null : new Foo();
    }
}

Может быть, вы можете уточнить, что именно вы хотите выполнить.

7
ответ дан 8 December 2019 в 14:46
поделиться

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

Это не объектно-ориентированное программирование:

$o = new myObject();
if (!is_object($o)) // then what???
2
ответ дан 8 December 2019 в 14:46
поделиться

Я чувствую запах прокси, приближающийся к вам. Вы пытаетесь достичь не корректного отказа конструктора , а запрета вызова методов для объекта на основе некоторого критерия $ active .

Это может укажет вам верное направление. Или, может быть, нет (= >> Мне не очень нравится страница, на которую я ссылаюсь, но это было лучшее, что я мог найти для PHP). Прочтите Proxy, возможно, из других источников. По сути, ваш ProxyObject будет иметь ссылку на реальный объект, который будет выполнять методы . Ваш клиентский код будет вызывать методы для ProxyObject, как если бы это был реальный объект , и ProxyObject решал бы, активен он или нет, передавать ли сообщение реальному объекту или ничего не возвращать, нули или фиктивные значения. Звучит хорошо?

3
ответ дан 8 December 2019 в 14:46
поделиться

Если ваш конструктор не работает, вы должны генерировать исключение, а не возвращать ложное значение. Если вы не используете такой язык, как C, в котором исключения при построении объекта означают, что он никогда не может быть деконструирован.

Причина в том, что исключение заставляет программу работать с ним, и оно дает вам неверные данные. Если вы вернете значение, скажем -1 или что-то еще, программа может молча продолжать и игнорировать это, пока это не вызовет проблему позже в будущем. Создание исключения предотвращает попадание этих тихих ошибок в код. Вы можете знать, что он возвращает false, если не удалось построить должным образом, но ваш коллега не может и может с радостью попытаться использовать объект, который, по его мнению, был тем, что он сконструировал, чтобы узнать, что это действительно логическое значение.

1
ответ дан 8 December 2019 в 14:46
поделиться

Я думаю, что N3rd предложил очень крутое решение, но вот еще один более простой метод.

class Foo {

    private $active = TRUE;

    function __construct() {

        $this->check ( $active ); 

            //OR
            //if ($this->check ( $active )) { do something } 
    }

    function check($var) {
        if (! $var) {
            $this->active = FALSE;
            return FALSE;
        }
        return TRUE;

    }
}
0
ответ дан 8 December 2019 в 14:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: