Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ForEach loop not changing property of class

I've seen a couple questions about this, and done some research.

My understanding is that when you run a foreach on IEnumerable: if T is a Reference Type (e.g. Class) you should be able to modify properties of the object from within the loop. If T is a value type (e.g. Struct) this would not work since the iteration variable would be a local copy.

I am working on a Windows Store app with the following code:

My Class:

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; }
}

The Code:

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;
}

Once the results get displayed the "Keywords" property is "Setting the keywords here". If I put a break point in the foreach loop I can see that the results object is not getting modified...

Any ideas as to what is going on? Am I just missing something obvious? Does IEnumerable behave differently in .NET For Windows Store Apps?

like image 756
Ted A. Avatar asked Feb 16 '13 23:02

Ted A.


1 Answers

This is known as deferred execution; results is a query that is executed every time you iterate over it. In your case it's evaluated twice, once in the for loop, and a second time when it's databound.

You can verify this by doing something like this

var results2 = results.ToList();

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

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

You should see that your changes persisted.

like image 74
Roman Avatar answered Sep 21 '22 11:09

Roman