foreach有2个声明

时间:2014-01-30 08:00:19

标签: c# foreach

嗨,我想用这样的2个语句创建一个foreach

foreach (CSheet mySheet in mySheets && CSheet nameQuiz in nameQuizs ) {
    //problem if i just used one statement in foreach i can't give property 'name' to  
            nameQuiz...so it's limited like this
    oSheet = mySheet.name.toString(); 

    //i wanna make nameQuiz have property name too like mysheet
    oSheet = mySheet.name.toString();
    oName = nameQuiz.name.toString();
}

这是我的CSheets

public class CSheet
{
    public string name;
    public CCell[] cells;
}

mysheets& nameQuizs是数组
任何想法?


阿图尔

public static string exportToExcel(string fileName, CSheet[] mySheets, CSheet[] nameQuizs)

基于该代码mySheets& nameQUizs相关与否?我怎么知道它们是否相关?

5 个答案:

答案 0 :(得分:4)

你可以zip两个序列(即从两个序列中取相应的项目):

foreach (var item in mySheets.Zip(nameQuizs, (s,nq) => new { mySheet = s, nameQuiz = nq }))
{
     oSheet = item.mySheet.name;    
     oSheet = item.mySheet.name;
     oName = item.nameQuiz.name;    
}

更新:因此您使用的是.NET 3.5 Zip扩展不可用。但你可以写自己的:

public static IEnumerable<TResult> Zip<TFirst, TSecond, TResult>(
    this IEnumerable<TFirst> firstSource, 
    IEnumerable<TSecond> secondSource,
    Func<TFirst, TSecond, TResult> selector)
{
    using(var firstIterator = firstSource.GetEnumerator())
    using(var secondIterator = secondSource.GetEnumerator())
    {
        while(firstIterator.MoveNext() && secondIterator.MoveNext())
            yield return selector(firstIterator.Current, secondIterator.Current);
    }  
}

答案 1 :(得分:3)

你不能这样做。但是,您可以使用一个for循环执行此操作:

for (int i = 0; i < Math.Min(mySheets.Count, nameQuizs.Count); i++)
{
    CSheet mySheet = i < mySheets.Count ? mySheets[i] : null;
    CSheet nameQuiz = i < nameQuizs.Count ? nameQuizs[i] : null;

    oSheet = mySheet != null ? mySheet.name : String.Empty;
    oName = nameQuiz != null ? nameQuiz.name : String.Empty;
}

在您的mySheetsnameQuizs列表实际上是数组时,您需要将Count替换为Length

此外,您不需要name.ToString();,因为name成员已经是String

答案 2 :(得分:2)

如果mySheets和nameQuizs相关,你可以将它们放在一个字典中, Dictionary<CSheet, CSheet>并列举该内容。

或者使用for循环和每个元素的索引。

答案 3 :(得分:1)

如果你想要循环,而两个元素都存在,请使用:

var mySheetsEnum = mySheets.GetEnumerator();
var nameQuizsEnum = nameQuizs .GetEnumerator();

while(mySheetsEnum.MoveNext() && nameQuizsEnum.MoveNext())
{
   ...
}

否则您可以使用||代替&&

答案 4 :(得分:1)

使用Zip extension method

,您可以非常优雅地将其整合到一个循环中
foreach (var item in mySheets.Zip(nameQuizs, (s, q) => Tuple.Create(s, q)))
{
    var mySheet = item.Item1;
    var nameQuiz = item.Item2;
}

匿名类型可能是更好的解决方案,而不是Tuple。请参阅Sergey's answer

它的作用基本上是迭代到序列并将每个集合的下一个元素相互压缩合并。通常,您会以某种方式合并它们,或将它们复制到Tuple或任何自定义对象中。

虽然这个比喻并不完美,但您可能会想到两条高速公路合并为一条,其中拉链合并的概念适用于此。但是,在这里我们得到一对汽车而不是一条长线。