为什么C#在完全知道它没有结构类型时会取笑?

naw*_*fal 2 c# casting interface structural-typing explicit-conversion

我很惊讶今天看到这是可能的,但我担心这必须在之前讨论过.

public interface ICanAdd
{
    int Add(int x, int y);
}

// Note that MyAdder does NOT implement ICanAdd, 
// but it does define an Add method like the one in ICanAdd:
public class MyAdder
{
    public int Add(int x, int y)
    {
        return x + y;
    }
}

public class Program
{
    void Main()
    {
        var myAdder = new MyAdder();
        var iCanAdd = (ICanAdd)myAdder; //compiles, but for what sake?
        int sum = iCanAdd.Add(2, 2); //na, not game for it, cast had already failed
    }
}
Run Code Online (Sandbox Code Playgroud)

编译器(正确地?)告诉我在上述情况下存在显式转换.我很高兴在那里感觉到结构类型,但没有运行时间失败.那么C#什么时候有用呢?任何场景这样的投射会起作用?不管它是什么,我确信编译器事先知道myAdder不是ICanAdd技术上的.

Jer*_*odd 9

C#允许从类到接口的显式转换(即使类没有实现该接口),因为对于所有编译器都知道,实际上可能引用某种类型(不确定性是为什么它是显式的而不是隐式的转化率)是派生类型的一个实例确实实现的接口.扩展您的示例,假设您有:

public class DerivedAdder : MyAdder, ICanAdd
{
  int ICanAdd.Add(int x, int y)
  {
    return base.Add(x, y);
  }
}

...

MyAdder myAdder = new DerivedAdder();
var iCanAdd = (ICanAdd)myAdder; // Valid in this case
int sum = iCanAdd.Add(2, 2);    // sum = 4
Run Code Online (Sandbox Code Playgroud)

如果你查看C#规范的第6.2.4节,你会发现如果你把你的MyAdder类标记为sealed,编译器实际上会抱怨,因为它会确定不可能转换,因为不存在派生类型.但只要不能消除每一丝疑问,它都会允许明确的转换.