【问题标题】:In F#, what is the object initializer syntax with a mandatory constructor parameter?在 F# 中,带有强制构造函数参数的对象初始值设定项语法是什么?
【发布时间】:2014-09-05 17:11:58
【问题描述】:

假设有一个类有一个公共构造函数,它接受一个参数。此外,我还想设置多个公共属性。 F# 中的语法是什么?例如在 C# 中

public class SomeClass
{
    public string SomeProperty { get; set; }

    public SomeClass(string s)
    { }
}

//And associated usage.
var sc = new SomeClass("") { SomeProperty = "" };

在 F# 中,我可以使用构造函数或 property setters 来完成此操作,但不能像在 C# 中那样同时使用两者。例如,以下内容无效

let sc1 = new SomeClass("", SomeProperty = "")
let sc2 = new SomeClass(s = "", SomeProperty = "")
let sc3 = new SomeClass("")(SomeProperty = "")

我好像遗漏了什么,但是什么?

正如 David 所指出的,在 F# 中做这一切是可行的,但出于某种原因,至少对我而言 :),当在 F# 中使用的类在 C# 中定义。至于这样的例子是TopicDescription(为了补充一些足够公开的东西作为一个附加的例子)。例如,可以写作

let t = new TopicDescription("", IsReadOnly = true)

相应的编译器错误将是Method 'set_IsReadOnly' is not accessible from this code location

【问题讨论】:

    标签: c# f# c#-to-f#


    【解决方案1】:

    您遇到的问题是 IsReadOnly 有一个内部设置器。

    member IsReadOnly : bool with get, internal set
    

    如果你想直接设置它,你需要继承TopicDescription

    您正在查看的构造函数语法是完全可以接受的。

    let test = new Microsoft.ServiceBus.Messaging.TopicDescription("", EnableBatchedOperations=true)
    

    对我来说编译得很好。

    【讨论】:

    • 你是对的。让我感到困惑的是,当我在 C#var td = new TopicDescription("") { IsReadOnly = true }; 中尝试时,我的 VS 没有添加曲线。所以,我只是假设在这种情况下TopicDescription 和一堆其他 C# 类初始化会编译。我是多么愚蠢!
    【解决方案2】:

    我从不使用 F# 编程,但这对我来说似乎很好用:

    type SomeClass(s : string) =
        let mutable _someProperty = ""
        let mutable _otherProperty = s
        member this.SomeProperty with get() = _someProperty and set(value) = _someProperty <- value
        member this.OtherProperty with get() = _otherProperty and set(value) = _otherProperty <- value
    
    let s = new SomeClass("asdf", SomeProperty = "test");
    
    printf "%s and %s" s.OtherProperty s.SomeProperty;
    

    输出"asdf and test"


    此外,以下代码对我来说很好用:

    public class SomeClass
    {
        public string SomeProperty { get; set; }
        public string OtherProperty { get; set; }
    
        public SomeClass(string s)
        {
            this.OtherProperty = s;
        }
    }
    

    然后在 F# 中:

    let s = SomeClass("asdf", SomeProperty = "test")
    

    【讨论】:

    • 确实如此,但在这种情况下,SomeClass 是我需要使用的 C# 类(例如TopicDescription)就是这样一个。不过,谢谢你把这个放在这里,我知道我需要澄清我的问题。