This is a simplified example, to isolate the purpose of the question. In my actual scneario, the ColumnReader returned by GetColumnReader will actually do more work than merely ReadLine.
If I run the following program, I will get an error when I try to call Reader(), because of course the TextReader has already been disposed by the using statement.
public class Play{
delegate string ColumnReader();
static ColumnReader GetColumnReader(string filename){
using (TextReader reader = new StreamReader(filename)){
var headers = reader.ReadLine();
return () => reader.ReadLine();
}
}
public static void Main(string[] args){
var Reader = GetColumnReader("Input.tsv");
Console.WriteLine(Reader());
}
}
Alternatively, I can remove the “using” and directly declare the TextReader, which would function, but now we no longer have a guarantee that the TextReader will be eventually closed.
Is there a way to add a “destructor” to the returned lambda function where I might be able to Dispose of the TextReader as soon as the lambda function goes out of scope (no more references)?
I also welcome other suggestions but wish to keep the basic closure structure (that is, fits into the scope of the question).
Essentially you need the scope of the disposable element outside of the delegate itself. In these situations I would make the delegate accept the disposable instance (I.e. TextReader) rather than a file name.