I disagree that dynamic is the best way. The problem here is that you need to ensure that callers pass in a type T , which BinaryWriter.Write() can handle. Since there is no common class or interface that can guarantee this by restricting T , the best way to do this is to โtransfer the dollarโ to the caller as follows:
private static void WriteToDisk<T>(string fileName, T[] vector, Action<BinaryWriter, T> callWrite) { using (var stream = new FileStream(fileName, FileMode.Create)) { using (var writer = new BinaryWriter(stream)) { foreach (T v in vector) callWrite(writer, v); writer.Close(); } } }
This is called the following:
WriteToDisk("filename", new int[0], (w, o) => w.Write(o)); // compiles WriteToDisk("filename", new string[0], (w, o) => w.Write(o)); // compiles WriteToDisk("filename", new DateTime[0], (w, o) => w.Write(o)); // doesn't compile (as desired)
Of course, if there is only a small set of known types, you can create "convenient methods" as such:
private static void WriteToDisk(string fileName, int[] vector) { WriteToDisk(fileName, vector, (w, o) => w.Write(o)); } private static void WriteToDisk(string fileName, string[] vector) { WriteToDisk(fileName, vector, (w, o) => w.Write(o)); }
and now your calls are simple:
WriteToDisk("filename", new int[0]); WriteToDisk("filename", new string[0]);
A bit more code, but much more security and speed in compilation mode.