Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 926 Vote(s) - 3.5 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Literal notation for Dictionary in C#?

#1
I currently have a WebSocket between JavaScript and a server programmed in C#. In JavaScript, I can pass data easily using an associative array:

var data = {'test': 'val',
'test2': 'val2'};

To represent this data object on the server side, I use a `Dictionary<string, string>`, but this is more 'typing-expensive' than in JavaScript:

Dictionary<string, string> data = new Dictionary<string,string>();
data.Add("test", "val");
data.Add("test2", "val2");

Is there some kind of literal notation for associative arrays / `Dictionary`s in C#?
Reply

#2
While, the dictionary initializer answer is totally correct, there is another approach to this that I would point out (but I might not recommend it). If your goal is to provide terse API usage, you could use anonymous objects.

var data = new { test1 = "val", test2 = "val2"};

The "data" variable is then of an "unspeakable" anonymous type, so you could only pass this around as `System.Object`. You could then write code that can transform an anonymous object into a dictionary. Such code would rely on reflection, which would potentially be slow. However, you could use `System.Reflection.Emit`, or `System.Linq.Expressions` to compile and cache a delegate that would make subsequent calls much faster.

Asp.net MVC APIs use this technique in a number of places that I've seen. A lot of the Html Helpers have overloads that accept either an object or a dictionary. I assume the goal of their API design is the same as what you are after; terse syntax at the method call.
Reply

#3
You use the [collection initializer](

[To see links please register here]

) syntax, but you still need to make a `new Dictionary<string, string>` object first as the shortcut syntax is translated to a bunch of `Add()` calls (like your code):

var data = new Dictionary<string, string>
{
{ "test", "val" },
{ "test2", "val2" }
};

In C# 6, you now have the option of using a more intuitive syntax with Dictionary as well as any other type that supports [indexers](

[To see links please register here]

). The above statement can be rewritten as:

var data = new Dictionary<string, string>
{
["test"] = "val",
["test2"] = "val2"
};

Unlike collection initializers, this invokes the indexer setter under the hood, rather than an appropriate `Add()` method.
Reply

#4
Using `DynamicObject`, it is not that difficult to create a simpler dictionary initializer.

Imagine you want to call the following method

void PrintDict(IDictionary<string, object> dict) {
foreach(var kv in dict) {
Console.WriteLine (" -> " + kv.Key + " = " + kv.Value);
}
}

using a literal syntax like

var dict = Dict (Hello: "World", IAm: "a dictionary");
PrintDict (dict);

This can be accomplished by creating a dynamic object like this

dynamic Dict {
get {
return new DynamicDictFactory ();
}
}

private class DynamicDictFactory : DynamicObject
{
public override bool TryInvoke (InvokeBinder binder, object[] args, out object result)
{
var res = new Dictionary<string, object> ();
var names = binder.CallInfo.ArgumentNames;

for (var i = 0; i < args.Length; i++) {
var argName = names [i];
if(string.IsNullOrEmpty(argName)) throw new ArgumentException();
res [argName] = args [i];
}
result = res;
return true;
}
}
Reply

#5
# Use Dictionary Literals (C#9 proposal) [rejected] or the `new` syntax (beginning with C#9)

[this may happens but is currently rejected]

C#9 introduces a simpler syntax to create initialized `Dictionary<TKey,TValue>` objects without having to specify either the Dictionary type name or the type parameters. The type parameters for the dictionary are inferred using the existing rules used for array type inference.

// C# 1..8
var x = new Dictionary <string,int> () { { "foo", 4 }, { "bar", 5 }};
// C# 9
var x = ["foo":4, "bar": 5];

This synthax makes the work with dictionaries in C# simpler and removing the redundant code.

You can follow the issue on [GitHub](

[To see links please register here]

) (and here is the [milestone for C#9](

[To see links please register here]

)).

Edit: This proposal is currently **rejected**:

> [...] We think there are a number of interesting use cases around initializing data, particularly for things like immutable dictionaries. We don't find the existing syntax for initializing a dictionary that onerous, nor do we see it as a frequent pattern in code that would benefit much from a language feature. We thing that the general area of initializing data should be looked at again after we do records and withers. [...]

current milestone:

[![likely never][1]][1]


Note that beginning with C# 9.0, constructor invocation expressions are target-typed. That is, if a target type of an expression is known, you can omit a type name, as the following example shows:

Dictionary<int, List<int>> lookup = new()
{
[1] = new() {1, 2, 3},
[2] = new() {5, 8, 3},
[5] = new() {1, 0, 4}
};

As the preceding example shows, you always use parentheses in a target-typed new expression.

If a target type of a new expression is unknown (for example, when you use the var keyword), you must specify a type name.

[MSDN](

[To see links please register here]

)

[1]:
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through