我在F#中有一个对象如下......
type Person(?name : string) =
let name = defaultArg name ""
member x.Name = name
我希望能够在C#项目中创建此对象的实例。我已经将正确的库作为参考添加到项目中,并且可以通过intellisense查看对象,但是我不确定在正确的语法上创建对象的实例。
目前我在C#项目中有以下内容 - 编译器不喜欢...
var myObj1 = new Person("mark");
答案 0 :(得分:9)
您可能更乐意提供构造函数的两个重载:
type Person(name : string) =
new() = Person("")
member x.Name = name
然后从F#和C#都可以很好地工作。
答案 1 :(得分: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("")
答案 2 :(得分:5)
可选参数在F#中的工作方式与在C#中的工作方式不同,所以我相信您需要在C#代码中模拟F#方法:
var myObj1 = new Person(new FSharpOption<string>("mark"));
答案 3 :(得分:0)
您可以使用F#兼容和C#兼容的可选构造函数参数创建Person类,如下所示:
// 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。