为什么C#不允许使用组合的类型对接口进行隐式转换?

时间:2011-01-31 18:27:55

标签: c# .net class interface

  

可能重复:
  Why can't I use interface with explicit operator?

当我这样做时:

public struct Effect
{
    public IEffect IEffect { get; private set; }

    public Effect ( IEffect effect )
    {
        this.IEffect = effect;
    }

    public static implicit operator IEffect ( Effect effect )
    {
        return effect.IEffect;
    }

    public static explicit operator Effect ( IEffect effect )
    {
        return new Effect ( effect );
    }
}

我得到一个像这样的编译器错误:

  

'ImageEditor.Effect.implicit运算符   ImageEditor.IEffect(ImageEditor.Effect)“:   用户定义的转换或来自   接口是不允许的。

为什么不允许这样做?这不是一个好习惯吗?

3 个答案:

答案 0 :(得分:7)

这在C#语言规范的第10.10.3节中有详细说明。

原因的总结原因是......

  • 转换运算符不应取代内置转换。允许这只会导致极其混乱的行为
  • 一般情况下,无法确定对接口的隐式转换是否正在替换内置转换,因此不允许

答案 1 :(得分:1)

主要原因是实现接口的对象始终可以隐式转换为其基类,并且始终可以从其基类显式转换为自身。覆盖此行为是多余且令人困惑的,并且您无法覆盖所有必要的行为以使其正常工作,因此不允许这样做。在您的情况下,您将覆盖一些但不是所有继承行为。例如,显式转换时的最佳做法是:

IEffect anIEffectInstance = GetEffectAsInterface();

if(anIEffectInstance is Effect) //<--you cannot override this behavior to return true,
   var interfaceAscConcrete = (Effect)anIEffectInstance; //<-- so this overridden code would never execute

答案 2 :(得分:0)

听起来像Jon Skeet之类的问题,但无论如何我都会对它进行拍摄。

您所描述的隐式运算符在很大程度上是不必要的。如果Effect已经实现IEffect,您可以在需要实现Effect的对象的任何地方使用IEffect,而无需使用用户定义的转换。

明确的运算符问题可能更具哲学性。我的理解是,隐式和显式转换的关键是将一种类型的对象转换为另一种类型的对象,由于某种原因,这种对象的关系对于编译器来说并不明显。但是,接口不是对象。一个人不能直接实例化一个接口;相反,接口需要由某个类实现。使用隐式或显式转换时,结果对象不会按类型关联到先前对象。这意味着转换产生的对象需要能够独立存在并具有实际的对象类型,而接口本身并不是这样。

也许更直接:隐式转换结果的具体类型是什么?编译器无法知道,因此无法实例化对象。

如果你真的需要做这样的事情,你会想要创建一个实现接口的抽象基类。然后你应该能够转换&#34;来自抽象基类,它有一个对象类型。