views:

858

answers:

3

If you were to define some extension [static, instance] 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.

+16  A: 
[<System.Runtime.CompilerServices.Extension>]
module Methods =   
    [<System.Runtime.CompilerServices.Extension>]   
    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<char>) method.Invoke(null, new object[] {'a', 'z'});
            foreach (var c in rangeChar)
            {
                Console.WriteLine(c);
            }
        }
    }

Now, give me my freaking medal!

alex
Thanks, but what about instance extension properties and static methods, and static extension properties? Would they be called too? The reason I asked this is because, I know that C# only has instance extension methods.
Joan Venge
Thanks, just saw your update.
Joan Venge
YES! works like a charm
Mo Flanagan
+3  A: 

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

Brian
Do you know if there are plans to unify F#'s and C#'s ways of implementing type extensions. It would be nice if one did not need to use the extra attributes.
Joh
It doesn't look like we'll do this for the first version of F# (e.g. not in the VS2010 timeframe).
Brian
+5  A: 

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
[<System.Runtime.CompilerServices.Extension>]
module ExtensionMethods =
    [<System.Runtime.CompilerServices.Extension>]
    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.

Brian
Thanks, but isn't this just an instance extension method?
Joan Venge
Thanks, I was more interested in other extensions of F# to show up in C#, but your other reply sort of addresses that.
Joan Venge