2013-05-21 58 views
6

Tôi muốn thay đổi giá trị tiền trong danh sách của tôi, nhưng tôi luôn luôn nhận được một thông báo lỗi:Không thể sửa đổi cấu trúc trong danh sách?

Không thể sửa đổi các giá trị trở lại của 'System.Collections.Generic.List.this [int]' vì nó là không phải là biến số

Điều gì là sai? Làm thế nào tôi có thể thay đổi giá trị?

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; 

Trả lời

8

Bạn đã khai báo AccountContainerstruct. Vì vậy,

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

tạo phiên bản mới của trường hợp đó là AccountContainer và thêm bản sao của cá thể đó vào danh sách; và

AccountList[0].Money = 547885; 

lấy một bản sao của mục đầu tiên trong danh sách, thay đổi Money lĩnh vực sao chép và loại bỏ các bản sao – mục đầu tiên trong danh sách vẫn không thay đổi. Vì đây rõ ràng không phải là những gì bạn dự định, trình biên dịch cảnh báo bạn về điều này.

Giải pháp: Không được tạo đột biến struct s. Tạo một bất biến struct (tức là, không thể thay đổi được sau khi đã tạo) hoặc tạo class.

9

Bạn đang sử dụng cấu trúc có thể tắt evil.

Thay đổi thành lớp học và mọi thứ sẽ hoạt động tốt.

+2

Đáng tiếc về 'Điểm',' Hình chữ nhật' và 'Kích thước'. Ít nhất thì Microsoft đã học được một chút trước khi tạo ra 'Complex'. Sẽ rất khó chịu nếu * đó * có thể thay đổi được. –

0

lẽ không được khuyến khích, nhưng nó giải quyết vấn đề:

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

Xóa mục đầu tiên trong danh sách yêu cầu di chuyển tất cả các mục xuống một chỉ mục và sau đó thêm mục sẽ yêu cầu di chuyển chúng trở lại. Thay vào đó bạn chỉ cần đặt giá trị tại chỉ mục đó: 'list [index] = new ...;' – Servy

+0

Điểm tốt - Tôi không cố duy trì thứ tự danh sách. – bigtech

1

Đây là cách tôi sẽ giải quyết nó cho kịch bản của bạn (sử dụng bất biến struct phương pháp, chứ không phải là thay đổi nó vào một 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); 
+0

Nhưng 'AccountContainer' nghĩa là đại diện cho một giá trị? Nó là một cấu trúc? – Servy

+0

@Servy Đó là một câu hỏi tuyệt vời. Nếu ví dụ được đưa ra về việc thay đổi 'Tiền' là một hoạt động được thực thi, thì' AccountContainer' có thể sẽ được phục vụ tốt hơn như một thực thể (theo cách thức DDD). Cảm giác ruột của tôi là những gì được hiển thị là một vết cắt nhỏ hơn của một bức tranh lớn hơn, trong đó thậm chí có thể có cơ hội tốt hơn để phân tích chức năng của dữ liệu thực thể so với giá trị. –

Các vấn đề liên quan