List with BindingSource

  • Thread starter Thread starter Miriam Niggles
  • Start date Start date
M

Miriam Niggles

I have a simple List<Customer> like:

List<Customer> lstCustomers = GetAllCustomers();

and i have another list like:

List<Customer> lstCustomersBB = lstCustomers;

My problem is that when i set mi bindongsource like:

mybindingSource.DataSource = lstCurtomersBB and i update any item, the
datasource updates the list lstCustomers too.

I don´t undestand by.... any help please ?

Thanks in advaced.
 
Some more code would be helpful, but I suspect...

lstCustomersBB is the same object as lstCustomers as defined by:

lstCustomersBB = lstCustomers;

If you simply want to have listCustomersBB as a copy of what listCustomers
is RIGHT NOW (without later changes), then use:

listCustomersBB = listCustomers.ToList();

This basically gives you a clone, and future changes to one or the other
wont be reflected in both.

Hope this helps,
 
Miriam said:
I have a simple List<Customer> like:

List<Customer> lstCustomers = GetAllCustomers();

and i have another list like:

List<Customer> lstCustomersBB = lstCustomers;

My problem is that when i set mi bindongsource like:

mybindingSource.DataSource = lstCurtomersBB and i update any item, the
datasource updates the list lstCustomers too. [...]

It's not that "the data source updates the list lstCustomers too". It's
that both "lstCustomers" and "lstCustomersBB" refer to the same object.

If you don't want modifications to the list assigned to the DataSource
property to affect the list assigned to the variable "lstCustomers", you
need to create a new list and use that for the DataSource.

One easy way to do that is to just create a new copy of the original.
For example:

List<Customer> lstCustomerBB = new List<Customer>(lstCustomers);

This creates a new instance of List<Customer>, and initializes it with
the same values found in the instance referred to by "lstCustomers".

Note that if Customer is a reference type (i.e. it's a class, not a
struct), then a change to any individual element of the list will still
be visible in the copied list, because the elements of each list refer
to the same objects.

But at least the list instances themselves will be different, and
modifications to one list will not affect the organization of the other
list.

Pete
 
Thanks for the reply.

Peter, how can i have two list and when i update one item from one list
doesn´t update the other item from the other list ?

Thanks!!

Peter Duniho said:
Miriam said:
I have a simple List<Customer> like:

List<Customer> lstCustomers = GetAllCustomers();

and i have another list like:

List<Customer> lstCustomersBB = lstCustomers;

My problem is that when i set mi bindongsource like:

mybindingSource.DataSource = lstCurtomersBB and i update any item, the
datasource updates the list lstCustomers too. [...]

It's not that "the data source updates the list lstCustomers too". It's
that both "lstCustomers" and "lstCustomersBB" refer to the same object.

If you don't want modifications to the list assigned to the DataSource
property to affect the list assigned to the variable "lstCustomers", you
need to create a new list and use that for the DataSource.

One easy way to do that is to just create a new copy of the original. For
example:

List<Customer> lstCustomerBB = new List<Customer>(lstCustomers);

This creates a new instance of List<Customer>, and initializes it with the
same values found in the instance referred to by "lstCustomers".

Note that if Customer is a reference type (i.e. it's a class, not a
struct), then a change to any individual element of the list will still be
visible in the copied list, because the elements of each list refer to the
same objects.

But at least the list instances themselves will be different, and
modifications to one list will not affect the organization of the other
list.

Pete
 
Miriam said:
Thanks for the reply.

Peter, how can i have two list and when i update one item from one list
doesn´t update the other item from the other list ?

Same thing. Just as preventing the list itself from being updated
requires that a second copy of the list be used in the context where the
update might occur, so too do the elements contained within the list
need to be copied if you want to prevent them from being changed in one
list when updated from the other list.

Note that when dealing with reference types, this problem is recursive.
The List<T> is itself a reference type, so changes to an instance are
visible to any code using the reference to that instance, and when T is
itself a reference type, changes to an instance of any T in the list are
visible to any code using that same reference (such as a copy of the
original List<T>).

Likewise, your type T could itself contain references to other class
instances, and so on.

Cloning is certainly one option. However, if you have more control over
the design of the code, there are a couple of other options that would
result in simpler, easier-to-maintain code:

-- Use a value type in the List<T> instead of a reference type. This
is only a suitable solution if you're dealing with relatively simple
types. But in those scenarios, using a value type automatically results
in copies of each value being made when you create a copy of the List<T>
itself, avoiding the problem altogether.

-- If a reference type should or must be used, but you still have
control over the design of that type, making the type immutable also
will prevent the problem. See the System.String class for an example of
an immutable type. The basic idea is that with an immutable type, if
you want a different value, you don't change the existing instance, you
have to create a new one based on the existing one (e.g.
String.Replace(), String.Substring(), etc. all don't modify the original
String instance, but instead return a new instance).

With the latter approach, there is some added complexity to code that
wants to change the list elements, but not much. Instead of getting the
reference from the list and modifying that instance, you have to get the
reference from the list, and then reassign a new instance based on
whatever mutation method you've called.

Using immutable reference types causes them to wind up working in a very
similar way to the way value types work, and so have some of the same
benefits (along with other reference-type benefits value types don't have).

Pete
 
Thanks a lot Peter!

Peter Duniho said:
Same thing. Just as preventing the list itself from being updated
requires that a second copy of the list be used in the context where the
update might occur, so too do the elements contained within the list need
to be copied if you want to prevent them from being changed in one list
when updated from the other list.

Note that when dealing with reference types, this problem is recursive.
The List<T> is itself a reference type, so changes to an instance are
visible to any code using the reference to that instance, and when T is
itself a reference type, changes to an instance of any T in the list are
visible to any code using that same reference (such as a copy of the
original List<T>).

Likewise, your type T could itself contain references to other class
instances, and so on.

Cloning is certainly one option. However, if you have more control over
the design of the code, there are a couple of other options that would
result in simpler, easier-to-maintain code:

-- Use a value type in the List<T> instead of a reference type. This is
only a suitable solution if you're dealing with relatively simple types.
But in those scenarios, using a value type automatically results in copies
of each value being made when you create a copy of the List<T> itself,
avoiding the problem altogether.

-- If a reference type should or must be used, but you still have
control over the design of that type, making the type immutable also will
prevent the problem. See the System.String class for an example of an
immutable type. The basic idea is that with an immutable type, if you
want a different value, you don't change the existing instance, you have
to create a new one based on the existing one (e.g. String.Replace(),
String.Substring(), etc. all don't modify the original String instance,
but instead return a new instance).

With the latter approach, there is some added complexity to code that
wants to change the list elements, but not much. Instead of getting the
reference from the list and modifying that instance, you have to get the
reference from the list, and then reassign a new instance based on
whatever mutation method you've called.

Using immutable reference types causes them to wind up working in a very
similar way to the way value types work, and so have some of the same
benefits (along with other reference-type benefits value types don't
have).

Pete
 
Back
Top