Skip to content

How useful is C# "dynamic" with System.Text.Json.Nodes.JsonObject? #53195

@steveharter

Description

@steveharter

Currently JsonObject supports C# "dynamic" which primarily means an instance of JsonObject can get\set a property value without having to use a string for the property name.

Although dynamic support has been requested, I believe it was primarily desired as a work-around since System.Text.Json didn't have a writeable DOM feature yet.

Since System.Text.Json now has a writable DOM through JsonNode without dynamic, is the dynamic capability redundant and should it be removed?

In theory, support for dynamic could make code sharing between C# and scripting languaged like JavaScript a bit easier, but what are other benefits are there?

Some negatives of dynamic:

  • Dynamic is slower.
  • There is no IntelliSense or type checking (also the case with non-dynamic cases).
  • The current implementation requires casts to the appropriate type or call to GetValue<T>(), so the copy-paste ability for JavaScript doesn't quite work.
  • Requires System.Text.Json.dll to have a reference to the large System.Linq.Expressions.dll, although the IL Linker removes that if dynamic is not used.
  • Doesn't help with arrays.

Here's a brief sample of dynamic and non-dynamic programming models:

const string Json = "{\"MyNumber\":42, \"MyArray\":[10,11]}";

// dynamic
{
    dynamic obj = JsonNode.Parse(Json);
    int number = (int)obj.MyNumber;
    Debug.Assert(number == 42);
    
    obj.MyString = "Hello";
    Debug.Assert((string)obj.MyString == "Hello");
}

// non-dynamic
{
    JsonObject obj = JsonNode.Parse(Json).AsObject();
    int number = (int)obj["MyNumber"];
    Debug.Assert(number == 42);
    
    obj["MyString"] = "Hello";
    Debug.Assert((string)obj["MyString"] == "Hello");
}

Note that properties on a strongly-typed POCO and collection elements can also be declared as dynamic, and the JsonSerializer can also support dynamic.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions