cppNoob
cppNoob

Reputation: 432

Generic method that can return different types

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

Answers (3)

Mike Zboray
Mike Zboray

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

usr
usr

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

hunter
hunter

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

Related Questions