为什么C#中的隐式类型转换失败?
背景:
我们假设我有以下课程:
class Wrapped : IDisposable { public Wrapped(T obj) { /* ... */ } public static implicit operator Wrapped(T obj) { return new Wrapped(obj); } public void Dispose() { /* ... */ } }
如您所见,它为T
→ Wrapped
提供了隐式类型转换运算符。 最后,我希望能够使用这个类如下:
interface IX { /* ... */ } class X : IX { /* ... */ } ... IX plainIX = new X(); using (Wrapped wrappedIX = plainIX) { /* ... */ }
问题:
但是,上面using
子句中的类型转换失败。 虽然我可以直接为wrappedIX
分配一个new X()
,但我不允许为它分配任何类型IX
的东西。 编译器会抱怨以下错误:
编译器错误CS0266:无法将类型“IX”隐式转换为“Wrapped ”。 存在明确的反转(你是否错过了演员?)
我不明白这一点。 这有什么问题?
我相信这是因为IX
是一个界面。 编译器认为类型IX
的值可能已经从Wrapped
派生(即使Wrapped
被密封),因此它不使用转换。
细节非常复杂,在C#3.0规范的6.4.3和6.4.4节中。 基本上因为IX
是一个接口,它不是“包含”任何类型,这意味着6.4.4中的后续步骤失败。
我建议您使用此方法创建一个非generics类型:
public static Wrapped Of (T item) { return new Wrapped (item); }
然后你可以写:
using (Wrapped wrappedIX = Wrapped.Of(plainIX))
基本上由于各种原因,转换可能有点棘手 – 简单的方法通常更容易理解,IMO。