关于这个主题有很多问题,但是我没有找到一个涵盖我特别需要理解的内容 .
我的一位开发人员编写了这段代码:
//
// ValidationDataTable is a typed DataTable, generated by the Framework
ValidationDataTable validationTable;
using (ValidationTableAdapter adapter = new ValidationTableAdapter ()) {
using (validationTable = adapter.GetData()) { }
}
datafeedValidators.Add(new CountryFieldValidator(validationTable.ToDictionary(key => key.CountryCode, value => value.CountryName)));
// Party on...
//
我的理解:当在最后一个代码行中引用validationTable时,它已被处理但不是垃圾收集 - 但仍应在 .ToDictionary()
调用上抛出 ObjectDisposedException
. 但是这段代码很乐意构建一个有效的字典并继续前进 .
我有理论,但找不到确定或击落其中任何一个的确定性 . 并且可以通过十几种方式重写代码以避免问题;那不是问题 . 我只需要知道我理解的差距是什么 .
我的问题:
-
此代码是否有效且表现如何?
-
如果没有,我们看到的成功是否只是一个废话?
-
是否有一些特定的
DataTable
允许在对象被释放后进行访问 - 类似于GZipStream
类要求你处理对象以刷新流的方式,因此允许在对象被处置后调用.ToArray()
和.GetBuffer()
? -
...调用方法时实际导致抛出ObjectDisposedException的原因是什么?我一直认为它来自.NET框架本身 .
.
CLARIFICATION:
这是一个.NET Framework问题 . 共识是我的理解是正确的 - DataTable本身必须抛出 ObjectDisposedException
. 除了它没有't. Not anywhere in the DataTable source code - hence my asking. I assumed that the framework would ensure an ObjectDisposedException after it had been disposed, which apparently isn' t的情况......不像GZipStream,它只允许在Dispose()之后访问两个方法,即DataTable DGAF . 精细 .
因此,让我重新解释一个问题:DataTable内部是否有任何内容可以轰炸我们,因为允许调用已分配的表?我可以假设微软似乎不是一个安全的假设 . 这段代码无论如何都会消失 - 我只想了解微软是否允许在 Dispose()
之后访问DataTable,或者是疏忽,而不是关心等等 .
此外,如果您投票或投票关闭它,请留下评论原因 .
3 回答
我认为除了程序员在
IDisposable.Dispose
实现中定义的内容之外,你还可以做任何事情 . 除了提供对using
语句的支持之外,语言或框架不会做任何特殊操作 .使用
using
语句,该语言只提供以下内容:如果您的对象实现了名为IDisposable
的特定接口,则它承诺在using
块存在时调用Dispose
方法 . 通过以特殊方式跟踪处置的物体,'s it. It has no knowledge of which objects have been 1360841 or not. It doesn' t抛出ObjectDisposedException
.是什么抛出
ObjectDisposedException
?那么,实现IDisposable
类型的程序员需要在那里的某处编写这样的代码:所以在你的情况下,如果
ValidationDataTable
以一种在内存中没有数据的方式实现,那么它将像往常一样工作 . 语言或框架并不能阻止这种情况发生 .更新:回答评论,它看起来像
DataTable
不直接实现IDisposable
但它的基类(MarshalByValueComponent
)确实如此 . 他们必须继承该基类才能支持WinForms设计师的体验 . 在设计模式之外,Dispose
不需要在using
块中使用它 .这是正常的吗?不可以 . 通常情况下,
IDisposable
对象应放置在正常生命周期的某个地方 . 有一个不需要处理的IDisposable
肯定令人困惑 .正如Lee在评论中指出的那样,DataTable是一次性的,因为它继承了MarshalByValueComponent . Dispose()本身并不是一个意外事故,但没有什么能阻止框架的后续版本做一些确实导致异常的事情 .
我认为依靠这个是一个坏主意,我会在包装它的使用中移动使用DataTable的代码 .
根据documentation on using:
是的 . 见报价下面 .
不适用
不适用 . 如果查看IDisposable.Dispose(),则表明"Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources."如果可以在没有托管资源的情况下提供功能,则不需要配置对象来阻止访问该功能 .
实现了您正在访问的方法或属性的类的开发人员添加了代码以检测对象是否已被处置并根据需要抛出异常 .
也来自documentation on using:
简而言之,
validationTable
已被释放,不再可以访问其非托管资源,但托管资源(数据的本地副本)仍然可用 . 假设ValidationDataTable
已正确实施 . 由于我没有通过谷歌或msdn找到它,我假设它是一个内部类,所以任何事情都有 .