Mein Ziel ist es, ein Wörterbuch, das eindeutige Schlüssel und Werte hat, die ich mit einem zusätzlichen HashSet lösen. Ich möchte eine Basisklasse haben, von der spezifischere Typen erben.Wie IDIssiction Interface und Unterklasse korrekt zu implementieren ist
Wie ich verstanden habe, ist die add-Methode der Dictionary-Klasse nicht virtuell und kann daher nicht überschrieben werden. Der einzige Weg, dies zu tun, ist die Implementierung der IDictionary-Schnittstelle.
So ist die Grundstruktur meiner Basiswörterbuch-Klasse ist:
public class BaseCustomDictionary<TKey,TValue>:IDictionary<TKey,TValue> {
public virtual Dictionary<TKey,TValue> InternalDict {
get;
set;
}
public BaseCustomDictionary() {
this.InternalDict = new Dictionary<TKey,TValue>();
}
// Here I start implementing all the required methods, e.g. Add, TryGetValue
public virtual void Add(TKey key, TValue value) {
InternalDict.Add(key, value);
}
public bool TryGetValue (TKey key, out string value) {
return InternalDict.TryGetValue (key, out value);
}
// And so on and so forth
}
Jetzt habe ich eine konkrete Unterklasse haben will, die int
s als Schlüssel und string
als Wert hat:
public class IntStringDictionary<TKey,TValue>:BaseCustomDictionary<TKey,TValue> {
public override Dictionary<int,string> InternalDict {
get;
set;
}
HashSet<string> UniqueValues;
public IntStringDictionary() {
InternalDict = new Dictionary<int,string>();
UniqueValues = new HashSet<string>();
}
public override void Add (TKey key, TValue value) {
if (InternalDict.ContainsKey (key)) {
return;
}
string randomStr = RandomString();
if (!UniqueValues.Add(randomStr)) {
Add(key,value);
return;
} else {
InternalDict.Add(key,randomStr);
return
}
}
}
I Here auf alle möglichen Probleme stoßen. Erste ist The best overloaded method match for 'System.Collections.Generic.Dictionary<int,string>.ContainsKey(string) has some invalid arguments'. Cannot convert type 'TKey' to 'string'.
Zustimmen. Also ändere ich die InternalDict
zu new Dictionary<TKey,short>()
und die Parameter für Add
zu (TKey key, TValue value)
.
Das nächste Problem ist, wie auf Methoden zugegriffen wird. Sagen meine Implementierung sieht wie folgt aus:
public static IntStringDictionary<int,string> myDict = new IntStringDictionary<int,string>();
// Assuming the class is named Constructor
public Constructor() {
myDict.Add(1,"foobar");
}
public static string GetValue (int key) {
string value;
myDict.TryGetValue(key, out value);
if (value == '') {
throw new NullReferenceException ("Value not found for given key");
}
return value;
}
Diese GetValue
Methode der implementierten Ausnahme immer aus, wenn ich 1
passieren, und ich verstehe wirklich nicht, warum. Ich debuggte den Code und kann feststellen, dass das 'InternalDict' tatsächlich den Schlüssel 1
und den Wert foobar. The
TryGetValue call on
myDict jumps into the implementation of the
BaseCustomDictionary class and writes an empty string into the
value` variable enthält.
Natürlich könnte ich jetzt meine eigene TryGetValue
in meiner Unterklasse implementieren, aber das scheint den Zweck der Unterklassen zu besiegen, wenn ich jede Methode implementieren muss.
public bool TryGetValue(TKey key, out int value) {
return InternalDict.TryGetValue(key, out value);
}
Ich fühle mich wie etwas grundlegend falsch mit der Vererbung tun.
Es ist hauptsächlich die "Add" -Methode. Abhängig vom Typ meiner Werte werde ich eine andere Methode aufrufen, um einen Pseudozufallswert zu erzeugen. Ansonsten weiß ich nicht, wie ich diese Unterscheidung in der 'BaseCustomDictionary'-Klasse hinzufügen könnte. – ShitakeOishii
Leider habe ich die Add-Methode nicht bemerkt. Aber Ihre Add-Methode-Implementierung scheint seltsam. Ich denke, Sie sollten diese Logik dem Benutzer der Wörterbuchklasse überlassen. Eine andere Möglichkeit besteht darin, dem BaseCustomDictionary Erweiterungsmethoden hinzuzufügen. – Sweeper