2010-12-10 2 views
2

항상 using 전에 변수를 선언하여 using 안에 할당 할 수 있다고 생각했습니다. 그리고 나서 여전히 변수를 읽을 수있었습니다. 알고 보니 나는 할 수 없습니다 :-)C#에서 사용하고 사용하는 변수 사용하기 및 사용하기

 ReadOnlyCollection<string> collection; 
     using (var archive = new SevenZipArchive(varRarFileName)) { 
      collection = archive.Volumes; 
      MessageBox.Show(collection.Count.ToString()); // Output 10 
     } 
     MessageBox.Show(collection.Count.ToString()); // output 0 

using

전체 시험 방법 사용을 중지하지 않고 작업을 할 수있는 방법 :

private ReadOnlyCollection<string> ExtractRar(string varRarFileName, string varDestinationDirectory) { 
     ReadOnlyCollection<string> collection; 
     using (var archive = new SevenZipArchive(varRarFileName)) { 
      collection = new ReadOnlyCollection<string>(archive.Volumes); 
      MessageBox.Show(collection.Count.ToString()); // output 10 


     } 
     MessageBox.Show(collection.Count.ToString()); // output 0 
     return collection; 
    } 

답변

3

는 컬렉션 인 CLE입니다 아카이브가 폐기되는 동안. 그러나 랩된 목록을 복사하지 않으므로 ReadonlyCollection에 랩핑하면 작동하지 않습니다.

ReadOnlyCollection<string> collection; 
using (var archive = new SevenZipArchive(varRarFileName)) 
{ 
    collection = new ReadOnlyCollection<string>(archive.Volumes.ToList()); 
} 
+0

그게 효과가 :-) – MadBoy

+0

예. 확인 된 문서와 나의 '새로운'이론은이 경우에는 확실히 작동하지 않을 것입니다. 이것은 훨씬 낫다. –

6

복사 archive.Volumes 대신 단지 가진 콜렉션 참조 그것. 그런 다음 아카이브를 사용 끝나면 폐기하면 컬렉션이 삭제되지 않습니다.

+0

복사 하시겠습니까? – MadBoy

+0

나는 그걸로 바꿨고 사용하지 않을 때는 여전히 0이된다. 나는 내 게시물에 내가 사용하는 예를 추가했다. – MadBoy

2

변수에서 확실히 읽을 수 있습니다. 명확한 할당 문제에는 문제가 없으며 컴파일 타임 오류가 발생합니다. 예를 들어 괜찮습니다.

using System; 
using System.IO; 

class Test 
{ 
    static void Main() 
    { 
     string x; 
     using (new MemoryStream()) 
     { 
      x = "hello"; 
     } 
     Console.WriteLine(x); 
    } 
} 

정말 괜찮습니다.

을 반환하는 경우 보통은 아카이브 자체가 삭제 된 후에도 여전히 유효하다고 생각합니다. 그러나 ReadOnlyCollection<T>은 단순히 다른 컬렉션을 둘러싼 래퍼입니다 ... 그리고 해당 컬렉션이 archive을 삭제하여 무효화되는 경우 확실하게 설명 할 수 있습니다.

불행히도 Joel이 제안한 컬렉션 복사 방법은 또 다른 래퍼를 만드는 것입니다. 첫 번째 래퍼에게 개수를 물어보고 원래의 (무효화 된) 컬렉션을 묻습니다.

private ReadOnlyCollection<string> ExtractRar(string varRarFileName, 
               string varDestinationDirectory) { 
    ReadOnlyCollection<string> collection; 
    using (var archive = new SevenZipArchive(varRarFileName)) { 
     collection = new ReadOnlyCollection<string>(archive.Volumes.ToList()); 
     MessageBox.Show(collection.Count.ToString()); // output 10 
    } 
    MessageBox.Show(collection.Count.ToString()); // output 0 
    return collection; 
} 

ToList()에 추가 전화 :

여기에 작동해야 한 가지 방법입니다. 그러면 컬렉션이 처음에 List<string>에 복사됩니다. 단지 래퍼를 만드는 것이 아니라 복사됩니다. 당신이 여분의 진단을 필요로하지 않을 때 다음

private List<string> ExtractRar(string varRarFileName, 
           string varDestinationDirectory) { 
    List<string> collection; 
    using (var archive = new SevenZipArchive(varRarFileName)) { 
     collection = archive.Volumes.ToList(); 
     MessageBox.Show(collection.Count.ToString()); // output 10 
    } 
    MessageBox.Show(collection.Count.ToString()); // output 0 
    return collection; 
} 

을 ... 그리고 : : 방법이 목록을 반환하는 경우 당신이 정말로 괜찮다면 물론

, 당신은 사용할 수

private List<string> ExtractRar(string varRarFileName, 
           string varDestinationDirectory) { 
    using (var archive = new SevenZipArchive(varRarFileName)) { 
     return archive.Volumes.ToList(); 
    } 
} 

(난 당신이 ToList 확장 방법을 사용, 그런데 .NET 3.5 이상을 사용하고 있으리라 믿고있어.) 조엘 론도는 그의 대답에서 지적한대로

+0

그렇다면 왜 내부에서 사용할 때 카운트 = 10을 얻고 외부에서는 0이 될까요? – MadBoy

+0

처분을 사용하지 않는 경우를 제외하고 처분을 방지하려면 어떻게해야합니까? – MadBoy

+0

@MadBoy : 내 편집물보기. –

1

내가 비슷한 시도하고 나는 통과 시험을 얻을 : 수동이 복사본을 만들 필요가

[Test] public void CollectionCountShouldBeGreaterThanZero() { 
    // arrange 
    string tempDir = Path.GetTempPath(); 
    var fileInfo = new FileInfo(tempDir + Path.DirectorySeparatorChar + "test.zip"); 
    File.WriteAllBytes(fileInfo.FullName, Resources.TestZipFile); 

    SevenZipBase.SetLibraryPath(@"c:\7z.dll"); 

    // act 
    ReadOnlyCollection<string> collection; 
    using(var archive = new SevenZipExtractor(fileInfo.FullName)) 
    collection = archive.ArchiveFileNames; 

    // assert 
    Assert.IsTrue(collection.Count > 0); 
} 
+0

다른 SevenZipLib을 사용 중입니다. SevenZipLib을 사용하면 SevenZipSharp를 사용하는 것처럼 보입니다. SevenZipSharp는 다르게 작동하는 것 같습니다. 그리고 내 말은 존이 말하는 것처럼 행동하는 것 같습니다. – MadBoy

+0

예, 둘 다 내부에서 무슨 일이 일어나는지 살펴 보는 것이 흥미로울 것입니다. –

0

문제는 당신이 참조하는 필드 아카이브의 일부임을입니다. 아카이브 객체는 클로저를 사용하기 때문에 그 시점에 존재하지 않습니다.

값 목록에 대한 참조 대신 목록의 복사본을 제공하는 값 내에서 값을 복제 할 수 있으며 작업을 수행 할 수 있습니다.

관련 문제