CSharp · Console
using System;
using System.Text;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
var myDict = new MultiKeyDictionary<string, double, double, string>
{
{"Goodbye", 0.55, 9.00, "yaya"} // collection initializer works fine
};
myDict.Add("Hello", 1.11, 2.99, "hi");
Console.WriteLine(myDict.ContainsKey("Hello", 1.11, 2.99)); // true
Console.WriteLine(myDict.ContainsKey("a", 1.11, 2.99)); // false
Console.WriteLine(myDict["Hello", 1.11, 2.99]); // hi
// myDict.Add(TripleKey.Create("Hello", 1.11, 2.99), "gh"); // bang! exception,
// key already exist
}
}
[Serializable]
public struct TripleKey<TKeyA, TKeyB, TKeyC>
{
private readonly TKeyA _keyA;
private readonly TKeyB _keyB;
private readonly TKeyC _keyC;
public TKeyA KeyA => _keyA;
public TKeyB KeyB => _keyB;
public TKeyC KeyC => _keyC;
public TripleKey(TKeyA keyA, TKeyB keyB, TKeyC keyC)
{
this._keyA = keyA;
this._keyB = keyB;
this._keyC = keyC;
}
// this code is almost the same as it is in Microsoft implementation
public override string ToString()
{
var sBuilder = new StringBuilder();
sBuilder.Append('(');
if (KeyA != null)
{
sBuilder.Append(KeyA.ToString());
}
sBuilder.Append(", ");
if (KeyB != null)
{
sBuilder.Append(KeyB.ToString());
}
sBuilder.Append(", ");
if (KeyC != null)
{
sBuilder.Append(KeyC.ToString());
}
sBuilder.Append(')');
return sBuilder.ToString();
}
}
public static class TripleKey
{
public static TripleKey<TKeyA, TKeyB, TKeyC> Create<TKeyA, TKeyB, TKeyC>(TKeyA keyA, TKeyB keyB, TKeyC keyC)
{
return new TripleKey<TKeyA, TKeyB, TKeyC>(keyA, keyB, keyC);
}
}
public class MultiKeyDictionary<TKeyA, TKeyB, TKeyC, TValue> : Dictionary<TripleKey<TKeyA, TKeyB, TKeyC>, TValue>
{
public TValue this[TKeyA keyA, TKeyB keyB, TKeyC keyC]
{
get
{
var key = TripleKey.Create(keyA, keyB, keyC);
return base.ContainsKey(key) ? base[key] : default(TValue);
}
set
{
var key = TripleKey.Create(keyA, keyB, keyC);
if (!ContainsKey(key))
base.Add(key, value);
this[key] = value;
}
}
public bool ContainsKey(TKeyA keyA, TKeyB keyB, TKeyC keyC)
{
var key = TripleKey.Create(keyA, keyB, keyC);
return base.ContainsKey(key);
}
public void Add(TKeyA keyA, TKeyB keyB, TKeyC keyC, TValue value)
{
base.Add(TripleKey.Create(keyA, keyB, keyC), value);
}
}