C#6的新集合初始化程序 - 澄清?

Roy*_*mir 16 c# dictionary collection-initializer c#-6.0

我读过:

团队一直忙于实现初始化程序的其他变体.例如,您现在可以初始化Dictionary对象

但看看:

var Dic = new Dictionary<string,int>{ {"x",3}, {"y",7} };
Run Code Online (Sandbox Code Playgroud)

VS

var Dic = new Dictionary<string,int>{ ["x"]=3, ["y"]=7 };
Run Code Online (Sandbox Code Playgroud)

我不知道好处在哪里.它看起来一样.两者都只是一个名值集合.
他们用成对的方括号和一些逗号交换成对的花括号

题:

使用新语法的附加值是什么?一个现实世界的例子将非常感激.

Ree*_*sey 24

字典的主要优点是一致性.使用字典,初始化与用法看起来不一样.

例如,您可以这样做:

var dict = new Dictionary<int,string>();
dict[3] = "foo";
dict[42] = "bar";
Run Code Online (Sandbox Code Playgroud)

但是使用初始化语法,你必须使用大括号:

var dict = new Dictionary<int,string>
{
    {3, "foo"},
    {42, "bar"}
};
Run Code Online (Sandbox Code Playgroud)

新的C#6索引初始化语法使初始化语法与索引使用更加一致:

var dict = new Dictionary<int,string>
{ 
    [3] = "foo",
    [42] = "bar"
};
Run Code Online (Sandbox Code Playgroud)

但是,更大的优势是此语法还提供了允许您初始化其他类型的好处.具有索引器的任何类型都将允许通过此语法进行初始化,其中旧的集合初始值设定项仅适用于实现IEnumerable<T>并具有Add方法的类型.这恰好与a一起使用Dictionary<TKey,TValue>,但这并不意味着它适用于任何基于索引的类型.

  • Reed,abit offtopic,但仍然相关 - 我也看到(在视频中,现在)c#6也在寻找Add方法,超出了实例方法,我的意思是它可能在扩展方法中.所以如果有人有一个名为`Insert`的方法,你将无法做到`new MyIenumerableType <> {{...,...},{...,...}}`因为它的类型没有`Add`方法.但C#6也将搜索"添加"作为扩展方法.(如果您无法控制代码) (3认同)

Jef*_*ado 9

第一种情况中的代码使用集合初始化程序语法.为了能够使用集合初始化程序语法,类必须:

集合初始化器:

  1. 实现IEnumerable接口.
  2. 定义可访问的Add()方法.(从C#6/VS2015开始,它可能是一种扩展方法)

所以这样定义的类可能会使用以下语法:

public class CollectionInitializable : IEnumerable
{
    public void Add(int value) { ... }
    public void Add(string key, int value) { ... }
    public IEnumerator GetEnumerator() { ... }
}

var obj = new CollectionInitializable
{
    1,
    { "two", 3 },
};
Run Code Online (Sandbox Code Playgroud)

并非所有对象都是IEnumerable或者具有add方法,因此无法使用该语法.


另一方面,许多对象定义(可设置)索引器.这是使用dicionary初始化程序的地方.拥有索引器可能有意义,但不一定如此IEnumerable.使用字典初始化程序,您不需要IEnumerable,您不需要Add()方法,您只需要一个索引器.

能够在单个表达式中完全初始化对象通常是有用的(在某些情况下,需要).字典初始化器语法使得在没有使用集合初始化器的苛刻要求的情况下更容易实现.


ven*_*eis 6

这可能是一个值得怀疑的功能,但新语法允许您多次设置相同的功能.

        private static Dictionary<string, string> test1
        = new Dictionary<string, string>() {
            ["a"] = "b",
            ["a"] = "c"
        };
Run Code Online (Sandbox Code Playgroud)

允许:这里的键"a"有值"c".

相比之下,使用

private static Dictionary<string, string> test2
    = new Dictionary<string, string>() {
        { "a","b" },
        { "a","c" },
    };
Run Code Online (Sandbox Code Playgroud)

创建一个例外:

Unbehandelte Ausnahme: System.TypeInitializationException: Der Typeninitialisierer für "ConsoleApplication1.Program" hat eine Ausnahme verursacht. 
---> System.ArgumentException: Ein Element mit dem gleichen Schlüssel wurde bereits hinzugefügt.
   bei System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
   bei System.Collections.Generic.Dictionary``2.Insert(TKey key, TValue value, Boolean add)
   bei System.Collections.Generic.Dictionary``2.Add(TKey key, TValue value)
   bei ConsoleApplication1.Program..cctor() in Program.cs:Zeile 19.
   --- Ende der internen Ausnahmestapelüberwachung ---
   bei ConsoleApplication1.Program.Main(String[] args)
Run Code Online (Sandbox Code Playgroud)