tags:

views:

299

answers:

4

I have an object with the following structure: (pseudocode)

class Client
{
- int ID
- int? ParentID
- string Name
- datetime CreateDate
- int ACClientID
- List <Client> Clients }

I want to loop through the whole nested structure using a recursive foreach, to set the ACClientID of ALL to a value.

I know that the enumerator in a foreach is immutable so the following doesn't work:

 private static bool AssignToChildren(ref ATBusiness.Objects.Client client, int ACClientID)
        {
            client.ACClientID = ACClientID;

            foreach (ATBusiness.Objects.Client child in client.Clients)
            {
                AssignToChildren(ref child, ACClientID);
            }
        }

What would be the most efficient way of achieving my goal?

PS: I will not be adding or removing from the structure, merely setting one attribute for every nested Client object.

[edit] I've looked at http://stackoverflow.com/questions/759966/what-is-the-best-way-to-modify-a-list-in-a-foreach but it does not provide me with the answer I need.

A: 

Try this:

private static bool AssignToChildren(ref ATBusiness.Objects.Client client, int ACClientID)
{
  client.ACClientID = ACClientID;
  for (int i = client.Clients.Count - 1; i >= 0; i--) 
  {
    AssignToChildren(ref client.Clients[i], ACClientID);
  }
}
Sani Huttunen
The compiler still does not allow this: Error 5 "A property or indexer may not be passed as an out or ref parameter"
callisto
+11  A: 

Since you never assign to the parameter client you need not pass it using ref.

Since you are not modifing the List<T> object themselves there is no reason you can't modify the ACCClientID property even during an enumeration. Its only when you try to tamper with the list membership that is behind the enumeration that you will get an exception.

AnthonyWJones
Gonna test with a unit test BRB.
callisto
Tested, works as expected. Thank you!
callisto
+1  A: 
    private static bool AssignToChildren(ATBusiness.Objects.Client client, int ACClientID)
    {
        client.ACClientID = ACClientID;

        foreach (ATBusiness.Objects.Client child in client.Clients)
        {
            AssignToChildren(child, ACClientID);
        }
    }
tster
A: 

Can I suggest a specific property for this?

class Client
{
    public Client()
    {
        Clients = new List<Client>();
    }

    public List<Client> Clients { get; private set; }

    private int aCClientID;

    public int ACClientID
    {
        get { return aCClientID; }
        set { aCClientID = value; }
    }

    public int ACClientIDRecursive
    {
        get
        {
            return aCClientID;
        }
        set
        {
            aCClientID = value;
            foreach (var c in Clients)
            {
                c.ACClientIDRecursive = value;
            }
        }
    }
}
bruno conde