代码之家  ›  专栏  ›  技术社区  ›  Mark Pearl

从带有可选参数的F对象在C中创建对象

  •  6
  • Mark Pearl  · 技术社区  · 16 年前

    我在F中有一个物体,如下所示…

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

    我希望能够在C_项目中创建此对象的实例。我已经将正确的库添加到项目中作为引用,并且可以通过IntelliSense查看对象,但是我不确定是否使用正确的语法来创建对象的实例。

    目前我在我的C项目中有以下内容-编译器不喜欢这些内容…

    var myObj1 = new Person("mark");            
    
    4 回复  |  直到 13 年前
        1
  •  9
  •   Tomas Petricek    16 年前

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

    在C中,参数在元数据(.net 4.0特定功能)中特别表示,并指定默认值。 在元数据中 . 不幸的是,无法在f_中创建与c_4.0兼容的可选参数。

    如果您想让C代码更好一点,您可以定义一个静态实用程序类,它允许您在创建时使用类型推断 选项<'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
  •  9
  •   Brian    16 年前

    如果提供两个构造函数重载,您可能会更高兴:

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

    然后从F和C都可以很好地工作。

        3
  •  5
  •   kvb    16 年前

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

    var myObj1 = new Person(new FSharpOption<string>("mark"));
    
        4
  •  0
  •   Marc Sigrist    13 年前

    您可以使用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
    

    毛里西奥·谢弗在这个问题上做了进一步的扩展。 here .