Skip to content

Instantly share code, notes, and snippets.

@aholmes
Last active February 2, 2023 00:18
Show Gist options
  • Save aholmes/36b784ae56161ef2152537e83b920ee5 to your computer and use it in GitHub Desktop.
Save aholmes/36b784ae56161ef2152537e83b920ee5 to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Linq;
public class MyDictionary<T, V>: Dictionary<(string, T), V>
{
private IEnumerable<(string Name, T Value)> GetMembers(object obj)
{
var properties = obj.GetType().GetProperties(BindingFlags.Public).Select(o => (o.Name, Value: (T)o.GetValue(obj)));
var fields = obj.GetType().GetFields(BindingFlags.Public).Select(o => (o.Name, Value: (T)o.GetValue(obj)));
var rtFields = obj.GetType().GetRuntimeFields().Select(o => (o.Name, Value: (T)o.GetValue(obj)));
return properties.Concat(fields).Concat(rtFields);
}
public void Add(T key, V value)
{
foreach(var x in GetMembers(key))
{
base.Add((x.Name, x.Value), value);
}
}
public V this[T key]
{
get
{
V value = default;
foreach(var x in GetMembers(key))
{
value = base[(x.Name, x.Value)];
}
return value;
}
}
public List<V> this[string key]
{
get
{
var keys = base.Keys.Where(o => o.Item1 == key || o.Item1.StartsWith($"<{key}>"));
if (keys.Equals(default)) throw new KeyNotFoundException();
var values = new List<V>();
foreach(var _key in keys)
{
values.Add(base[_key]);
}
return values;
}
}
public List<V> this[string key]
{
get
{
var keys = base.Keys.Where(o => o.Item1 == key || o.Item1.StartsWith($"<{key}>"));
if (keys.Equals(default)) throw new KeyNotFoundException();
var values = new List<V>();
foreach(var _key in keys)
{
values.Add(base[_key]);
}
return values;
}
}
public bool ContainsKey(object obj)
{
foreach(var x in GetMembers(obj))
{
if (!base.ContainsKey((x.Name, (T)x.Value))) return false;
}
return true;
}
public bool ContainsKey(string key)
{
var keys = base.Keys.Where(o => o.Item1 == key || o.Item1.StartsWith($"<{key}>"));
if (!keys.Any()) return false;
return true;
}
}
public class MyFoo
{
public int a;
public string b;
public double c;
}
public static class ConsoleExt
{
public static void Dump(this object obj)
{
Console.WriteLine(obj);
}
}
class Program
{
public static void Main (string[] args)
{
var fooStr = "foo";
var dict = new MyDictionary<object, object>
{
{ new { a = "A", b = "B", c = "C" }, fooStr },
{ new { c = "D" }, fooStr },
{ new MyFoo { a = 1, b = "two", c = 3.3 }, fooStr }
};
dict.ContainsKey(new { a="A" }).Dump(); // true
dict.ContainsKey(new { a="A", b="B" }).Dump(); // true
dict.ContainsKey(new { a="A", b="B", c="C" }).Dump(); // true
dict.ContainsKey(new { c="D" }).Dump(); // true
dict.ContainsKey(new { a="A", b="B", c="D" }).Dump(); // true
dict.ContainsKey(new { a = "A", b = "B", c = "Z" }).Dump(); // false
dict.ContainsKey(new { a = "A", b = "B", c = "C", d = "D" }).Dump(); // false
dict.ContainsKey(new MyFoo { a = 1, b = "two", c = 3.3 }).Dump(); // true
dict.ContainsKey(new MyFoo { a = 1, b = "two", c = 9.9 }).Dump(); // false
dict[new { a = "A" }].Dump();
dict[new { a = "A", b = "B" }].Dump();
dict[new { a = "A", b = "B", c = "C" }].Dump();
dict[new { c = "D" }].Dump();
dict[new MyFoo { a = 1, b = "two", c = 3.3 }].Dump();
dict["c"].ForEach(o => o.Dump());
dict.ContainsKey("c").Dump(); // true
dict.ContainsKey("z").Dump(); // false
//dict[new { c = 3.3 }].Dump(); // KeyNotFoundException
//dict[new {a="A", b="B", c="C", d="D"}].Dump(); // KeyNotFoundException
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment