Можно создать дубликат:
Should I Dispose() DataSet and DataTable?C# - Я знаю, я знаю, еще один вопрос об Dispose (больше связан с дизайном)!OP комментарий: "Должен ли я Dispose() DataSet и DataTable" Я хотел бы сказать, что ссылка не является возможным решением. Это хорошая ссылка, но это больше связано с дизайном. Вместо этого игнорируйте, что открытое свойство является DataSet и заменяет его тем, что должно быть удалено. Там же будет применяться тот же вопрос.
Я возился с Crystal Reports, и у меня есть класс 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, вы лучше уничтожаете его. DataSet реализует IDisposable, поэтому нам нужно утилизировать его.
Вот где дизайн часть приходит в:
Вопрос 1a: Должен ли я сделать мой ReportData класс IDisposable?
Другими словами, это выглядит, как я мог бы просто сделать это и сделать с ней:
private void SetReportDataSource()
{
using (DataSet1 ds = m_RptData.GetDataSet)
{
m_Rpt.SetDataSource(ds);
}
}
Вопрос 1b: Должен ли я быть более оборонительный каким-то образом?
Я не знаю, я думаю, я действительно пытаюсь обеспечить, чтобы он был утилизирован. Например, возьмем функцию SetReportDatsSource в качестве примера. Я использовал «использование», но кто-то другой может использовать класс и забыть добавить использование или вызвать 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;
}
Итак, теперь этот класс имеет деструктор/финализатор и его общедоступный метод Dispose, распоряжающийся ReportData. Мы гарантируем, что мы избавимся от DataSet!
Но опять же, это приведет к вызову метода Dispose DataSet дважды. Поскольку функция SetReportDataSource предоставляет открытый DataSet, а класс ReportData также утилизирует одно и то же (и нет простого способа определить, удалил ли кто-нибудь из выставленного DataSet).
Кажется, орех.Мне кажется, что я:
a) Может быть, это переусердствует (или просто пытается быть действительно защитным, что хорошо)!
b) Возможно, вы прыгаете через кучу обручей.
Возможно, это правило должно быть: если мой класс собирается его выставить, вызывающая функция должна нести ответственность за его удаление.
Единственная проблема, которую я вижу с этим (и именно поэтому я отправил здесь):
В период между этой переменной член ReportData конкретизируется, и SetReportDataSource называется, какая-то ошибка/исключение может произойти. Таким образом, у нас никогда не будет возможности использовать «использование» (внутри SetReportDataSource) в нашем DataSet. Но этот набор данных был сконструирован с помощью ReportData (и мы хотим вызвать его на себя!)
Итак, теперь мы вернемся к созданию ReportData IDisposable, потому что нам понадобится хотя бы какая-то публичная функция «CleanUp». . ладно, я готов. :)
Я хотел бы сказать, что «Должен ли я Dispose() DataSet и DataTable?» ссылка не является возможным решением. Это хорошая ссылка, но это больше связано с дизайном. Вместо этого игнорируйте, что открытое свойство является DataSet и заменяет его тем, что должно быть удалено. – JustLooking
Кто-то проголосовал за то, чтобы закрыть это как «нагло оскорбительное»? Egad. – Beska
Возможно, это связано с вашим аргументированным тоном и вашим смешным названием? Как насчет вашего неприлично длинного поста, который не составляет много? Как насчет отсутствия форматирования или смешных смайлов, которые вы используете в своем посте? Мне было бы интересно, почему кто-то ** не будет ** находить это наступление. – GEOCHET