Да, это абсолютно связано с int
, являющимся типом значения. Общая дисперсия в C # 4 работает только со ссылочными типами. Это в первую очередь потому, что ссылки всегда имеют одно и то же представление: ссылка - это просто ссылка, поэтому CLR может использовать те же биты для того, что, как он знает, является строковой ссылкой, что и для ссылки на объект. CLR может убедиться, что код будет безопасным, и использовать собственный код, который знает только о IInputBoxService<object>
при передаче IInputBoxService<string>
- значение, возвращаемое из Result
, будет представительно совместимо (если такой термин существует!).
С int
=> object
должен быть бокс и т. Д., Поэтому вы не получите один и тот же код - который в основном нарушает дисперсию.
EDIT: спецификация C # 4.0 говорит об этом в разделе 13.1.3.2:
Цель аннотации отклонений
обеспечить более снисходительный (но все же
безопасный тип) преобразования в интерфейс
и типы делегатов. Для этого
определения неявного (§6.1) и
явные преобразования (§6.2) используют
понятия
конвертируемость дисперсии, которая
определяется следующим образом: тип T может быть преобразован в тип дисперсии
Т, если Т является либо
интерфейс или тип делегата объявлен
с параметрами типа варианта T и для каждого типа варианта
параметр Xi один из следующих
имеет место:
Си является ковариантным и
неявная ссылка или личность
существует преобразование из Ai в Bi
Xi
является контравариантным и неявным
ссылка или преобразование личности
существует от Bi до Ai
Си инвариантен
и преобразование идентичности существует из
От Аи до Би
Это не делает это ужасно очевидным, но в основном ссылочные преобразования существуют только между ссылочными типами, что оставляет только преобразования идентичности (то есть от типа к себе).
Что касается обходных путей: я думаю, что вам, по сути, нужно создать свой собственный класс-обертку. Это может быть так просто, как:
public class Wrapper<T>
{
public T Value { get; private set; }
public Wrapper(T value)
{
Value = value;
}
}
Это довольно противно, хотя: (