c#:在异构字典上公开类型安全的API



我想公开一个特定JSON格式的类型安全API。下面是我目前的基本内容:

public class JsonDictionary
{
Dictionary<string, Type> _keyTypes = new Dictionary<string, Type>  {
{ "FOO", typeof(int) },
{ "BAR", typeof(string) },
};
IDictionary<string, object> _data;
public JsonDictionary()
{
_data = new Dictionary<string, object>();
}
public void Set<T>(string key, T obj)
{
if (typeof(T) != _keyTypes[key])
throw new Exception($"Invalid type: {typeof(T)} vs {_keyTypes[key]}");
_data[key] = obj;
}
public dynamic Get(string key)
{
var value = _data[key];
if (value.GetType() != _keyTypes[key])
throw new Exception($"Invalid type: {value.GetType()} vs {_keyTypes[key]}");
return value;
}
}

可以很好地用作:

JsonDictionary d = new JsonDictionary();
d.Set("FOO", 42);
d.Set("BAR", "value");

然而,读取值有点令人失望,并且依赖于后期绑定:

var i = d.Get("FOO");
var s = d.Get("BAR");
Assert.Equal(42, i);
Assert.Equal("value", s);

是否有一些c#魔法,我可以用它来实现一个类型安全的泛型Get<T>,而不是依赖dynamic在这里(理想的类型应该在编译时检查)?我还想对Set<T>使用这种模式,以便d.Set("BAR", 56);触发编译警告。


Dictionary<string, Type> _keyTypes如有需要可制成static。以上只是正在进行的工作。

我正在使用类似的解决方案:

public class JsonDictionary
{
public static readonly Key<int> Foo = new Key<int> { Name = "FOO" };
public static readonly Key<string> Bar = new Key<string> { Name = "BAR" };

IDictionary<string, object> _data;
public JsonDictionary()
{
_data = new Dictionary<string, object>();
}

public void Set<T>(Key<T> key, T obj)
{
_data[key.Name] = obj;
}
public T Get<T>(Key<T> key)
{
return (T)_data[key.Name];
}

public sealed class Key<T>
{
public string Name { get; init; }
}
}

我会将T转换为对象并使用。gettype()检查对象类型

public class JsonDictionary
{
Dictionary<string, Type> _keyTypes = new Dictionary<string, Type>  {
{ "FOO", typeof(int) },
{ "BAR", typeof(string) },
};
IDictionary<string, object> _data;
public JsonDictionary()
{
_data = new Dictionary<string, object>();
}
public void Set(string key, object obj)
{
if (obj.GetType() != _keyTypes[key])
throw new Exception($"Invalid type: {obj.GetType()} vs {_keyTypes[key]}");
_data[key] = obj;
}
public object Get(string key)
{
return _data[key];
}
}

我试着这样做,它工作:

JsonDictionary d = new JsonDictionary();
d.Set("FOO", 42);
d.Set("BAR", "value");
var i = d.Get("FOO");
var s = d.Get("BAR");
Console.WriteLine(i);
Console.WriteLine(s);

但说实话,我不喜欢你想达到的目的。

最新更新