在 F# 中是否有等效于 C# 的 nameof(..)? [英] Is there an equivalent of C#'s nameof(..) in F#?
问题描述
我想将以下几行代码从 C# 移植到 F#:
I have the following lines of code I want to port from C# to F#:
private const string TypeName = nameof(MyClass);
private const string MemberName = nameof(MyClass.MyMember);
TypeName
的值为 "MyClass"
,MemberName
的值为 "MyMember"
.我必须用 F# 写什么?
The value of TypeName
then is "MyClass"
and the value of MemberName
then is "MyMember"
. What do I have to write in F#?
推荐答案
从 F# 4.7 开始,有一个 nameof
运算符:
As of F# 4.7, there is a nameof
operator:
let months =
[
"January"; "February"; "March"; "April";
"May"; "June"; "July"; "August"; "September";
"October"; "November"; "December"
]
let lookupMonth month =
if (month > 12 || month < 1) then
invalidArg (nameof month) ($"Value passed in was %d{month}.")
months.[month-1]
printfn "%s" (lookupMonth 12)
printfn "%s" (lookupMonth 1)
printfn "%s" (lookupMonth 13)
正如评论中提到的,一个合适的 nameof
操作符正在进行中.
同时,您可以使用 F# 引用(类似于 C# 表达式树)来实现类似的功能——它有点丑陋并且需要一些纪律(您需要将实际成员访问权限放在引用中),但至少检查成员是否存在并防止输入错误:
In the meantime, you can use F# quotations (similar to C# expression trees) to implement similar functionality - it is a bit uglier and requires some discipline (you need to put actual member access in the quotation), but it at least checks that the member exists and prevents typos:
open Microsoft.FSharp.Quotations
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 "!"
any
定义只是一个通用值,您可以使用它来引用实例成员:
The any
definition is just a generic value that you can use to refer to instance members:
nameof <@ any<System.Random>.Next @>
nameof <@ System.Char.IsControl @>
这篇关于在 F# 中是否有等效于 C# 的 nameof(..)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!