foreach循环的当前索引

时间:2011-01-01 22:41:01

标签: c# loops foreach indexing

有没有办法知道当前的foreach运行而不必:

Int32 i;
foreach
   i++;

或者这是我得到的最佳选择?另外,我怎么知道该循环中的最大项目数?我想要做的是在我的表单上的foreach循环期间更新进度条。

这是我到目前为止所做的:

    FileInfo[] directoryFiles = (new DirectoryInfo(folderBrowserDialog.SelectedPath)).GetFiles("*.*");
    foreach (FileInfo file in directoryFiles)
    {
        if ((file.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden || (file.Attributes & FileAttributes.System) == FileAttributes.System)
            continue;

        backgroundWorkerLoadDir.ReportProgress(i, file.Name);
        System.Threading.Thread.Sleep(10);
    }

所以它应该如下,对吗?

   for (Int32 i = 0; i < DirectoryFiles.Length; i++)
   {
       if ((DirectoryFiles[i].Attributes & FileAttributes.Hidden) == FileAttributes.Hidden || (DirectoryFiles[i].Attributes & FileAttributes.System) == FileAttributes.System)
           continue;

       backgroundWorkerLoadDir.ReportProgress((i / DirectoryFiles.Length) * 100, DirectoryFiles[i].Name);
       System.Threading.Thread.Sleep(10);
   }

6 个答案:

答案 0 :(得分:7)

Foreach是一个相当大的交易,它的底层管道是一个非常简单的仅向前迭代器,它不需要预先知道集合中有多少项。的IEnumerator&LT;&GT;

一般来说,与ProgressBar相比,这是一个相当令人讨厌的不匹配。当您事先知道要迭代的项目数时,您只能有意义地更新标准项目。所以你可以设置它的最大属性。如果 可能,那么您无疑可以访问Count属性并拥有索引器。然后,它允许你使用for()语句,问题解决了。

但是你很不知道有多少项要迭代。例如,典型的dbase查询。由于您无法确定迭代可能需要多长时间,因此进度条上只有一个选项:Style = Marquee。 “我没有死,我正在努力”报告进展的方式。问题解决了。

答案 1 :(得分:6)

使用for循环代替foreach。在这种情况下,情况会更好。

像这样使用:

count = DirectoryFiles.Length;
for (int k = 0; k < count; k++)
{
    FileInfo file = DirectoryFiles[k];
    if ((file.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden || 
        (file.Attributes & FileAttributes.System) == FileAttributes.System)
    {
        continue;
    }

    backgroundWorkerLoadDir.ReportProgress(i, file.Name);
    System.Threading.Thread.Sleep(10);
}

答案 2 :(得分:2)

不,IEnumerable是不可能的,因为它没有Count / Length属性。而且,您可以轻松想象无限的IEnumerable序列,例如:

private readonly Random rand = new Random();
private IEnumerable<int> GetInfiniteRandomSequence() 
{
    while(true)
    {
        yield return rand.Next();
    }
}

答案 3 :(得分:1)

这是您最好的选择,因为标准for循环不适用于不可索引的IEnumerable。如果您需要知道项目数,请使用Count属性;如果没有,那么显然你可以提前知道。

答案 4 :(得分:1)

using System.Linq;

for (var i = 0; i < items.Count(); i++)
{
    // Update progress bar here.
}

答案 5 :(得分:1)

此问题的基本原则如下:

List<string> numbers = new List<string>() { "one", "two", "three" };

foreach (var num in numbers.Select((value, index) => new { value, index }))
{
    Console.WriteLine("Value: {0}, Index: {1}", num.value, num.index);
}

这将在foreach循环中创建一个新的匿名类型,其中包含num变量中的valueindex

所以要解决OP中提供的问题:

FileInfo[] directoryFiles = (new DirectoryInfo(folderBrowserDialog.SelectedPath)).GetFiles("*.*");
foreach (FileInfo file in directoryFiles.Select((value, index) => new {value, index}))
{
    if ((file.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden
          ||
        (file.Attributes & FileAttributes.System) == FileAttributes.System)
        continue;

    int progress = (file.index / DirectoryFiles.Length) * 100;

    backgroundWorkerLoadDir.ReportProgress(progress, file.value.Name);
    System.Threading.Thread.Sleep(10);
}