ich das bin Entsendung pedantisch zu sein. Ich mag die Anbindung an Dictionary nicht, da diese sehr häufige Art von Zugriff kostenintensiv ist - wenn Ihr häufigster Fall ein bereits existierendes Element berührt, müssen Sie den Hashwert dreimal nachschlagen. Glaub mir nicht? Ich schrieb DK-Lösung hier:
static void AddInc(Dictionary<string, int> dict, string s)
{
if (dict.ContainsKey(s))
{
dict[s]++;
}
else
{
dict.Add(s, 1);
}
}
Wenn in IL setzen - Sie diese:
L_0000: nop
L_0001: ldarg.0
L_0002: ldarg.1
L_0003: callvirt instance bool [mscorlib]System.Collections.Generic.Dictionary`2<string, int32>::ContainsKey(!0)
L_0008: ldc.i4.0
L_0009: ceq
L_000b: stloc.0
L_000c: ldloc.0
L_000d: brtrue.s L_0028
L_000f: nop
L_0010: ldarg.0
L_0011: dup
L_0012: stloc.1
L_0013: ldarg.1
L_0014: dup
L_0015: stloc.2
L_0016: ldloc.1
L_0017: ldloc.2
L_0018: callvirt instance !1 [mscorlib]System.Collections.Generic.Dictionary`2<string, int32>::get_Item(!0)
L_001d: ldc.i4.1
L_001e: add
L_001f: callvirt instance void [mscorlib]System.Collections.Generic.Dictionary`2<string, int32>::set_Item(!0, !1)
L_0024: nop
L_0025: nop
L_0026: br.s L_0033
L_0028: nop
L_0029: ldarg.0
L_002a: ldarg.1
L_002b: ldc.i4.1
L_002c: callvirt instance void [mscorlib]System.Collections.Generic.Dictionary`2<string, int32>::Add(!0, !1)
L_0031: nop
L_0032: nop
L_0033: ret
, die ContainsKey, get_item Anrufe und set_item, von denen alle Hash und nachschlagen.
Ich schrieb etwas weniger hübsch, die eine Klasse verwendet, die ein int enthält und die Klasse können Sie Seite-Wirkung (Sie können nicht wirklich eine Struktur ohne die gleiche Strafe wegen der Struktur kopieren Semantik).
class IntegerHolder {
public IntegerHolder(int x) { i = x; }
public int i;
}
static void AddInc2(Dictionary<string, IntegerHolder> dict, string s)
{
IntegerHolder holder = dict[s];
if (holder != null)
{
holder.i++;
}
else
{
dict.Add(s, new IntegerHolder(1));
}
}
Dies gibt Ihnen die folgende IL:
L_0000: nop
L_0001: ldarg.0
L_0002: ldarg.1
L_0003: callvirt instance !1 [mscorlib]System.Collections.Generic.Dictionary`2<string, class AddableDictionary.IntegerHolder>::get_Item(!0)
L_0008: stloc.0
L_0009: ldloc.0
L_000a: ldnull
L_000b: ceq
L_000d: stloc.1
L_000e: ldloc.1
L_000f: brtrue.s L_0023
L_0011: nop
L_0012: ldloc.0
L_0013: dup
L_0014: ldfld int32 AddableDictionary.IntegerHolder::i
L_0019: ldc.i4.1
L_001a: add
L_001b: stfld int32 AddableDictionary.IntegerHolder::i
L_0020: nop
L_0021: br.s L_0033
L_0023: nop
L_0024: ldarg.0
L_0025: ldarg.1
L_0026: ldc.i4.1
L_0027: newobj instance void AddableDictionary.IntegerHolder::.ctor(int32)
L_002c: callvirt instance void [mscorlib]System.Collections.Generic.Dictionary`2<string, class AddableDictionary.IntegerHolder>::Add(!0, !1)
L_0031: nop
L_0032: nop
L_0033: ret
Welche get_item einmal nennt - es gibt keine zusätzlichen Hashing ist im Fall eines Objekts vorhanden. Ich habe ein wenig sleazy und machte das Feld öffentlich, um die Methode zu vermeiden, die Zugriff auf Eigentum verlangt.
Wenn es nach mir ginge, würde ich diese gesamte Funktionalität in seine eigenen Klasse wickeln und die IntegerHolder Klasse aus der Öffentlichkeit verstecken - hier ist eine Kurzversion:
public class CountableItem<T>
{
private class IntegerHolder
{
public int i;
public IntegerHolder() { i = 1; }
}
Dictionary<T, IntegerHolder> dict = new Dictionary<T, IntegerHolder>();
public void Add(T key)
{
IntegerHolder val = dict[key];
if (val != null)
val.i++;
else
dict.Add(key, new IntegerHolder());
}
public void Clear()
{
dict.Clear();
}
public int Count(T key)
{
IntegerHolder val = dict[key];
if (val != null)
return val.i;
return 0;
}
// TODO - write the IEnumerable accessor.
}
Ok, Ihre Lösung scheint zu funktionieren. Was denkst du über die Wörterbuchalternative? Was passiert, wenn ich nur (int) htColors [color] + 1, würde das den Schlüssel oder Wert ändern? – Xaisoft
Danke für die Hilfe mit der HashTable. Es sieht so aus, als würde ich doch mit einem Wörterbuch gehen. – Xaisoft
Jemand kann mich korrigieren, wenn ich hier falsch liege, aber ich glaube, das automatische Boxen/Unboxing tritt für jeden Werttyp auf, der in den Heap verschoben wird, sogar (in diesem Fall) ints in einem typisierten Wörterbuch (Dictionary). Was Wörterbuch eliminiert, ist Unordnung vom Casting. –