2009-11-10 57 views
1

再次免責聲明還在學習C#和OOP一般,所以我希望你能耐心陪我:)初學者:在C#中擴展一個類,我做錯了嗎?

我目前正在與一個CMS,有一個叫FileVersion類,它基本上包含的屬性屬於一個工作列表以文件名,文件類型,字節大小,ID,上傳日期,最新版本等文件。

FileVersion的列表被包含在File中,該列表具有它自己的唯一ID。

string URL = "/files/"+file.id.toString()+"/"+file.fileVersion.Last().filename; 

現在對於我的工作(與該文件是文件專門處理)特定的控制,它:當你要下載從CMS特定文件,URL中使用類似以下內置有意義的是能夠將URL與所有其他FileVersion信息一起存儲以供以後使用。所以我決定創建一個名爲DocumentVersion的類,它擴展了FileVersion。這是什麼樣子:

public partial class DocumentVersion : FileVersion 
{ 
    public DocumentVersion() : base() { } 
    public string link; 
} 

現在我應該注意,看來我不需要在這裏實現接口 - 但不要把它看作是福音,這就是爲什麼我在這裏。

然而,當我嘗試投我FileVersionDocumentVersion像這樣:

DocumentVersion dv = ((DocumentVersion)fileversion); 

我得到以下異常:

無法轉換 類型的對象Foo.CMS.FileVersion '鍵入 'CoA.DocumentVersion'。

我的暗示是,那是因爲我想從這裏原來駐留在不同的命名空間擴展一個類,但就像我說的,OOP是比較新的給我,所以我可能是錯的。

在此先感謝您的幫助。這個社區非常寶貴!我只希望一旦我更熟練起來,我可以回饋一些:)。

+0

你可以編輯你的問題來包含'FileVersion'的類聲明嗎?你可能無法擴展它 – 2009-11-10 10:45:35

+0

我很喜歡Russ,但不幸的是我不能這樣做,因爲FileVersion的類聲明位於我沒有源代碼的dll中。一般來說,如何判斷一個類是否可擴展? – 2009-11-10 11:01:02

+0

非常感謝大家爲你所有的偉大答案。最後我接受了Brian's,因爲他是最完整的,而且線程結束的過程中,我學到了我需要的一切。再次感謝大家的時間。啊哈! – 2009-11-12 00:18:27

回答

5

你試圖沮喪嗎?即採取現有的FileVersion並聲明它是DocumentVersion

如果是這樣,你不能這樣做,因爲你擁有的只不過是一個FileVersion

相反,您需要創建一個新的DocumentVersion對象。您的DocumentVersion構造函數將採用FileVersion所需的參數,然後通過base()調用FileVersion構造函數。

請注意,如果你有一個現有的FileVersion對象,你可能想要一個對象包裝這個,而不是有一個從它派生的對象。例如您的DocumentVersion不會衍生自FileVersion,但包含對FileVersion的私人引用,以及所需的其他數據。在這種情況下這可能更合適。

例如(在OO而言,這是組合物

public class DocumentVersion { 
    private FileVersion fv; 
    private String url; 
    public DocumentVersion(FileVersion fv, String url) { 
     this.fv = fv; 
     this.url = url; 
    } 
} 

關於組合物的詳細信息見here

+0

啊!看起來我在馬前有推車!這聽起來很像我想要做的是封裝FileVersion而不是擴展它。我肯定會google你的建議,但如果這是簡單的幾行,你會介意告訴我如何做到這一點? – 2009-11-10 11:04:37

+0

見上文。我是一個Java人,所以我的C#有點生疏。但上面應該給你這個想法。 – 2009-11-10 11:12:01

+0

包裝:您的DocumentVersion類將包含指向您要存儲的FileVersion和附加字段的實例變量。問題是你需要照顧自己存儲這個DocumentVersion,你不能只將*附加到現有的FileVersion或File中。所以,你需要創建自己的'Dictionary '來存儲附加信息。當然,一旦你這樣做了,DocumentVersion中的FileVersion引用就不再需要了,因爲它可以通過File來訪問。 – Heinzi 2009-11-10 11:14:51

1

您不能讓父親(FileVersion)像兒子一樣行事(DocumentVersion)。
只有vica纔會=>你可以讓兒子當父親。

(文件版本)documentVersion //有效
(DocumentVersion)FILEVERSION //無效的(因爲FILEVERSION無法知道這些派生類型有東西)

這是OOP的基礎知識。

1
DocumentVersion dv = null; 

if (fileversion is DocumentVersion) 
{ 
    dv = fileversion as DocumentVersion; 
} 
4

,因爲你的文件版本變量包含一個文件版本,而不是一個DocumentVersion你不能投你的FileVersionDocumentVersion繼承意味着:

  • 每DocumentVersion是一個文件版本,但
  • 每個文件版本是DocumentVersion!

如果該對象是作爲FileVersion創建的,則它只是一個FileVersion。期。如果它是作爲DocumentVersion創建的,則可以在任何要使用FileVersion(請參閱上面的規則#1)的地方使用它,可以使用它的DocumentVersion功能。

因此,當創建 FileVersion對象時,您需要改爲創建一個DocumentVersion(如果您可以控制該部分代碼),則該轉換將起作用。這些DocumentVersion可以存儲在與FileVersions相同的列表中,因爲每個DocumentVersion也是一個FileVersion。


編輯:由於上述兩個規則是理解OO原則如此重要,讓我說明他們用一個例子:DocumentVersion =狗和文件版本=動物。那麼上面的規則是:(1)每隻狗都是一隻動物,但(2)並非每一隻動物都是一隻狗。所以,你可以創建一個動物列表,在那裏存儲各種動物(狗,貓,只是「動物」的東西,......),但是你不能把一個動物類型變成一隻狗,除非在那裏被創造了作爲狗(或者作爲貴賓狗(class貴賓犬:狗),其中是由規則(1)的狗)。

在OO方面:如果保存一個狗類動物的一個變量,則靜態類型的對象是「動物」,和動態類型是「狗」。如果動態類型爲T或其子類型,則只能將某個元素轉換爲某種類型的T。

1

(正如大多數答案所說的,你不能重鑄 - FileVersion不知道什麼是DocumentVersion)。繞過它

一種方法是複製的字段的DocumentVersion

public partial class DocumentVersion : FileVersion 
{ 
    public DocumentVersion() : base() { } 

    public DocumentVersion(FileVersion version) : this() 
    { 
     this.id = version.id; 
     // etc. 
    } 

    public string Link { get;set; } 
} 

構造函數或創建DocumentVersion一個靜態方法,它返回從你提供給它的FileVersion一個DocumentVersion,如:

public static void New(FileVersion version) 
{ 
    this.id = version.id; 
    // etc. 
} 

提到的另一種技術是組合。您存儲FileVersion的財產DocumentVersion

public class DocumentVersion 
{ 
    public FileVersion FileVersion { get;set; } 
    public string Link { get;set; } 
} 
0

既然你不能轉換FileVersionDocumentVersion和所有你需要做的就是添加一個方法來獲取URL,你可以創建一個extension method,需要一個FileVersion

public static string GetLink(this FileVersion fileVersion) { 
    return "/files/"+fileVersion.id.ToString()+"/"+fileVersion.FileVersion.Last().Filename 
} 

注意:這隻適用於如果您使用C#3.0。