简体   繁体   English

使用可选参数从F#对象在C#中创建对象

[英]Create an object in C# from an F# object with optional arguments

I have a object in F# as follows... 我在F#中有一个对象如下......

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. 我希望能够在C#项目中创建此对象的实例。 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. 我已经将正确的库作为参考添加到项目中,并且可以通过intellisense查看对象,但是我不确定在正确的语法上创建对象的实例。

Currently I have the following in my C# project - which the compiler doesn't like... 目前我的C#项目中有以下内容 - 编译器不喜欢...

var myObj1 = new Person("mark");            

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#. 然后从F#和C#都可以很好地工作。

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#编译器使用不同的方法来表示可选参数,这些参数不是(当前)与C#4.0方法兼容。 F# simply allows you to use a nicer syntax when the parameter has type option<'a> (and is marked as optional). 当参数具有类型option<'a> (并标记为可选)时,F#只允许您使用更好的语法。 You can use it as it is, or you can use the defaultArg function to provide default value in your code . 您可以按原样使用它,也可以使用defaultArg函数在代码中提供默认值。

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 . 在C#中,参数在元数据(.NET 4.0特定功能)中特别表示,默认值在元数据中指定。 Unfortunately, there is no way to create C# 4.0 compatible optional parameter in F#. 不幸的是,没有办法在F#中创建C#4.0兼容的可选参数。

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: 如果您想使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")); 

Or you can modify your F# declaration to use overloaded methods/constructors, which works in both of the languages: 或者您可以修改F#声明以使用重载的方法/构造函数,它们适用于以下两种语言:

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

可选参数在F#中的工作方式与在C#中的工作方式不同,因此我认为您需要在C#代码中模拟F#方法:

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和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 has expanded further on this topic here . Mauricio Scheffer在这里进一步扩展了这一主题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM