1

我使用 C# 和 .NET 已经有一段时间了,尽管我之前一直在使用 OOP 语言(更准确地说是 Java),但在处理 .NET 应用程序时,我发现使用的接口比我使用的要多得多在 Java 中看到。我根本没有太多经验,所以我并不是说接口在 .NET 中使用得更多,但现在我觉得有必要更深入地了解接口以及让人们经常使用它们的好处是什么.

我在互联网上有一些东西,这里有一些东西,对我来说最有意义的解释是——我怎么知道什么时候创建一个界面?.

我的问题来了。我根本不期望对接口进行一些神奇的解释,因为我已经阅读了足够多的内容,发现没有这样的东西。我希望通过经验和编码,更深层次的理解会自行产生,所以我决定尝试这个例子,指出使用链接中接受的答案中的接口的好处。我也会在这里复制粘贴:

您有 4 种不同类型的 a、b、c、d。在你的代码中,你有类似的东西:

a.Process();
b.Process();
c.Process();
d.Process();

为什么不让他们执行IProcessable,然后执行

List<IProcessable> list;

foreach(IProcessable p in list)
    p.Process();

当您添加例如 50 种都做同样事情的类时,这将更好地扩展。

问题是我似乎没有这个。阅读后,我打开我的 Visual Studio 2010 并尝试重新创建这样的示例 - 我创建了一个项目并创建了四个类 - a, b, c, d. 所有这些类都是相同的:

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

namespace ConsoleApplication1
{
    class a : ITest
    {
        public void Test()
        {
            System.Console.WriteLine("Hi from a");
        }
    }
}

只有 4 个不同的名称和Test()打印名称的方法。这是界面:

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

namespace ConsoleApplication1
{
    interface ITest
    {
        public void Test();
    }
}

根据我的理解,我Program.cs有这个:

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

namespace ConsoleApplication1
{
    class Program
    {
        List<ITest> list;
        static void Main(string[] args)
        {
            foreach (ITest p in list)
                p.Test();
        }
    }
}

好。看来我真的搞错了。我认为通过实现相同的接口,我可以自动获取所有类的列表并使用它们,例如在我上面的Main()方法中。但是我收到以下错误:

非静态字段、方法或属性需要对象引用

好吧,有人可以降低我的水平,并根据这个例子向我解释我如何通过使用界面来获得这样的好处。

4

4 回答 4

3

这里的问题与 interface 无关,而与 class 无关Program。字段list是实例成员,而方法Main是静态的。正如例外所说,您不能从静态方法中引用非静态成员。

此外,list从未实例化或初始化(至少不在您发布的片段中)。因此,即使list被声明为静态,您的代码也会生成一个NullReferenceException.

尝试将您的Program课程更改为:

class Program
{
    static List<ITest> list;
    static void Main(string[] args)
    {
        list = new List<ITest>();
        // ...
        // initialize list 
        // ...

        foreach (ITest p in list)
            p.Test();
    }
}
于 2013-02-26T19:30:04.190 回答
1

关于您的错误,它看起来list没有实例化,它是一个实例字段,可以从静态方法访问。


接口不是为了继承,而是为了多态。

接口不是用来保存代码的。如果您需要这样做,请使用抽象类。

接口所做的只是向编译器保证您的类将以特定方式运行。它没有指定任何有关实施的内容。

例如,您同时拥有两者List并且LinkedList实现方式不同,但它们都符合接口,因此可以在循环IEnumberable中迭代foreach

于 2013-02-26T19:30:23.437 回答
1

您的代码在创建将实现接口的类方面看起来不错。问题似乎在于您的初始化。

正如您声明的那样,它List<ITest> list不是静态字段。该Main函数是一个静态方法,因此它只能访问其他静态字段。

如果您想继续这个基本示例,请尝试设置list为静态字段,或设置为 中的变量Main,并实例化它,在foreach循环中使用它之前用一些对象填充它。

于 2013-02-26T19:31:01.840 回答
0

接口的使用定义了对象的占位符之类的东西,它肯定会有一些特定的行为,而实际上并不知道它。例如,您可以有 A 类和 B 类,它们都实现了 IMyInterface。如果您需要 IMyInterface 的实例,您可以同时使用它们并调用接口中指定但在 A 或 B 中实现的方法。此外,IoC 容器中的接口也有很好的基于约定的用法。

于 2013-02-26T19:35:18.813 回答