开发者

failwith in the explicit object constructor using F#

开发者 https://www.devze.com 2023-04-09 13:04 出处:网络
The following code type A (b) = new () = if true then A 4. else failwith \"\" gives an error: This is not a valid object construction expression. Explicit object con开发者_如何学Cstructors must e

The following code

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

gives an error:

This is not a valid object construction expression. Explicit object con开发者_如何学Cstructors must either call an alternate constructor or initialize all fields of the object and specify a call to a super class constructor.

This works:

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

Simple question. What is so bad about failwith in the constructor?


The issue is not failwith per se. As the error indicates, non-primary constructors are restricted. This is to encourage putting all initialization logic in the primary constructor. Your example seems contrived. If you show more of what you're trying to do perhaps someone can offer a solution.

Here's one way to rework your code:

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

then acts like a do binding in non-primary constructors.

See the MSDN page on Constructors for more options.

EDIT

kvb made a good point regarding primary constructors with side effects. If that's the case you may want to consider moving your logic to a static method. This makes it obvious that other work may be done prior to calling the constructor.

type A (b) =
  static member Create() =
    if true then failwith ""
    else A(4.0)


The problem you are seeing is not specific to failwith; it would also occur with any other expression of type A other than a constructor call, such as Unchecked.defaultof<A>. As the error message indicates, constructors have restrictions on the kinds of expressions that can be used within them to ensure that types are always initialized soundly.

As I mentioned in a comment on Daniel's answer, if you want to fail fast in certain cases you could do something like:

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

This will throw an exception before it gets a chance to execute the chained constructor call.

0

精彩评论

暂无评论...
验证码 换一张
取 消