Feedback

C# - Dictionary extension methods in .Net

Veröffentlicht von am 04.03.2017
(0 Bewertungen)
Dictionary extension methods in .Net
using System;
using System.Collections.Generic;
using System.Linq;

namespace CollectionExtensions
{
    public static class DictionaryExtension
    {
        public static void AddIfNotExists<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, TKey key, TValue value)
        {
            CheckDictionaryIsNull(dictionary);
            if (!dictionary.ContainsKey(key))
                dictionary.Add(key, value);
        }

        public static void DeleteIfExistsKey<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, TKey key)
        {
            CheckDictionaryIsNull(dictionary);
            if (dictionary.ContainsKey(key))
                dictionary.Remove(key);
        }

        public static void Update<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, TKey key, TValue value)
        {
            CheckDictionaryIsNull(dictionary);
            CheckKeyValuePairIsNull(key, value);
            dictionary[key] = value;
        }

        public static void Update<TKey, TValue>(this Dictionary<TKey, TValue> dictionary,
            KeyValuePair<TKey, TValue> pair)
        {
            CheckDictionaryIsNull(dictionary);
            CheckKeyValuePairIsNull(pair);
            dictionary[pair.Key] = pair.Value;
        }

        public static void DeleteIfExistsValue<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, TValue value)
        {
            CheckDictionaryIsNull(dictionary);
            if (!dictionary.ContainsValue(value)) return;
            var key = dictionary.GetKeyFromValue(value);
            dictionary.Remove(key);
        }

        public static bool AreValuesEmpty<TKey, TValue>(this Dictionary<TKey, TValue> dictionary)
        {
            CheckDictionaryIsNull(dictionary);
            return dictionary.All(x => x.Value == null);
        }

        public static bool AreKeysEmpty<TKey, TValue>(this Dictionary<TKey, TValue> dictionary)
        {
            CheckDictionaryIsNull(dictionary);
            return dictionary.All(x => x.Key == null);
        }

        private static TKey GetKeyFromValue<TKey, TValue>(this Dictionary<TKey, TValue> dictionary,
            TValue value)
        {
            var keys = new List<TKey>();
            foreach (var pair in dictionary)
                AddToKeysList(keys, pair, value);
            CheckCountGreaterZero(keys.Count, value);
            return !keys.Any() ? default(TKey) : keys.First();
        }

        private static void AddToKeysList<TKey, TValue>(List<TKey> keys, KeyValuePair<TKey, TValue> pair, TValue value)
        {
            if (pair.Value.Equals(value))
                keys.Add(pair.Key);
        }

        private static void CheckCountGreaterZero<TValue>(int count, TValue value)
        {
            if (count <= 0) throw new ArgumentOutOfRangeException(nameof(count));
            if (count > 1) throw new ArgumentException(nameof(value));
        }

        private static void CheckDictionaryIsNull<TKey, TValue>(this Dictionary<TKey, TValue> dictionary)
        {
            if (dictionary == null) throw new ArgumentNullException(nameof(dictionary));
        }

        private static void CheckKeyValuePairIsNull<TKey, TValue>(KeyValuePair<TKey, TValue> pair)
        {
            if (pair.Key == null || pair.Value == null) throw new ArgumentNullException(nameof(pair));
        }

        private static void CheckKeyValuePairIsNull<TKey, TValue>(TKey key, TValue value)
        {
            if (key == null) throw new ArgumentNullException(nameof(key));
            if (value == null) throw new ArgumentNullException(nameof(value));
        }
    }
}
Abgelegt unter Dictionary, extension, methods, method.

4 Kommentare zum Snippet

Koopakiller schrieb am 15.03.2017:
Es gilt erstmal mehr oder weniger das selbe wie ich unter den anderen Snippets schrieb.
https://dotnet-snippets.de/snippet/list-extension-methods-in-net/15164#LastComment

Außerdem gibt es noch ein paar andere Stellen die sich mir nicht so ganz erschließen. Beispielsweise warum du in CheckCountGreaterZero value als Parameternamen angibst, obwohl du count prüfst.

PS: Sieh es bitte als freundliche Kritik an, an sich scheinen deine Methoden je nach Projekt ganz nützlich zu sein :)
FranzHuber23 schrieb am 17.03.2017:
Zu CheckCountGreaterZero:

Wenn der Count <= 0 ist, soll eine ArgumentOutOfRangeException geworfen werden, weil dann ja kein Wert gefunden wird (Der Counter also out of range -1, 0, etc. ist).

Wenn Count > 1, dann soll ArgumentException mit Parameter value geworfen werden, weil ich ja nur einen Key für einen Value zurückbekommen will (nicht mehrere).
Xilefius schrieb am 31.03.2017:
Betreffend AreKeysEmpty: Ein Dictionary Key _kann_ nicht null sein, d.h. die Methode ist nutzlos :-)

var d = new Dictionary<object, string>();
d.Add(null, "foo");
--> ArgumentNullException: Value cannot be null.Parameter name: key



Betreffend DeleteIfExistsKey: Remove ist das bereits egal, ob der key existiert oder nicht.
var d = new Dictionary<object, string>();
d.Remove(new object());
--> Keine Exception



Betreffend GetKeyFromValue: Du wirfst eine OutOfRange Exception, wenn es keinen Eintrag mit dem gewünschten Value gibt, gibts am Ende aber doch "default(TKey)" zurück, wenn der key nicht gefunden wurde (was natürlich niemals passieren wird).

Ein
return keys[0];


wäre an der Stelle also direkter. Ansonsten die OutOfRange Exception entfernen, wenn kein key gefunden wurde (und dann einfach nur keys.FirstOrDefault() zurück geben, das bereits den default value liefert wenn es keine Elemente gibt) :-)
FranzHuber23 schrieb am 03.04.2017:
Hallo Xilefius. Da hast du natürlich Recht, war wohl etwas unüberlegt von mir, die Methoden ohne zu testen zu implementieren :D
 

Logge dich ein, um hier zu kommentieren!