Tôi có thể sử dụng trình khởi tạo bộ sưu tập cho các mục nhập Từ điển <TKey, TValue> không?


94

Tôi muốn sử dụng trình khởi tạo bộ sưu tập cho bit mã tiếp theo:

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;
}

Vì vậy, thông thường nó phải là một cái gì đó như:

return new Dictionary<int, string>
{ 
   1, "Adam",
   2, "Bart"
   ...

Nhưng cú pháp chính xác cho điều này là gì?


Kiểm tra bài đăng này: marcin-chwedczuk.github.io/…
csharpfolk


đừng nghĩ đó là một bản dupe, bởi vì họ đang hỏi, không phải về cú pháp khai báo từ điển tốc ký, mà vì lý do tại sao tốc ký không hoạt động trong thiết lập (cổ) ​​của họ.
NH.

Câu trả lời:


157
var names = new Dictionary<int, string> {
  { 1, "Adam" },
  { 2, "Bart" },
  { 3, "Charlie" }
};

1
Khi nào trình khởi tạo hoạt động? Nó chỉ dành cho các Dictionary<TKey, TValue>lớp con hay cũng sẽ hoạt động trên ICollection<KeyValuePair<TKey, TValue>>?
Shimmy Weitzhandler 17/12/12

sau C # 3.0, bạn có thể sử dụng varthay vì kiểu khai báo, hoặc nếu bỏ kiểu tuyên bố có thể bỏ qua new Dictio...- stackoverflow.com/questions/5678216/...
drzaus

1
@drzaus: Mặc dù vậy, sử dụng var là một thực hành xấu xí, xấu xí; C # là một ngôn ngữ được đánh máy mạnh.
Nyerguds

1
@Nyerguds: sao? vartheo nghĩa đen, chỉ giúp bạn tiết kiệm các lần gõ phím, nó được đánh máy một cách ngầm hiểu .
drzaus

4
@Nyerguds - tôi đoán là bạn có quyền đưa ra ý kiến ​​của mình, nhưng nếu bạn ngay lập tức khởi tạo các biến của mình thì thực sự không có sự khác biệt giữa việc sử dụng varvà lặp lại chính mình với SomeType obj = new SomeType.... Và vì bạn không thể khai báo var obj;mà không khởi tạo ngay lập tức, tôi chỉ không thấy vấn đề. Thực sự, tôi đang cố gắng học hỏi, nhưng tôi không thể dò dẫm vị trí của bạn.
drzaus

36

Cú pháp hơi khác:

Dictionary<int, string> names = new Dictionary<int, string>()
{
    { 1, "Adam" },
    { 2, "Bart" }
}

Lưu ý rằng bạn đang thêm các bộ giá trị một cách hiệu quả.

Là một phụ chú: bộ khởi tạo bộ sưu tập chứa các đối số về cơ bản là các đối số cho bất kỳ hàm Add () nào có ích liên quan đến loại đối số thời gian biên dịch. Đó là, nếu tôi có một bộ sưu tập:

class FooCollection : IEnumerable
{
    public void Add(int i) ...

    public void Add(string s) ...

    public void Add(double d) ...
}

mã sau là hoàn toàn hợp pháp:

var foos = new FooCollection() { 1, 2, 3.14, "Hello, world!" };

Câu trả lời tuyệt vời, tôi không biết về điều đó! Dù sao, khi nào thì trình khởi tạo từ điển hoạt động? Nó chỉ dành cho các lớp con của Dictionary <TKey, TValue> hay cũng sẽ hoạt động trên ICollection <KeyValuePair <TKey, TValue >>?
Shimmy Weitzhandler 17/12/12

Bộ khởi tạo @Shimmy Collection hoạt động trên bất kỳ thứ gì triển khai IEnumerable Add()phương thức.
Anton Gogolev

@Shimmy: từ điển là bộ sưu tập
John Saunders

@JohnSaunders Nhưng một trình khởi tạo từ điển chấp nhận hai tham số cho Add.
Shimmy Weitzhandler 22/12/12

2
@Shimmy: tại sao điều đó lại quan trọng? Vấn đề là nó sẽ hoạt động với bất kỳ lớp nào triển khai IEnumerable<T>và có một Addphương thức. Nếu Addphương thức có 3 tham số, thì bạn sẽ cần 3 đối tượng trong dấu ngoặc.
John Saunders

11
return new Dictionary<int, string>
{ 
   { 1, "Adam" },
   { 2, "Bart" },
   ...

10

Câu hỏi được gắn thẻ c#-3.0, nhưng để đầy đủ, tôi sẽ đề cập đến cú pháp mới có sẵn với C # 6 trong trường hợp bạn đang sử dụng Visual Studio 2015 (hoặc Mono 4.0):

var dictionary = new Dictionary<int, string>
{
   [1] = "Adam",
   [2] = "Bart",
   [3] = "Charlie"
};

Lưu ý: cú pháp cũ được đề cập trong các câu trả lời khác vẫn hoạt động, nếu bạn thích điều đó hơn. Một lần nữa, để hoàn thiện, đây là cú pháp cũ:

var dictionary = new Dictionary<int, string>
{
   { 1, "Adam" },
   { 2, "Bart" },
   { 3, "Charlie" }
};

Một điều thú vị khác cần lưu ý là với một trong hai cú pháp, bạn có thể để lại dấu phẩy cuối cùng nếu muốn, điều này giúp dễ dàng sao chép / dán các dòng bổ sung. Ví dụ: các biên dịch sau đây rất tốt:

var dictionary = new Dictionary<int, string>
{
   [1] = "Adam",
   [2] = "Bart",
   [3] = "Charlie",
};

5

Nếu bạn đang tìm kiếm cú pháp ít dài dòng hơn một chút, bạn có thể tạo một lớp con Dictionary<string, object>(hoặc bất kỳ loại nào của bạn) như sau:

public class DebugKeyValueDict : Dictionary<string, object>
{

}

Sau đó, chỉ cần khởi tạo như thế này

var debugValues = new DebugKeyValueDict
                  {
                       { "Billing Address", billingAddress }, 
                       { "CC Last 4", card.GetLast4Digits() },
                       { "Response.Success", updateResponse.Success }
                  });

Tương đương với

var debugValues = new Dictionary<string, object>
                  {
                       { "Billing Address", billingAddress }, 
                       { "CC Last 4", card.GetLast4Digits() },
                       { "Response.Success", updateResponse.Success }
                  });

