2

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

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,从技术上讲。

4

2 回答 2

10

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# Specification的第 6.2.4 节,您会发现如果将您的MyAdder类标记为sealed,编译器实际上会抱怨,因为它会确定无法进行转换,因为不存在派生类型。但只要它不能消除最后一丝怀疑,它就会允许显式转换。

于 2013-04-20T11:04:46.320 回答
1

C# 语言规范允许将类转换为接口。但是例如,如果 ICanAdd 是一个类 - 编译将失败

于 2013-04-20T10:51:37.957 回答