dev*_*ium 13 .net c# generics covariance
定义了这个接口:
public interface IInputBoxService<out T> {
bool ShowDialog();
T Result { get; }
}
Run Code Online (Sandbox Code Playgroud)
为什么以下代码有效:
public class StringInputBoxService : IInputBoxService<string> {
...
}
...
IInputBoxService<object> service = new StringInputBoxService();
Run Code Online (Sandbox Code Playgroud)
这不是吗?:
public class IntegerInputBoxService : IInputBoxService<int> {
...
}
...
IInputBoxService<object> service = new IntegerInputBoxService();
Run Code Online (Sandbox Code Playgroud)
与int是值类型有什么关系吗?如果是,我该如何规避这种情况?
谢谢
Jon*_*eet 14
是的,它绝对与int成为一种价值类型有关.C#4中的通用方差仅适用于引用类型.这主要是因为引用总是具有相同的表示:引用只是一个引用,因此CLR可以使用相同的位来表示它对象引用所知的字符串引用.CLR可以确保代码是安全的,并使用仅知道IInputBoxService<object>何时传递的本机代码IInputBoxService<string>- 返回的值Result将具有代表性兼容性(如果存在这样的术语!).
使用int=> object必须有拳击等,所以你不会得到相同的代码 - 这基本上会混淆方差.
编辑:C#4.0规范在第13.1.3.2节中说明了这一点:
方差注释的目的是为接口和委托类型提供更宽松(但仍然类型安全)的转换.为此,隐式(§6.1)和显式转换(§6.2)的定义使用了方差 - 可转换性的概念,其定义如下:如果T是一个类型,则类型T是方差可转换为类型T接口或使用变量类型参数T声明的委托类型,并且对于每个变体类型参数Xi,以下之一成立:
Xi是协变的,并且从Ai到Bi存在隐式参考或身份转换
Xi是逆变的,并且从Bi到Ai存在隐式参考或身份转换
Xi是不变的,并且从Ai到Bi存在身份转换
这并不是非常明显,但基本上引用转换只存在于引用类型之间,它只留下身份转换(即从类型到自身).
至于变通方法:我认为你必须创建自己的包装类,基本上.这可以很简单:
public class Wrapper<T>
{
public T Value { get; private set; }
public Wrapper(T value)
{
Value = value;
}
}
Run Code Online (Sandbox Code Playgroud)
虽然很讨厌:(
| 归档时间: |
|
| 查看次数: |
745 次 |
| 最近记录: |