2014-10-04 37 views
0

我一直在尋找一些接口實現,因爲我無法使用「使用」的關鍵字,以確保妥善處置在C#中的FileInfo對象,但編譯器給了我這個錯誤:一般接口和接口的含義是什麼?

'System.IO.FileInfo': type used in a using statement must be implicitly convertible to 'System.IDisposable'

所以,從我做起記錄關於這些特定接口的實現。

我最終看到所有簡化爲鍵入:類名旁邊的IDisposable並自己添加Dispose()方法,這就是您如何創建IDisposable。

第一個問題:

這是什麼意思?框架創建者不應該讓這些項目 - 一次性/可空或任何您想要的常用界面 - 而不讓我們擔心它?

我作爲一名程序員工作了兩年,但我作爲一個業餘愛好多年,我從未理解爲什麼界面是有用的或他們的目的是什麼。他們實際上對我來說似乎很沒用。

從我理解他們唯一的目的是作爲一個「契約」,這是一個我從來沒有完全理解的定義。像nto這樣的人說他們可以說:「它只是意味着你必須重新實現你所繼承的類的所有方法,即使你讓它們變成空的」,而不是那個尷尬的「契約」定義。

無論如何,爲什麼?爲什麼我需要編譯器告訴我需要實現這些方法?我想我永遠不會那樣做。

通常我從編程學習或應用這些概念,但是我發誓我從來沒有爲我和我的同事找到或看到過,一個界面是有用的,需要的,一個好的選擇或一些方便的情況...

我想即使我看到人們使用它們,我也會永遠不會使用它們......爲什麼?

+1

好吧,是不是有點明顯,一個接口是有用的,只是從*使用*關鍵字?您可以將任何*種類的對象傳遞給它。包括微軟從未設想過的那些,比如你創建的類。只要它實現了IDisposable。 *對每個*關鍵字來說都是相同的,它可以枚舉*任何*集合對象,而不僅僅是從.NET Framework類創建的對象,它只需要實現IEnumerable。 – 2014-10-04 09:12:53

+0

嗯,在所有令人困惑的東西,也許@HansPassant給了我一點點光... 無論如何,我不喜歡它...你必須知道所有接口說某人,嘿在我需要你的功能一個IDisposable,一個IEnumerable。自己創建接口意味着每個使用它的人都應該知道它具有什麼方法... 如果在需要某人將其實現到接口之前實現所需的方法來處理某些事情,那會更好嗎? 對不起,如果我聽起來很愚蠢,我沒有足夠的經驗 – user2235691 2014-10-05 17:28:56

+0

@ user2235691:你*不能實現所需的方法,因爲接口的每個實現者都可能以不同的方式實現它的方法。返回列表內容的'IEnumerable'的實現方式不同於'IEnumerable',它返回從數據庫服務器接收到的內容。唯一相同的部分是用於迭代列表/數據庫結果集中的項目的方法集 - 換句話說,public * interface *。 – 2014-10-06 06:14:33

回答

0

毫無疑問,您將使用接口。事實上,如果你正在寫一個using聲明,那麼你已經在使用一個。

using聲明的要點是創建一個對象並確保它在該塊的末尾顯示。爲了能夠處理該對象,它必須有一個Dispose方法。這就是IDisposable接口進來的地方。

IDisposable接口定義了Dispose方法。實施IDisposable的任何類別都簽署合同來實施該方法Disposeusing聲明要求對象具有Dispose方法,以便能夠將其置於塊的末尾,並且知道該方法存在的方式是您正在使用的對象實現了IDisposable

這種事情是全部看到的。當您編寫一個foreach循環時,循環的對象必須實現IEnumerable。在引擎蓋下,foreach循環使用該接口定義的功能枚舉指定的列表。

類似地,爲了結合一個WinForms控制像ComboBoxListBoxDataGridView到數據的列表,這是因爲底層的數據綁定機制使用由該接口所定義的功能,列表必須實現IList接口。

這基本上是什麼接口:他們保證一組特定的功能將可用。他們對如何實現該功能或者可能提供或不提供其他功能沒有任何承諾。

想想接口如何在別處工作。你使用一臺電腦,所以你大概熟悉USB接口。爲了符合USB標準,設備必須提供一組特定的功能。它是如何做到的,它做了什麼與計算機上的USB端口無關。只要它有一個合適的USB插頭,可以成功地發送和接收適當的消息,那麼它將工作。

將您的using聲明視爲IDisposable端口。無論你的對象在調用方法時調用Dispose還是其他屬性和方法都沒關係,只要它有一個名爲「Dispose」的方法,它沒有參數並且不返回任何值,它可以實現IDisosable並被using聲明接受。

+0

呃..所以這是關於使一個對象可用的其他東西? 似乎很容易發生在我身上的錯誤,如果你在一個界面中實現了一個你自己沒有創建的對象,我想你可能會在某個時候搞壞引擎蓋下的東西...... 無論如何感謝你的清晰解釋,我喜歡它 – user2235691 2014-10-05 17:30:13

+0

@ user2235691:你如何「實現一個你自己沒有創建的對象」? – 2014-10-05 18:39:08

