7

Let's say there's a class that with one public constructor, which takes one parameter. In addition, there are also multiple public properties I'd like to set. What would be the syntax for that in F#? For instance in C#

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

    public SomeClass(string s)
    { }
}

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

In F# I can get this done using either the constructor or property setters, but not both at the same time as in C#. For example, the following aren't valid

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

It looks like I'm missing something, but what?

<edit: As pointed out by David, doing it all in F# works, but for some reason, at least for me :), it gets difficult when the class to be used in F# is defined in C#. As for an example on such is TopicDescription (to make up something public enough as for an added example). One can write, for instance

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

and the corresponding compiler error will be Method 'set_IsReadOnly' is not accessible from this code location.

Community
  • 1
  • 1
Veksi
  • 3,556
  • 3
  • 30
  • 69

2 Answers2

6

I never program in F#, but this seems to work fine for me:

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;

That outputs "asdf and test".


Additionally, the following code works fine for me:

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

    public SomeClass(string s)
    {
        this.OtherProperty = s;
    }
}

Then in F#:

let s = SomeClass("asdf", SomeProperty = "test")
David Sherret
  • 101,669
  • 28
  • 188
  • 178
  • It does, but in this case ``SomeClass`` is a C# class I need to use (e.g. [TopicDescription](http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.topicdescription.aspx)) is such one. Thanks for putting this here, though, I see I need to clarify my question. – Veksi Jul 15 '14 at 13:54
6

The problem you're having is that IsReadOnly has an internal setter.

member IsReadOnly : bool with get, internal set

If you want to set it directly you're going to need to subclass TopicDescription.

The constructor syntax you're looking at is perfectly acceptable.

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

compiles just fine for me.

N_A
  • 19,799
  • 4
  • 52
  • 98
  • 1
    You are right. What has led me astry is that my VS didn't add squiggles when I tried in C# ``var td = new TopicDescription("") { IsReadOnly = true };``. So, I just assumed that in this case ``TopicDescription`` and a bunch of other C# class initializations would compile. How silly I've been! – Veksi Jul 15 '14 at 14:25