C# 在C中使用并获取内部指定的变量#

C# 在C中使用并获取内部指定的变量#,c#,using,C#,Using,我一直认为,通过在之前使用声明var,将允许使用在内部分配它,然后我仍然可以读取它外部的变量。结果我不能:-) 复制archive.Volumes,而不只是让集合引用它。然后,在使用结束时释放存档时,您的集合将不会被释放。您肯定仍然可以从变量中读取。在确定赋值方面没有问题,否则会出现编译时错误。例如,这很好: using System; using System.IO; class Test { static void Main() { string x;

我一直认为,通过在
之前使用
声明var,将允许使用
内部分配它,然后我仍然可以读取它外部的变量。结果我不能:-)


复制
archive.Volumes
,而不只是让集合引用它。然后,在使用结束时释放存档时,您的集合将不会被释放。

您肯定仍然可以从变量中读取。在确定赋值方面没有问题,否则会出现编译时错误。例如,这很好:

using System;
using System.IO;

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

现在,如果
SevenZipArchive
返回一个
ReadOnlyCollection
,我通常希望在释放存档本身后,它仍然有效。然而,
ReadOnlyCollection
只是另一个集合的包装。。。如果通过处置
归档文件
而使该集合无效,这肯定可以解释问题

不幸的是,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;
}
。。。然后,当您不需要额外的诊断时:

private List<string> ExtractRar(string varRarFileName,
                                string varDestinationDirectory) {
    using (var archive = new SevenZipArchive(varRarFileName)) {
        return archive.Volumes.ToList(); 
    }
}
private List ExtractRar(字符串varRarFileName,
字符串varDestinationDirectory){
使用(var archive=new SevenZipArchive(varRarFileName)){
返回archive.Volumes.ToList();
}
}

(顺便说一句,我假设您正在使用.NET 3.5或更高版本来使用
ToList
扩展方法。)

正如Joel Rondeau在他的回答中指出的那样,随着归档文件的处理,收集正在被清除。但是,将其包装到
ReadonlyCollection
中将不起作用,因为这不会复制包装的列表。您需要手动创建此副本:

ReadOnlyCollection<string> collection;
using (var archive = new SevenZipArchive(varRarFileName))
{
    collection = new ReadOnlyCollection<string>(archive.Volumes.ToList());
}
ReadOnlyCollection集合;
使用(var archive=new SevenZipArchive(varRarFileName))
{
collection=new ReadOnlyCollection(archive.Volumes.ToList());
}

我尝试了类似的方法,结果通过了测试:

[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);
}
[Test]公共无效集合计数应开始创建坦泽罗(){
//安排
字符串tempDir=Path.GetTempPath();
var fileInfo=newfileinfo(tempDir+Path.directoryseportorchar+test.zip);
writealBytes(fileInfo.FullName,Resources.TestZipFile);
SevenZipBase.SetLibraryPath(@“c:\7z.dll”);
//表演
只读集合;
使用(var archive=new SevenZipExtractor(fileInfo.FullName))
collection=archive.archivefilename;
//断言
Assert.IsTrue(collection.Count>0);
}

问题在于您引用的字段是存档的一部分。由于使用闭包,此时不存在存档对象


您可以克隆using中的值,这将为您提供列表的副本,而不是列表值的引用,这将完成此工作。

那么,为什么在using中得到count=10,而在using外得到0?除了不使用disposing之外,我如何防止它被处置?是,我的错是没有检查文件就写了。我已删除了令人不快的评论。我正在使用.NET 4.0,因此ToList()没有问题。谢谢你的帮助,我自己肯定不会解决这个问题:-)我把它改成了那个,但在使用之外它仍然是0。。我已经在我的帖子中添加了我使用的示例。是的。检查过的文档和我的
理论在这种情况下肯定不起作用。这要好得多。您使用的是不同的SevenZipLib。我用的是SevenZipLib,而你用的是SevenZipSharp,它的作用似乎不同。我的行为似乎和乔恩说的一样。是的,看看两者的内部情况会很有趣
private List<string> ExtractRar(string varRarFileName,
                                string varDestinationDirectory) {
    using (var archive = new SevenZipArchive(varRarFileName)) {
        return archive.Volumes.ToList(); 
    }
}
ReadOnlyCollection<string> collection;
using (var archive = new SevenZipArchive(varRarFileName))
{
    collection = new ReadOnlyCollection<string>(archive.Volumes.ToList());
}
[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);
}