2010-05-01 62 views
6

我在F#一个对象,如下所示:创建从F#对象在C#中的对象...与可选参数

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

我希望能够在C#项目,以创建该对象的实例。我已经为项目添加了一个引用正确的库,并且可以通过intellisense查看对象,但是我无法确定创建对象实例的正确语法。

目前,我有我的C#项目如下 - 该编译器不喜欢......

var myObj1 = new Person("mark");    
+0

编译器说什么?微软的C#编译器在遇到不理解的事情时通常很明确。 – 2010-05-01 14:59:03

回答

9

要添加一些细节,F#编译器使用不同的方法来表示可选参数,这与C#4.0方法不兼容(当前)。当参数的类型为option<'a>(并标记为可选)时,F#只允许您使用更好的语法。您可以按原样使用它,也可以使用defaultArg函数在您的代码中提供默认值

在C#中,该参数在元数据(.NET 4.0特定功能)中特别表示,并且元数据中的默认值为。不幸的是,在F#中无法创建与C#4.0兼容的可选参数。

如果你想在C#代码一点位的更好,你可以定义一个静态实用类,允许你使用类型推断创建option<'a>值时:

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")); 

或者,您可以修改您的F#声明使用重载的方法/构造函数,这两种语言的工作:

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

可选参数工作方式不同在F#比在C#中做的,所以我相信你会需要仿效F#的方式在你的C#代码:

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

你可能会更快乐只是提供了构造函数的两个重载:

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

然后从F#和C#都可以正常工作。

0

您可以创建一个Person类既F#兼容和C#兼容可选的构造函数的参数是这样的:

// 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在此主题上进一步扩展here