I need to write & read to binary streams. It would seem like BinaryWriter
& BinaryReader
would fit nicely, but BinaryReader
is not generic in any sense of the word, and AFAIK BinaryWriter
doesn't seem to be extendable to anything beyond primitives. Coming from C++ & knowing that C# also have generic programming techniques I thought this would be an easy problem to fix.
In C++ I'd write something along the lines of:
// 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] );
}
By providing a better match I can easily support serialization for both my own types and 3rd party types. Is there a way to do a similar solution i C#? I've tried with both generic helper classes & static function but can't quite seem to get it to mesh.
So as we discussed in the comments there are 2 solutions:
Generics with constraints
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
}
where IWriter would be:
interface IWriter
{
void Save<U>(U itemToSave) where U : ISerializable;
}
To do the specialisation, you would just overload the method. See this example for how that would work.
dyanamic
type
You can use the dynamic
type to allow you to call arbitary methods, but you loose compile time type checking.
static void Save(dynamic a, dynamic b)
{
a.Save(b);
}
I'm not sure how that would work with overloading to provide the specialisation you require.