C#Dispose:处置时和处理它

时间:2012-05-26 19:40:37

标签: c# dispose

我在处理和完成之间陷入了困境。这是我的示例代码:

public class Car:IDisposable
    {
        public string name;
        public Car()
        {
            name = "My Car";
        }
        public void Dispose()
        {
            Console.WriteLine("This object has been disposed");
        }
    }
public static void Main()
        {
            Car anotherCar;
            using (var car = new Car())
            {
                anotherCar = car;
                Console.WriteLine("Before dispose. Name is: "+anotherCar.name);
            }

            Console.WriteLine("After dispose. Name is: "+anotherCar.name);

        }

结果是:

Before dispose. Name is My Car
This object has been disposed
After dispose. Name is My Car

我的问题是:因为C#会在using{}之后自动处理对象,所以我想在第34行"处理后#34;。 anotherCar.name必须为NULL。为什么它仍然是"我的车" ?

我的另一个问题是:我的书说你出于某种原因不应该使用GC.Collect(),其中一个就是性能。那么,谁处置对象?如果那是垃圾收集器,我认为dipose()finalizer()具有相同的性能问题

谢谢:)

3 个答案:

答案 0 :(得分:5)

我认为你误解了Dispose实际上做了什么。它不会破坏您的对象,将任何内容设置为null,或以其他方式执行任何类型的魔法。当您使用using语句时,这只是保证将调用Dispose。您在Dispose方法中执行的操作决定了对象的行为。不是语言或.NET框架。

答案 1 :(得分:4)

如果你再次查看代码,你会立刻意识到简单地在一个类上放置一个Dispose()方法并实现IDisposable并不会添加任何幕后魔法,它只是一个普通的方法,增加了它的便利性在使用声明结束时调用。

通常在Dispose方法中,您应该清除自己想要释放的任何(非托管)资源,例如关闭数据库连接或打开以供读取/保存的文件...

Microsoft对于正确实现IDisposable有一个很好的help page

答案 2 :(得分:2)

.net中的对象通常是类型引用与该类型所需的公共和私有字段的组合(有一些特殊情况,如数组和字符串)。一旦创建,只要存在某种形式的对象,.net中的对象将继续存在。一旦不再有任何对象的引用,如果有效地不再存在;它占用的任何内存都只是未使用的内存,有资格在下一次垃圾收集时重复使用。

Dispose的目的不是要销毁一个对象,而是允许一个对象在它消失之前用外部的东西执行必要的操作。举一个简单的例子,假设一个对象要求远程服务器授予它对文件的独占访问权;服务器提供一个令牌,承诺只允许访问该令牌的代码。如果对象只是消失,外部服务器将保持文件锁定,以便独占使用包含不再存在的令牌的代码。换句话说,文件永远(*)无法被任何人使用。向要求令牌的对象添加Dispose方法将允许对象向服务器发送“Okay - 我已完成文件XYZ1493”消息,从而使该文件可供其他实体使用。

请注意,Dispose方法实际上不会销毁文件对象。它可以提示对象擦除存储在其字段中的一些数据,但只要对其存在任何引用,该对象将继续存在,并且此后将不再存在。在某些情况下,调用对象上的Dispose可能会加速对象本身的消亡,通过询问其他持有对象的外部对象来销毁这些引用。但是,即使在这些情况下,Dispose的目的是允许对象向其他事物发出请求。