抑制lambda上的Microsoft.Reliability警告

时间:2012-11-23 12:00:20

标签: c# idisposable fxcop

我在类似单身的类中得到了以下代码:

    private readonly Lazy<IWindsorContainer> LazyContainer =
        new Lazy<IWindsorContainer>(() => new WindsorContainer().Install(new WindsorInstaller()));

并且考虑到WindsorContainer确实需要发布,我稍后会在主机中这样做,所以我很自然地想要压制淘气的Microsoft.Reliability警告IDisposable可能没有发布。问题是它是在lambda中创建的,看起来像SuppressMessage对它没有任何影响,我绝对不希望它在整个类中。

我在构造函数中使用抑制属性来解决这个问题。但仍然不满意。

我错过了什么或者SuppressMessage没有赶上c#的演变吗?

2 个答案:

答案 0 :(得分:2)

我认为它正在考虑调用Install()失败的可能性,然后尚未处理尚未分配给任何变量的容器。你可以在那里添加一个try / catch,使表达式更加冗长但符合规则(未经过测试,但你会明白这一点):

private readonly Lazy<IWindsorContainer> LazyContainer =
    new Lazy<IWindsorContainer>(() => { 
        var container = new WindsorContainer();
        try { container.Install(new WindsorInstaller())); }
        catch { using(container) {} throw; }
        return container; });

答案 1 :(得分:0)

正如fsimonazzi正确地指出这是关于调用新的WindsorContainer()。安装(新的WindsorInstaller())在将它保存到成员变量之前使用IDisposable(因此不能保证它将永远存在)。

对于我自己,我决定将事情重构为以下内容:

class Program : IDisposable
{

    private Disposo _disposo = new Disposo();
    //private Disposo _disposo = new Disposo().Yeah(); // this will cause warning

    public Program()
    {
        _disposo.Yeah(); // this will not
    }

    public void Dispose()
    {
        if (_disposo != null)
        {
            _disposo.Dispose();
            _disposo = null;
        }
    }

    static void Main(string[] args)
    {
        using (var p = new Program()) { }
    }
}

class Disposo : IDisposable
{
    public void Dispose() { }

    public Disposo Yeah() { return this; }
}

和某处

    private static readonly Lazy<Program> LazyInstance = new Lazy<Program>();

道德?尽管声称“CA2000:在所有引用之前处置对象超出范围”。被打破,可以被忽视和压制,情况并非总是如此。