我试图创建一个类,其中一个属性是通用的,没有类本身是通用的。我发现你不能这样做;不允许使用通用属性。我对线程Making a generic property进行了一些挖掘,我找到了一个可以很好地为我工作的工作。
随后,我结束了这堂课......
[Serializable]
public class ConfigurationItem
{
private readonly Type type;
public string Description { get; set; }
public IDictionary<string, ConfigurationItem> Items { get; private set; }
public string Name { get; set; }
public string Summary { get; set; }
public object Value { get; private set; }
public ConfigurationItem(string name, Type type = null, object value = null)
{
this.Name = name;
this.type = type ?? typeof(string);
this.Value = value;
Items = new Dictionary<string, ConfigurationItem>();
}
public string Export()
{
return JsonConvert.SerializeObject(this);
}
public T GetValue<T>()
{
return (T)Convert.ChangeType(Value, type);
}
}
现在唯一的问题是,如果我想获得值,正确投射,我必须在调用GetValue()
时提供类型。本能地,我不禁感到,鉴于该类知道应该返回的类型,我应该可以构建一个GetValue()
方法,不需要我提供任何其他信息。
我无法弄清楚如何。
我确实发现线程Getting a generic method to infer the type parameter from the runtime type似乎表明它是可能的,但我对Reflection很少了解,也无法理解所说的内容。
有没有办法构建一个GetType()
方法,不需要我提供泛型类型?你能用一种我虚弱的大脑能理解它的方式解释它吗?
修改
很多人实际上已经指出,无论如何我真的不需要这样做,但作为一个学习练习我跟随@ShoaibShakeel的建议来查看C#dynamic
类型并想出了这些额外的方法...
public dynamic GetValue()
{
return typeof(ConfigurationItem)
.GetMethod("GetReturnValue", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)
.MakeGenericMethod(type)
.Invoke(this, new object[] { });
}
private T GetReturnValue<T>()
{
return (T)Convert.ChangeType(Value, type);
}
答案 0 :(得分:1)
本能地,我不禁感到,因为该类知道应该返回的类型
虽然Value
对象确实知道它自己的类型,但是这个信息仅在运行时可用(一旦有一个具有类型的实际对象)。因此,为了在编译时获得类型信息,您需要提供必要的信息。毕竟,不可能静态地知道在那里分配了什么对象。
但假设GetValue()
能够自动返回类型对象,您想要用它做什么?
var x = configurationItem.GetValue();
那么x
应该是什么类型,以及之后你想用它做什么?你只想打印它还是什么?那么object
就足够了。你想用它计算一些东西吗?那么你已经要求它是int
或float
或者其他东西,所以你需要一个实际的静态类型 - 这就是你必须提供那种类型信息的原因。
仅仅因为返回类型为object
并不意味着对象本身会丢失类型信息。分配给object
属性的字符串仍然是一个字符串,即使您稍后检索它也是如此。如果你期望一个字符串并希望用它做一些事情,那么你肯定可以将它转换为字符串。
答案 1 :(得分:0)
没有
编译器无法从它所分配的变量中推断出类型,因为它是不明确的,特别是在大型继承树中。
考虑一下
行object o = configurationItem.GetValue<int>();
int
可能是您的有效转化,但object
不是,因为object
未实现IConvertible
接口({{1}需要}}
答案 2 :(得分:0)
我能够让我的类返回一个值,使用反射和动态来正确地投射,使用以下对我原始类的添加。
public dynamic GetValue()
{
return typeof(ConfigurationItem)
.GetMethod("GetReturnValue", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)
.MakeGenericMethod(type)
.Invoke(this, new object[] { });
}
private T GetReturnValue<T>()
{
return (T)Convert.ChangeType(Value, type);
}