Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wrapping a Non-inheritable class in C#

Tags:

c#

I have a simple problem.

I want to decorate the SqlDataReader class so that when the dispose or close methods are called I can dispose of a hidden resource at the same time.

the SqlDataReader class is not inheritable.

How can I accomplish this? I really don't want to implement the DbDataReader, IDataReader, IDisposable & IDataRecord interfaces

like image 437
Andrew Harry Avatar asked Jan 05 '10 04:01

Andrew Harry


1 Answers

Even if you could inherit from SqlDataReader it wouldn't matter anyway because you couldn't make SqlCommand create an instance of your derived class.

Implementing IDataReader in a wrapper is really not hard at all when you're just deferring to the underlying SqlDataReader. It's just a little time consuming but not that bad.

But I'm curious, is the resource you want disposed the connection? If so there is a CloseConnection member of the CommandBehavior enum that ensures the connection will be closed when the data reader is closed.

var reader = command.ExecuteReader(CommandBehavior.CloseConnection);
...
reader.Close(); // also closes connection

Note that Close/Dispose are the same thing on SqlDataReader.

Finally, here's one last suggestion that has served me well in the past. Note that in the following loose example, you own the SqlDataReader from start to finish even though you are "yielding" back to the caller at each record.

private static IEnumerable<IDataRecord> GetResults(this SqlCommand command) {
    using (var myTicket = new MyTicket())
    using (var reader = command.ExecuteReader()) {
        while (reader.Read()) {
            yield return reader;
        }
    }
    // the two resources in the using blocks above will be
    // disposed when the foreach loop below exits
}

...

foreach (var record in myCommand.GetResults()) {

    Console.WriteLine(record.GetString(0));

}

// when the foreach loop above completes, the compiler-generated
// iterator is disposed, allowing the using blocks inside the
// above method to clean up the reader/myTicket objects
like image 50
Josh Avatar answered Sep 29 '22 23:09

Josh