มีวิธีที่หรูหรากว่าในการเพิ่มรายการลงในพจนานุกรม <> อย่างปลอดภัยหรือไม่?


141

ฉันต้องเพิ่มคู่คีย์ / วัตถุลงในพจนานุกรม แต่แน่นอนฉันต้องตรวจสอบก่อนว่ามีกุญแจอยู่แล้วหรือไม่ฉันได้รับข้อผิดพลาด" คีย์มีอยู่แล้วในพจนานุกรม " รหัสด้านล่างแก้ปัญหานี้ แต่ clunky

เป็นวิธีที่สง่างามมากขึ้นในการทำสิ่งนี้โดยไม่ต้องทำวิธีการช่วยเหลือสตริงเช่นนี้?

using System;
using System.Collections.Generic;

namespace TestDictStringObject
{
    class Program
    {
        static void Main(string[] args)
        {
            Dictionary<string, object> currentViews = new Dictionary<string, object>();

            StringHelpers.SafeDictionaryAdd(currentViews, "Customers", "view1");
            StringHelpers.SafeDictionaryAdd(currentViews, "Customers", "view2");
            StringHelpers.SafeDictionaryAdd(currentViews, "Employees", "view1");
            StringHelpers.SafeDictionaryAdd(currentViews, "Reports", "view1");

            foreach (KeyValuePair<string, object> pair in currentViews)
            {
                Console.WriteLine("{0} {1}", pair.Key, pair.Value);
            }
            Console.ReadLine();
        }
    }

    public static class StringHelpers
    {
        public static void SafeDictionaryAdd(Dictionary<string, object> dict, string key, object view)
        {
            if (!dict.ContainsKey(key))
            {
                dict.Add(key, view);
            }
            else
            {
                dict[key] = view;
            }
        }
    }
}

คำตอบ:


246

เพียงใช้ตัวสร้างดัชนี - มันจะเขียนทับถ้ามันมีอยู่แล้ว แต่มันไม่จำเป็นต้องอยู่ที่นั่นก่อน:

Dictionary<string, object> currentViews = new Dictionary<string, object>();
currentViews["Customers"] = "view1";
currentViews["Customers"] = "view2";
currentViews["Employees"] = "view1";
currentViews["Reports"] = "view1";

โดยทั่วไปใช้Addหากการมีอยู่ของคีย์บ่งชี้ข้อผิดพลาด (ดังนั้นคุณต้องการที่จะโยน) และตัวสร้างดัชนีเป็นอย่างอื่น (เหมือนกับความแตกต่างระหว่างการคัดเลือกนักแสดงและการใช้asสำหรับการแปลงอ้างอิง)

หากคุณใช้ C # 3 และคุณมีชุดของคีย์ที่แตกต่างกันคุณสามารถทำให้เป็นแบบนี้ได้:

var currentViews = new Dictionary<string, object>()
{
    { "Customers", "view2" },
    { "Employees", "view1" },
    { "Reports", "view1" },
};

แต่นั่นจะไม่ทำงานในกรณีของคุณเนื่องจากตัวรวบรวมการเริ่มต้นใช้Addซึ่งจะใช้กับCustomersรายการที่สองเสมอ


6
ยอดเยี่ยมไม่ทราบว่าการมอบหมายง่าย ๆ ดูแลปัญหาการเพิ่ม / เขียนทับดี
Edward Tanguay

49

เกิดอะไรขึ้นกับ ...

dict[key] = view;

มันจะเพิ่มคีย์โดยอัตโนมัติหากไม่มีอยู่


3
สิ่งหนึ่งที่ฉันคิดว่าน่าสังเกตว่าถ้าคุณเก็บ int ไว้dict[key] += amountจะไม่ทำงานหากไม่มีคีย์
Chris S

22

ง่ายดาย

dict[key] = view;

จากเอกสาร MSDN ของ Dictionary.Item

ค่าที่เกี่ยวข้องกับคีย์ที่ระบุ ถ้าคีย์ที่ระบุไม่พบการดำเนินการรับพ่น KeyNotFoundException และการดำเนินงานชุดสร้างองค์ประกอบใหม่ที่มีคีย์ที่ระบุ

ความสำคัญของฉัน


10

ตามปกติแล้ว John Skeet จะมาพร้อมกับความเร็วแสงพร้อมกับคำตอบที่ถูกต้อง แต่ที่น่าสนใจคือคุณสามารถเขียน SafeAdd ของคุณเป็นวิธีเสริมบน IDictionary ได้

public static void SafeAdd(this IDictionary<K, T>. dict, K key, T value)...

9

แม้ว่าการใช้ตัวจัดทำดัชนีจะเป็นคำตอบที่ถูกต้องสำหรับปัญหาเฉพาะของคุณ แต่คำตอบทั่วไปเพิ่มเติมสำหรับปัญหาของการเพิ่มฟังก์ชันการทำงานเพิ่มเติมให้กับประเภทที่มีอยู่คือการกำหนดวิธีการขยาย

เห็นได้ชัดว่านี่ไม่ใช่ตัวอย่างที่มีประโยชน์เป็นพิเศษ แต่มีบางสิ่งที่ควรคำนึงถึงในครั้งต่อไปที่คุณพบความต้องการที่แท้จริง:

public static class DictionaryExtensions
{
    public static void SafeAdd<TKey, TValue>(this Dictionary<TKey, TValue> dict, 
                                             TKey key, TValue value)
    {
        dict[key] = value;
    }
}

2
ฉันพูดถึงสิ่งนี้ใช้ได้กับ C # 3.0 ขึ้นไปเท่านั้น
Mehrdad Afshari
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.