failwith в явном конструкторе объектов с использованием F # - PullRequest
3 голосов
/ 29 сентября 2011

следующий код

type A (b) =
  new () =
    if true then A 4.
    else failwith ""

выдает ошибку:

Это недопустимое выражение конструкции объекта. Явные конструкторы объектов должны либо вызывать альтернативный конструктор, либо инициализировать все поля объекта и указать вызов конструктора суперкласса.

Это работает:

type A (b) =
  new () =
    if true then A 4.
    else failwith ""; A 4.

Простой вопрос. Что такого плохого в failwith в конструкторе?

Ответы [ 2 ]

3 голосов
/ 29 сентября 2011

Проблема не failwith сама по себе. Как указывает ошибка, неосновные конструкторы ограничены. Это должно стимулировать помещение всей логики инициализации в основной конструктор. Ваш пример кажется надуманным. Если вы покажете больше того, что вы пытаетесь сделать, возможно, кто-то может предложить решение.

Вот один из способов переработать ваш код:

type A (b) =
  new () = A(4.0) then 
    if true then failwith ""

then действует как привязка do в неосновных конструкторах.

См. Страницу MSDN на Конструкторы для получения дополнительных параметров.

EDIT

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

type A (b) =
  static member Create() =
    if true then failwith ""
    else A(4.0)
2 голосов
/ 29 сентября 2011

Проблема, которую вы видите, не относится к failwith; это также может произойти с любым другим выражением типа A, отличным от вызова конструктора, например Unchecked.defaultof<A>. Как указывается в сообщении об ошибке, конструкторы имеют ограничения на виды выражений, которые могут использоваться в них, чтобы гарантировать, что типы всегда будут правильно инициализированы.

Как я уже упоминал в комментарии к ответу Даниэля, если вы хотите быстро потерпеть неудачу в некоторых случаях, вы можете сделать что-то вроде:

new() =
    if true then failwith ""
    A 4.0

Это вызовет исключение, прежде чем он получит возможность выполнить цепочечный вызов конструктора.

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