2009-12-08 3 views
0

나는 코드 러시와 리팩토링 프로 (ReSharper와 같은 가능한 코드 문제 등을 강조 표시)를 사용하고 있으며, 사람들에게 알려지지 않은 지역민 (IDisposable 구현)이 있다는 말을 들었습니다. 이 솔루션에서 분명히.NET IDisposable 인라인 temps

using (Reports.StudentRegisters.StudentQueriesDataTable studentDataTable = new Reports.StudentRegisters.StudentQueriesDataTable()) 
     { 
       try 
       { 
        (new StudentQueriesTableAdapter()).FillByQAbsenceRegRow(studentDataTable, year, school, division, progArea, sinceWeek, missedLessons, includeWdlTrn, ageMin, ageMax, studentGLH); 
        ds = new DataSet(); 
        ds.Tables.Add((DataTable)studentDataTable); 
        ReportDocument.SetDataSource(ds.Tables[0]); 
       } 
       catch (Exception err) 
       { 
        LogReportError(err, this.CrystalViewer, null, ErrorType.Reporting); 
       } 
     } 

지금 방법으로이 없다 : 라인 아래처럼 내가 할 수있는 일단 studentTableAdapter가 사용되기 때문에

using (Reports.StudentRegisters.StudentQueriesDataTable studentDataTable = new Reports.StudentRegisters.StudentQueriesDataTable()) 
     { 
      using (StudentQueriesTableAdapter studentTableAdapter = new StudentQueriesTableAdapter()) 
      { 
       try 
       { 
        studentTableAdapter.FillByQAbsenceRegRow(studentDataTable, year, school, division, progArea, sinceWeek, missedLessons, includeWdlTrn, ageMin, ageMax, studentGLH); 
        ds = new DataSet(); 
        ds.Tables.Add((DataTable)studentDataTable); 
        ReportDocument.SetDataSource(ds.Tables[0]); 
       } 
       catch (Exception err) 
       { 
        LogReportError(err, this.CrystalViewer, null, ErrorType.Reporting); 
       } 
      } 
     } 

: 그래서 두 using 문에이에 코드를 변경 StudentQueriesTableAdapter에서 dispose를 호출하십시오. 더 이상 객체에 대한 참조가 없거나 잠재적으로 적절하게 배치되지 않은 객체를 남겨 둘 수 있으므로이 객체가 자동으로 호출됩니다.

나는 실제로 두 객체에서 처리해야하는지 여부에 관심이 없다는 것을 강조 할 것이며, 일부는 구현하고 실제로는 필요하지는 않습니다. (항상 수행해야하지만). 나는 그것이 특별히 부름 받았는지에 관심이있다.

답변

4

아니요, 수신되지 않습니다. 당신의 StudentQueriesTableAdapter가 배치되지 않습니다,이 때문에

var objectToDispose = foo as IDisposable; 
try 
{ 
    DoSomething(); 
} 
finally 
{ 
    if(objectToDispose != null) 
     objectToDispose.Dispose(); 
} 

: Using(foo){ DoSomething() }는 (대략) 기능적으로 동일합니다. 어떤 사양의

using (var foo = new Foo()) 
using (var bar = new Bar(foo)) 
{ 
    DoSomething(); 
} 
+0

나는 두껍게 보이게하는 기술을 사용하여 더블을 좋아합니다. 중첩은 원래 코드 레이아웃이 마음에 들지 않는 주된 이유입니다. – PeteT

+0

그래, 여분의 들여 쓰기를 피하기 위해 중첩 된'using' 블록을 포맷하는 관용적 방법입니다. –

1

Dispose()은 범위를 벗어나는 객체에 대해서는 자동으로 호출되지 않으므로 올바르게 배치하려면 StudentQueriesTableAdapter에 대한 참조를 using() {...}으로 묶어야합니다.

또 다른 옵션은 다소 중첩 줄이기 위해 usingtry를 결합하는 것입니다 :

using (Reports.StudentRegisters.StudentQueriesDataTable studentDataTable = new Reports.StudentRegisters.StudentQueriesDataTable()) 
    { 
     StudentQueriesTableAdapter studentTableAdapter; 

     try 
     { 
      studentTableAdapter = new StudentQueriesTableAdapter(); 
      studentTableAdapter.FillByQAbsenceRegRow(studentDataTable, year, school, division, progArea, sinceWeek, missedLessons, includeWdlTrn, ageMin, ageMax, studentGLH); 
      ds = new DataSet(); 
      ds.Tables.Add((DataTable)studentDataTable); 
      ReportDocument.SetDataSource(ds.Tables[0]); 
     } 
     catch (Exception err) 
     { 
      LogReportError(err, this.CrystalViewer, null, ErrorType.Reporting); 
     } 
     finally 
     { 
      if (studentTableAdapter != null) 
       studentTableAdapter.Dispose(); // or Close(), depending on which method is public 
     } 
    } 

이것은 using {}이 무엇을 본질적으로 - 시도/마침내 절에 포장

하는 것으로, 일부 개체는 Dispose 메서드로 아무 것도 수행하지 않는 IDisposable을 구현할 수 있지만 항상 에 IDisposable 개체를 래핑해야합니다.이 개체는 공동 작업자의 일부입니다. 그 클래스를 사용하는 중 ntract, 그렇지 않으면 리소스가 누출 될 수 있습니다 (예 : 나중에 빈 버전의 Dispose 메서드가 나중에 버전으로 채워지는 경우)

1

finalizer를 사용하기 위해 IDisposable을 구현하는 항목을 갖는 사양 이전에 수행하지 않은 호출을 수행하는 경우 이것은 나쁜, 나쁜 습관입니다. IDisposable을 구현하고 완료된 객체를 인스턴스화하는 경우 Dispose으로 호출하십시오.

+0

부 :

나는 종종 다수의이 같은 처분하는과 중첩 줄이기 위해 시도? 내가 IDisposable을 구현할 때, 나는 보통 Finalizer에서 Debug.Assert (false)를 수행하고, 뭔가를 버리는 것을 잊어 버리면 최대한 빨리 배웁니다. – erikkallen

+0

@erik : http://msdn.microsoft.com/en-us/library/system.idisposable을 참조하십시오.자세한 내용은 aspx를 참조하십시오. 'IDisposable' 컴포넌트/클래스를 설계한다면, * 관리되지 않는 * 리소스를 해제하는 finalizer를 구현해야합니다 (그러나 관리 리소스는 없습니다). 이것은'Dispose (bool disposing)'오버로드를 가지며,'Dispose()'가'true'를 전달하고 finalizer가'false'를 전달하는 패턴입니다. –

+0

사양의 일부보다 제안 된 구현을 더 많이 고려합니다. – erikkallen

1

Dispose는 using 블록 사용을 사용하는 IDisposable()을 구현하는 개체에서만 호출됩니다.

감사합니다.