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);
The value of TypeName
then is "MyClass"
and the value of MemberName
then is "MyMember"
. What do I have to write in F#?
The closest thing you can get is a struct . There is a feature in C intended to facilitate a sort of pseudo-inheritance, but it doesn't come close to an actual object-oriented class system.
It allows efficient development without the need to incorporate or switch to C++ or languages with builtin template systems, if desired. Using generics and templates in C can also make programs more type safe, and prevent improper access of memory.
C mostly uses functional/structural programming instead of implementing Object Oriented Programming as in languages like C++ , Java , Python etc. which use classes .
A macro is a piece of code in a program that is replaced by the value of the macro. Macro is defined by #define directive. Whenever a macro name is encountered by the compiler, it replaces the name with the definition of the macro. Macro definitions need not be terminated by a semi-colon(;).
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)
As mentioned in the comments, a proper nameof
operator is work in progress.
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 "!"
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 @>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With