Reputation: 432
I have a base abstract class which is meant to allow implementors to return different types:
protected abstract T GetMyValue<T>();
I would like the implementing class to be able to do something like this:
T myResult;
public override T GetMyValue<T>()
{
return _myResult;
}
I would like the caller to specify the type:
int i = obj.GetMyValue<int>();
Is this possible?
Upvotes: 5
Views: 9241
Reputation: 40838
One option would just be to store the field as an object. This will cause boxing for structs, but there isn't better way without a more significant change.
class Derived : Base
{
private object o;
protected override T GetMyValue<T>()
{
if (o is T)
return (T)o;
return default(T);
}
}
You can't really have a generic field unless the abstract class is itself generic, not the specific method. Of course this is a significant design change. One implementation can now only return one type. Something like
abstract class BaseClass<T>
{
protected abstract T GetMyValue();
}
class Derived : Base<int>
{
private int i;
protected override int GetMyValue()
{
return i;
}
}
Upvotes: 3
Reputation: 171246
You somehow have to make the field have the same type that you want to return. Here's a trick for that:
public override T GetMyValue<T>()
{
return ValueHolder<T>.GetMyValue();
}
class ValueHolder<T> {
static T myResult;
public static T GetMyValue()
{
return myResult;
}
}
Because this is a static class there can only be one such value.
If you want to have one value per type in your instance you need a Dictionary<Type, object>
.
Upvotes: 0
Reputation: 63562
Like an object extension?
public static class ObjectExtension
{
public static T GetValue<T>(this object obj)
{
var converter = TypeDescriptor.GetConverter(typeof(T));
if (converter == null)
return default(T);
return (T)converter.ConvertFrom(obj);
}
}
Upvotes: 3