定义了这个接口:

public interface IInputBoxService<out T> {
    bool ShowDialog();
    T Result { get; }
}

为什么以下代码有效:
public class StringInputBoxService : IInputBoxService<string> {
    ...
}

...

IInputBoxService<object> service = new StringInputBoxService();

这不是吗?:
public class IntegerInputBoxService : IInputBoxService<int> {
    ...
}

...

IInputBoxService<object> service = new IntegerInputBoxService();

它与int是值类型有什么关系吗?如果是的话,我怎样才能规避这种局面呢?
谢谢

最佳答案

是的,这绝对与int是一种值类型有关。C 4中的泛型差异仅适用于引用类型。这主要是因为引用总是具有相同的表示形式:引用只是一个引用,所以CLR可以使用相同的位来表示它对于对象引用的字符串引用。CLR可以确保代码是安全的,并且使用只知道“cc>”的本机代码,当通过“ccc>”时,从IInputBoxService<object>返回的值将具有代表性的兼容性(如果存在这样的术语).
有了IInputBoxService<string>=>Result就必须有拳击等,所以你不会得到相同的代码——这基本上会扰乱方差。
编辑:C 4.0规范在第13.1.3.2节中说明了这一点:
差异注释的目的是
提供更多的宽大(但仍然
类型安全)到接口的转换
和委托类型。为此目的
含蓄的定义(§6.1)和
显式转换(§6.2)使用
关于
方差可兑换
定义如下:类型t是可转换为类型的方差
如果t是
声明的接口或委托类型
使用变量类型参数t,对于每个变量类型
参数XI之一
持有:
XI是协变的
隐式引用或标识
存在从ai到bi的转换

是反变的,隐式的
引用或标识转换
从bi到ai
Xi是不变量
身份转换存在于
人工智能双向接口
这并不十分明显,但基本上引用转换只存在于引用类型之间,这只留下标识转换(即从类型到自身)。
至于解决方法:基本上,我认为您必须创建自己的包装类。这可以简单到:

public class Wrapper<T>
{
    public T Value { get; private set; }
    public Wrapper(T value)
    {
        Value = value;
    }
}

不过,这很讨厌:(

10-01 02:57
查看更多