在泛型类型中但是相同类型的转换问题

时间:2009-06-07 00:20:41

标签: c# generics

界面:
接口IPlay < T > {}

类:
class Mp3Player:IPlay < int > {}
class OggPlayer:IPlay < double > {}
DummyPlayer类:IPlay <对象> {}

尝试使用:
1. IPlay <对象>播放器=新Mp3Player();
2. IPlay < int > player2 = new OggPlayer();

为什么1和2的用法无法投射?
int to object,或int to double。在非一般情况下这是可能的。还有其他方法吗?

5 个答案:

答案 0 :(得分:4)

您正在尝试执行无效的强制转换。 Mp3Player不是IPlay&lt; object&gt;,它是IPlay&lt; int&gt;。您的OggPlayer是IPlay&lt; double&gt;,而不是IPlay&lt; int&gt;。你不能施放IPlay&lt; int&gt;到IPlay&lt;对象&gt;或者IPlay&lt; double&gt;到IPlay&lt; int&gt;像那样。它们不是相互继承的,因为它们是通用的,它们是彼此强烈区分的不同类型。

在C#4.0中,这种隐式演员可能,并且我可能会强调,因为它将具有改进的共同/反差。但一般来说,跨越不同类型边界的这种隐式转换是不可能的。

答案 1 :(得分:3)

想象:

interface IPlay<T>
{
    T GetSomething();
    DoSomething(T value);
}

所以,使用时:

IPlay<object> player = new Mp3Player();

然后GetSomething()可能是类型安全的,但DoSomething(object value)怎么样? ...该调用无法保证逻辑将对某个对象起作用,因为该播放器需要整数。

请注意,.NET 4有一种机制来指示接口的方差,因此您可以将接口标记为仅使用T作为返回值,在这种情况下,至少您的第一个分配将起作用。< / p>

但请注意,无论如何,第二个(IPlay<int> player2)都不起作用,因为doubleint之间没有继承关系。能够隐式地转换值与继承不同。

答案 2 :(得分:2)

您要做的事情称为covariance,接口类型的C#4将支持此功能。

答案 3 :(得分:1)

来自PDC的Anders Hejlsberg的

Here is a good talk,他描述了协同/反演在C#4.0中的作用(以及其他内容)。

答案 4 :(得分:0)

有一种常见的误解,即IPlay<T>会产生一个共同的祖先,即IPlay<object>。这可能很有价值,但事实并非如此。

您必须自己生成并命名共同的祖先:

interface IPlay {}
interface IPlay<T> : IPlay {}