Lợi ích là bạn nhận được tất cả những thứ mà bạn có thể muốn, chẳng hạn như có thể nói

is DebugKeyValueDict thay vì is IDictionary<string, object>

hoặc thay đổi loại khóa hoặc giá trị vào một ngày sau đó. Nếu bạn đang làm điều gì đó như thế này trong một trang cshtml dao cạo thì sẽ đẹp hơn rất nhiều.

Cũng như ít dài dòng hơn, tất nhiên bạn có thể thêm các phương thức bổ sung vào lớp này cho bất cứ điều gì bạn có thể muốn.


Về cơ bản đây là cách ViewDataDictionary hoạt động trong MVC - stackoverflow.com/questions/607985/…
Simon_Weaver

Tôi đã thử nghiệm với các kiểu làm 'bí danh' cho Từ điển và mảng đã nhập, cho rằng nó sẽ an toàn hơn, trong một thế giới được đánh máy, sử dụng các kiểu được xác định trước .. Hóa ra không hữu ích như vậy khi nói đến generics và linq.
Patrick

1

Trong ví dụ mã sau, a Dictionary<TKey, TValue>được khởi tạo với các thể hiện của kiểu 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}}
  };

từ msdn


-3

Có, chúng ta có thể sử dụng trình khởi tạo bộ sưu tập trong từ điển. Nếu chúng ta có một từ điển như thế này-

Dictionary<int,string> dict = new Dictionary<int,string>();  
            dict.Add(1,"Mohan");  
            dict.Add(2, "Kishor");  
            dict.Add(3, "Pankaj");  
            dict.Add(4, "Jeetu");

Chúng ta có thể khởi tạo nó như sau.

Dictionary<int,string> dict = new Dictionary<int,string>  
            {  

                {1,"Mohan" },  
                {2,"Kishor" },  
                {3,"Pankaj" },  
                {4,"Jeetu" }  

            }; 

4
Đã có 6 câu trả lời khác hướng dẫn cách làm điều này. Chúng ta không cần câu trả lời thứ 7 cho thấy điều tương tự.
Servy
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.