代码之家  ›  专栏  ›  技术社区  ›  stakx - no longer contributing Saravana Kumar

为什么c中的这种隐式类型转换会失败?

  •  4
  • stakx - no longer contributing Saravana Kumar  · 技术社区  · 15 年前

    背景:

    假设我有以下课程:

    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”转换为“wrapped<ix>”。存在显式onversion(是否缺少cast?)

    我不明白。这里有什么问题?

    1 回复  |  直到 15 年前
        1
  •  5
  •   Jon Skeet    15 年前

    我相信是因为 IX 是一个接口。编译器认为 可能已经从 Wrapped<IX> (即使 Wrapped<T> 是密封的),所以它不使用转换。

    在C 3.0规范的6.4.3和6.4.4节中,细节相当复杂,主要是因为 是一个接口,它没有被任何类型“包围”,这意味着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,简单的方法通常更容易理解。