同时使用值和引用类型的泛型的协方差解决方法



前言:我知道协方差目前不适用于值类型(c.f. [1], [2](。


我有一个泛型类型,可以简化如下:

public interface IDynamicValue<out T>
{
T Get(Context context);
}
public abstract class DynamicValue<T> : IDynamicValue<T>
{
public abstract T Get(Context context);
}

在不同情况下,T类型同时用作引用类型和值类型。

现在我遇到了类似以下情况的情况:

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();
}
}

由于协方差,如果我传递一个DynamicValue<string>作为对象,那么它将成功转换为IDynamicValue<object>,并且Get函数将被执行。

但是,如果我传递一个DynamicValue<int>,它不会被转换(如前所述,我理解为什么会发生这种情况(,o.ToString()将被返回。

在这种情况下,有什么解决方法可以允许我在引用和值类型DynamicValues上执行Get(context)函数?为不使用反射而表扬,如果可能的话:D

也许,您可以添加一个没有泛型的接口并用它标记一些类:

public interface IDynamicValue
{
object Get(Context context);
}
public interface IDynamicValue<out T>
{
T Get(Context context);
}

并检查:

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();
}
}