Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# NET中的析构函数_C#_Destructor - Fatal编程技术网

C# NET中的析构函数

C# NET中的析构函数,c#,destructor,C#,Destructor,NET很长一段时间了,现在已经开始学习C。我想我可能在几年前问过一件事,得到了答案,但现在已经完全忘记了,因为我没有经常使用析构函数。在学习C#的过程中,我读了一篇关于如何在C#中创建这些的文章,但这让我感到疑惑。假设我实例化了一个类,它有一个对象指向另一个类 Class C1 { // Do something here } Class A { C1 objObjectToClass1 = new C1(); } Class Main { A objObjectToCl

NET很长一段时间了,现在已经开始学习C。我想我可能在几年前问过一件事,得到了答案,但现在已经完全忘记了,因为我没有经常使用析构函数。在学习C#的过程中,我读了一篇关于如何在C#中创建这些的文章,但这让我感到疑惑。假设我实例化了一个类,它有一个对象指向另一个类

Class C1
{
  // Do something here
}

Class A
{
  C1 objObjectToClass1 = new C1();
}   

Class Main
{
   A objObjectToClassA = new A();
}
我将对象
objObjectToClassA
设置为
null
,因为我一直认为这等同于VB.NET中的
object=nothing

objObectToClassA = null;

此操作是否也会销毁
objObjectToClass1

并非如此,否。垃圾收集器将在对象符合收集条件后的一段时间内回收该对象。这可能是在您清除最后一个引用之后,但如果您在某一点之后不再需要该引用,则它可能已经在之前。但通常,将存储实例的字段设置为
null
将有助于对象变得不再可访问并被回收

通常,您无法控制GC何时回收对象。您可以编写终结器,这些终结器是在回收对象之前调用的方法,但如果您能提供帮助,我不推荐使用它。如果需要一个可预测的方法,使对象释放它可能持有的任何资源(C++中的析构函数通常是什么),那么实现:

这还允许您在中使用该类的实例,该类将在其块末尾调用
Dispose

using (var c1 = new C1()) {
  // do stuf with c1 here
} // at this point c1.Dispose() is automatically called

垃圾收集器知道什么时候不再有对对象的引用,就我所知,它甚至会销毁只被另一个对象引用的对象


这意味着,如果取消引用
objObjectToClassA
(将其设置为
null
),如果没有对其中任何一个对象的更多引用,这两个对象都将被销毁。简单地让它超出范围也足够了。

破坏是错误的词,C(据我所知)在C++意义上没有析构函数。不再使用的对象由垃圾收集器收集/销毁


如果没有保留对
objectToClass1
的其他引用,如果将
ObjectToClassa
设置为
null

,则也可以收集
objectToClass1
,但不会立即销毁。在本例中,将变量设置为null意味着您的应用程序不再使用该对象,因此它符合垃圾收集的条件。简单地考虑一下(我相信GC比这更聪明),一旦收集了
objectToClassA
,那么
objectToClass1
就不再被引用,也将被收集


乔伊对IDisposable的评论绝对值得记住;尽量不要考虑C#的决赛选手,因为你无法控制他们何时参赛。使用
IDisposable
将为您提供整理资源所需的控制。

您为什么需要将
objObjectToClassA
设置为
null
,或者使用Destructor?GC没有对未使用的对象进行分类吗?4个DownVotet,没有一个解释?WTF的家伙?没有什么错误,将对象设置为空,并帮助GC标记一个对象,以收集一个真实的不公平的投票,而没有理由在C++意义上完全不公平,但是它确实有一个终结器形式的析构函数,它帮助GC确定了肯定的目标对象集合,否则,我们甚至可以使用DISCOFE来完全抑制终结,这就是为什么我不在C++意义上写的原因。终结器提供了一些类似的功能,但与C++析构函数非常不同。并且终结器也不是确定性的。这不是苹果的比较,因为C++中没有GC用于内存管理,所以不是一个公平的比较。与Java的比较将更加相关。顺便说一句,我没有投反对票。因为OP使用了“析构函数”这个词,所以看起来他很可能来自C/C++并且值得指出其中的区别。为什么我要将它与Java进行比较?这是否意味着将它设置为null将删除任何引用,并将其级联到我设置为null的对象中的所有对象。对不起,我的错误应该用更好的措辞,我知道在GC来收集它之前它仍然存在,但这是我使用VB.NET明确告诉GC我不再使用这个对象的方式之一“通常你没有控制权…”-技术上是这样的。但是既然你说的很笼统,我想你是对的。@altaaf.hussein:将字段设置为
null
将删除一个引用。如果只剩下这一个,那么是的,该对象应该符合收集条件。但是有很多方法可以泄漏实例,例如,通过事件处理程序、闭包等,这些方法都不是很明显。因此,一般来说,将某物设置为
null
不会保证GC收集某个对象实例。@ToastGeret:大多数.NET开发人员都不应该接触这种方法;-)Skeet先生给出了一个很好的例子,说明了什么时候使用GC。Collect在他的应用程序中可能没什么问题。除了.NET对象没有引用计数外;当没有指向根的引用路径时,而不是当对象不再被引用时,对象符合收集条件;我已经删除了引用计数的内容。我真的认为垃圾收集器的工作方式在这里并不重要;关键是垃圾收集器决定何时清理,因此您无法控制Finalizers何时运行。。。
using (var c1 = new C1()) {
  // do stuf with c1 here
} // at this point c1.Dispose() is automatically called