2014-01-31 104 views
3

我需要寫&讀取到二進制流。它看起來好像BinaryWriter & BinaryReader會很好地吻合,但BinaryReader不是通用的任何意義上的單詞,並且AFAIK BinaryWriter似乎不能擴展到基本以外的任何東西。來自C++ &知道C#也有通用編程技術,我認爲這將是一個容易解決的問題。似乎無法寫出通用讀寫

在C++中我會寫的線沿線的東西:

// Default works for primitives since BinaryWriter::Write has overloads 
template< typename SinkT, typename SourceT > 
static void Save(SinkT& a_Sink, const SourceT& a_Source) 
{ 
    a_Sink.Write(a_Source); 
} 

// Lets create a better match for some 3rd party vector3 type 
template< typename SinkT > 
static void Save(SinkT& a_Sink, const SomeVendor::Vector3& a_Source) 
{ 
    Save(a_Sink, a_Source[0]); 
    Save(a_Sink, a_Source[1]); 
    Save(a_Sink, a_Source[2]); 
} 

通過提供更好的匹配,我可以輕鬆支持序列爲我自己的類型和第三方類型兩者。有沒有辦法在C#上做類似的解決方案?我已經嘗試過使用兩個通用幫助類&靜態函數,但似乎無法使其進行網格劃分。

+1

我很同情我可能是錯的,但是好像很多C#IO操作是在泛型之前編寫的,所以不要使用它們,這有點令人失望。 但是,要做第一種方法,那麼可以使用帶有約束的泛型來完成,如果這是您正在嘗試執行的操作? 更新:思考它,你可以重載方法做專業化 –

+0

真棒,我想我需要看看約束和它們是如何工作的,我猜這有點像C++中的概念? – Ylisar

+0

你可以在通用助手類和靜態函數中添加你的嘗試嗎? – Stijn

回答

1

因此,當我們在評論中討論的有2個解決方案:

泛型與約束

static void Save<T, U>(T sink, U source) where T : IWriter, 
               U : ISerializable 
{ 
     // do stuff using that fact that U is serialisable and T implements IWriter 
} 

其中IWriter是:

interface IWriter 
{ 
    void Save<U>(U itemToSave) where U : ISerializable; 
} 

要做的pecialisation,你會只是超載的方法。請參閱this example瞭解如何工作。

dyanamic

可以使用dynamic類型,讓你打電話arbitary方法,但是你失去編譯時類型檢查。

static void Save(dynamic a, dynamic b) 
{ 
     a.Save(b); 
} 

我不知道這是如何與超載提供您需要的專業化。

1

你想要什麼(模板)根本不存在於C#中。你可以做一些黑客行爲,並使用dynamic(以鴨子的方式圍繞它),但我真的不推薦它。您可能需要簡單地找到一種不同的方法。

+0

可能只是去骯髒,它蠻力嘿:) – Ylisar