F# extension methods in C#

匿名 (未验证) 提交于 2019-12-03 08:48:34

问题:

If you were to define some extension methods, properties in an assembly written in F#, and then use that assembly in C#, would you see the defined extensions in C#?

If so, that would be so cool.

回答1:

[] module Methods =        []        let Exists(opt : string option) =                     match opt with        | Some _ -> true                          | None -> false

This method could be used in C# only by adding the namespace (using using) to the file where it will be used.

if (p2.Description.Exists()) {   ...}

Here is a link to the original blogpost.

Answering question in comments "Extension Static Methods":

namespace ExtensionFSharp   module CollectionExtensions =     type System.Linq.Enumerable with        static member RangeChar(first:char, last:char) =        {first .. last}

In F# you call it like so:

open System.Linq  open ExtensionFSharp.CollectionExtensions   let rangeChar = Enumerable.RangeChar('a', 'z')  printfn "Contains %i items" rangeChar.CountItems

In C# you call it like so:

using System; using System.Collections.Generic; using ExtensionFSharp;      class Program     {         static void Main(string[] args)         {             var method = typeof (CollectionExtensions).GetMethod("Enumerable.RangeChar.2.static");               var rangeChar = (IEnumerable) method.Invoke(null, new object[] {'a', 'z'});             foreach (var c in rangeChar)             {                 Console.WriteLine(c);             }         }     }

Now, give me my freaking medal!



回答2:

Despite my other answer, I did just try this with the F# CTP (on VS shell) and C# Express from my box at home (all free dev tools!), and this works:

F#

#light namespace MyFSharp  // C# way [] module ExtensionMethods =     []     let Great(s : System.String) = "Great"      // F# way     type System.String with         member this.Awesome() = "Awesome"     let example = "foo".Awesome()        

C#

using System; using MyFSharp;  // reference the F# dll class Program {     static void Main(string[] args)     {         var s = "foo";         //s.Awesome(); // no         Console.WriteLine(s.Great());  // yes     } }

I was not aware you could do this; nifty. Credit to @alex.



回答3:

Per the language spec, section 10.7 "Type extensions":

Optional extension members are syntactic sugar for static members. Uses of optional extension members elaborate to calls to static members with encoded names where the object is passed as the first argument. The encoding of names is not specified in this release of F# and is not compatible with C# encodings of C# extension members



回答4:

For some reason, the accepted answer suggests using reflection to get an F# type extension method. Since the compiled method name is different between versions of F#, and may be different depending on arguments, inlining and other naming related issues, I would rather suggest using CompiledNameAttribute instead, which is much easier and blends in easily with C#. Besides, no reflection (and its performance and type safety issues) necessary.

Suppose you have this in F#:

namespace Foo.Bar module StringExt =     type System.String with         static member ToInteger s = System.Int64        
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!