views:

434

answers:

2

I can't find the proper syntax for coding a type D that inherits a base class B (written in C#) and his constructors other than the base class implicit constructor:

C# code:

public class B
{
    private int _i;
    private float _f;
    public B()
    {
        _i = 0;
        _f = 0.0f;
    }
    public B(int i)
    {
        _i = 0;
        _f = 0.0f;
    }
    public B(int i, float f)
    {
        _i = i;
        _f = f;
    }
}

F# code:

type D() =
    inherit B()
    //how to inherit from other constructors ?

Thanks

+3  A: 

From the docs: "The arguments for the base class constructor appear in the argument list in the inherit clause." For example:

type D(i: int) =
   inherit B(i)

I am not sure if you can call different base class constructors from different F# constructors, because F# requires all constructors to go through the "primary" constructor (because the primary constructor arguments are in scope for the entire class, so they have to be initialised). In your case, you can get away with it because your base class has a maximal constructor:

type D(i : int, f : float) =
  inherit B(i, f)
  new(i : int) = D(i, 0.0)
  new() = D(0, 0.0)

But for a base class without a maximal constructor I'm not sure this is possible.

itowlson
but how about inheriting multiple constructors ?
Stringer Bell
I've updated the answer to discuss that (though I've run up again the limitations of my own knowledge here, so hopefully someone else will chime in if I'm wrong...).
itowlson
It is possible to have different derived class constructors call different base constructors, but only when switching to the 'explicit' class syntax. I'll try to post an example of this later. In any case, this is a good answer that covers the 97% case.
Brian
Btw itowlson, if you look good at the second constructor of B, it initializes _i and _f to 0 values, which I did on purpose. So when using new(i : int) = D(i, 0.0) the behavior of the base class will be broken..
Stringer Bell
+2  A: 

I found a way to do it thanks this blog !

type D =
    class
        inherit B

        new () = {
            inherit B()
        }
        new (i : int) = {
            inherit B(i)
        }
        new ((i,f) : int*single) = {
            inherit B(i, f)
        }
    end

Yes, it's a bit cumbersome, but like Brian said it's not the majority of the cases.

EDIT: Actually, class/end keywords are not mandatory for that (so I take back what i said about cumbersomeness). As Brian said on his blog here, F# normally infers the kind of type being defined, making these tokens unnecessary/redundant.

type D =
    inherit B

    new () = {
        inherit B()
    }
    new (i : int) = {
        inherit B(i)
    }
    new ((i,f) : int*single) = {
        inherit B(i, f)
    }
Stringer Bell