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;
        }
    }
}

그러나 Clauses에서 중 하나를 제거하면 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 Method에서 어떻게해야합니까?

편집 : 전체 FXCOP 오류는 다음과 같습니다.

" 'Wikipage'에 Idisposable을 구현하기 때문에 다음과 같은 idisposable 유형의 구성원을 생성하기 때문에 'Wikitomedatacontext'. 이전에 선적 된 경우,이 유형에 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 데이터 컨텍스트에 대한 폐쇄와 함께. 클로저의 인스턴스에는 Datacontext의 필드가있어 FXCOP 경고를 유발합니다. 이것은 걱정할 것이 없습니다.

DataContext의 인스턴스는 하나 뿐이며 사용 블록을 통해 정리합니다. 클로저에는 파이널 라이저가 없기 때문에 FXCOP 경고에는 성능이나 안전한 영향이 없습니다.

다른 팁

나는 이것이 부분적인 수업임을 알았다. 클래스의 다른 구현 파일을 확인하고 폐기되지 않은 idisposable 멤버가 있는지 확인 했습니까?

나는 여기에서 생성 된 폐쇄가 잘못되었다고 생각하지 않습니다. FXCOP가 이와 같은 경고를 무시하게하는 특정 속성으로 클로저가 생성됩니다.

편집하다

OP에 의한 추가 조사에 따르면 이것은 idisposable 필드가 폐쇄로 들어 올려지는 문제임을 보여주었습니다.

불행히도 이것에 대해 할 수있는 일은 많지 않습니다. 폐쇄를 구현할 수있는 방법은 없습니다. 이벤트 이벤트 클로저 인스턴스에서 idisposable을 호출 할 수있는 방법이 없습니다.

이 문제에 접근하는 가장 좋은 방법은 일회용 가치가 폐쇄에서 캡처되지 않는 방식으로 코드를 다시 작성하는 것입니다. 일회용 필드는 완료되면 항상 폐기해야하며 폐쇄에서 캡처하면이 작업을 수행하지 못하게해야합니다.

방법에서 LINQ 쿼리를 반환하는 경우 소비자는 Foreach를 사용하여 결과를 반복합니다.

소비자가 Foreach 루프를 완료하면 내부적으로 Ienumerable 소스 (이 경우 LINQ 쿼리)를 처리합니다. 이것은 Wikitomedatacontext를 처리합니다.

그러나 소비자가 LINQ 쿼리를 반환하는 메소드를 호출했지만 결과를 반복하지 않으면 열거 가능한 것으로 보이지 않을 것입니다 (즉, 쓰레기 수집가가 객체를 정리할 때까지). 이로 인해 Wikitomedatacontext가 쓰레기 수거까지 폐기되지 않습니다.

이 문제를 해결할 수있는 한 가지 방법은 LINQ 쿼리의 결과에서 .toArray를 호출하고 컨텍스트에 대한 호출 DRISPOS를 한 다음 배열을 반환하는 것입니다.

오류를 제공하는 코드는 wikidatacontext를 사용합니다.

오류를 제공하지 않는 두 가지 예는 wikitomedatacontext를 사용합니다.

어쩌면이 두 가지 사이에는 오류가 발생하는 차이가있을 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top