为什么FxCop的提升错误“类型的拥有一次性字段应该是一次性的”上没有可支配的领域一类?
-
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。
也许在这两个之间的一些差异,导致该错误。