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