我 草
  .net里面的所有代码都经过托管来编译和运行,任何函数或者方法都会占用内存,当然相应的也有托管内存了。
   Dataset继承了六个派生类,包括百多个实体或虚拟函数,可不止IDispose

解决方案 »

  1.   

    DataSet要支持序列化,所以继承于MarshalByValueComponent
    而MarshalByValueComponent需要dispose
      

  2.   

    说什么“IDisposable接口是用来释放非托管资源的内存”的,基本上都是在瞎说,绝无直接的根据。根本不是为了这个目的。如果一个托管对象,你需要用代码提前调用其Close之类的方法(而不是等到GC清理它的时候自动调用),那么它通常就会有这个接口。例如需要及时向数据库连接池归还连接对象、需要及时将加锁的缓冲数据去除独占、需要及时关闭正在访问的文件、需要及时给对方发送“网络关闭”消息、需要及时通知性能分析机制以便更准确地统计时间、当系统及其容易崩溃时需要及时保存当时的运行状态、需要让系统界面及时地画上一个通知界面,等等。这些基本上都是业务逻辑需要,只有极其个别的东西才是涉及到必须“释放非托管资源”。看不到业务逻辑需要 IDisposable 接口,就好像只能看到“c这一片叶子”而看不到“c#这一片树林”一样。
      

  3.   

    当你写一个数据展现对象,例如叫做 MyDataReport,你写了一堆处理方法并且把它适配给不同的界面和通讯平台以后,你会考虑给它写一个类似 Close 这样的方法吗?你会想到要研究出来几个测试用来来利用和测试这个 Close 方法吗?那么你就可以考虑更加规范的 IDisposable 接口习惯。并且进一步地你可以使用到 using(...){} 之类的编程语法。因为你标记出了 IDisposable 这个习惯的接口,成文自明,用不着写什么累赘的文字注释。
      

  4.   

    其实还有很多类型实现了IDisposable只是为了可以使用using语法
      

  5.   

    托管下又有几个功能是直接利用托管做的?目前情况下,你所说的功能包括关闭网络,文件啦之类,又有哪一个是直接用托管做到的?底层还不是调用win api,所以归根到底还是非托管资源的访问
      

  6.   

    我特别要强调的是,这个接口跟什么“释放内存”的关系,基本上根本扯硬性关系。因为 GC 在清理对象时,会首先判断对象是否有这个接口,如果有则会先去调用其 dispose 方法,然后才释放所占用的内存。因此,GC会自动调用这个接口,用不着你去画蛇添足地调用它。有些人望文生义,“disposeable意思就是释放啊?!”,“而释放的意思就是(他觉得更加时髦的c语言最初级的初学者必定学到的那个词儿,也就是)释放内存啊?!”。实际上 IDisposable 不是这个功能。根本不能把 .net 跟低级的东西划等号。
      

  7.   


    晕!我们这里所说的是 IDisposable 是否是等于“释放”非托管资源?如果我在代码中写var file =  File.Open(....);
    file.Write(....);
    file.Close();
    那么我写了什么 IDisoiseable 接口实现了吗?根本没有!我当然调用了windows api,这是废话了。我们这里说的是,我根本没有去搞什么 IDisposable 接口,甚至就算是我不去调用 file.close 语句的话,它也会过几秒钟自动释放。因此,IDisposable 的作用并不是等价于专门干这种事情的,而是真正用来实现各种业务逻辑上需要的任何一种关闭行为的(包括释放某些非托管资源)。
      

  8.   

    这里说的,之所以许多.net里的类型的设计上会使用这个接口,是要了解 IDisposable 接口是干什么的,不是要把这个接口非纠缠在什么“非托管资源”上而津津乐道。
      

  9.   

    大神,我还是有点不明白, Dispose的存在,没有手动去调用,反而会导致两次的回收才能释放对象
    那实现的必要在哪里的,就像DataSet的Dispose,那其实当适配器给DataSet填充完毕后就已经将连接关闭了,并且向连接池归还了连接对象,那Dispose还有什么存在的必要呢?
      

  10.   

    你说的不能算答案,我说的亦是如此.net是微软推出,应该听听他如何去说,而不是凭自己的想象,在此瞎说!
    IDisposable 接口 Visual Studio 2013Visual Studio 2013 本文内容已由机器翻译。如果您连接了 Internet,请选择“联机查看本主题”以在可编辑模式下对照英文内容查看此页。
    向 Microsoft 发送有关本主题的反馈。 联机在默认浏览器中联机查看本主题。 
    定义一种释放分配的资源的方法。
    命名空间:   System 
    程序集:mscorlib(在 mscorlib.dll 中) 
    语法
    --------------------------------------------------------------------------------JavaScriptC#C++F#JScriptVB以带有颜色区分的格式查看复制到剪贴板[ComVisibleAttribute(true)]
    public interface IDisposable[ComVisibleAttribute(true)]
    public interface IDisposable
    [ComVisibleAttribute(true)]
    public interface class IDisposable[ComVisibleAttribute(true)]
    public interface class IDisposable
    [<ComVisibleAttribute(true)>]
    type IDisposable =  interface end[<ComVisibleAttribute(true)>]
    type IDisposable =  interface end
    '声明 
    <ComVisibleAttribute(True)> _
    Public Interface IDisposable'声明 
    <ComVisibleAttribute(True)> _
    Public Interface IDisposableIDisposable 类型公开以下成员。方法
    --------------------------------------------------------------------------------显示: 继承的保护
    没有与当前筛选器匹配的成员
     名称 说明 
    公共方法 由 XNA Framework 提供支持 受 可移植类库 支持 受 适用于 Windows 应用商店应用的 .NET 支持 Dispose 执行与释放或重置非托管资源相关的应用程序定义的任务。 
    页首
    备注
    --------------------------------------------------------------------------------此接口的主要用途是释放非托管资源。 当不再使用托管对象时,垃圾回收器会自动释放分配给该对象的内存。 但无法预测进行垃圾回收的时间。 另外,垃圾回收器对窗口句柄或打开的文件和流等非托管资源一无所知。将此接口的 Dispose 方法与垃圾回收器一起使用来显式释放非托管资源。 当不再需要对象时,对象的使用者可以调用此方法。向现有类添加 IDisposable 接口是重大的更改,因为这更改了类的语义。重要说明 重要事项 
    C++ 程序员应当阅读 析构函数和终结器在 Visual C++。 在 .NET Framework 版本中,C++ 编译器为实现资源的确定释放提供支持,同时不允许 Dispose 方法的直接实现。
     有关如何使用此接口和 Object.Finalize 方法的详细讨论,请参见 垃圾回收和 实现 Dispose 方法主题。调用 IDisposable 接口
    在调用可实现 IDisposable 接口的类时,请使用 try/finally 模式来确保非托管资源能够释放出来,即使应用程序因出现异常而中断也是如此。有关 try/finally 模式的更多信息,请参见 Try...Catch...Finally 语句 (Visual Basic)、 try-finally(C# 参考)或 尝试最终语句(c)。请注意,您可以使用 using 语句(在 Visual Basic 中为 Using)来代替 try/finally 模式。 有关更多信息,请参见 Using 语句 (Visual Basic) 文档或 using 语句(C# 参考) 文档。
      

  11.   


    晕!我们这里所说的是 IDisposable 是否是等于“释放”非托管资源?如果我在代码中写var file =  File.Open(....);
    file.Write(....);
    file.Close();
    那么我写了什么 IDisoiseable 接口实现了吗?根本没有!我当然调用了windows api,这是废话了。我们这里说的是,我根本没有去搞什么 IDisposable 接口,甚至就算是我不去调用 file.close 语句的话,它也会过几秒钟自动释放。因此,IDisposable 的作用并不是等价于专门干这种事情的,而是真正用来实现各种业务逻辑上需要的任何一种关闭行为的(包括释放某些非托管资源)。其实你说的我有点认同的,但是实现了Dispose的时候,你忘记了手动调用,就可能导致了2次的回收才能释放,那为什么要实现Dispose, 去掉Dispose直接给个Close方法实现同样的功能啊
    难道或许这是为了遵循统一的模式?
      

  12.   

    你这个回答,也太搞了吧,哪有这样的可能,实现Dispose可是有代价的,难道微软只是为了又这个语法去实现Dispose, 你觉得这样有意义吗,
    using的语法,因为Dispose的实现,才产生出来的,这样为了防止你万一忘记去调用Dispse,那么有了这个语法,最后编译好的代码,就默认给你调用Dispose
      

  13.   

    你这个回答,也太搞了吧,哪有这样的可能,实现Dispose可是有代价的,难道微软只是为了又这个语法去实现Dispose, 你觉得这样有意义吗,
    using的语法,因为Dispose的实现,才产生出来的,这样为了防止你万一忘记去调用Dispse,那么有了这个语法,最后编译好的代码,就默认给你调用Dispose实现IDisposable会有什么代价??
      

  14.   

    你这个回答,也太搞了吧,哪有这样的可能,实现Dispose可是有代价的,难道微软只是为了又这个语法去实现Dispose, 你觉得这样有意义吗,
    using的语法,因为Dispose的实现,才产生出来的,这样为了防止你万一忘记去调用Dispse,那么有了这个语法,最后编译好的代码,就默认给你调用Dispose
    前边已经告诉你了,dataset 继承于 MarshalByValueComponent
    MarshalByValueComponent 和远程调用有关,以前好像叫remoting,现在叫什么不清楚,既然是远程调用,可能会跨进程,甚至跨机器,所以MarshalByValueComponent肯定要涉及非托管的资源,所以它需要实现IDisposeable。
    至于MarshalByValueComponent如何使用非托管资源,我对这方面没有太详细的研究,你可以查一下msdn 
      

  15.   

    而且你要知道MarshalByValueComponent之类的对象不是直接由开发人员直接控制生死的,而是由框架来管理的,所以这个对象关闭用close,另外一个用dispose等等,框架将无法处理,想你所说要遵循某种规范。
      

  16.   

    这位“大师”貌似很厉害的一样,每次看到这个“胖子”头像回复,我都想笑,他总是想显示出与众不同的样子。msdn里说得那么明白,还要自己搞一套说法,咬文嚼字。
      

  17.   

    你这个回答,也太搞了吧,哪有这样的可能,实现Dispose可是有代价的,难道微软只是为了又这个语法去实现Dispose, 你觉得这样有意义吗,
    using的语法,因为Dispose的实现,才产生出来的,这样为了防止你万一忘记去调用Dispse,那么有了这个语法,最后编译好的代码,就默认给你调用Dispose实现IDisposable会有什么代价??
    你不知道实现该接口,是需要两次垃圾回收才有可能清除内存吗?
      

  18.   

    你这个回答,也太搞了吧,哪有这样的可能,实现Dispose可是有代价的,难道微软只是为了又这个语法去实现Dispose, 你觉得这样有意义吗,
    using的语法,因为Dispose的实现,才产生出来的,这样为了防止你万一忘记去调用Dispse,那么有了这个语法,最后编译好的代码,就默认给你调用Dispose实现IDisposable会有什么代价??
    你不知道实现该接口,是需要两次垃圾回收才有可能清除内存吗?那是你自己设想的吧,有什么微软官方的根据吗?
      

  19.   

    你这个回答,也太搞了吧,哪有这样的可能,实现Dispose可是有代价的,难道微软只是为了又这个语法去实现Dispose, 你觉得这样有意义吗,
    using的语法,因为Dispose的实现,才产生出来的,这样为了防止你万一忘记去调用Dispse,那么有了这个语法,最后编译好的代码,就默认给你调用Dispose
    实现IDisposable会有什么代价??
    你不知道实现该接口,是需要两次垃圾回收才有可能清除内存吗?那是你自己设想的吧,有什么微软官方的根据吗?
    我靠,大哥,我估计你是没看过CLR这本书,这里面讲的很清楚,你回头去看看。
      

  20.   

    你这个回答,也太搞了吧,哪有这样的可能,实现Dispose可是有代价的,难道微软只是为了又这个语法去实现Dispose, 你觉得这样有意义吗,
    using的语法,因为Dispose的实现,才产生出来的,这样为了防止你万一忘记去调用Dispse,那么有了这个语法,最后编译好的代码,就默认给你调用Dispose
    实现IDisposable会有什么代价??
    你不知道实现该接口,是需要两次垃圾回收才有可能清除内存吗?那是你自己设想的吧,有什么微软官方的根据吗?
    我靠,大哥,我估计你是没看过CLR这本书,这里面讲的很清楚,你回头去看看。GC只会调用析构函数,不会调用Dispose,为什么会有什么两次回收?
      

  21.   

    你这个回答,也太搞了吧,哪有这样的可能,实现Dispose可是有代价的,难道微软只是为了又这个语法去实现Dispose, 你觉得这样有意义吗,
    using的语法,因为Dispose的实现,才产生出来的,这样为了防止你万一忘记去调用Dispse,那么有了这个语法,最后编译好的代码,就默认给你调用Dispose
    实现IDisposable会有什么代价??
    你不知道实现该接口,是需要两次垃圾回收才有可能清除内存吗?那是你自己设想的吧,有什么微软官方的根据吗?
    我靠,大哥,我估计你是没看过CLR这本书,这里面讲的很清楚,你回头去看看。GC只会调用析构函数,不会调用Dispose,为什么会有什么两次回收?
    呵呵,好像是我理解错了,有析构函数才会两次。