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 に答える