c#明明知道没有结构类型,为什么还要戏弄它呢?

本文关键字:戏弄 为什么 明知道 明明 类型 结构 | 更新日期: 2023-09-27 18:10:11

今天看到这是可能的,我很惊讶,但我担心这必须事先讨论。

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
    }
}

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

c#明明知道没有结构类型,为什么还要戏弄它呢?

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

如果你检查c#规范的6.2.4节,你会看到,如果你把MyAdder类标记为sealed,编译器实际上会报错,因为它会确定没有转换是可能的,因为没有派生类型可以存在。但只要它不能消除所有的疑问,它就会允许显式转换。

c#语言规范允许将类强制转换为接口。但是,如果ICanAdd是一个类,编译就会失败