Introduction
The normal List
class in C# is not capable of providing notifications when an item is added or removed.
The .NET Framework provides an ObservableCollection
class which is capable of providing these features. In this Article I will demonstrate how
ObservableCollection
can be used to prevent the addition of a
duplicate entry into a List
/Collection
.
Background
The overall concept is demonstrated using two simple classes Company
and
Customer
. Company
can have many customers but if anyone tries to add a duplicate
customer to a Company
, that will not be allowed and an exception will be thrown.
Using the code
The class Customer
consists of two properties Id
,
Name
and a constructor to set the values for these properties.

The class Company
consist of properties Id
, Name
,
Customers
, and a constructor to set values for these properties.

It also associates the CustomerCollectionChanged
method to the
CollectionChanged
event of the ObservableCollection
.
private ObservableCollection<Customer> customers = null;
public IList<Customer> Customers
{
get
{
return this.customers;
}
private set
{
this.customers = new ObservableCollection<Customer>(value);
}
}
public Company(int id, string name)
{
this.customers = new ObservableCollection<Customer>();
this.customers.CollectionChanged += this.CustomerCollectionChanged;
this.Id = id;
this.Name = name;
}
Whenever a customer is added to the Customers
list of the Company
, the
CustomerCollectionChanged
method will be invoked which in turn invokes the
ValidateCustomerCollection
to prevent the duplicate entry into the
Customers
list.
private void CustomerCollectionChanged(object sender,
System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
ValidateCustomerCollection(e);
}
private void ValidateCustomerCollection(NotifyCollectionChangedEventArgs eventArg)
{
if (eventArg.Action == NotifyCollectionChangedAction.Add ||
eventArg.Action == NotifyCollectionChangedAction.Replace)
{
for (int i = 0; i < eventArg.NewItems.Count; i++)
{
Customer customer = eventArg.NewItems[i] as Customer;
if (Customers.Where(c => c.Id == customer.Id).Count() > 1)
{
customers.Remove(customer);
throw new ArgumentException("Customer cannot be duplicated.");
}
}
}
}
The Unit Test project contains the positive and negative scenarios for testing the
Customers
list validation.
[TestMethod]
public void CreateCompany()
{
int count = 0;
int[] arr = new int[] { 101, 102, 103 };
Company company = new Company(201, "Microsoft");
Customer customer1 = new Customer(101,"Walmart");
Customer customer2 = new Customer(102, "Tesco");
Customer customer3 = new Customer(103, "QFC");
company.Customers.Add(customer1);
company.Customers.Add(customer2);
company.Customers.Add(customer3);
foreach (Customer c in company.Customers)
{
Assert.AreEqual(arr[count++],c.Id);
}
}
[TestMethod]
public void CreateCompanyWithException()
{
try
{
Company company = new Company(201, "Microsoft");
Customer customer1 = new Customer(101, "Walmart");
company.Customers.Add(customer1);
company.Customers.Add(customer1);
}
catch (ArgumentException ex)
{
Assert.AreEqual("Customer cannot be duplicated.", ex.Message);
}
}
You can download the source code DuplicateNotifierList.zip.
History
- This is the first version as on 7 March 2012.