编辑(更新帖子):
有没有办法通过使用类型对名称进行散列来获取类型?
这是你想要的吗? dotnetfiddle link
public interface IProperty
{
object Value { get; }
Type TypeOfValue { get; }
}
public class Property : IProperty
{
public object Value { get; set; }
public Type TypeOfValue { get; set; }
public override string ToString() { return TypeOfValue.FullName + ": " + Value; }
}
public class Observable
{
public readonly Dictionary<string, Property>
Properties = new Dictionary<string, Property>();
// use interface so consumer of your property can't mess with the
// type or value stored in your dictionary within Observable
public IProperty Get(string name)
{
Property obj;
if (Properties.TryGetValue(name, out obj)){
return obj;
}
// throw something which makes more sense to you
throw new ArgumentException(name + " does not exist in the dictionary");
}
// sample of how you'd store these properties
public void Set(string name, object val)
{
if (Properties.ContainsKey(name)){
Properties[name].Value = val;
Properties[name].TypeOfValue = val.GetType();
} else {
Properties[name] = new Property {
Value = val,
TypeOfValue = val.GetType()
};
}
}
}
原始答案:
您可能不小心将string 插入到Observable 内部的字典中,而不是Property<string>,如果是这样,问题不在您发布的代码中,而是在您发布的任何地方'正在插入 string 而不是 Property<string>。
如果您不喜欢无效的强制转换异常,有两种解决方案。
解决方案 1:自定义函数抛出的错误。
如果您想保留Get<T>(...) 的签名,我建议您进行一些错误处理。您看到的错误是因为您的字典中的属性是string 类型,而不是Property<string> 类型。以下代码将为您提供一些可用于更多错误处理的东西。
public class Observable
{
public readonly Dictionary<string, object>
Properties = new Dictionary<string, object>();
public Property<T> Get<T>(string name)
{
object obj;
if (Properties.TryGetValue(name, out obj)){
try {
return (Property<T>) obj;
} catch(InvalidCastException){
// throw something which makes more sense to you
throw new ArgumentException("Could not cast the given object to the desired type");
}
}
// throw something which makes more sense to you
throw new ArgumentException(name + " does not exist in the dictionary");
}
}
解决方案2:返回一般object
public class Observable
{
public readonly Dictionary<string, object>
Properties = new Dictionary<string, object>();
public object Get(string name)
{
object obj;
if (Properties.TryGetValue(name, out obj)){
return obj;
}
// or do whatever you want when the given key doesn't exist.
return null;
}
}