Foreword: I understand that covariance doesn't currently work with value types (c.f. [1], [2]).
I have a generic type that can be simplified as follows:
public interface IDynamicValue<out T>
{
T Get(Context context);
}
public abstract class DynamicValue<T> : IDynamicValue<T>
{
public abstract T Get(Context context);
}
The type T
is being used as both reference and value types in different situations.
Now I've run into something like the following situation:
public class SomeClass
{
public object thing;
public string ObjectToString(Context context)
{
if (thing is IDynamicValue<object>)
{
return (thing as IDynamicValue<object>).Get(context).ToString();
}
return thing.ToString();
}
}
Thanks to covariance, if I pass a DynamicValue<string>
as the object, then it will successfully be converted to an IDynamicValue<object>
and the Get
function will be executed.
However, if I pass a DynamicValue<int>
, it will not be converted (as mentioned, I understand why this happening), and o.ToString()
will be returned.
What workaround exists that will allow me to execute the Get(context)
function on both reference and value typed DynamicValues
in this situation? Kudos for not using reflection, if possible :D
Maybe, you can add an interface without generic and mark some classes with it:
public interface IDynamicValue
{
object Get(Context context);
}
public interface IDynamicValue<out T>
{
T Get(Context context);
}
And check:
public class SomeClass
{
public object thing;
public string ObjectToString(Context context)
{
if (thing is IDynamicValue<object>)
{
return (thing as IDynamicValue<object>).Get(context).ToString();
}
if (thing is IDynamicValue)
{
return (thing as IDynamicValue).Get(context).ToString();
}
return thing.ToString();
}
}