2013-01-08 30 views
3

我有一個公共的泛型方法,它接受一個泛型參數。我也有一個私有方法接受具體類型參數,我從泛型方法調用。爲了更好地描述我的問題,看看下面的代碼:動態鑄造調用適當的過載

public void Save<T>(T entity) where T : class 
    { 
     if(entity is LibraryItem)  Save(entity as LibraryItem); 
     else if(entity is Folder)  Save(entity as Folder); 
     else if(entity is ProductType) Save(entity as ProductType); 
     else if(entity is ProcessName) Save(entity as ProcessName); 
    } 

和私有方法:

private void Save(ProcessName proc){} 
private void Save(ProductType type){} 
private void Save(Folder folder){} 
... 

看代碼,我真的不喜歡這個解決方案,檢查每一個可能的類型看起來像一個不好的練習imho。所以我想知道我的問題是否有更清潔的解決方案?也許可以在運行時動態調用T並調用適當的私有方法?

回答

6

使用運行時類型定義:

public void Save<T>(T entity) where T : class 
{ 
    Save((dynamic)entity); 
} 

private void Save(LibraryItem lib){} 
private void Save(ProcessName proc){} 
private void Save(ProductType type){} 
private void Save(Folder folder){} 

您還需要與對象類型的參數的一個方法,其中的實體是不LibraryItem,ProcessName,ProductType,或文件夾來處理情況:

private void Save(object obj) { } 
+3

你好,downvoter。一些解釋,如果有的話? –

+1

就這麼簡單?我期待更復雜的東西,如反思:)高興地發現。謝謝:) – Davita

+0

@Davita'dynamic'不是魔術。您應該意識到使用它的後果,因爲它們很重要。 – Servy

3

你在正確的軌道上。使用dynamic關鍵字獲得運行overload resolution

Save((dynamic)entity); 

通常重載決策過程中的靜態類型編譯時(這是object一個通用型)來完成。通過投影到dynamic,您將解析延遲到運行時間,並使用運行時類型而不是靜態類型。

+0

Downvoter,請解釋... –

+2

看起來像downvoter不知道C#,但有足夠的聲望downvoting :) –

+0

感謝我的+1 :) – Davita

1

理想的機制是採取任何方面的Save是特定於該類型,並使其成爲每個具體類型的一部分,以便您可以使用多態性。

它可能不適合每個項目負責保存自己,但它應該做的是暴露足夠的信息,以允許別人寫一個通用的方法,只需接受一個接口或基類型的所有你的類型實現了這個類型的足夠的信息,以允許它被保存。