【问题标题】:How to call extension method when there is a property with same name?存在同名属性时如何调用扩展方法?
【发布时间】:2021-02-27 00:19:10
【问题描述】:

我正在尝试使用OwaspHeaders.Core nuget 包,但我无法弄清楚如何在 F# 中使用他们流畅的样式配置生成器。以下是他们文档中的 C# 代码转换为 F#(并稍微简化了一点)。

#r "nuget: OwaspHeaders.Core, 4.2.0"
open OwaspHeaders.Core.Extensions

let config =
    SecureHeadersMiddlewareBuilder
        .CreateBuilder()
        .UseHsts(1200, false)
        .Build()

问题是CreateBuilder返回的对象也有UseHsts属性,不管我怎么尝试都会解决这个问题。

FS0003: This value is not a function and cannot be applied.

如何调用UseHsts扩展方法,而不是访问同名的属性?

【问题讨论】:

    标签: f#


    【解决方案1】:

    一种方法是直接调用UseHsts方法

    let config =
        SecureHeadersMiddlewareBuilder
            .UseHsts(SecureHeadersMiddlewareBuilder.CreateBuilder(), 1200, false)
            .Build()
    

    【讨论】:

    • 谢谢,我最终使用了这种方法。它看起来确实很糟糕,但可以解决问题。由于构建器是可变的,因此可以创建一个构建器,使用它一个一个地调用扩展方法,而无需将返回的构建器向前传递,这使得代码不那么冗长。
    • 您可以使用类型别名,请参阅下面的答案:stackoverflow.com/a/66389316/423890
    【解决方案2】:

    根据@nilekirk 的回答,您可以创建自己的扩展方法,使用不同的名称,以保持流畅的语法:

    #r "nuget: OwaspHeaders.Core, 4.2.0"
    open OwaspHeaders.Core.Extensions
    open OwaspHeaders.Core.Models
    
    type SecureHeadersMiddlewareConfiguration with
        member config.MyUseHsts(maxAge, includeSubDomains) =
            SecureHeadersMiddlewareBuilder.UseHsts(config, maxAge, includeSubDomains)
    
    let config =
        SecureHeadersMiddlewareBuilder
            .CreateBuilder()
            .MyUseHsts(1200, false)
            .Build()
    

    如果你想保持相同的默认参数,我认为你可能不得不这样做:

    type SecureHeadersMiddlewareConfiguration with
        member config.MyUseHsts(?maxAge, ?includeSubDomains) =
            match maxAge, includeSubDomains with
                | Some maxAge', Some includeSubDomains' ->
                    SecureHeadersMiddlewareBuilder.UseHsts(config, maxAge', includeSubDomains')
                | Some maxAge', None ->
                    SecureHeadersMiddlewareBuilder.UseHsts(config, maxAge')
                | None, Some includeSubDomains' ->
                    SecureHeadersMiddlewareBuilder.UseHsts(config, includeSubDomains = includeSubDomains')
                | None, None ->
                    SecureHeadersMiddlewareBuilder.UseHsts(config)
    

    它有点难看,但它会让你的代码的其余部分更好。

    【讨论】:

      【解决方案3】:

      以上两个都是很好的答案,另一种方法是使用类型别名,它可以使您的代码简短流畅,并且也可以处理所有默认参数。

      #r "nuget: OwaspHeaders.Core, 4.2.0"
      open OwaspHeaders.Core.Extensions
      
      type SHMB = SecureHeadersMiddlewareBuilder
      
      let config = SHMB.UseHsts(SHMB.CreateBuilder(),1200,false).Build()
      

      【讨论】:

      • 这是个好主意,但它不是流畅的风格,因为您仍然明确地将构建器作为参数传递给UseHsts
      • 它在 C# 意义上很流利。虚线链。 UseHsts 需要 CreateBuilder() 作为参数。我们都知道 .Net 对象系统不适合 F#(尤其是 wrt 类型推断),但考虑到所有因素仍然很好..
      猜你喜欢
      • 1970-01-01
      • 2022-01-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-18
      • 2013-05-19
      • 1970-01-01
      相关资源
      最近更新 更多