2010-12-10 14 views
2

私はいつもusingの前にvarを宣言することによって、usingの中に変数を読み込むことができると思っていました。だけではなく、コレクションの参照を持つのC#で使用している変数を使用して使用することを使用する

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:それはusing

完全なテスト方法を使用することを停止することなく動作させるために私がすることができません:-)

 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 

判明任意の方法それ。その後、アーカイブが使用の最後に処分されると、コレクションは廃棄されません。

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

これは絶対に問題ありません。

SevenZipArchiveReadOnlyCollection<string>を返す場合、私はとなります。通常、はアーカイブ自体が破棄された後でも有効であると考えます。しかし、ReadOnlyCollection<T>は、単に別のコレクションのラッパーです...そして、そのコレクションがarchiveの処分によって無効にされている場合、それは確かに事柄を説明します。

残念ながら、コレクションをコピーするには、別のラッパーを作成することをお勧めします。最初のラッパーにカウントを求め、元の(無効にされた)コレクションを要求します。

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を使用しているようです。そして、私のように振る舞うようです。 – MadBoy

+0

はい、両方の内部を見て、何が起こっているのかを見ると面白いでしょう –

0

問題は、あなたが参照しているフィールドは、アーカイブの一部であるということです。クローズを使用しているため、その時点でアーカイブオブジェクトは存在しません。

リスト内の値を複製して、リスト値の参照ではなくリストのコピーを与えることができます。これはジョブを実行します。

関連する問題