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.
精彩评论