In .NET (and with the extension F #), you need to initialize an object before you can call any method on it or pass it to another method. Thus, your Line object must be initialized before it is passed to the base Geometry<Line>(self) constructor. But it cannot be initialized before the base constructor is called, so there is no direct way to do what you want.
Having said that, F # has a system that must catch illegal recursive values ββof values ββbefore they are determined, so I am surprised that you will not get a more meaningful exception instead of a NullReferenceException (or better, but a compile-time error). Compare, for example, what happens if you try to call new Rec() with the following definition:
type Rec(r:Rec) = new() as self = Rec(self)
One way to solve this problem is to use laziness to delay the use of the self identifier:
type Geometry<'t>(child: Lazy<'t>) = let values = List() member o.add (v: float) = values.Add v; child.Value and Line() as self = inherit Geometry<Line>(lazy self) member o.length v = o.add v
Unfortunately, this will not work, giving even more importance to the theory that in this case there is an F # error with checking the reliability of initialization. Fortunately, this can be circumvented by using the explicit constructor for Line instead of the main constructor:
type Geometry<'t>(child: Lazy<'t>) = let values = List() member o.add (v: float) = values.Add v; child.Value and Line = inherit Geometry<Line> new() as self = { inherit Geometry<Line>(lazy self) } member o.length v = o.add v
source share