C# 是使用“创建”创建的对象;内联“;自动处理新语句?
以下代码片段取自上的C# 是使用“创建”创建的对象;内联“;自动处理新语句?,c#,C#,以下代码片段取自上的ComboBox::DrawItem实现示例: 我对这部分提出质疑:newsolidbrush(animalColor) 由于这既不是故意指定的Dispose,也不是使用将其包装在中,因此我假设这也是一个形式不佳的示例,因为将创建SolidBrush对象,并且永远不会对其进行处理 我总是在这样一种假设下工作,即我必须直接使用上述处理机制之一,否则就有内存泄漏的风险 我是对的,还是有一些我不知道的更深层次的隐含处理?可能是因为它从未分配给变量?与所有托管对象一样,它会自动释放。
ComboBox::DrawItem
实现示例:
我对这部分提出质疑:newsolidbrush(animalColor)
由于这既不是故意指定的Dispose
,也不是使用将其包装在中,因此我假设这也是一个形式不佳的示例,因为将创建SolidBrush
对象,并且永远不会对其进行处理
我总是在这样一种假设下工作,即我必须直接使用上述处理机制之一,否则就有内存泄漏的风险
我是对的,还是有一些我不知道的更深层次的隐含处理?可能是因为它从未分配给变量?与所有托管对象一样,它会自动释放。这是了解.NET和C#的一个关键方面
然而,这可能不会及时完成。由于这个对象使用的是系统资源,所以实际上我并不认为这是一个好的表单。 < P>我应该说这是MSDN的一个很差的例子。你应该处置它;不会自动处置任何对象
它不一定是泄漏,Brush
实现了一个终结器
,当垃圾被收集时,它将处理它
,但你不应该依赖它。应该处理该对象,是的
也就是说,如果处置某些轻质物体确实不方便,那么不处置这些物体是一种有效的做法<代码>任务
就是一个很好的例子。WPF中的SolidColorBrush
可能相当轻。如果您确定不会“泄漏”太多,那么这段代码就可以了
请记住,在此处添加处理机制(例如使用
)会使代码混乱。这显然是这样做的一个(小)缺点。它应该在中使用
语句,或者它应该显式调用Dispose
,但是
SolidBrush
类继承定义了析构函数/finalize的Brush
类:
来源于
/**
*对象清理
*/
///
///
///
///释放为此分配的内存。
///
///
~Brush()
{
处置(虚假);
}
一旦类的对象SolidBrush
超出范围,最终将调用其析构函数。此时,Dispose
将被调用以释放任何未绑定的资源
见:
析构函数隐式调用
反对
依赖析构函数/终结器的唯一问题是,您无法预测对象最终何时被释放 我很确定这是MSDN的另一个坏代码示例。他们的例子中充斥着未经处理的对象。许多.NET程序员多年来都编写过这样的代码,但从未意识到处理它可能很重要。他们将很容易地摆脱它,它是一个非常短暂的对象,下一代GC和finalizerpass将释放它。直到他们开始修补位图,它才会受到伤害。我不认为有任何API级别的保证也会释放非托管资源,尽管一个合理的实现会这样做。它不会被自动处理。如果它有一个终结器(并且有资格进行垃圾收集),它将被终结,但这与被处置的情况不同。我在哪里说过可以保证释放非托管资源?我说的是托管对象。而且,是的,任何合理的实现都有希望处理任何非托管资源。@JonSkeet:当对象被释放时,任何合理的实现都不会执行任何dispose操作吗?你是说上面的代码永远不会释放系统笔刷对象吗?@JonathanWood:Jon的评论是针对你的术语的。一个包含非托管或稀缺资源的对象的合理实现将提供一个终结器,以确保最终释放资源,无论程序员是否调用IDisposable.Dispose()。这与“处置”对象不同。该对象最终将被处置,因为它实现了一个确保处置的终结器。见@Habib的答案。然而,如果不检查源代码,人们就不可能知道,当然,.NET的一些实现可能会有所不同。@EricJ。我在回答中已经提到了这一点。你在哈比卜的回答中看到了什么不同?还请注意终结器不会始终运行。“依赖析构函数/终结器的唯一问题是,您无法预测对象最终何时被处置。”-考虑到这些对象通常是在
OnPaint
处理程序中创建的,可能会很快被多次调用,这可能是一个大问题。
e.Graphics.FillRectangle(new SolidBrush(animalColor), rectangle);
/**
* Object cleanup
*/
/// <include file='doc\Brush.uex' path='docs/doc[@for="Brush.Finalize"]/*' />
/// <devdoc>
/// <para>
/// Releases memory allocated for this <see cref='System.Drawing.Brush'/>.
/// </para>
/// </devdoc>
~Brush()
{
Dispose(false);
}