3

だから私はインターフェースを持っています:

interface IFoo
{
    int Bar();
    int this[int i] {get; set;}
}

そしてそれから派生するクラス

class Foo : IFoo
{
    public int IFoo.Bar()
    {
        //Implementation
    {
    public int IFoo.this[int i]
    {
        //Implementation
    }
}

今、私はこれをやろうとしています:

var fooey = new Foo();
int i = Fooey.Bar();

またはこれ:

int i = Fooey[4];

私はこれらが適切に機能することを期待します。ただし、コンパイラは、そのようなメンバーが存在しないかのようにエラーを生成します。何故ですか?キャストできることは承知していますがFoo as IFoo、キャストはパフォーマンスにコストがかかることも承知しています。これが、そもそもインターフェイスを使用する理由であることがよくあります。

編集1:これらは生成されたエラーです

「Foo」には「Bar」の定義が含まれておらず、「Foo」タイプの最初の引数を受け入れる拡張メソッド「Bar」が見つかりませんでした(usingディレクティブまたはアセンブリ参照がありませんか?)

「タイプ「Foo」の式にインデックスを適用できません」

4

2 に答える 2

11

明示的に実装 IFooしました。つまり、そのメンバーには、明示的に次のように入力された参照を介してのみアクセスできますIFoo

// This will work
Foo fooey = new Foo();
int i = ((IFoo)fooey).Bar();

キャストせずにメンバーを表示したい場合は、実装で、インターフェイスの名前を前に付けずに、メンバー名を単独で使用します。

class Foo : IFoo
{
    public int Bar() { /* implementation */ }
    public int this[int i] { /* implementation */ }
}

// now this will also work:
Foo fooey = new Foo();
int i = fooey.Bar();
于 2012-09-21T03:32:43.563 に答える
0

あなたがクラスをインスタンス化しているとは思わない。このコードはあなたのために働くはずです:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            IFoo foo = new Foo();
            Console.WriteLine("Will return 10: {0}", foo.Bar());

            foo[10] = 20;
            Console.WriteLine("Will return 20: {0}", foo[10]);
        }
    }

    interface IFoo
    {
        int Bar();
        int this[int i] { get; set; }
    }

    class Foo : IFoo
    {
        private int[] array = new int[100];
        public int Bar()
        {
            return 10;
        }

        public int this[int i]
        {
            get
            {
                if (i >= 100)
                {
                    throw new IndexOutOfRangeException("Maximum range is 100");
                }
                return array[i];
            }
            set
            {
                array[i] = value;
            }
        }
    }
}

最後に、キャストを減らすことだけがインターフェースを使用する理由ではありません。インターフェイスは、ファクトリパターンと、コントラクトパターンで最もよく説明されている一般的な抽象化を使用している場合にもうまく機能します。つまり、IFooから継承する複数のクラスを作成し、コントラクト(インターフェイス)を実際に実装するクラスを実際に知らなくても、コントラクトを利用するコードの他のセクションにそれらを渡すことができます。

于 2012-09-21T03:32:26.123 に答える