13

ここの誰かが私がしている間違った仮定を説明できることを願っています。C#4.0には、2つのインターフェイスと、両方を実装するクラスがあります。メソッドでは、最初のインターフェイスのタイプで変数を宣言し、両方のインターフェイスを実装するクラスを使用してインスタンス化し、次のコードのように2番目のインターフェイスに正常にキャストできます。

    public interface IFirstInterface 
    {
        void Method1();
    }

    public interface ISecondInterface
    {
        void Method2();
    }

    public class InterfaceImplementation : IFirstInterface, ISecondInterface
    {
        public void Method1() { }
        public void Method2() { }
    }

    public class SomeClass
    {
        public void SomeMethod()
        {
            IFirstInterface first = new InterfaceImplementation();
            first.Method1();

            // Shouldn't the next line return null?
            ISecondInterface second = first as ISecondInterface; 
            // second is not null and the call to Method2() works fine
            second.Method2();
        }
    }

キャストが成功する理由を理解しようとしています。はい、クラスは両方のインターフェイスを実装しますが、最初の変数はIFirstInterface(ISecondInterfaceから継承しない)として宣言されているため、キャストは失敗するはずです。

'as'を使用しないなど、他の方法でコードを再構築しようとしましたが、キャストは引き続き成功します。

私は何が欠けていますか?

4

6 に答える 6

10

あなたの例から、機能を呼び出す前にタイプタイプをテストすることでうまくいくはずです。最初の作成では、両方のインターフェイスをサポートする完全修飾の「InterfaceImplementation」が作成されます。ただし、最初のインターフェイスのみの宣言されたタイプに入れています。したがって、「最初の」オブジェクトの観点からは、IFirstInterface実装として関連付けられているもののみを考慮します。

さて、次に2番目に...オブジェクトを作成したとしても、質問することができます...ちなみに...あなたも2番目のインターフェイスですか?もしそうなら、これを行います...

IFirstInterface first = new InterfaceImplementation();

if( first is ISecondInterface )
  // typecast since the second interface is legit, then call it's method 2
  ((ISecondInterface)first).Method2();
于 2012-05-02T17:56:05.347 に答える
3

インスタンスの実際のタイプは、first両方のインターフェースを実装することを指します。したがって、明らかに両方Method1Method2がオブジェクトで使用可能です。

の静的タイプでは、にfirstのみアクセスできますMethod1。の静的タイプでは、にsecondのみアクセスできますMethod2。いずれかのインターフェースを使用してオブジェクトへの参照を宣言します。選択したコントラクト(インターフェース)を満たすオブジェクトとしてインスタンスを表示することを選択するだけです。

両方のインターフェースを実装しているためInterfaceImplementation、どちらかのインターフェースを使用してインスタンスを参照するオプションがあります。

于 2012-05-02T17:54:23.577 に答える
1

具体的なオブジェクトの観点から見ると、「私はIFirstInterfaceですが、ISecondInterfaceでもあります」と言うことができます。それはあなたが意味することですか?あなたが説明した質問は、継承/実装チェーンのすぐ内側にキャストすることになります。

于 2012-05-02T17:46:51.380 に答える
1

あなたが見逃している唯一のことは、それがまさにそれが意図されている方法であり、それは問題ではなく、便利な機能であるということです。キャストするとき、コードは基本的に「このオブジェクトのタイプが何であるかは関係ありません。タイプTに変換できるかどうかを確認したい」と考えることができます。この場合、基になるオブジェクトはタイプInterfaceImplementationであるため、現在はとして知られているという事実に関係なくIFirstInterface、答えは「はい」に変換できますISecondInterface

于 2012-05-02T17:49:30.730 に答える
0

ポリモーフィズムへようこそ。オブジェクトfirstは常にInterfaceImplementationのインスタンスになります。どのように参照するかは、オブジェクトが実際に「何であるか」には影響しません。これが、抽象化の概念が全体としてどのように機能するかです。

于 2012-05-02T17:51:30.137 に答える
0

これは本当に設計上の欠陥を示しています。クライアントは、両方のインターフェースが同じオブジェクトによって実装されていることを知っています。たとえば、これは問題ありませんが、これらのインターフェイスが個別に実装されている場合、最初のインターフェイスから2番目のインターフェイスにジャンプすることはできません。理想的には、あるタイプから別のタイプに移動できる、ある種のクエリインターフェイスがある方がよいでしょう。

于 2020-03-11T15:42:52.290 に答える