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 を開いて、この例を再作成しようとしました。プロジェクトを作成し、4 つのクラスを作成しaました。これらのクラスはすべて同じです:bcd

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

ここでの問題は、インターフェースとは何の関係もありませんが、クラスとは関係ありませんProgram。フィールドlistはインスタンス メンバーですが、メソッドMainは静的です。例外が示すように、静的メソッドから非静的メンバーを参照することはできません。

さらに、listインスタンス化または初期化されたことはありません(少なくとも投稿したスニペット内では)。したがってlist、 が static として宣言されていたとしても、コードは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は、インスタンス化されていないようで、静的メソッドからアクセスされているインスタンス フィールドです。


インターフェイスは継承用ではなく、ポリモーフィズム用です。

インターフェイスは、コードを保存するためのものではありません。それが必要な場合は、Abstract クラスを使用してください。

インターフェイスが行うことは、クラスが特定の方法で動作することをコンパイラに保証することだけです。実装については何も指定しません。

たとえば、両方が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 に答える