ForEach循环未改变类属性

7

我看到了一些关于这个问题的问题,并进行了一些研究。

据我了解,当您在IEnumerable上运行foreach时:如果T是引用类型(例如类),则应该能够在循环内部修改对象的属性。 如果T是值类型(例如结构体),则不起作用,因为迭代变量将是局部副本。

我正在使用以下代码开发Windows Store应用程序:

我的类:

public class WebResult
{
    public string Id { get; set; }
    public string Title { get; set; }
    public string Description { get; set; }
    public string DisplayUrl { get; set; }
    public string Url { get; set; }
    public string TileColor
    {
        get
        {
            string[] colorArray = { "FFA200FF", "FFFF0097", "FF00ABA9", "FF8CBF26",
            "FFA05000", "FFE671B8", "FFF09609", "FF1BA1E2", "FFE51400", "FF339933" };
            Random random = new Random();
            int num = random.Next(0, (colorArray.Length - 1));
            return "#" + colorArray[num];
        }
    }
    public string Keywords { get; set; }
}

代码如下:
IEnumerable<WebResult> results = from r in doc.Descendants(xmlnsm + "properties")
                                 select new WebResult
                                 {
                                     Id = r.Element(xmlns + "ID").Value,
                                     Title = r.Element(xmlns + "Title").Value,
                                     Description = r.Element(xmlns +
                                                       "Description").Value,
                                     DisplayUrl = r.Element(xmlns + 
                                                      "DisplayUrl").Value,
                                     Url = r.Element(xmlns + "Url").Value,
                                     Keywords = "Setting the keywords here"
                                 };

foreach (WebResult result in results)
{
    result.Keywords = "These, are, my, keywords";
}

if (control is GridView)
{
    (control as GridView).ItemsSource = results;
}

一旦结果显示,"Keywords"属性就是"在此设置关键字"。如果我在foreach循环中放置断点,我可以看到结果对象没有被修改...有什么想法吗?我是不是错过了一些明显的东西?IEnumerable在.NET For Windows Store Apps中的行为是否不同?

1
如果你手头有Resharper,警告“可能多次枚举IEnumerable”可能是一个提示。你正在为每个枚举生成一个新的集合。 - Joachim Isaksson
可能是重复的问题:IEnumerable 中的更改在查询之间未被保留 - Roman
1个回答

10

这被称为延迟执行results是一个查询,每次迭代它时都会执行。在您的情况下,它会在for循环中评估一次,在数据绑定时评估第二次。

您可以通过执行以下操作进行验证

var results2 = results.ToList();

foreach (WebResult result in results2)
{
    result.Keywords = "These, are, my, keywords";
}

if (control is GridView)
{
    (control as GridView).ItemsSource = results2;
}

您应该看到您所做的更改已经保存。


多次迭代是导致结果未被修改的原因,还是类型IEnumerable的原因? - Sunny
谢谢,我从可能的重复链接中得到了它。这是由于多次迭代造成的。 - Sunny
@Sundeep,这不是多次迭代的问题,而是您可能误解了IEnumerable的语义。很多人第一次都会犯这个错误。 - Roman
是的,我以为IEnumerable只是作为迭代器,但不知道它每次都在新实例上运行。 - Sunny
1
@Sundeep Slacks在这个问题上给出了比我更好的解释。 - Roman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接