【发布时间】:2021-08-27 07:15:04
【问题描述】:
我想通过特定的 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。以上只是进行中的工作。
【问题讨论】:
-
d.Get(new Random().NextDouble() > 0.5 ? "FOO" : "BAR")会返回什么类型? -
在这种情况下应该等于
typeof(_keyTypes[key]) -
但是编译器必须在编译时知道该表达式的类型(如果您想要编译时类型检查)。
typeof(_keyTypes[key])不是编译器可以知道的。检查必须在运行时完成,但不一定是dynamic。您是否考虑过与Set做类似的事情? -
使用 C++ 元编程,您可以从
enum派生出type,这在 C# 中不可能吗? -
没有。 C# 不是 C++。
标签: c# generics .net-core containers