我不知道这个数据结构的正确名称(它是一个同构的地图吗?),但基本上我正试图得到类似的东西。
SmartDict dict = new SmartDict();
Key<string> NameKey = new Key<string>("nameID"); // Should this be a generated GUID for serialization that must be registered?
Key<int> HealthKey = new Key<int>("healthID"); //Should this be a generated GUID for serialization that must be registered?
dict[NameKey] = "Ryan";
dict[HealthKey] = 20;
String name = dict[NameKey]; //name is now Ryan
int health = dict[HealthKey];
假设这是在某个数据类实例的Base类上定义的,该类实例不容易为每次使用自定义。 通过将SmartDict附加到基类,然后您可以向类中添加其他数据(以及将来将其序列化为blob)并让数据驱动需要附加哪些类型和附加数据(只要它们也是序列化的。)
class BaseEntity {
public SmartDict dict = new SmartDict();
Key<string> NameKey = new Key<string>("name");
public void Initialize(){
dict[NameKey] = "Ryan";
}
}
class HealthSystem {
Key<int> Health = new Key<Health>();
public void InitHealth(BaseEntity entity){
entity.dict[Health] = 20;
}
public void DamageEntity(BaseEntity entity, int damage){
entity.dict[Health] = entity.dict[Health] - damage];
}
}
因此,从SmartDict获取值是围绕您是否有权访问密钥对象。对于用户授权很有用,或者确保人们不会从他们应该使用外观的上下文中弄乱数据。
你可以使用一个对象字典,只是依赖于记住你输入的类型,但我试图制作一些错误可能性较小的东西,并且最好用WCF序列化(但我假设这是一个不同的问题,这将需要提前注册兼容类型等,并使用GUID以便在反序列化后匹配键。)
我已经了解了ConditionalWeakTable,但是考虑到我希望能够序列化它,它也有可能并不总是需要的弱引用。
我的第一次尝试没有真正了解我的仿制药出了什么问题。
class HMap<K> where K : Key<?>
{
ConditionalWeakTable<K, object> data = new ConditionalWeakTable<K, object>();
public T this[Key<T> index]
{
get
{
T ret;
var success = data.TryGetValue(index, out ret);
if (!success) throw new KeyNotFoundException("Key not found: " + index);
return ret;
}
set
{
data.Add(index, value);
}
}
}
答案 0 :(得分:2)
使用索引器无法实现您想要的功能(因为您可以在.NET中使用通用索引器),但如果您愿意使用通用方法与您的交互SmartDict
相反,您可以轻松地实现类似外观的API:
SmartDict dict = new SmartDict();
Key<string> nameKey = new Key<string>("name");
Key<int> idKey = new Key<int>("id");
dict.Set(nameKey, "Ryan");
dict.Set(idKey, 123);
string name = dict.Get(nameKey); // name is now "Ryan".
int id = dict.Get(idKey); // id is now 123.
SmartDict
实施:
internal interface IKey
{
string Name { get; }
}
public sealed class Key<T> : IKey
{
public string Name { get; }
public Key(string name)
{
Name = name;
}
}
public sealed class SmartDict
{
private readonly Dictionary<IKey, object> Values = new Dictionary<IKey, object>();
public T Get<T>(Key<T> key)
{
if (Values.TryGetValue(key, out object value)) {
return (T)value;
}
throw new KeyNotFoundException($"'{key.Name}' not found.");
}
public void Set<T>(Key<T> key, T value)
{
Values[key] = value;
}
}
这不是一个非常有效的数据结构,因为所有值最终都存储为object
,这可能导致装箱 - 如果性能成为问题,您可以稍后处理。
答案 1 :(得分:0)
也许您不应该依赖于对象的类型,而是使用(大)枚举来定义您的类型。然后您可以使用Dictionary来存储它。
public enum types{
Name,
Health
}
然后你可以使用:
Dictionary<types, string>
管理您的数据