代码之家  ›  专栏  ›  技术社区  ›  Andrew Harry

在C中包装不可继承的类#

c#
  •  6
  • Andrew Harry  · 技术社区  · 16 年前

    我有一个简单的问题。

    我希望修饰sqldatareader类,以便在调用Dispose或Close方法时,可以同时处理隐藏的资源。

    sqldatareader类不可继承。

    我怎样才能做到这一点?我真的不想实现DBDataReader、IDataReader、IDisposable&IDataRecord接口

    3 回复  |  直到 16 年前
        1
  •  5
  •   Josh    16 年前

    即使您可以从sqldatareader继承,也不重要,因为您不能让sqlcommand创建派生类的实例。

    在包装器中实现IDataReader实际上并不难,因为您只需遵从底层的sqldataReader。只是有点费时,但没那么糟。

    但是我很好奇,你想要的资源是不是处理了连接?如果是这样,则commandBehavior枚举中有一个closeConnection成员,该成员确保在关闭数据读取器时关闭连接。

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

    请注意,close/dispose在sqldatareader上是相同的。

    最后,这里还有最后一个建议,它在过去对我很有帮助。请注意,在下面这个松散的示例中,您从开始到结束都拥有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
    
        2
  •  3
  •   Noon Silk    16 年前

    反转它;使用“隐藏”资源作为主要内容,实现IDisposable,然后在完成后关闭DataReader。

        3
  •  1
  •   Scott Chamberlain    16 年前

    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.
        }
    }
    

    编辑--- 刚刚读了原始评论,我看到它有一个私有的构造函数,让我把我的vs2008和ill brb

    看着它,每个人都在尝试这些花哨的解决方案,我唯一能做的就是

    public class myClass : IDisposable
    {
    
        public SqlDataReader dataReader { get; set; }
    
        #region IDisposable Members
    
        public void Dispose()
        {
            dataReader.Dispose();
            //My dispose code
        }
    
        #endregion
    }
    

    编辑---叹息,这是40分钟前丝般的发布。