Franco Tiveron
Franco Tiveron

Reputation: 2928

F# Object initialization with indexers

C# allows the following object initialization syntax for classes with Item indexer:

using System.Text.Json.Nodes;

namespace JsonNodeFromObjectExample;

...

// Create a new JsonObject using object initializers.
var forecastObject = new JsonObject
{
    ["Date"] = new DateTime(2019, 8, 1),
    ["Temperature"] = 25,
    ["Summary"] = "Hot",
    ["DatesAvailable"] = new JsonArray(new DateTime(2019, 8, 1),
                                       new DateTime(2019, 8, 2)),
    ["TemperatureRanges"] = new JsonObject
                            {
                                ["Cold"] = new JsonObject
                                           {
                                               ["High"] = 20,
                                               ["Low"] = -10
                                           }
                            },
    ["SummaryWords"] = new JsonArray("Cool", "Windy", "Humid")
};
...

In F# I can

let forecastObject = JsonObject()
forecastObject["Date"] <- DateTime(2019, 8, 1)
forecastObject["Temperature"] <- 25
...

But I need to repeatedly write the object name, which is uglier, less succinct and more error prone.

A potentially equivalent syntax would be the one available for properties initialization:

let forecastObject = JsonObject(
    ["Date"] = DateTime(2019, 8, 1),
    ["Temperature"] = 25,
...
)

However it doesn't work with indexers like Item().

Does anyone know if there is an equivalent syntax in F# like there is in C#?

Upvotes: 2

Views: 117

Answers (3)

Bent Tranberg
Bent Tranberg

Reputation: 3470

I often do this, which is not shorter, but sort of encapsulates the initialization of the thing.

let forecastObject =
    let x = JsonObject()
    x["Date"] <- DateTime(2019, 8, 1)
    x["Temperature"] <- 25
    x

Upvotes: 3

shingo
shingo

Reputation: 27404

You can initialize it with a dict.

let forecastObject = JsonObject(dict<string, JsonNode>[
    "Date", DateTime(2019, 8, 1);
    "Temperature", 25
])

Upvotes: 2

Brian Berns
Brian Berns

Reputation: 17153

There's no equivalent syntax in F#, but if you're willing to use a little helper method, you could do this:

type JsonObject with
    member this.Set(key : string, value) =
        this[key] <- value
        this

let forecastObject =
    JsonObject()
        .Set("Date", DateTime(2019, 8, 1))
        .Set("Temperature", 25)
        ...

Upvotes: 3

Related Questions