Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在C中包装不可继承的类#_C# - Fatal编程技术网

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

C# 在C中包装不可继承的类#,c#,C#,我有一个简单的问题 我想修饰SqlDataReader类,以便在调用dispose或close方法时可以同时处理隐藏的资源 SqlDataReader类不可继承 我怎样才能做到这一点?我真的不想实现DbDataReader、IDataReader、IDisposable和IDataRecord接口;使用“隐藏”资源作为主要任务,实现IDisposable,然后在完成后关闭DataReader。 这个班没有封条。您应该能够在重写开始时调用base.dispose(),然后将代码放在后面 我没有我的

我有一个简单的问题

我想修饰SqlDataReader类,以便在调用dispose或close方法时可以同时处理隐藏的资源

SqlDataReader类不可继承

我怎样才能做到这一点?我真的不想实现DbDataReader、IDataReader、IDisposable和IDataRecord接口;使用“隐藏”资源作为主要任务,实现IDisposable,然后在完成后关闭DataReader。

这个班没有封条。您应该能够在重写开始时调用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
}

编辑---唉,这当然是Silky在40分钟前发布的内容。

即使您可以从SqlDataReader继承,也没关系,因为您无法让SqlCommand创建派生类的实例

在包装器中实现IDataReader其实一点也不难,因为您只是遵从底层的SqlDataReader。只是有点费时,但没那么糟

但我很好奇,你想要的资源是否处理了连接?如果是,CommandBehavior枚举的CloseConnection成员可确保在数据读取器关闭时关闭连接

var reader = command.ExecuteReader(CommandBehavior.CloseConnection);
...
reader.Close(); // also closes connection
请注意,在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
private静态IEnumerable GetResults(此SqlCommand){
使用(var myTicket=new myTicket())
使用(var reader=command.ExecuteReader()){
while(reader.Read()){
回传阅读器;
}
}
//上面使用块中的两个资源将是
//当下面的foreach循环退出时释放
}
...
foreach(myCommand.GetResults()中的var记录){
Console.WriteLine(record.GetString(0));
}
//当上面的foreach循环完成时,编译器生成
//迭代器被释放,允许在
//上面的方法清理reader/myTicket对象


不可继承是什么意思?这是一门封闭的课程吗?你能详细介绍一下接口吗?你不需要实施这些吗?还有,你为什么不想呢?SqlDataReader不是密封的,所以它是可继承的,但它的构造函数是私有的,所以当你从它继承时,你不能满足基本构造函数的要求-我只是在细节上吹毛求疵,但你是对的。除了我对silky答案的评论之外,我不禁想知道。。。使用
SqlDataReader
打包可能需要什么?我真的希望它不是
SqlCommand
SqlConnection
…资源是一次性类的实例。它不是SqlCommand,也不是SqlConnection对象。资源是一个票据池中的票据,用于保护资源(在本例中为Sql DB)。我讨厌自己这样想,但我想知道除了您的行为之外,是否还有一种方法可以放置一个IL方法挂钩来调用原始的Close或Dispose。我不想尝试,只是想抛出一个想法。我真的希望调用代码对此一无所知。它当前需要一个SQLDataReader实例。您是否拥有调用代码?它真的需要接受
SqlDataReader
?这是你应该尽量避免传递的东西;如果您可以让它接受
IDataReader
,那么您可以非常轻松地包装
SqlDataReader
。是的,我拥有调用代码。我不想把这门课做完哈利:真倒霉。重新思考你的设计,因为你想要的是不可能的。执着于不可能做到的事情是不合逻辑的。您不需要实现
IDataReader
,我建议您只需实现
IDisposable
。也许你应该详细解释一下你在做什么,我们可以提供更具体的建议。这个问题实际上是一个很好的例子,说明了为什么共享接口而不是类,尤其是重系统类更好——你可以轻松地将一个实现换成另一个实现,而无需更改太多代码。前面的工作越多,后面的工作就越少。我想知道消费代码是什么-您甚至可能不需要
IDataReader
,也许消费者只使用了几个方法。对不起,我不是想说教,但丝琪是对的,不可能按照描述去做;重构时间::-)此代码导致编译错误:错误#1类型“System.Data.SqlClient.SqlDataReader”未定义构造函数。。。而且。。。错误#2“System.Data.SqlClient.SqlDataReader.SqlDataReader(System.Data.SqlClient.SqlCommand,System.Data.CommandBehavior)”由于其保护级别而不可访问链接的第一行:“此类无法继承。”只要Ticket实现Idisposable,就可以返回@Harry的元组,这可能是您的最佳选择。该资源是一个用于保护对SQL数据库访问的一次性Ticket好的,我在回答中添加了另一个建议,可能会有所帮助。这是一个非常有趣的解决方案。人们对此有何看法?我非常喜欢yield解决方案,因为它能够通过reader处理清理多个其他资源。事实上,我只是稍微修改了示例,使其成为SqlCommand上的扩展方法。除了资源处理之外,foreach看起来比while(reader.Read())更干净。。。