我可以为 Dictionary<TKey, TValue> 条目使用集合初始化程序吗?
Posted
技术标签:
【中文标题】我可以为 Dictionary<TKey, TValue> 条目使用集合初始化程序吗?【英文标题】:Can I use a collection initializer for Dictionary<TKey, TValue> entries? 【发布时间】:2010-10-04 10:45:02 【问题描述】:我想为下一段代码使用集合初始化器:
public Dictionary<int, string> GetNames()
Dictionary<int, string> names = new Dictionary<int, string>();
names.Add(1, "Adam");
names.Add(2, "Bart");
names.Add(3, "Charlie");
return names;
所以通常应该是这样的:
return new Dictionary<int, string>
1, "Adam",
2, "Bart"
...
但是正确的语法是什么?
【问题讨论】:
查看这篇文章:marcin-chwedczuk.github.io/… Proper way to initialize a C# dictionary with values already in it?的可能重复 不要认为这是骗人的,因为他们问的不是速记字典声明语法,而是为什么速记在他们的(古代)设置中不起作用。 【参考方案1】:return new Dictionary<int, string>
1, "Adam" ,
2, "Bart" ,
...
【讨论】:
【参考方案2】:语法略有不同:
Dictionary<int, string> names = new Dictionary<int, string>()
1, "Adam" ,
2, "Bart"
请注意,您实际上是在添加值的元组。
作为旁注:集合初始化器包含的参数基本上是任何 Add() 函数的参数,这些函数在编译时参数类型方面派上用场。也就是说,如果我有一个集合:
class FooCollection : IEnumerable
public void Add(int i) ...
public void Add(string s) ...
public void Add(double d) ...
以下代码完全合法:
var foos = new FooCollection() 1, 2, 3.14, "Hello, world!" ;
【讨论】:
很好的答案,我不知道!无论如何,字典初始化程序什么时候工作?它仅适用于 DictionaryIEnumerable
并且 具有Add()
方法的东西。
@Shimmy:字典是集合
@JohnSaunders 但是字典初始化程序接受Add
的两个参数。
@Shimmy:这有什么关系?关键是它可以与实现IEnumerable<T>
并具有Add
方法的any 类一起使用。如果 Add
方法采用 3 参数,那么括号中需要 3 个对象。【参考方案3】:
var names = new Dictionary<int, string>
1, "Adam" ,
2, "Bart" ,
3, "Charlie"
;
【讨论】:
初始化程序什么时候工作?它仅适用于Dictionary<TKey, TValue>
子类还是也适用于ICollection<KeyValuePair<TKey, TValue>>
?
在C# 3.0之后可以使用var
代替声明类型,或者如果离开声明类型可以省略new Dictio...
-- ***.com/questions/5678216/…
@drzaus:虽然使用 var 是一种丑陋、丑陋的做法; C# 是一种强类型语言。
@Nyerguds:什么? var
字面上只是节省了您的击键次数,它是 implicitly strongly typed。
@Nyerguds -- 我猜你有权发表你的意见,但如果你立即初始化你的变量,那么使用var
和重复使用SomeType obj = new SomeType...
之间几乎没有区别。而且由于您不能在不立即初始化的情况下声明var obj;
,所以我只是看不到问题所在。真的,我正在努力学习,但我无法理解你的立场。【参考方案4】:
如果您正在寻找稍微不那么冗长的语法,您可以像这样创建Dictionary<string, object>
(或任何您的类型)的子类:
public class DebugKeyValueDict : Dictionary<string, object>
然后就这样初始化
var debugValues = new DebugKeyValueDict
"Billing Address", billingAddress ,
"CC Last 4", card.GetLast4Digits() ,
"Response.Success", updateResponse.Success
);
相当于
var debugValues = new Dictionary<string, object>
"Billing Address", billingAddress ,
"CC Last 4", card.GetLast4Digits() ,
"Response.Success", updateResponse.Success
);
好处是你可以获得所有你可能想要的编译类型的东西,比如能够说
is DebugKeyValueDict
而不是is IDictionary<string, object>
或在以后更改键或值的类型。 如果你在一个 razor cshtml 页面中做这样的事情,看起来会更好看。
除了不那么冗长,你当然可以为这个类添加额外的方法来满足你的需要。
【讨论】:
这基本上是 ViewDataDictionary 在 MVC 中的工作方式 - ***.com/questions/607985/… 我尝试将类型作为字典和类型化数组的“别名”,假设在类型化世界中使用预定义类型会更安全。结果发现它并没有那么有用泛型和 linq。【参考方案5】:在以下代码示例中,Dictionary<TKey, TValue>
使用 StudentName
类型的实例进行初始化。
Dictionary<int, StudentName> students = new Dictionary<int, StudentName>()
111, new StudentName FirstName="Sachin", LastName="Karnik", ID=211,
112, new StudentName FirstName="Dina", LastName="Salimzianova", ID=317,
113, new StudentName FirstName="Andy", LastName="Ruth", ID=198
;
来自msdn
【讨论】:
【参考方案6】:这个问题被标记为c#-3.0
,但为了完整起见,我会提到 C# 6 中可用的新语法,以防您使用 Visual Studio 2015(或 Mono 4.0):
var dictionary = new Dictionary<int, string>
[1] = "Adam",
[2] = "Bart",
[3] = "Charlie"
;
注意:如果您更喜欢,其他答案中提到的旧语法仍然有效。同样,为了完整起见,这里是旧语法:
var dictionary = new Dictionary<int, string>
1, "Adam" ,
2, "Bart" ,
3, "Charlie"
;
需要注意的另一件很酷的事情是,无论使用哪种语法,您都可以根据需要保留最后一个逗号,这样可以更轻松地复制/粘贴其他行。例如,下面的编译就好了:
var dictionary = new Dictionary<int, string>
[1] = "Adam",
[2] = "Bart",
[3] = "Charlie",
;
【讨论】:
【参考方案7】:是的,我们可以在字典中使用集合初始化器。如果我们有这样的字典-
Dictionary<int,string> dict = new Dictionary<int,string>();
dict.Add(1,"Mohan");
dict.Add(2, "Kishor");
dict.Add(3, "Pankaj");
dict.Add(4, "Jeetu");
我们可以如下初始化它。
Dictionary<int,string> dict = new Dictionary<int,string>
1,"Mohan" ,
2,"Kishor" ,
3,"Pankaj" ,
4,"Jeetu"
;
【讨论】:
已经有 6 个其他答案展示了如何做到这一点。我们不需要显示相同内容的第 7 个答案。以上是关于我可以为 Dictionary<TKey, TValue> 条目使用集合初始化程序吗?的主要内容,如果未能解决你的问题,请参考以下文章
Dictionary<TKey, TValue> 的线程安全
ConcurrentDictionary与Dictionary
System.Collections.Generic.Dictionary<TKey,TValue>
Dictionary<TKey, TValue> 中的散列过程是如何工作的