开发者

Create an object in C# from an F# object with optional arguments

I hav开发者_如何学运维e a object in F# as follows...

type Person(?name : string) = 
    let name = defaultArg name ""
    member x.Name = name

I want to be able to create an instance of this object in a C# project. I have added as a reference the correct libraries to the project and can see the object via intellisense however I am not sure on the correct syntaxt to create an instance of the object.

Currently I have the following in my C# project - which the compiler doesn't like...

var myObj1 = new Person("mark");            


To add some details, the F# compiler uses different approach for representing optional parameters, which is not (currently) compatible with the C# 4.0 approach. F# simply allows you to use a nicer syntax when the parameter has type option<'a> (and is marked as optional). You can use it as it is, or you can use the defaultArg function to provide default value in your code.

In C#, the parameter is represented specially in the meta-data (.NET 4.0 specific feature), and the default value is specified in the meta-data. Unfortunately, there is no way to create C# 4.0 compatible optional parameter in F#.

If you want to make the C# code a little-bit nicer, you can define a static utility class that allows you to use type inference when creating option<'a> values:

static class FSharpOption {
  static FSharpOption<T> Some<T>(T value) {
    return new FSharpOption<T>(value);
  }
}

// Then you can write just:
var myObj1 = new Person(FSharpOption.Some("mark")); 

Or you can modify your F# declaration to use overloaded methods/constructors, which works in both of the languages:

type Person(name) = 
  do printfn "%s" name
  // Add overloaded constructor with default value of name'
  new () = Person("")


You may be happier just providing two overloads of the constructor:

type Person(name : string) =  
    new() = Person("")
    member x.Name = name 

Then it will work well from both F# and C#.


Optional arguments work differently in F# than they do in C#, so I believe that you'll need to emulate the F# approach in your C# code:

var myObj1 = new Person(new FSharpOption<string>("mark"));


You can create a Person class with both F#-compatible and C#-compatible optional constructor arguments like this:

// F#-compatible ctor with optional args
type Person(?name, ?dummy) = 
    let name = defaultArg name ""

    // C#-compatible ctor with optional arg
    new([<Optional; DefaultParameterValue "">] name) = 
        Person(name, null)

    member x.Name = name

Mauricio Scheffer has expanded further on this topic here.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