【问题标题】:Continued "Is there an equivalent of C#'s nameof(..) in F#?"继续“在 F# 中是否存在与 C# 的 nameof(..) 等效的内容?”
【发布时间】:2020-12-03 03:00:40
【问题描述】:

参考Is there an equivalent of C#'s nameof(..) in F#?

nameof 函数如何用于或扩展以下情况?

let nameof (q:Expr<_>) = 
    match q with 
    | Patterns.Let(_, _, DerivedPatterns.Lambdas(_, Patterns.Call(_, mi, _))) -> mi.Name
    | Patterns.PropertyGet(_, mi, _) -> mi.Name
    | DerivedPatterns.Lambdas(_, Patterns.Call(_, mi, _)) -> mi.Name
    | _ -> failwith "Unexpected format"

let any<'R> : 'R = failwith "!"

let s = _nameof <@ System.Char.IsControl @> //OK

type A<'a>() = 
    static member MethodWith2Pars(guid:Guid, str:string) = ""
    static member MethodWith2Pars(guid:Guid, ba:byte[]) = ""

let s1 = nameof <@ A<_>.MethodWith2Pars @> //Error  FS0503  A member or object constructor 'MethodWith2Pars' taking 1 arguments is not accessible from this code location. All accessible versions of method 'MethodWith2Pars' take 2 arguments
let s2 = nameof <@ A<_>.MethodWith2Pars : Guid * string -> string @> //Same error

编译器给出以下错误:

错误 FS0503 无法从此代码位置访问采用 1 个参数的成员或对象构造函数“MethodWith2Pars”。方法“MethodWith2Pars”的所有可访问版本都采用 2 个参数

【问题讨论】:

    标签: f# nameof


    【解决方案1】:

    您链接的答案有点过时了。 F# 5.0(最近发布)提供了真正的nameof 功能。见公告:https://devblogs.microsoft.com/dotnet/announcing-f-4-7/#nameof

    自 F# 4.7 起,此功能也存在于预览版中:https://devblogs.microsoft.com/dotnet/announcing-f-4-7/#nameof

    【讨论】:

    • 我知道这一点,但在这种情况下它不起作用。我的意思是,'nameof A<_>.MethodWith2Pars' 不适用于错误 FS3250:表达式没有名称。 'nameof A.MethodWith2Pars' 失败并出现不同的错误
    【解决方案2】:

    你可以这样写代码:

    open System
    
    type A() = 
        static member MethodWith2Pars(guid:Guid, str:string) = ""
        static member MethodWith2Pars(guid:Guid, ba:byte[]) = ""
    
    let s1 = nameof (A.MethodWith2Pars : Guid * byte[] -> string)
    let s2 = nameof (A.MethodWith2Pars : Guid * string -> string)
    

    由于重载,需要类型注释。不知道为什么类声明中有一个泛型类型参数,但它没有在任何地方使用,所以我只是删除了它。

    【讨论】:

    • 不幸的是泛型类型是必需的(我放在这里的代码是我所拥有的简化)。假设 A 改为 :: type A() = static member MethodWith2Pars(guid:Guid, str:string) = "" static member MethodWith2Pars(guid:Guid, ba:byte[]) = A<_>.P 静态成员 val P = Unchecked.defaultof with get, set
    • 好的,我明白了。这可能是该功能中的错误或设计上的怪癖,因为它解析名称的方式与其他代码相同。如果你需要使用nameof,我建议在此期间重写你的代码。
    猜你喜欢
    • 1970-01-01
    • 2012-03-03
    • 2010-11-27
    • 2016-12-20
    • 2011-03-20
    • 2012-02-11
    • 1970-01-01
    • 2018-11-09
    • 2018-04-09
    相关资源
    最近更新 更多