2013-02-26 37 views
1

我正在使用C#和.NET一段時間,即使我之前一直在使用OOP語言(更準確地說是Java),而.NET應用程序我看到的界面比我在Java中看到的要多得多。我沒有太多的經驗,所以我並不是說接口在.NET中被更多的使用,但是現在我覺得有必要更深入地理解接口,以及經常使用它們的好處是什麼。接口使用說明(C#透視圖)

我在網上有一些東西,這裏有些東西,對我來說最有意義的解釋是這樣的 - How will I know when to create an interface?

這裏來了我的問題。我根本不希望對接口有一些神奇的解釋,因爲我讀過的東西已經足以看出沒有這種東西。我希望藉助經驗和編碼,更深層次的理解本身就會出現,所以我決定嘗試使用鏈接中接受答案的接口的好處。我也會在這裏複製粘貼:

你有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()方法。不過,我得到以下錯誤:

An object reference is required for the non-static field, method, or property

好,有人可以降低水平,我解釋一下我在這個例子中的條款如何我正是受益像這樣使用的接口。

+3

這裏的接口不是問題 - 它是'Program'的'list'字段。這需要一個靜態字段來使用靜態方法'Main'。 (你可能也想把一些東西放在列表中) – kevingessner 2013-02-26 19:28:22

+1

這將是一個很好的閱讀 - http://stackoverflow.com/q/14482483/218882 – 2013-02-26 19:30:21

回答

1

您的代碼看起來很不錯創建類的術語,其將實現該接口。這個問題似乎在於你的初始化。

正如你聲明的那樣,List<ITest> list不是一個靜態字段。 Main函數是一個靜態方法,所以它只能訪問其他靜態字段。

如果你想用這個簡單的例子着手,嘗試設置list作爲靜態字段,或者作爲內Main一個變量,實例化它,在你foreach循環使用它之前與一些對象填充它。

3

這裏的問題與接口無關,但與類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(); 
    } 
} 
1

關於你的錯誤,它看起來像list沒有實例化,它是一個實例字段,從靜態方法訪問。


接口不是爲了繼承,而是爲了多態。

一個接口不用於保存你的代碼。如果您需要這樣做,請使用Abstract類。

接口所​​做的一切都是向編譯器保證你的類將以特定的方式工作。它沒有指定任何有關實現的內容。

例如,你有兩個ListLinkedList被不同implimented,但他們都符合IEnumberable接口,因此在該foreach循環中遍歷

0

接口的用法定義了類似於對象的佔位符,它肯定會有一些特定的行爲,但實際上並不知道它。例如,你可以有A類和B類,他們都實現IMyInterface。如果您需要IMyInterface實例,則可以使用它們並調用接口中指定但在A或B中實現的方法。IoC容器中的接口也有很好的基於約定的用法。