c#变量

时间:2017-07-21 08:52:52

标签: c# scope

我提取了一些代码来比较两个目录,这一切都运行正常,但我想为了我的目的改进它,所以我可以回收代码略有不同的要求。原始代码列出了所有目录,但我想添加一个开关,以便我可以决定是列出所有目录还是仅列出顶级。以下是我的代码中的代码段;

public void DoCompare(string pathA, string pathB, bool allDirs)
{
    DirectoryInfo dir1 = new DirectoryInfo(pathA);
    DirectoryInfo dir2 = new DirectoryInfo(pathB);

    if (allDirs)
    {
        IEnumerable<FileInfo> list1 = dir1.GetFiles("*.*", SearchOption.AllDirectories);
        IEnumerable<FileInfo> list2 = dir2.GetFiles("*.*", SearchOption.AllDirectories);
    }
    else
    {
        IEnumerable<FileInfo> list1 = dir1.GetFiles("*.*", SearchOption.TopDirectoryOnly);
        IEnumerable<FileInfo> list2 = dir2.GetFiles("*.*", SearchOption.TopDirectoryOnly);
    }

    //A custom file comparer defined later
    FileCompare myFileCompare = new FileCompare();

    bool areIdentical = list1.SequenceEqual(list2, myFileCompare);

现在没有if(allDirs),这个工作正常。当我把它放入时,list1和list 2在最后一行代码中不可见。实际错误是“名称列表1在当前上下文中不存在”。我尝试在if之外声明它们,但依赖于它们返回结果,如果没有决定,这是不可能的。那么如何在if语句之外显示这些内容呢?

4 个答案:

答案 0 :(得分:4)

它无法访问,因为它在内部作用域中声明,在外部作用域中不可见。但您只想根据SeachOption更改bool,所以为什么不简单:

SearchOption opt = allDirs ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly;
IEnumerable<FileInfo> list1 = dir1.GetFiles("*.*", opt);
IEnumerable<FileInfo> list2 = dir2.GetFiles("*.*", opt);
bool areIdentical = list1.SequenceEqual(list2, new FileCompare());

如果你不能这样做,你必须在外面宣布:

IEnumerable<FileInfo> list1;
IEnumerable<FileInfo> list2;
if(allDirs)
{
    list1 = ...
    list2 = ...
}
else
{
   list1 = ...
   list2 = ...
}
// now you can access them here because they are declared in the same scope

答案 1 :(得分:2)

它们无法访问,因为它们是在if/else的范围内定义的。有关accessibility of variables in scopes

的更多信息

您可以在Mark的答案中将其定义为外部,而是将if if更改为仅处理SearchOption。这样你就没有代码重复:

var option = allDirs ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly;

IEnumerable<FileInfo> list1 = (new DirectoryInfo(pathA)).GetFiles("*.*", option);
IEnumerable<FileInfo> list2 = (new DirectoryInfo(pathB)).GetFiles("*.*", option);

bool areIdentical = list1.SequenceEqual(list2, new FileCompare());

答案 2 :(得分:1)

简单,在if语句之外声明它们并在其中分配:

public void DoCompare(string pathA, string pathB, bool allDirs)
{
    DirectoryInfo dir1 = new DirectoryInfo(pathA);
    DirectoryInfo dir2 = new DirectoryInfo(pathB);

    IEnumerable<FileInfo> list1; // declare list1 here
    IEnumerable<FileInfo> list2; // declare list2 here

    if (allDirs)
    {
        list1 = dir1.GetFiles("*.*", SearchOption.AllDirectories);
        list2 = dir2.GetFiles("*.*", SearchOption.AllDirectories);
    }
    else
    {
        list1 = dir1.GetFiles("*.*", SearchOption.TopDirectoryOnly);
        list2 = dir2.GetFiles("*.*", SearchOption.TopDirectoryOnly);
    }

    //A custom file comparer defined later
    FileCompare myFileCompare = new FileCompare();

    bool areIdentical = list1.SequenceEqual(list2, myFileCompare);
}

它无法访问,因为它在内部作用域中声明,在外部作用域中不可见。

您还可以使用条件运算符?简化该方法。

IEnumerable<FileInfo> list1 = dir1.GetFiles("*.*", allDirs ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly);

答案 3 :(得分:1)

您也可以使用三元运算符并更改此

if (allDirs)
{
    IEnumerable<FileInfo> list1 = dir1.GetFiles("*.*", SearchOption.AllDirectories);
    IEnumerable<FileInfo> list2 = dir2.GetFiles("*.*", SearchOption.AllDirectories);
}
else
{
    IEnumerable<FileInfo> list1 = dir1.GetFiles("*.*", SearchOption.TopDirectoryOnly);
    IEnumerable<FileInfo> list2 = dir2.GetFiles("*.*", SearchOption.TopDirectoryOnly);
}

到此:

IEnumerable<FileInfo> list1 = allDirs?dir1.GetFiles("*.*", SearchOption.AllDirectories):dir1.GetFiles("*.*", SearchOption.TopDirectoryOnly);
IEnumerable<FileInfo> list2 = allDirs?dir2.GetFiles("*.*", SearchOption.AllDirectories):dir2.GetFiles("*.*", SearchOption.TopDirectoryOnly);