![]() |
1
21
以下几点:
打电话
对于编译器如何处理,没有明确而明显的机制。
例如,考虑采用
我称之为:
现在,我可能想要也可能不想要
同样,对于从构造函数以外的东西中检索到的实例,比如
提供用户控制权(并提供类似
最后,按照惯例,有两个原因可以实施
在第一种情况下,所有此类类型都应该实现调用
|
![]() |
2
16
让我再说一遍。自动呼叫
如果您有以下代码:
编译器如何知道何时使用
显式调用
现在,回到表演上来。简单呼叫
当使用未管理的资源时,性能会提高。如果托管对象没有正确地处置其未托管的资源,则会出现内存泄漏。丑陋的东西。
留下打电话的决心
|
![]() |
3
3
您要求编译器对代码执行语义分析。在源代码的某个点之后没有显式引用某个内容,这并不意味着它没有被使用。如果我创建一个引用链,并将其传递给一个方法,该方法可能或可能不会将该引用存储在属性或其他持久性容器中,那么我真的应该期望编译器跟踪所有这些内容并找出我真正需要的内容吗? 意味 ? 不稳定的实体也可能是一个问题。
此外,
作为工程师或程序员,我们努力做到 有效率的 但这与 懒惰的 . |
![]() |
4
3
看看
MSDN Artilce for the C# Using Statement
这个
如你所见,使用被翻译成。
编译器如何知道将finally块放在哪里?它在垃圾收集时调用它吗? GarabageCollection不会在您离开方法后立即发生。读这个 article 对垃圾收集有更好的了解。只有在没有对对象的引用之后。资源的占用时间可能比需要的时间长得多。 我一直在想,编译器不应该保护那些不清理资源的开发人员。仅仅因为语言是被管理的并不意味着它会保护自己。 |
![]() |
5
2
C++支持这一点;它们称之为“引用类型的堆栈语义”。我支持将它添加到C,但它需要不同的语法(根据是否将局部变量传递给另一个方法来更改语义不是一个好主意)。 |
![]() |
6
2
我认为你正在考虑定稿。终结器使用C中的析构函数语法,垃圾收集器会自动调用它们。终结器只适合在清理非托管资源时使用。 Dispose旨在允许对非托管资源进行早期清理(它也可用于清理托管资源)。 检测实际上比看起来更难。如果你有这样的代码怎么办:
Amethod中的一些代码可能保留了对MyDisposable的引用。
所有这些都使绝对确定您的对象不再使用变得困难,因此Dispose是为了让开发人员说“好的,我知道现在运行清理代码是安全的”); 还要记住,Dispose不会释放对象——只有GC可以这样做。(GC确实具有理解我描述的所有场景的魔力,它知道何时清理对象,如果您确实需要在GC检测不到引用时运行代码,则可以使用终结器)。不过,请注意终结器——它们只用于类所拥有的非托管分配。 您可以在此处阅读更多关于此内容的信息: http://msdn.microsoft.com/en-us/magazine/bb985010.aspx 这里: http://www.bluebytesoftware.com/blog/2005/04/08/DGUpdateDisposeFinalizationAndResourceManagement.aspx 如果需要非托管句柄清理,请阅读有关SafeHandles的内容。 |
![]() |
7
1
这不是 编译程序 解释应用程序中的作用域,并执行类似于确定何时不再需要内存的操作。事实上,我很确定这是一个不可能解决的问题,因为编译器不可能知道你的程序在运行时会是什么样子,不管它有多聪明。 这就是我们收集垃圾的原因。垃圾收集的问题在于它以不确定的间隔运行,通常如果对象实现IDisposable,原因是您希望能够立即处理它。像, 马上 立即。像数据库连接这样的构造不仅仅是一次性的,因为当它们被丢弃时,它们还有一些特殊的工作要做——这也是因为它们是稀缺的。 |
![]() |
8
0
对于G.C.来说,我似乎很难知道稍后在同一方法中将不再使用这个变量。显然,如果您离开该方法,并且不保留对变量的进一步引用,那么G.C.将处理它。但使用
|
![]() |
9
0
这个 using statement 与性能无关(除非考虑将避免资源/内存泄漏作为性能)。 它为您所做的一切就是确保当相关对象超出范围时,即使在using块内发生异常,也会对该对象调用IDisposable.Dispose方法。 然后,dispose()方法负责释放对象使用的任何资源。这些通常是非托管资源,如文件、字体、图像等,但也可以是托管对象上的简单“清理”活动(但不是垃圾收集)。 当然,如果Dispose()方法实现得不好,那么using语句就没有任何好处。 |
![]() |
10
0
我认为OP是在说“当编译器可以很容易地神奇地解决问题时,为什么还要“使用”呢?” 我想手术室是这么说的
应等于
因为foo不再使用了。 当然,答案是编译器不能很容易地解决问题。垃圾收集(在.NET中神奇地称为“dispose()”)是一个非常复杂的字段。仅仅因为下面没有使用符号,这并不意味着变量没有被使用。 举个例子:
在这个例子中,somerandomObject和someotherClass 可以 两者都引用了foo所指出的内容,所以如果我们调用foo.dispose(),就会破坏它们。你说你只是在想象一个简单的例子,但是唯一一个“简单的例子”就是你所提议的方法有效,你不从foo调用任何方法,也不将foo或它的任何成员传递给任何其他东西——实际上,当你根本不使用foo的时候,在这种情况下,你可能不需要声明它。即使在那时,你也不能确定某种反射或事件黑客并没有仅仅通过它的创建就获得对foo的引用,或者foo在其构造过程中没有连接到其他东西上。 |
![]() |
11
0
除了上面列出的细微原因之外,由于问题在所有情况下都无法可靠地解决,所以这些“简单”的情况是代码分析工具能够并且确实能够检测到的。让编译器确定性地做一些事情,让你的自动代码分析工具告诉你什么时候你在做一些愚蠢的事情,比如忘记调用Dispose。 |