问有关C#4.0的泛型协方差 [英] Question about C# 4.0's generics covariance

查看:169
本文介绍了问有关C#4.0的泛型协方差的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在定义了这个接口:

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

为什么以下code的工作:

Why does the following code work:

public class StringInputBoxService : IInputBoxService<string> {
    ...
}

...

IInputBoxService<object> service = new StringInputBoxService();

和这不?

public class IntegerInputBoxService : IInputBoxService<int> {
    ...
}

...

IInputBoxService<object> service = new IntegerInputBoxService();

是否有什么关系INT是值类型?如果是的话,我怎么能绕过这个情况?

Does it have anything to do with int being a value type? If yes, how can I circumvent this situation?

感谢

推荐答案

是的,这是绝对必须与 INT 是值类型。在C#4通用方差仅适用于引用类型。这主要是因为引用总是具有相同的重presentation:基准只是一个参考,所以在CLR可以使用相同的比特的东西它知道是一个字符串引用作为一个对象引用。在CLR可以确保在code将是安全的,并使用原生code,只知道 IInputBoxService&LT;对象&gt; 时,通过了 IInputBoxService&LT;字符串&GT; - 从结果返回的值将被重新presentationally兼容(!如果这样的长期存在)

Yes, it absolutely has to do with int being a value type. Generic variance in C# 4 only works with reference types. This is primarily because references always have the same representation: a reference is just a reference, so the CLR can use the same bits for something it knows is a string reference as for an object reference. The CLR can make sure that the code will be safe, and use native code which only knows about IInputBoxService<object> when passed an IInputBoxService<string> - the value returned from Result will be representationally compatible (if such a term exists!).

使用 INT => 对象有将不得不拳击等,这样你就不会结束与同code - 基本上弄乱方差

With int => object there would have to be boxing etc, so you don't end up with the same code - that basically messes up variance.

编辑:C#4.0规范说,这在第13.1.3.2:

The C# 4.0 spec says this in section 13.1.3.2:

方差注解的目的是   提供更为宽松的(但仍   类型安全)的转换接口   和委托类型。为此目的   隐式(第6.1节)的定义和   显式转换(第6.2节)利用   的概念的   方差可兑换,这是   定义如下:A型T是方差转换为一个类型   ■如果T是要么是   接口或声明的委托类型   与变量类型参数T,并为每个变量类型   以下参数熙1   认为:

The purpose of variance annotations is to provide for more lenient (but still type safe) conversions to interface and delegate types. To this end the definitions of implicit (§6.1) and explicit conversions (§6.2) make use of the notion of variance-convertibility, which is defined as follows: A type T is variance-convertible to a type T if T is either an interface or a delegate type declared with the variant type parameters T, and for each variant type parameter Xi one of the following holds:

      
  • 曦是协变和   隐式引用或身份   转换存在从艾毕

  • Xi is covariant and an implicit reference or identity conversion exists from Ai to Bi

曦   是逆变和隐   引用或标识转换   存在从碧艾

Xi is contravariant and an implicit reference or identity conversion exists from Bi to Ai

曦是不变   并且存在从身份转换   艾毕

Xi is invariant and an identity conversion exists from Ai to Bi

这并不能使它非常明显的,但基本上引用转换只引用类型之间存在着,这让唯一的身份转换(即从一个类型本身)。

This doesn't make it terribly obvious, but basically reference conversions only exist between reference types, which leaves only identity conversions (i.e. from a type to itself).

至于解决办法:我想你必须创建自己的包装类,基本上是这样。这可以是简单的:

As for workarounds: I think you'd have to create your own wrapper class, basically. This can be as simple as:

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

这是pretty的讨厌,但:(

It's pretty nasty though :(

这篇关于问有关C#4.0的泛型协方差的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