设置每个子元素的每个子元素的属性

时间:2017-07-11 10:08:41

标签: c#

我有一组从第三方XML填充的类(因此我无法真正控制结构):

public class Category
{
    // some properties...

    public Tournament[] Tournaments {get;set;}
}

public class Tournament
{
    // some properties...

    public Match[] Matches {get;set;}
}

public class Match
{
    // some properties...

    public Competitors Competitors {get;set;}
}

public class Competitors 
{
    // some properties...

    public Teams[] Teams {get;set;}
}

等等。

现在,我需要在团队级别设置来自不同类的一些属性 - 例如,我需要类别的ID,比赛的性别等。

所以现在,我有一个foreach循环,用于设置每个锦标赛的类别ID,稍后在代码中我有3个嵌套foreach循环,用于将值从锦标赛的属性复制到属于团队。

        foreach (var tournament in tournaments)
        {
            foreach (var match in tournament.Matches)
            {
                match.SomeProperty = tournament.SomeProperty;

                foreach (var team in match.Competitors.Teams)
                {
                    team.CategoryId = tournament.CategoryId;
                    team.Gender = tournament.Gender;
                    // and a few more here...
                }
            }
        }

毋庸置疑,这是一个非常难看的代码。 我想知道是否有更好的方法来做,也许使用LINQ或类似的东西。

更新

现在我已经更改了我的代码,以便每个类都引用它的父级。这样我就不需要在链中再设置任何属性了 而不是team.CategoryId我现在正在使用team.Match.Tournament.Category.Id
但是,我仍然有同样的问题,只是现在它只集中在一个地方 - 反序列化完成后,我有4个嵌套的foreach循环 - 所以看起来像这样:

foreach (var category in MainClass.Categories)
{
    category.FileName = MainClass.FileName;
    foreach (var tournament in category.Tournaments)
    {
        tournament.Category = category;
        foreach (var match in tournament.Matches)
        {
            match.Tournament = tournament;
            foreach (var team in match.Fixture.Competitors.Teams)
            {
                team.Match = match;
            }
        }
    }
}

找到避免这些嵌套循环的方法会很好......

1 个答案:

答案 0 :(得分:1)

您可以将内部foreach与SelectMany - LINQ操作合并。

foreach (var tournament in tournaments)
{
    //// We take every team in every competitors to on Enumeration
    foreach (var team in tournament.Matches.SelectMany(match => match.Competitors.Teams))
    {
        team.CategoryId = tournament.CategoryId;
        team.Gender = tournament.Gender;
    }
}

编辑:

当你在第一个foreach设置一个属性时,SelectMany将不起作用(因为该投影只会保持匹配竞争对手的所有团队)。

使其有点更好的一种方法是提取方法

foreach (var tournament in tournaments)
{
    SetMatchPropertiesFromTournament(tournament);
}
...

private void SetMatchPropertiesFromTournament(Tournament tournament)
{
    foreach (var match in tournament.Matches)
    {
        match.SomeProperty = tournament.SomeProperty;

        foreach (var team in match.Competitors.Teams)
        {
            team.CategoryId = tournament.CategoryId;
            team.Gender = tournament.Gender;
            // and a few more here...
        }
    }
}

一个不错的小功能,只做一件事......这太棒了!