2013-10-28 4 views
0

Сегодня я увидел обломок, который выглядел действительно ужасно для меня, но, к сожалению, я не могу просто изменить его, поэтому я задаюсь вопросом, могу ли я как-нибудь обойти это. У меня есть класс с конструктором, который имеет выходной параметр для успеха. Но это выглядит очень уродливо для меня. И теперь, когда я получаю этот класс, я должен взять этот параметр со мной - если захочу или нет.Конструктор с выходным параметром

class ClassA { 
    ClassA(out bool success) {...} 
} 

class B: ClassA { 
    // call the constructor from ClassA but without the out-param 
} 

Так что я знаю, если его хорошая практика или если не так, как я могу избежать объявления out-param из ClassB.

+0

Нет, вы не можете обойти его. – GrantByrne

+1

Это действительно плохая практика программирования. Пожалуйста, стреляйте * того парня, который написал это (обратите внимание, что вы можете стрелять в него только в том случае, если это законно в вашей стране, иначе удалите его из него). – Steven

+0

Я рад, что я не единственный человек, который так чувствует себя ... спасибо Стивен: D – HimBromBeere

ответ

1

Ну, дизайн этого класса нарушается в любом случае, так что давайте разберем его немного больше (Примечание Я не рекомендую этот подход!):

void Main() 
{ 

} 

public class ClassA 
{ 
    public ClassA(out bool success) 
    { 
     success = true; 
    } 
} 

public class B: ClassA 
{ 
    private static bool success; 

    // call the constructor from ClassA but without the out-param 
    public B() 
     : base(out success) 
    { 
    } 
} 

Кроме этого, ближе всего вам может получить делает фабричный метод:

public class B : ClassA 
{ 
    public static B Create() 
    { 
     bool success; 
     var result = new B(out success); 
     if (success) 
      return result; 
     // TODO: Dispose result? 
     throw new StupidProgrammerException(); 
    } 
} 
+1

Завод-метод был бы лучшей практикой с моей точки зрения, хорошая идея – HimBromBeere

3

Вы можете сделать что-то вроде этого:

class ClassA 
{ 
    protected ClassA(out bool success) 
    { 
     success = true; 
    } 
} 

class B : ClassA 
{ 
    [ThreadStatic] 
    static bool success; // static to use in base(out success) call 

    public bool Success 
    { 
     get; 
     private set; 
    } 

    public B() 
     : base(out success) 
    { 
     Success = success; 
     success = false; // reset value 
    } 
} 

Это некрасиво, но по крайней мере вы избавитесь от параметра out, если хотите.

+0

Вам даже не нужна [ThreadStatic]. Поскольку 'success' никогда не используется, нет возможности вводить какие-либо ошибки параллелизма при удалении [ThreadStatic]. И вам не нужно его перезагружать. – Steven

+0

Или рассмотрите возможность исключения исключения, когда 'success' является ложным (но в этом случае вам понадобится [ThreadStatic]). – Steven

+0

@Steven хорошо базовый класс init 'success', и я храню его в собственности, на всякий случай. Я подумал о том, чтобы сделать исключение, но не уверен. –

2

При прохождении ref или out параметры конструктора уродливы, существуют некоторые типы, в которых попытки создать полезный экземпляр будут иметь побочные эффекты и могут выйти из строя после того, как некоторые из этих побочных эффектов уже произошли. Если невозможно создать допустимый объект, единственные способы, с помощью которых конструктор может передать информацию вызывающему, - это сохранить его в поле threadstatic, инкапсулируя его в заброшенное исключение, сохраняя или подавая его на переданный объект или делегировать, или записать его в параметр ref/out. Из них только параметр ref/out делает очевидным существование информации, с которой клиентский код должен что-то делать.

Существование ref или out параметров часто является признаком того, что конструктор должен быть protected, и что вне код должен пройти через фабричные методы, которые гарантируют, что если исключение переданный из объекта привыкнет соответствующим образом. Однако для класса, способного разумно поддерживать наследование, он должен предлагать по крайней мере один конструктор, который виден вне его. При использовании этого конструктора параметр out или ref может быть наименее злым способом для класса, чтобы позвонивший знал, что нужно будет очистить, если строительство завершится неудачей.

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