C# tutorials > Core C# Fundamentals > Data Structures and Collections > What are observable collections (`ObservableCollection<T>`)?
What are observable collections (`ObservableCollection<T>`)?
Understanding Observable Collections in C#
Observable collections (`ObservableCollection
Basic Concept and Implementation
This code demonstrates a basic implementation of `ObservableCollection
using System.Collections.ObjectModel;
public class Example
{
public ObservableCollection<string> Names { get; set; }
public Example()
{
Names = new ObservableCollection<string>();
Names.CollectionChanged += Names_CollectionChanged;
}
private void Names_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
switch (e.Action)
{
case System.Collections.Specialized.NotifyCollectionChangedAction.Add:
if (e.NewItems != null)
{
foreach (var item in e.NewItems)
{
Console.WriteLine($"Added: {item}");
}
}
break;
case System.Collections.Specialized.NotifyCollectionChangedAction.Remove:
if (e.OldItems != null)
{
foreach (var item in e.OldItems)
{
Console.WriteLine($"Removed: {item}");
}
}
break;
case System.Collections.Specialized.NotifyCollectionChangedAction.Replace:
if (e.OldItems != null && e.NewItems != null)
{
Console.WriteLine($"Replaced {e.OldItems[0]} with {e.NewItems[0]}");
}
break;
case System.Collections.Specialized.NotifyCollectionChangedAction.Reset:
Console.WriteLine("Collection was reset");
break;
}
}
public void AddName(string name)
{
Names.Add(name);
}
public void RemoveName(string name)
{
Names.Remove(name);
}
public void ReplaceName(string oldName, string newName)
{
int index = Names.IndexOf(oldName);
if (index != -1)
{
Names[index] = newName;
}
}
public void Reset()
{
Names.Clear();
}
}
Concepts Behind the Snippet
The core concept behind `ObservableCollection
Real-Life Use Case
In a WPF application, you might bind a `ListBox` to an `ObservableCollection
<!-- XAML Example -->
<ListBox ItemsSource="{Binding Names}" />
// C# ViewModel
public class ViewModel : INotifyPropertyChanged
{
private ObservableCollection<string> _names = new ObservableCollection<string>();
public ObservableCollection<string> Names
{
get { return _names; }
set
{
_names = value;
OnPropertyChanged(nameof(Names));
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public ViewModel()
{
Names.Add("Alice");
Names.Add("Bob");
}
}
Best Practices
Interview Tip
When asked about `ObservableCollection
When to Use Them
Use `ObservableCollection
Memory Footprint
The memory footprint of an `ObservableCollection
Alternatives
Pros
Cons
FAQ
-
Is `ObservableCollection
` thread-safe?
No, `ObservableCollection` is not inherently thread-safe. You need to implement your own synchronization mechanisms (e.g., using `lock` statements) if you are modifying the collection from multiple threads. -
What is the difference between `ObservableCollection
` and `List `?
`ObservableCollection` implements the `INotifyCollectionChanged` interface, which allows it to notify listeners (e.g., UI elements) when the collection changes. `List ` does not have this functionality. If you need automatic UI updates, use `ObservableCollection `. If not, `List ` is generally more performant. -
How do I handle property changes within objects in an ObservableCollection?
The objects within the `ObservableCollection` should implement `INotifyPropertyChanged`. When a property changes on one of these objects, it raises the `PropertyChanged` event. You can then subscribe to this event to update the UI accordingly.