-1

I have implemented the following code and when I want to update(add or remove) from the ColumnsList of one of the instances, it affectss all the other instances.

    public class XMLAttributeStructure
    {
        public string TableName { get; set; }
        public int Row { get; set; }
        public List<string> ColumnsList { get; set; }
        public string Attribute { get; set; }
        public string Value { get; set; }

        public XMLAttributeStructure(string tablename, int row, List<string> columnlist, string attribute, string value)
        {
            TableName = tablename;
            Row = row;
            ColumnsList = columnlist;
            Attribute = attribute;
            Value = value;
        }
    }

output :

For example think I already have 2 objects with columnsList which contains "No", "Status". And think I removed "ST" from the first instance's columnList using the following.

selectedObj.ColumnsList.Remove("ST");

selectedObj is the first instance. But "ST" in the second object also gets removed.

Kalpani Ranasinghe
  • 111
  • 1
  • 1
  • 11
  • Can you show a [mcve] of how "it affectss all the other instances"? – Sweeper Feb 24 '21 at 07:39
  • 2
    Obviously, you share the same `columnlist` between several `XMLAttributeStructure` instances. Since `List` is a reference type, passing the same `columnlist` in every ctor just passes reference to the same object. – Dennis Feb 24 '21 at 07:39
  • @Dennis How can I fix that? – Kalpani Ranasinghe Feb 24 '21 at 07:48
  • 1
    @KalpaniRanasinghe: show the code sample, which creates two `XMLAttributeStructure`s. – Dennis Feb 24 '21 at 07:51
  • `ColumnsList = columnlist.ToList();` This will allocate a new list. – TheGeneral Feb 24 '21 at 07:53
  • @Dennis Here the code ```for(int i = 0; i < noOfRows; i++) { XMLAttributes.Add(new XMLAttributeStructure(tableName, i, colList, attribute, value)); }``` – Kalpani Ranasinghe Feb 24 '21 at 07:53
  • @00110001 Thank you very much! Adding ```ColumnsList = columnlist.ToList();``` this to the constructor solved the problem :) – Kalpani Ranasinghe Feb 24 '21 at 07:58
  • The list is a reference type. You pass the same list to each object, so they all have the same list. You have to give each object it's own list, if you don't want them to all use the same list. See duplicate for all the details you need to know about reference types and how they differ from value types. – Peter Duniho Feb 24 '21 at 08:15

1 Answers1

2

Disregarding any other problem, the simplest solution would be to just reallocate your list

public XMLAttributeStructure(string tablename, int row, List<string> columnlist, string attribute, string value)
{
    ...
    ColumnsList = columnlist.ToList();

Another solution would be to do this when you call the constructor. That way the constructor isn't doing anything unexpected, and it lets the caller choose if they want the class to have a new instance or not

XMLAttributes.Add(
   new XMLAttributeStructure(
       tableName, 
       i, 
       colList.ToList(),
       attribute, 
       value));

The longer story, is when you copy a reference type, you aren't making a copy of the actual object (clone), you are making a copy of the reference to the object


Additional Resources

TheGeneral
  • 79,002
  • 9
  • 103
  • 141