开发者

Overriding Constructors in F#

开发者 https://www.devze.com 2022-12-25 05:20 出处:网络
How would I write the following C# code in F#? namespace Shared { public class SharedRegistry : PageRegistry {

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)
0

精彩评论

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

关注公众号