Overriding Constructors in F#
How would I write the following C# code in F#?
namespace Shared {
public class SharedRegistry : PageRegistry {
public SharedRegistry(bool useCache = true)
: base(useCache) {
// Repositories
ForRequestedType<IAddressRepository>().TheDefaultIsConcr开发者_如何学运维eteType<SqlAddressRepository>();
ForRequestedType<ISharedEnquiryRepository>().TheDefaultIsConcreteType<SharedEnquiryRepository>();
// Services
ForRequestedType<IAddressService>().TheDefaultIsConcreteType<AddressService>();
ForRequestedType<ISharedEnquiryService>().TheDefaultIsConcreteType<SharedEnquiryService>();
}
}
}
As is as far as I have managed, but I can't work out to inherit from PageRegistry
at the same time as declaring my own default constructor.
type SharedRegistry(useCache: bool) =
inherit PageRegistry(useCache)
new() = new SharedRegistry(true)
Rich
I'm not sure that I understand your question; what you've written above looks like it ought to work fine. If you're asking where to put the rest of the constructor logic, try this:
type SharedRegistry(useCache) as this =
inherit PageRegistry(useCache)
do
this.ForRequestedType<IAddressRepository>().TheDefaultIsConcreteType<SqlAddressRepository>()
// etc.
new() = SharedRegistry(true)
If you want to define each constructor individually, you can do that too:
type SharedRegistry =
inherit PageRegistry
new(useCache) as this =
{ inherit PageRegistry(useCache) } then
this.ForRequestedType<IAddressRepository>().TheDefaultIsConcreteType<SqlAddressRepository>()
// etc.
new() = SharedRegistry(true)
Or, you could use an optional argument to your main constructor:
type SharedRegistry(?useCache) as this =
inherit PageRegistry(defaultArg useCache true)
do
this.ForRequestedType<IAddressRepository>().TheDefaultIsConcreteType<SqlAddressRepository>()
// etc.
Your C# class uses parameters with default value which is slightly different than overloaded constructors. In any case, F# supports both overloaded constructors and default parameters.
Using default values of a parameters, the code would look like this:
type SharedRegistry(?useCache: bool) =
do
// constructor logic
inherit PageRegistry(defaultArg useCache true)
Now you can create an instance as follows:
let r1 = new SharedRegistry() // using the default value
let r2 = new SharedRegistry(false) // specified explicitly
let r3 = new SharedRegistry(useCache=false) // using named parameter
I belive that using named parameters is slightly more elegant in F#. The way it works is that the parameter useCache
becomes an option<bool>
under the cover (This may be a problem if you wanted to use the class from C#)
Regarding overloaded constructors - Your F# code should be correct (see the answer from kvb). In general, it is probably better to have at least one implicit constructor (as that allows you to access constructor parameters inside the body of the class automatically, declare fields using let
and implement constructor logic using do
). The implicit constructor should be the one that takes all the parameters. In some cases, you may want to make it private, which can be done like this:
type SharedRegistry private (useCache: bool) =
inherit PageRegistry(useCache)
do
// constructor logic
new () = SharedRegistry(true)
精彩评论