我有一个简单的问题。
我想装饰SqlDataReader类,这样当调用dispose或close方法时,我可以同时处理一个隐藏的资源。
SqlDataReader类不可继承。
我怎样才能做到这一点?我真的不想实现DbDataReader,IDataReader,IDisposable& IDataRecord接口
答案 0 :(得分:5)
即使您可以从SqlDataReader继承也无关紧要,因为您无法使SqlCommand创建派生类的实例。
当你刚刚推迟到底层的SqlDataReader时,在包装器中实现IDataReader实际上并不难。这只是耗费一点时间,但并不是那么糟糕。
但我很好奇,你想要的资源是否已经解决了连接问题?如果是这样,CommandBehavior枚举的CloseConnection成员将确保在数据读取器关闭时关闭连接。
var reader = command.ExecuteReader(CommandBehavior.CloseConnection);
...
reader.Close(); // also closes connection
请注意,SqlDataReader上的Close / Dispose是相同的。
最后,这是最后一个在过去很好用的建议。请注意,在下面的松散示例中,您从头到尾拥有SqlDataReader,即使您在每条记录中“回放”回调用者。
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
答案 1 :(得分:3)
扭转它;使用“隐藏”资源作为主要内容,实现IDisposable,然后在完成后关闭DataReader。
答案 2 :(得分:1)
<击> http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqldatareader.aspx 班级没有密封。您应该只能在覆盖开始时调用base.dispose(),然后将代码放在后面。
我没有在我面前使用我的IDE,但它应该看起来像
public myClass : SqlDataReader
{
protected overide void Dispose(bool disposing) : Base(disposing)
{
myCleanupCode();
}
protected overide void Dispose()
{
myCleanupCode();
}
private myCleanupCode()
{
//Do cleanup here so you can make one change that will apply to both cases.
}
}
击> <击> EDIT --- 只是阅读原始评论,我看到它有私人构造函数,让我打破我的VS2008和病态
看着它,每个人都在尝试这些奇特的解决方案,我唯一能看到的就是public class myClass : IDisposable
{
public SqlDataReader dataReader { get; set; }
#region IDisposable Members
public void Dispose()
{
dataReader.Dispose();
//My dispose code
}
#endregion
}
编辑---叹了口气,这真是40分钟前Silky发布的。