Обходной путь Covariance для универсальных типов значений и ссылочных типов - PullRequest
0 голосов
/ 29 июня 2018

Предисловие: я понимаю, что ковариация в настоящее время не работает с типами значений (например, [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() будет возвращено.

Какой обходной путь существует, который позволит мне в этом случае выполнить функцию Get(context) как для ссылки, так и для значения, введенного DynamicValues? Престижность за неиспользование отражения, если это возможно: D

1 Ответ

0 голосов
/ 29 июня 2018

Может быть, вы можете добавить интерфейс без универсального и пометить некоторые классы этим:

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