+1

@ user2235691,足以說接口非常有用,並使C#開發中的生活更輕鬆。接口本身並不容易出錯。如果你編寫不好的代碼,那麼你編寫的代碼不好,如果他們努力工作,任何人都可能搞砸了。你顯然還沒有把握這個概念。如果你正在開發,那麼你將來會在某個時候出現,而且可能會出現一個燈泡。如果你從來沒有真正掌握界面的用處,那麼這就表明你不是一個真正的開發者。 – jmcilhinney 2014-10-06 01:09:51

1

與許多其他語言一樣,C#不支持多重繼承。例如,請參閱the Diamond Problem

在任何情況下,接口都是C#通過避免一些與之相關的問題來實現多重繼承的方法。如果Class A有一個名爲Foo()的方法,並且Class B也有一個方法,稱爲Foo()當你從兩者中派生出來時,你怎麼可能解決哪一個要調用?通過指定接口什麼和對象可以做,但不是它如何它做到這一點。

考慮IList<T> - 表示可擴展列表的集合的通用形式。它有方法,如Add,RemoveClear。如果有人使用你的班級,他們不應該需要擔心你的實施細節,只是它的工作。因此,您可以擁有List<int>LinkedList<int>,並且它對您的客戶端仍然具有相同的功能,因爲您只顯示接口 - 基本合同 - 可讓他們使用

+0

不清楚。對不起,但我沒有得到你的解釋 – user2235691 2014-10-05 17:19:33

0

關於特別IDisposable:首先,是一次性東西被可空很大的不同。

  • 每個參考類型的變量都可以自動爲空,這意味着您可以將它們設置爲null。你做不是需要執行IDisposable
  • 當你實現IDisposable接口時,你這樣做是爲了釋放運行時不能自動釋放的資源,或者應該不受(有點不確定的)垃圾回收的影響。
    例如,您可能會編寫一個實例打開文件並寫入其中的類 - 如果不再需要類的實例,則應關閉該文件。它應該在那之後關閉(因爲其他情況下可能要從那時起訪問文件),而不是「在不再需要該類之後的某一時刻,最遲在該過程終止時」。因此,你應該聲明你自己的類來實現IDisposable(因此你的類的用戶知道需要調用Dispose,並且他們也可以在using塊中使用你的類)並以關閉文件的方式實現Dispose方法。

現在,正如你所說,接口通常用作「合同」 - 爲呼叫者保證你的類實現了一組特定的成員。因此,你的問題的簡單答案

Why do I need compiler to tell me that I need to implement those methods?

是「所以他們可以被稱爲。」

請看下面的例子 - 首先,接口和兩個類實現它,聲明:

public interface ISomeInterface 
{ 
    bool DoSomething(); 

    int SomeValue { get; } 
} 

public class Example1 : ISomeInterface 
{ 
    public bool DoSomething() 
    { 
     return true; 
    } 

    public int SomeValue { 
     get { 
      return 42; 
     } 
    } 
} 

public class Example2 : ISomeInterface 
{ 
    public bool DoSomething() 
    { 
     return DateTime.IsLeapYear(DateTime.Now.Year); 
    } 

    public int SomeValue { 
     get { 
      return DateTime.Now.Year; 
     } 
    } 
} 

現在,讓我們添加一個類返回的ISomeInterface實現的方法:

public class SomeMasterClass 
{ 
    public static ISomeInterface CreateObject() 
    { 
     if (DateTime.Now.Year % 3 == 0) { 
      return new Example1(); 
     } else { 
      return new Example2(); 
     } 
    } 
} 

根據內部條件,將返回Example1的實例或Example2的實例。當調用該方法,你不知道哪一個類將實際實例化,你不需要知道 - ,因爲兩者實現的接口的成員,你要使用:

ISomeInterface myObject = SomeMasterClass.CreateObject(); 
Console.WriteLine(myObject.DoSomething()); 
Console.WriteLine(myObject.SomeValue); 

沒有接口,的SomeMasterClass.CreateObject()返回值將不得不分型爲System.Object(因爲這是Example1Example2最專業的共同祖先。然而,由於這兩個類實現ISomeInterface接口,從而履行合同通過該接口強加的,你可以依靠它們爲DoSomething方法提供的實現和SomeValue屬性。

+0

不清楚我。對不起,但這讓我更加困惑。 此外,我從來沒有見過這樣的語法公共靜態ISomeInterface的CreateObject(),所以我甚至不知道你在說什麼 – user2235691 2014-10-05 17:18:46

+0

@ user2235691:如果你可以比「這讓我更加困惑」特別是不清楚(用什麼句子,什麼詞,我失去了你?),我可以改進我的描述。在任何情況下,'public static X Y()'聲明一個名爲'Y'的公共靜態方法,它返回一個'X'類型的值。 'public'是[訪問修飾符](http://msdn.microsoft.com/en-us/library/ms173121.aspx),['static'表示該方法可以在沒有其類的實例的情況下被調用]( http://msdn.microsoft.com/en-us/library/98f28cdx.aspx)。請閱讀這些話題,然後重新閱讀這個答案。 – 2014-10-05 18:32:47