2012-07-06 31 views
4

我正在使用大量可重用程序集的C#.NET解決方案。這三個是:將類型傳遞給未知的類庫通用方法 - 爲什麼它可以工作

  • 一個WinForms組件
  • 一個WebClient類庫
  • 包含該數據模型類

我在類庫作爲這樣的通用方法的組件:

namespace Company.WebClient { 
    public class GetData<T>() 
    { 
    ... 
    } 
} 

但是,當我從WinForms程序集內調用該方法時,我傳遞了一個Type th在類庫不會知道,因爲它包含在數據模型組件:

namespace Company.WinFormsApp { 
    public class App 
    { 
    public void Main() 
    { 
     Company.WebClient.GetData<TypeFromTheDataModel>(); 
    } 
    } 
} 

出人意料的是,它似乎工作。但是它爲什麼起作用? webclient程序集沒有對數據模型程序集的硬編碼引用,所以我很驚訝它沒有報告「找不到類型」或某些此類錯誤。這是一種安全的工作方式,還是應該爲我的項目添加更多引用(即從類庫到數據模型)?

+0

它不只是將'TypeFromTheDataModel'視爲'Object',因爲您使用的是非限制類型參數?這就是它在Java中的作用,至少是iirc。 – JAB 2012-07-06 12:44:40

回答

2

庫不需要知道任何有關該類型的信息 - 畢竟,它並不試圖使用任何類型的成員。在執行時間GetData可能找出關於T - 但在編譯時它不需要。

想一想 - 如果這個沒有工作,那麼LINQ to Objects就會被完全破壞,因爲你只能用它來處理系統類型的序列!

基本上,這是完全安全的。

+0

好吧,我想我明白了。但是請忍受我吧?在類庫中,我使用JSON.NET反序列化爲List - 所以大概在運行時,類庫必須找出T? – 2012-07-06 12:50:47

+0

@CarlosP:是的,但它可以使用'typeof(T)'來實現。它沒有任何編譯時的需求來了解這種類型。 – 2012-07-06 13:12:22

+0

感謝您的額外信息,我有適當的通知 – 2012-07-06 14:25:19

1

這基本上就是泛型的一點。 CLR在運行時知道定義您想要用於T的類型的特定類;以及您在GetData中編寫的代碼說明如何處理T類型的對象。 CLR提供拼接,以便您不必考慮它。

注意,在這個例子中,你將沒有約束T(沒有where條款)。這意味着您可以用T類型的對象完成的所有操作都將它們視爲object,但這並不實用。如果你限制它們,比如實現一個接口IMoreInteresting,肯定會出現庫和調用者都需要訪問IMoreInteresting的定義。

+0

認爲JonSkeet只是擊敗你,但我欣賞額外的信息。我想我現在得到它 - 但看到我對喬恩的答案的評論;我仍然不太清楚webclient庫如何能夠'使用'數據模型類將JSON對象反序列化爲對象。那是因爲所有程序集在運行時一起加載到內存中? – 2012-07-06 12:55:23

+0

@CarlosP是的,並且在.NET中,即使在運行時,類型都會帶着它們的*元數據。一旦一個類型被CLR加載,它可以對它做任何事情。 – AakashM 2012-07-06 13:05:39

+0

欣賞澄清 - 現在更有意義 – 2012-07-06 14:25:31

相關問題