【问题标题】:c# foreach loop access variablec# foreach 循环访问变量
【发布时间】:2026-01-12 21:25:02
【问题描述】:

我有以下问题: 我有一个字符串变量,它必须存储一个文件路径。 在 foreach 循环中,我遍历某个目录中的所有文件,并寻找最旧的文件,该文件保存在该字符串变量中。 循环完成后,我尝试删除该文件,但出现错误: 使用未分配的局部变量。

代码如下:

DateTime min = DateTime.Now;
string[] fileNames = Directory.GetFiles(somePath);
string fileDelete;
int countFiles = fileNames.Length;
if (countfiles > 5)
{
    foreach (string someFile in fileNames)
    {
        FileInfo infoFile = new FileInfo(someFile);
        if (infoFile.CreationTime <= min)
        {
            min = infoFile.CreationTime;
            fileDelete = someFile;
        }   
    }
    File.Delete(fileDelete);
}   

它表示 File.Delete(fileDelete) 中的字符串 fileDelete 没有值, 但有趣的是,当我在一开始就给它一个值时:

string fileDelete = "blabla";

它工作得很好。 这只是方法的一个片段,以防您想知道

【问题讨论】:

  • 当您执行string fileDelete = "blabla"; 时,该变量不再未分配。 countFiles 是否大于 5?是否至少有一个文件的创建时间早于DateTime.Now?您的代码不能保证分配了fileDelete,所以它在某些时候会出错。
  • 正如其他人所说,编译器只有在显式初始化时才能使用变量。所以只需使用string fileDelete = "";
  • 谢谢大家的遮阳篷。我现在明白了这个问题。我只是忘记了编译器无法知道条件 2 总是满足条件 1 时(在我的程序中),并且编译器看到了一个案例,其中 File.Delete 将在没有值的情况下执行,即使这不会发生在我的代码。

标签: c# .net foreach unassigned-variable


【解决方案1】:

在 C# 中,您必须初始化变量,否则您可能会将垃圾值传递给 File.Delete。

我推荐使用

string fileDelete = null; // or ""

稍后再检查。

if (!string.IsNullOrEmpty(fileDelete))
{
  File.Delete(fileDelete);
}

【讨论】:

    【解决方案2】:

    它完全按照预期工作。

    在 C# 中,局部变量不会在声明时自动初始化。

    在声明 fileDelete 并仅在循环中的某些条件下分配它时,您不会为它分配任何值。

    但是您试图在循环中在此条件之外使用它的值,因此编译器无法推断 - fileDelete 在运行时是否具有某些值(如果条件下的代码不会被执行 - 那么 fileDelete will 没有价值)。

    因此编译器会产生这个错误。

    【讨论】:

    • 没错,谢谢。我只是忘记了编译器无法知道条件 2 总是满足条件 1 时(在我的程序中)。
    【解决方案3】:

    想象一下这个场景:

    • countFiles &gt; 5 是真的
    • infoFile for someFile 大于 min

    fileDelete 传递给 File.Delete 时会有什么值?

    Answer: 在这种情况下fileDelete 将未初始化,因此会出现错误消息。

    【讨论】:

    • 100% 正确。我只是没有看到这种情况,因为它不可能在我的程序中发生,但编译器当然认为它可能发生。
    【解决方案4】:

    您必须初始化您的变量。 见Why compile error "Use of unassigned local variable"?

    【讨论】:

      【解决方案5】:

      使用这个

      DateTime min = DateTime.Now;
      string[] fileNames = Directory.GetFiles(somePath);
      string fileDelete;
      int countFiles = fileNames.Length;
      if (countfiles > 5)
      {
          foreach (string someFile in fileNames)
          {
              FileInfo infoFile = new FileInfo(someFile);
              if (infoFile.CreationTime <= min)
              {
                  min = infoFile.CreationTime;
                  fileDelete = someFile;
                  File.Delete(fileDelete);
              }   
          }
      
      }   
      

      【讨论】:

      • 这会使 fileDelete 完全冗余
      • 我没有对此进行测试,但我认为这只会删除所有比现在更旧的文件。但我只想删除某个目录中最旧的文件