C# 是否有用于创建键/值对的简写语法?

ser*_*0ne 4 c# dictionary key-value

我有一个 C# 方法,如下声明:

public void Process<K, V>(params KeyValuePair<K, V>[] items)
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

这种方法的使用看起来有点难看;例如:

Process(
    new KeyValuePair("key", "value"),
    new KeyValuePair(123, Guid.NewGuid())
);
Run Code Online (Sandbox Code Playgroud)

在 Kotlin 中,您可以使用 infix 函数创建对to;例如:

val pair1 = "key" to "value"
val pair2 = 123 to UUID.randomUUID()
Run Code Online (Sandbox Code Playgroud)

所以等效方法的用法看起来更整洁一些;例如:

val pair1 = "key" to "value"
val pair2 = 123 to UUID.randomUUID()
Run Code Online (Sandbox Code Playgroud)

C# 没有中缀函数,但可以通过扩展方法实现几乎等效的功能;例如:

process("key" to "value", 123 to UUID.randomUUID())
Run Code Online (Sandbox Code Playgroud)

这似乎不是最优雅的解决方案,所以我考虑的另一件事是 C# 有字典初始化语法;例如:

public static KeyValuePair<K, V> To<K, V>(this K key, V value) where K : notnull
{
    return new KeyValuePair(key, value);
}

var pair1 = "key".To("value");
var pair2 = 123.To(Guid.NewGuid());

Process("key".To("value"), 123.To(Guid.NewGuid()));
Run Code Online (Sandbox Code Playgroud)

或者

new Dictionary<object, object>()
{
    ["key"] = "value",
    [123] = Guid.NewGuid()
}
Run Code Online (Sandbox Code Playgroud)

所以我想知道字典初始化语法是否可以应用于方法参数;例如:

new Dictionary<object, object>()
{
    { "key", "value" },
    { 123, Guid.NewGuid() }
}
Run Code Online (Sandbox Code Playgroud)

或者

Process({ ["key"] = "value", [123] = Guid.NewGuid() });
Run Code Online (Sandbox Code Playgroud)

问题

字典初始值设定项语法是否可以作为方法参数,或者是编译器在使用字典时提供的语法糖吗?

还有其他优雅的方式来创建paramsof吗KeyValuePair<K, V>

Gro*_*roo 9

这是目前(截至 2023 年,C# 11)使用 C# 开箱即用所能获得的最佳效果。

正如您自己所写的,C# 3 引入了使用大括号的简写 init,C# 6 引入了命名参数 init,而 C# 9 允许您new()在可以推断实例化类型时使用。

这意味着你可以这样做:

// C# 3+
CallMethod(new Dictionary<string, string> { { "ka", "a" }, { "kb", "b" } });

// C# 6+
CallMethod(new Dictionary<string, string> { ["ka"] = "a", ["kb"] = "b" });

// C# 9+
CallMethod(new() { { "ka", "a" }, { "kb", "b" } });
Run Code Online (Sandbox Code Playgroud)

如果您确实想使用参数,减少击键的一种方法是使用ValueTuples,例如

public static Dictionary<K, V> CallMethod<K, V>(params (K key, V value)[] values)
{
    var dict = new Dictionary<K, V>();
    foreach (var kvp in values)
    {
        dict[kvp.key] = kvp.value;
    }
    return dict;
}
Run Code Online (Sandbox Code Playgroud)

然后你可以做

// C# 7+, return type is inferred to be Dictionary<string, string>
CallMethod(("ka", "a"), ("kb", "b"));
Run Code Online (Sandbox Code Playgroud)

[更新]

C#12 中还有一个针对集合文字的建议更新,它允许您使用以下语法:

// C# 12+ proposal
CallMethod(["ka": "a", "kb": "b"]);
Run Code Online (Sandbox Code Playgroud)