En C# 8.0, puedo modificar el valor dentro de una tupla directamente accediendo al nombre del campo:
(string name, int score) student = ("Tom", 100); student.name = "Jack"; Console.WriteLine(student);Y puedo modificar la propiedad del elemento de la lista de la siguiente manera:
var list = new List<Student>(); // assume I have a Student class which has a Name property list.Add(new Student { Name = "Tom" }); list[0].Name = "Jack"; Console.WriteLine(list[0]);Pero, ¿por qué no puedo modificar el valor del elemento de tipo tupla de esta manera?
var list = new List<(string name, int score)>(); list.Add(("Tom", 100)); list[0].name = "Jack"; // Error! Console.WriteLine(list[0]);Los tipos de valores mutables son malos, es difícil ver por qué esto imprime "Tom" y no "Jack":
(string name, int score) student = ("Tom", 100); (string name, int score) student2 = student; student.name = "Jack"; Console.WriteLine(student2);La razón es que siempre creas una copia. Debido a que no es obvio, debe evitar los tipos de valores mutables. Para evitar que la gente caiga en esa trampa, el compilador solo permite modificar el objeto directamente a través de las propiedades (como arriba). Pero si intenta hacerlo a través de una llamada de método, obtiene un error del compilador "No se puede modificar el valor de retorno de... porque no es una variable".
Así que esto no está permitido:
list[0].name = "Jack"; Crearía una nueva copia de ValueTuple , asigna un valor pero no lo usa ni lo almacena en ninguna parte.
Esto se compila porque lo asigna a una nueva variable y lo modifica a través de la propiedad:
(string name, int score) x = list[0]; x.name = "Jack"; // CompilesEntonces compila pero te da nuevamente un resultado sorprendente:
Console.WriteLine(list[0]); // TomLea más sobre esto aquí: No definir tipos de valores mutables