C#中使用和obj以及直接构造函数之间的区别

时间:2013-07-22 11:29:28

标签: c# .net oop object constructor

假设我有一个名为“ABC”的类

Class ABC:IDisposable
{
    public string name {get;set;}
    public string Method1()
    {
    // Implements 
    }
    //end of class
}

我从其他人那里听说你应该总是继承IDisposable来释放内存创建上面这类的对象:

using(ABC objABC = new ABC())
{
  objABC.Method1();
}

但是还有其他方法可以调用和使用上面的类和方法,例如

private string testmethods()
{
    ABC objABC = new ABC();
    string test =  objABC.Method1();
    // I want to know this above `objABC` 's memory is free after finish `testmethods()`?
    // we can also call using this like below
    string test2 = new ABC().Method1();
}

我想知道实现这一目标的最佳途径是什么?

我还想知道,testmethods()来电结束后对象内存会自动清除吗?

4 个答案:

答案 0 :(得分:6)

假设ABC没有保留任何非托管资源,则不需要实现IDisposable。一旦没有对它们的实时引用,C#中的对象就有资格进行垃圾收集,当垃圾收集器运行时,它们使用的内存将自动释放。

如果您的类只拥有需要释放的非托管资源,或者拥有其他实现IDisposable的托管对象,那么它们只需要实现IDisposable。如果您的类拥有非托管资源,那么如果在收集Dispose之前未调用objABC,则还应实施finalizer以释放它们。

因此,第二种方法是首选方法,objABC.Method1在{{1}}返回后有资格进行收集(实际上可以尽快收集,但这是一种内部GC机制)。请注意,它不会在此时自动释放,但仅在GC下次运行时才会释放,假设没有更多的引用。

答案 1 :(得分:5)

存在Disposable pattern以释放非托管资源。因此,除非您的C#程序调用某些本机API,或者使用自己实现Disposable模式的类,让您的类实现IDisposable并始终使用using处理它是完全没有意义的。

答案 2 :(得分:2)

IDisposable接口设计用于支持Disposable模式,用于显式释放除内存资源之外的 :因为垃圾收集器(GC)只能处理内存,其他资源如打开文件,数据库连接,各种不受管理 资源等应该明确关闭。

http://msdn.microsoft.com/en-us/library/fs2xkftw.aspx

使用IDisposable的典型方案是

  // MyResourceWrapper is IDisposable
  using (MyResourceWrapper wrapper = new MyResourceWrapper()) { // <- acquire resource
    ... // <- work with resource
  } // <- free resource   

例如

  String text;

  using (StreamReader sr = new StreamReader(@"C:\MyText.txt")) { // resource (file stream) opened
    text = sr.ReadToEnd(); // <- resource (file stream) utilized (read)
  } // <- resource freed (file stream closed)

如果您的班级中没有任何资源可供使用,则无需实施IDisposable

答案 3 :(得分:1)

首先问自己 - 你会在问题的第二个代码部分写一个try-finally块吗?如果是,那么你会在finally块中写什么?如果您的ABC类正在使用非托管资源,并且它实现了IDisposable接口,那么您将在finally块中调用Dispose方法。

using(ABC objABC = new ABC())
{
  objABC.Method1();
}

相当于: -

ABC objABC = new ABC()
try
{
   objABC.Method1();
}
finally
{
   objABC..Dispose()
}

现在,如果您没有在ABC类中处理任何非托管的内容,为什么要在此类上实现IDisposable接口?

具有非托管资源的类的示例是实现IDisposable的SqlConnection,并且在其Dispose方法中它处理所有这些非托管资源。这就是为什么你看到人们使用如下代码: -

using (SqlConnection connection = new SqlConnection(connectionString))
{
...........
}