【发布时间】:2015-10-21 18:20:47
【问题描述】:
我试图创建一个类,其中一个属性是通用的,而类本身是通用的。我发现你不能那样做;不允许使用通用属性。我也在这里挖掘了一下线程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,这似乎表明这是可能的,但我对反射知之甚少,无法理解所说的内容。
有没有一种方法可以构造一个不需要我提供泛型类型的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);
}
【问题讨论】:
-
如果不指定类型,CLR 将无法知道要从内存中读取多少数据以及如何解析它。我认为你应该看看
dynamictype 。 msdn.microsoft.com/en-us/library/dd264736.aspx -
为什么不只是
object?在这里注入运行时评估类型没有意义。毕竟,返回类型只能帮助您进行编译时类型检查。在这种情况下,这显然是不可能的。所以object很好。或者,如果调用者知道类型,那么您的泛型方法可能更可取。 -
@NicoSchertler 我明白你的意思,我想我在这方面没有考虑。但是,请参阅我的编辑。
-
为什么不只是
return Value;?无需调用泛型函数。