为什么FxCop的提升错误“类型的拥有一次性字段应该是一次性的”上没有可支配的领域一类?

StackOverflow https://stackoverflow.com/questions/1219086

  •  10-07-2019
  •  | 
  •  

我有添加到它的附加方法的LINQ对象。类没有一次性属性或方法,但FxCop的是提高该错误和“那些拥有一次性字段应该是一次性类型”引用该类。

我已经减少了代码这远和仍然收到错误:

partial class WikiPage
{
    public PagePermissionSet GetUserPermissions(Guid? userId) {
        using (WikiTomeDataContext context = new WikiTomeDataContext()) {
            var permissions =
                from wiki in context.Wikis
                from pageTag in context.VirtualWikiPageTags
                select new {};

            return null;
        }
    }
}

然而,如果删除的从子句EITHER,停止的FxCop给出错误:

partial class WikiPage
{
    public PagePermissionSet GetUserPermissions(Guid? userId) {
        using (WikiTomeDataContext context = new WikiTomeDataContext()) {
            var permissions =
                from pageTag in context.VirtualWikiPageTags
                select new {};

            return null;
        }
    }
}

或者

partial class WikiPage
{
    public PagePermissionSet GetUserPermissions(Guid? userId) {
        using (WikiTomeDataContext context = new WikiTomeDataContext()) {
            var permissions =
                from wiki in context.Wikis
                select new {};

            return null;
        }
    }
}

PagePermissionSet不是一次性的。

这是一个假阳性?抑或是LINQ代码的类莫名其妙地产生一种一次性场?如果它不是一个误报,在的FxCop建议,我实现IDisposable接口,但我会在Dispose方法呢?

编辑: 全FxCop的错误是:

  

“上‘的wiki页面’实现IDisposable,因为它   创建以下的IDisposable类型的成员:   'WikiTomeDataContext'。如果“Wiki页面”以前有   发货,并称实现IDisposable新成员   这种类型被认为是一个重大更改现有   消费者“。

编辑2: 这是反汇编代码引发此错误:

public PagePermissionSet GetUserPermissions(Guid? userId)
{
    using (WikiTomeDataContext context = new WikiTomeDataContext())
    {
        ParameterExpression CS$0$0001;
        ParameterExpression CS$0$0003;
        var permissions = context.Wikis.SelectMany(Expression.Lambda<Func<Wiki, IEnumerable<VirtualWikiPageTag>>>(Expression.Property(Expression.Constant(context), (MethodInfo) methodof(WikiTomeDataContext.get_VirtualWikiPageTags)), new ParameterExpression[] { CS$0$0001 = Expression.Parameter(typeof(Wiki), "wiki") }), Expression.Lambda(Expression.New((ConstructorInfo) methodof(<>f__AnonymousType8..ctor), new Expression[0], new MethodInfo[0]), new ParameterExpression[] { CS$0$0001 = Expression.Parameter(typeof(Wiki), "wiki"), CS$0$0003 = Expression.Parameter(typeof(VirtualWikiPageTag), "pageTag") }));
        return null;
    }
}

修改3: 确实出现了是包含到DataContext的基准的封闭类。下面是其反汇编代码:

[CompilerGenerated]
private sealed class <>c__DisplayClass1
{
    // Fields
    public WikiTomeDataContext context;

    // Methods
    public <>c__DisplayClass1();
}
有帮助吗?

解决方案

我的猜测是,这两个条款From产生一个电话与您的数据上下文封闭到SelectMany。封闭的实例有一个领域是导致的FxCop警告DataContext的。这没什么可担心的。

有只有一个你的datacontext,您通过使用块清理的实例。由于关闭不具备终结有一个在FxCop的警告没有性能或这里saftey含义。

其他提示

我注意到,这是一个局部类。你检查过其他实现文件的类,看看它是否有没有被设置在了IDisposable成员?

我不认为产生闭合这里有毛病。关闭与该应引起FxCop的忽略这样的警告某些属性生成。

修改

由OP进一步调查显示这是与IDisposable的领域中的问题被提升到一个闭合。

不幸的是,不是一大堆你可以做这件事。有没有办法让封闭实现IDisposable。事件如果你能有没有办法来调用IDisposable接口上关闭实例。

要解决这个问题的最好办法是重写代码以这样的方式,一次性价值没有得到在封闭拍摄。当他们完成,并在关闭捕捉它阻止你这样做一次性的字段应该总是布置。

如果你正在返回从你的方法LINQ查询,消费者会遍历使用的foreach的结果。

当消费者完成foreach循环,它在内部调用Dispose了IEnumerable源(在这种情况下,您的LINQ查询)上。这将处置WikiTomeDataContext。

然而,如果消费者作出方法的调用返回LINQ查询,但从未遍历的结果,它会出现枚举永远不会被设置(即,直到垃圾收集器清理对象)。这将导致你的WikiTomeDataContext没有被设置到垃圾收集。

您也许能够解决这个问题的方法之一是通过调用.ToArray你的LINQ查询的结果,调用Dispose您的上下文,然后返回数组。

您的代码,提供了错误使用WikiDataContext。

您两个例子不给出错误使用WikiTomeDataContext。

也许在这两个之间的一些差异,导致该错误。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top