2011-09-21 48 views
7

开启代码分析在VS建议调用Dispose对象上(这点我是不previuosly)我结束了包含此方法:设置一HTMLControl时

using (var favicon = new HtmlLink 
         { 
          Href = "~/templates/default/images/cc_favicon.ico" 
         }) 
{ 
    favicon.Attributes.Add("rel", "shortcut icon"); 
    Header.Controls.Add(favicon); 
} 

这个困惑我咯,如果在将它添加到Controls集合之后处理这个对象是个好主意吗?

这是如何工作的?是否因为Controls.Add方法在使用后放置对象而不是坚持使用它?

+2

R#真的建议你应该配置'HtmlLink'吗?你可以截图吗?这不应该发生。 – bzlm

+0

@bzlm,我会换个话题,它给了我重新使用的选择,对于混淆抱歉。 – Mantorok

+1

那么你的担心是正确的。您不应该处理添加到控件集合的ASP.NET Web窗体控件。作为一般说明,R#提供的选项并不总是适用的;你应该谨慎使用它们。 :)如果您尝试在代码中输入许多不同的东西,您很快就会注意到这一点。 – bzlm

回答

2

我要说的是,这个代码不应该工作,但如果你说这是工作的话,我能想到的唯一的事情是:

  • Header.Controls.Add添加对象的副本使处理原件没有问题。
  • Dispose方法不会清除以后使用的任何内容。

希望这会有所帮助。

+3

它是后者添加不复制对象 –

+0

不知道为什么有人低估了我。我想争论你为什么认为我的回答不正确。请告诉我。 –

+0

我没有让你失望,但猜测DV可能是因为第一个项目符号不正确 –

1

如果使用任何非托管资源调用favicon上的方法,它将会发出异常。

从MSDN:

您可以实例化资源对象,然后传递变量 using语句,但这并不是最好的做法。在这种情况下, 对象在控制离开使用块(即使 )后仍保留在范围内,尽管它可能不再有权访问其非托管 资源。换句话说,它将不再完全初始化。如果 您尝试使用使用块之外的对象,则可能会导致引发 异常。由于这个原因, 实例化using语句中的对象并将其范围限制为 using块通常更好。

using statement msdn

+0

这很有趣,因为每个控件在ASP.Net中都有一个Render方法,那么它是如何在一个处理对象上实现的呢? – Mantorok

+0

是的,如果它仍然有效,你就是幸运的。它可以打破任何更新或稍后更改。 – Peter

+1

你认为Code Analysis知道吗?或者它只是运气!? – Mantorok

0

我假设你在更改代码之前给你的代码分析给了你CA2000: Dispose objects before losing scope。问题是,即使从方法返回后(它已被添加到集合中),您也不应该丢弃对象,因为您要使用它。

您可以使用SuppressMessage attribute消息打压,或者你可以重写你的代码是真正的偏执:

var favicon = new HtmlLink { Href = "~/templates/default/images/cc_favicon.ico" }; 
try { 
    favicon.Attributes.Add("rel", "shortcut icon"); 
} 
catch { 
    favicon.Dispose(); 
    throw; 
} 
Header.Controls.Add(favicon); 

这段代码的正常流动增加favicon到随后的处置它负责收集。但是,异常流程favicon.Attributes.Add引发异常将在传播异常之前处理favicon

在大多数情况下,因为垃圾收集器最终会完成它的工作,所以你不需要偏执狂版本的代码。