在F#中重写构造函数

4

我该如何用F#编写以下C#代码?

namespace Shared {
    public class SharedRegistry : PageRegistry {
        public SharedRegistry(bool useCache = true)
            : base(useCache) {
            // Repositories
            ForRequestedType<IAddressRepository>().TheDefaultIsConcreteType<SqlAddressRepository>();
            ForRequestedType<ISharedEnquiryRepository>().TheDefaultIsConcreteType<SharedEnquiryRepository>();

            // Services
            ForRequestedType<IAddressService>().TheDefaultIsConcreteType<AddressService>();
            ForRequestedType<ISharedEnquiryService>().TheDefaultIsConcreteType<SharedEnquiryService>();
        }
    }
}

我目前已经实现了继承,但我无法同时声明自己的默认构造函数和从PageRegistry继承。
type SharedRegistry(useCache: bool) =
    inherit PageRegistry(useCache)
    new() = new SharedRegistry(true)

丰富

2个回答

5
我不确定我理解你的问题;你写的内容看起来应该是可以正常工作的。如果你想知道在哪里放置其余的构造函数逻辑,请尝试以下代码:
type SharedRegistry(useCache) as this =
  inherit PageRegistry(useCache)
  do
    this.ForRequestedType<IAddressRepository>().TheDefaultIsConcreteType<SqlAddressRepository>()
    // etc.
  new() = SharedRegistry(true)

如果您想单独定义每个构造函数,您也可以这样做:
type SharedRegistry =
  inherit PageRegistry
  new(useCache) as this = 
    { inherit PageRegistry(useCache) } then
    this.ForRequestedType<IAddressRepository>().TheDefaultIsConcreteType<SqlAddressRepository>()
    // etc.
  new() = SharedRegistry(true)

或者,您可以在主构造函数中使用可选参数:
type SharedRegistry(?useCache) as this =
  inherit PageRegistry(defaultArg useCache true)
  do
    this.ForRequestedType<IAddressRepository>().TheDefaultIsConcreteType<SqlAddressRepository>()
    // etc.

我所做的唯一修改是将StructureMap方法包装在Ignore()方法中,因为它们返回类型。 - kim3er
@kim3er - 是的,如果你调用一个返回值的函数,那么你需要忽略它。在调用后使用 |> ignore 可能更符合惯用语法,而不是将整个内容放在 ignore(...) 中,但这些方法的命名过于冗长,两种选项都不太好看。 - kvb

5
您的C#类使用了具有默认值的参数,这与重载构造函数略有不同。无论如何,F#都支持重载构造函数和默认参数。
使用参数的默认值,代码将如下所示:
type SharedRegistry(?useCache: bool) = 
    do 
      // constructor logic
    inherit PageRegistry(defaultArg useCache true) 

现在你可以按照以下方式创建一个实例:
let r1 = new SharedRegistry() // using the default value
let r2 = new SharedRegistry(false) // specified explicitly
let r3 = new SharedRegistry(useCache=false) // using named parameter

我相信在F#中使用命名参数会更加优雅。它的工作原理是,参数useCache在内部变成了一个option<bool>(如果您想从C#中使用该类,则可能会有问题)。
关于重载构造函数 - 您的F#代码应该是正确的(请参见kvb的答案)。一般来说,最好至少有一个隐式构造函数(这允许您自动访问构造函数参数,在类体中使用let声明字段,并使用do实现构造函数逻辑)。隐式构造函数应该是接受所有参数的构造函数。在某些情况下,您可能希望将其设置为私有,可以像这样完成:
type SharedRegistry private (useCache: bool) = 
    inherit PageRegistry(useCache) 
    do 
      // constructor logic
    new () = SharedRegistry(true)

一个小问题... 构造函数体中的额外 new 是无害的;在大多数情况下,F# 中不需要它,但如果需要可以显式使用。 - kvb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接