Imagine this struct
:
struct Person
{
public string FirstName { get; set; }
public string LastName { g
Redo your struct
as such:
struct Person
{
private readonly string firstName;
private readonly string lastName;
public Person(string firstName, string lastName)
{
this.firstName = firstName;
this.lastName = lastName;
}
public string FirstName { get { return this.firstName; } }
public string LastName { get { return this.lastName; } }
}
And following code as :
var list = new List<Person>();
list.Add(new Person("F1", "L1"));
list.Add(new Person("F2", "L2"));
list.Add(new Person("F3", "L3"));
// Can modify the expression because it's a new instance
list[1] = new Person("F22", list[1].LastName);
This is due to the copy semantics of struct
. Make it immutable and work within those constraints and the problem goes away.
Obviously a part of the question is still unanswered. What is difference between List<Person>
and Person[]
. In term of getting element by index the List
calls indexer (method) which returns copy of value-type instance, in opposite array by index returns not a copy but managed pointer to element at the index (used special IL instruction ldelema).
Of course mutable value-types are evil as mentioned in other answers. Look at the simple example.
var en = new {Ints = new List<int>{1,2,3}.GetEnumerator()};
while(en.Ints.MoveNext())
{
Console.WriteLine(x.Ints.Current);
}
Surprised?
When you return the struct
via the List[]
indexer, it returns a copy of the entry. So if you assigned the FirstName
there, it would just be thrown away. Hence the compiler error.
Either rewrite your Person
to be a reference type class
, or do a full reassignment:
Person person = list[1];
person.FirstName = "F22";
list[1] = person;
Generally speaking, mutable structs bring about issues such as these that can cause headaches down the road. Unless you have a really good reason to be using them, you should strongly consider changing your Person
type.
Why are mutable structs “evil”?