วิธีการเพิ่มรายการใหม่หรืออัปเดตรายการที่มีอยู่ในพจนานุกรม


235

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

วิธีที่ 1 (รหัสดั้งเดิม)

public static void CreateNewOrUpdateExisting<TKey, TValue>(
    this IDictionary<TKey, TValue> map, TKey key, TValue value)
{            
    if (map.ContainsKey(key))
    {
        map[key] = value;
    }
    else
    {
        map.Add(key, value);
    }
}

แม้ว่าฉันได้ตรวจสอบว่าmap[key]=value ทำหน้าที่เดียวกัน นั่นคือวิธีนี้สามารถแทนที่ด้วยวิธีที่ 2 ด้านล่าง

วิธีที่ 2

public static void CreateNewOrUpdateExisting<TKey, TValue>(
    this IDictionary<TKey, TValue> map, TKey key, TValue value)
{
    map[key] = value;
}

ตอนนี้คำถามของฉันคือ .. อาจมีปัญหาใด ๆ ถ้าฉันแทนที่ Method-1 โดย Method-2? มันจะแตกในสถานการณ์ที่เป็นไปได้หรือไม่?

นอกจากนี้ฉันคิดว่าสิ่งนี้เคยเป็นความแตกต่างระหว่าง HashTable และพจนานุกรม HashTable อนุญาตให้อัปเดตรายการหรือเพิ่มรายการใหม่โดยใช้ตัวจัดทำดัชนีในขณะที่ Dictionary ไม่ได้ !! ความแตกต่างนี้ถูกกำจัดในรุ่น C #> 3.0 หรือไม่

วัตถุประสงค์ของวิธีนี้ไม่ใช่ข้อยกเว้นหากผู้ใช้ส่งคีย์ - ค่าเดียวกันอีกครั้งวิธีควรอัปเดตรายการด้วยค่าใหม่และเพื่อสร้างรายการใหม่หากคู่คีย์ - ค่าใหม่ถูกส่งไปยังเมธอด .

คำตอบ:


243

อาจมีปัญหาใด ๆ หรือไม่หากฉันแทนที่ Method-1 ด้วย Method-2

map[key] = valueไม่เพียงแค่ใช้ ตัวเลือกทั้งสองนั้นเทียบเท่ากัน


เกี่ยวDictionary<>กับ vs. Hashtable: เมื่อคุณเริ่มตัวสะท้อนแสงคุณจะเห็นว่าตัวตั้งค่าตัวทำดัชนีของการเรียกคลาสthis.Insert(key, value, add: false);และaddพารามิเตอร์มีหน้าที่รับผิดชอบในการโยนข้อยกเว้นเมื่อใส่คีย์ที่ซ้ำกัน ดังนั้นพฤติกรรมจึงเหมือนกันสำหรับทั้งสองคลาส


44

ไม่มีปัญหา ฉันจะลบออกCreateNewOrUpdateExistingจากแหล่งที่มาและใช้map[key] = valueโดยตรงในรหัสของคุณเพราะสิ่งนี้สามารถอ่านได้มากขึ้นเพราะนักพัฒนามักจะรู้ว่าmap[key] = valueหมายถึงอะไร


22

คำถามเก่า แต่ฉันรู้สึกว่าฉันควรเพิ่มสิ่งต่อไปนี้มากยิ่งขึ้นเนื่องจาก. net 4.0 ได้เปิดตัวไปแล้วในขณะที่คำถามถูกเขียนขึ้น

เริ่มต้นด้วย. net 4.0 มีเนมสเปซSystem.Collections.Concurrentซึ่งมีคอลเลกชันที่ปลอดภัยต่อเธรด

คอลเลกชันSystem.Collections.Concurrent.ConcurrentDictionary<>ทำสิ่งที่คุณต้องการ มันมีAddOrUpdate()วิธีการที่มีข้อได้เปรียบเพิ่มเติมจากการเป็นเธรดที่ปลอดภัย

หากคุณอยู่ในสถานการณ์ที่มีประสิทธิภาพสูงและไม่จัดการหลายเธรดคำตอบที่ได้รับแล้วmap[key] = valueจะเร็วขึ้น

ในสถานการณ์ส่วนใหญ่ประโยชน์ด้านประสิทธิภาพนี้ไม่มีนัยสำคัญ ถ้าเป็นเช่นนั้นฉันอยากจะแนะนำให้ใช้ ConcurrentDictionary เพราะ:

  1. มันอยู่ในกรอบ - มันถูกทดสอบมากกว่าและคุณไม่ได้เป็นคนที่ต้องรักษารหัส
  2. สามารถปรับขนาดได้: หากคุณเปลี่ยนเป็นมัลติเธรดรหัสของคุณได้เตรียมไว้แล้ว

7

หน้าที่พวกเขาจะเทียบเท่า

การทำงานที่ชาญฉลาดmap[key] = valueจะเร็วขึ้นเนื่องจากคุณทำการค้นหาเพียงครั้งเดียวแทนที่จะเป็นสองรายการ

สไตล์ชาญฉลาดยิ่งสั้นยิ่งดีเท่านั้น :)

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

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