gpt4 book ai didi

C# - 我知道,我知道,关于 Dispose 的另一个问题(与设计更相关)!

转载 作者:太空宇宙 更新时间:2023-11-03 18:18:39 25 4
gpt4 key购买 nike

Possible Duplicate:
Should I Dispose() DataSet and DataTable?

OP comment: I would like to say that the "Should I Dispose() DataSet and DataTable?" link isn't a possible solution. It's a good link, but this is more design related. Instead, ignore that the exposed property is a DataSet and replace it with something that should be disposed. The same question would apply there.


我在搞乱 Crystal 报表,我有一个“ReportData”类。换句话说,这个类封装了我将使用的 DataSet 的“填充”。
public class ReportData
{
private DataSet1 m_DS = null; // Notice this disposable member variable

public ReportData( ... some parameters ...)
{
m_DS = new DataSet1();
// Plus some other manipulation on m_DS
}

public DataSet1 GetDataSet
{
get
{
return m_DS;
}
}

// Everything else is pretty much private.
// This class is here to generate my DataSet
}
以下是其他类如何使用它:
private void SetReportDataSource()
{
DataSet1 ds = m_RptData.GetDataSet;
m_Rpt.SetDataSource(ds);
}
我几乎是在快速学习 C#(阅读了一本介绍书中的几章,然后就开始学习了,一路上用谷歌搜索了所有内容)。据我了解,如果它实现了 IDisposable,你最好 Dispose 它。 DataSet 实现了 IDisposable,所以我们需要 Dispose 它。
这是设计部分的用武之地:
问题 1a:我是否将 ReportData 类设为 IDisposable?
换句话说,看起来我可以这样做并完成它:
private void SetReportDataSource()
{
using (DataSet1 ds = m_RptData.GetDataSet)
{
m_Rpt.SetDataSource(ds);
}
}
问题 1b:我是否应该在某些方面更具防御性?
我不知道,我想我真的,真的在努力确保它得到处理。例如,以我的 SetReportDatsSource 函数为例。我使用了“using”,但其他人可能会使用该类而忘记添加 using 或以某种方式调用 Dispose。因此,我去我的 ReportData 类:
public class ReportData : IDisposable
{
private DataSet1 m_DS = null; // Notice this disposable member variable
private bool m_IsDisposed = false; // This is new!

public ReportData( ... some parameters ...)
{
m_DS = new DataSet1();
// Plus some other manipulation on m_DS
}

// New code here (up until the GetDataSet property)
~ReportData()
{
Dispose(false);
}

public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}

protected virtual void Dispose(bool disposing)
{
if (m_IsDisposed == true)
{
return;
}

if (m_DS != null)
{
m_DS.Dispose();
m_DS = null;
}

m_IsDisposed = true;
}

// Done with new code

public DataSet1 GetDataSet
{
get
{
return m_DS;
}
}

// Everything else is pretty much private.
// This class is here to generate my DataSet
}
现在,让我们回到调用类,我们还有:
private void SetReportDataSource()
{
using (DataSet1 ds = m_RptData.GetDataSet)
{
m_Rpt.SetDataSource(ds);
}
}
但是,我现在也将 ReportData (m_RptData) 设为一次性!所以,我们要处理掉它!而且因为它是一个成员变量(而且我不能像在 SetReportDataSource 中那样使用“使用”),你开始考虑让这个调用类 IDisposable,所以我可以:
    protected virtual void Dispose(bool disposing)
{
if (m_IsDisposed == true)
{
return;
}

if (m_ReportData != null)
{
m_ReportData.Dispose();
m_ReportData = null;
}

m_IsDisposed = true;
}
所以,现在这个类有析构函数/终结器和它的公共(public) Dispose 方法,处理 ReportData。我们保证会处理掉 DataSet!
但是话又说回来,这将导致 DataSet 的 Dispose 方法被调用两次。因为 SetReportDataSource 函数处理公开的 DataSet,而 ReportData 类也在处理同样的事情(并且没有简单的方法来确定是否有人处理了公开的 DataSet)。
好像有点牛逼在我看来,我:
a) 可能是想多了(或者只是想真正防御,这很好)!
b) 可能正在跳过一堆铁环。
也许规则应该是:如果我的类要公开它,调用函数应该负责处理它。
我看到的唯一问题(这就是我在这里发布的原因):
在实例化 ReportData 成员变量和调用 SetReportDataSource 之间,可能会发生一些错误/异常。因此,我们永远没有机会对我们的数据集进行“使用”(在 SetReportDataSource 内部)。但是那个数据集是用 ReportData 构建的(我们想在它上面调用 dispose!)
所以,现在我们回到制作 ReportData IDisposable,因为我们至少需要一些公共(public)的“CleanUp”功能......好吧,我完成了。 :)

最佳答案

如果您持有实现 IDisposable 的东西,最简单的模式是自己实现 IDisposable,并在您拥有的所有 IDisposable 上调用 Dispose 方法。比看起来不可行的更具防御性;如果有人使用你的类忘记调用你的 Dispose 方法,那么你怎么知道他们已经使用你了?

编辑:再想一想,Finalize 电话告诉您您的客户已经使用您了;他们没有更多的引用你...

关于C# - 我知道,我知道,关于 Dispose 的另一个问题(与设计更相关)!,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2014026/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com