Leo
Leo

Reputation: 267

Cannot modify struct in a list?

I want to change the money value in my list, but I always get an error message:

Cannot modify the return value of 'System.Collections.Generic.List.this[int]' because it is not a variable

What is wrong? How can I change the value?

struct AccountContainer
{
    public string Name;
    public int Age;
    public int Children;
    public int Money;

    public AccountContainer(string name, int age, int children, int money)
        : this()
    {
        this.Name = name;
        this.Age = age;
        this.Children = children;
        this.Money = money;
    }
}

List<AccountContainer> AccountList = new List<AccountContainer>();

AccountList.Add(new AccountContainer("Michael", 54, 3, 512913));
AccountList[0].Money = 547885;

Upvotes: 18

Views: 18811

Answers (4)

dtb
dtb

Reputation: 217401

You have declared AccountContainer as a struct. So

AccountList.Add(new AccountContainer("Michael", 54, 3, 512913));

creates a new instance of AccountContainer and adds a copy of that instance to the list; and

AccountList[0].Money = 547885;

retrieves a copy of the first item in the list, changes the Money field of the copy and discards the copy – the first item in the list remains unchanged. Since this is clearly not what you intended, the compiler warns you about this.

Solution: Do not create mutable structs. Create an immutable struct (i.e., one that cannot be changed after it has been created) or create a class.

Upvotes: 21

Jesse C. Slicer
Jesse C. Slicer

Reputation: 20157

Here's how I would solve it for your scenario (using the immutable struct method, rather than changing it to a class):

struct AccountContainer
{
    private readonly string name;
    private readonly int age;
    private readonly int children;
    private readonly int money;

    public AccountContainer(string name, int age, int children, int money)
        : this()
    {
        this.name = name;
        this.age = age;
        this.children = children;
        this.money = money;
    }

    public string Name
    {
        get
        {
            return this.name;
        }
    }

    public int Age
    {
        get
        {
            return this.age;
        }
    }

    public int Children
    {
        get
        {
            return this.children;
        }
    }

    public int Money
    {
        get
        {
            return this.money;
        }
    }
}

List<AccountContainer> AccountList = new List<AccountContainer>();

AccountList.Add(new AccountContainer("Michael", 54, 3, 512913));
AccountList[0] = new AccountContainer(
    AccountList[0].Name,
    AccountList[0].Age,
    AccountList[0].Children,
    547885);

Upvotes: 0

bigtech
bigtech

Reputation: 484

Probably not recommended, but it solves the problem:

AccountList.RemoveAt(0);
AccountList.Add(new AccountContainer("Michael", 54, 3, 547885));

Upvotes: 0

SLaks
SLaks

Reputation: 888107

You're using an evil mutable struct.

Change that to a class and everything will work fine.

Upvotes: 12

Related Questions