gpt4 book ai didi

c# - using block 中的对象初始值设定项生成代码分析警告 CA2000

转载 作者:IT王子 更新时间:2023-10-29 04:47:52 27 4
gpt4 key购买 nike

如果我在 using block 中使用对象初始值设定项,我会收到有关未正确处理对象的代码分析警告:

CA2000:Microsoft.Reliability:在方法“ReCaptcha.CreateReCaptcha(this HtmlHelper, string, string)”中,对象“<>g__initLocal0”未沿所有异常路径放置。在对象“<>g__initLocal0”的所有引用超出范围之前调用 System.IDisposable.Dispose。

代码如下:


using (var control = new ReCaptchaControl()
{
ID = id,
Theme = theme,
SkipRecaptcha = false
})
{
// Do something here
}

如果我不使用对象初始值设定项,代码分析很高兴:


using (var control = new ReCaptchaControl())
{
control.ID = id;
control.Theme = theme;
control.SkipRecaptcha = false;

// Do something here
}

这两个代码块有什么区别?我认为它们会产生相同的 IL。或者这是代码分析引擎中的错误?

最佳答案

不,有区别。

对象初始值设定项仅在所有属性都已设置后才分配给变量。换句话说,这:

Foo x = new Foo { Bar = "Baz" };

相当于:

Foo tmp = new Foo();
tmp.Bar = "Baz";
Foo x = tmp;

这意味着如果其中一个属性 setter 在您的情况下抛出异常,则该对象将不会被释放。

编辑:如我所想...试试这个:

using System;

public class ThrowingDisposable : IDisposable
{
public string Name { get; set; }

public string Bang { set { throw new Exception(); } }

public ThrowingDisposable()
{
Console.WriteLine("Creating");
}

public void Dispose()
{
Console.WriteLine("Disposing {0}", Name);
}
}

class Test
{
static void Main()
{
PropertiesInUsingBlock();
WithObjectInitializer();
}

static void PropertiesInUsingBlock()
{
try
{
using (var x = new ThrowingDisposable())
{
x.Name = "In using block";
x.Bang = "Ouch";
}
}
catch (Exception)
{
Console.WriteLine("Caught exception");
}
}

static void WithObjectInitializer()
{
try
{
using (var x = new ThrowingDisposable
{
Name = "Object initializer",
Bang = "Ouch"
})
{
// Nothing
}
}
catch (Exception)
{
Console.WriteLine("Caught exception");
}
}
}

输出:

Creating
Disposing In using block
Caught exception
Creating
Caught exception

请注意没有“Disposing Object initializer”行。

关于c# - using block 中的对象初始值设定项生成代码分析警告 CA2000,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3514902/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com