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.