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 回答