I was trying to create a class were one of the properties was generic without the class itself being generic. I discover that you can't do that; generic properties aren't allowed. A bit of digging here too me to the thread Making a generic property were I found a work around that works nicely for me.
Subsequently, I ended up with this class...
[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);
}
}
Now the only issue I have is that if I want to get the value, properly cast, I have to supply the type when I call GetValue()
. Instinctively, I can't help but feel, given that the class knows the type that should be returned, it should be possible for me to construct a GetValue()
method that doesn't require any additional information from me.
I can't figure out how.
I did find the thread Getting a generic method to infer the type parameter from the runtime type which appears to suggest that it is possible, but I understand very little about Reflection and couldn't make any sense of what was being said.
Is there a way of constructing a GetType()
method that doesn't require that I supply the generic type? And can you explain it in a way that my feeble brain can comprehend it?
EDIT
A number of people have actually pointed out that really I don't need to do this anyway, nonetheless as a learning exercise I followed up the suggestion from @ShoaibShakeel to look at the C# dynamic
type and came up with these additional methods...
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);
}