为什么在C#这种隐式类型转换失败?
-
22-09-2019 - |
题
背景:
让我们假设我有以下类:
class Wrapped<T> : IDisposable
{
public Wrapped(T obj) { /* ... */ }
public static implicit operator Wrapped<T>(T obj)
{
return new Wrapped<T>(obj);
}
public void Dispose() { /* ... */ }
}
可以看到,它提供了一个隐式类型转换操作者T
→Wrapped<T>
。最终,我想能够使用这个类,如下所示:
interface IX { /* ... */ }
class X : IX { /* ... */ }
...
IX plainIX = new X();
using (Wrapped<IX> wrappedIX = plainIX)
{
/* ... */
}
问题:
但是,在上述using
子句中的类型转换失败。虽然我可以直接分配给new X()
wrappedIX
,我不允许类型IX
的任何分配给它。编译器将用下面的错误抱怨:
编译器错误CS0266:无法隐式转换类型 'IX' 到 '缠
'。一个明确的onversion存在(是否缺少强制转换?) 的
我不明白这一点。有什么问题吗?
解决方案
我相信这是因为IX
是一个接口。编译器认为也许类型IX
的值可能已经被从Wrapped<IX>
(即使Wrapped<T>
是密封的)衍生的,以便它不使用转换。
的细节是相当复杂的,在部分6.4.3和6.4.4的C#3.0规范的。基本上是因为IX
是一个接口,它不是任何类型的“涵盖的”,这意味着在6.4.4后面的步骤中失败。
建议你创建使用此方法的非通用型Wrapped
:
public static Wrapped<T> Of<T>(T item)
{
return new Wrapped<T>(item);
}
然后,你可以这样写:
using (Wrapped<IX> wrappedIX = Wrapped.Of(plainIX))
基本上转换可以是一个有点棘手出于各种原因 - 简单方法通常更容易理解,IMO
不隶属于 StackOverflow