Каков наилучший способ сообщить о том, что ваш конструктор потерпел неудачу в C #? - PullRequest
9 голосов
/ 23 января 2009

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

// okay
Banana banana1 = new Banana("green");

// fail
Banana banana2 = new Banana("red");

Бросить исключение? Если так, то как?

Ответы [ 5 ]

23 голосов
/ 23 января 2009
throw new ArgumentException("Reason", "param name");
9 голосов
/ 23 января 2009

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

Обратите внимание, что классы в .NET Framework, которые ведут себя аналогично вашему примеру "Banana" (где для создания экземпляра объекта подходят только определенные значения), не используют конструкторы, а вместо этого используют статические фабричные методы. Например, System.Net.WebRequest не имеет открытого конструктора и вместо этого использует статический метод Create , который может вызвать исключение, если предоставленная строка не является допустимым URI. За некоторыми исключениями - см. Мое обновление ниже.

Итак, для вашего кода я бы изменил конструктор Banana на защищенный и ввел метод, подобный этому:

public static Banana Create(string color) 
{
    if (color != "green" && color != "yellow")
    {
        throw new ArgumentException("Color must be 'green' or 'yellow'", 
            "color");
    }
    return new Banana(color);
}

Обновление

Ладно, похоже, это не плохая идея выбросить исключения из конструктора. Фактически, System.IO.FileStream делает именно это, если вы передаете неверное имя файла его конструктору. Я предполагаю, что идея использования статического метода фабрики - это всего лишь один из способов более подробно рассказать о том, как вы создаете экземпляр (например, если вышеприведенный метод назывался «FromColor»).

4 голосов
/ 23 января 2009

Наиболее приемлемым решением является исключение. Чтобы доказать это, откройте рефлектор и взгляните на большинство классов из BCL и исключения, которые они могут создавать при создании.

В качестве примера. List (IEnumerable collection) выдаст исключение, если collection равна нулю. Совершенно правильный способ сообщения об ошибках вызывающей стороне.

1 голос
/ 23 января 2009

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

public class Banana 
{
    public Banana(string color)
    {
        if ( color == "red" )
          throw new SomeException("intialization failed, red is an invalid color");

    }
}
//////////////////////////////////////////////////////////     
try
{
    Banana banana1 = new Banana("green");
    banana1.whatever();
}
catch( SomeException error )
{
    // do something
}
finally
{
    // always do  this stuff
}
0 голосов
/ 23 января 2009

Я думаю, что вы хотите ArgumentException ...

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