Dart UnmodifiableListView
last modified April 4, 2025
In Dart, UnmodifiableListView is an unmodifiable view of a List. It wraps an existing List and prevents modifications through the view.
UnmodifiableListView implements List but throws UnsupportedError for operations that would modify the list. It's useful for exposing internal lists safely.
Creating an UnmodifiableListView
The simplest way to create an UnmodifiableListView is using its constructor.
import 'dart:collection'; void main() { var numbers = [1, 2, 3, 4, 5]; var unmodifiableView = UnmodifiableListView(numbers); print(unmodifiableView); try { unmodifiableView.add(6); // Will throw } catch (e) { print('Error: $e'); } }
We create an unmodifiable view of a mutable list. Attempting to modify it throws an UnsupportedError. The original list can still be modified.
$ dart main.dart [1, 2, 3, 4, 5] Error: Unsupported operation: Cannot add to an unmodifiable list
UnmodifiableListView with List Operations
UnmodifiableListView supports all non-modifying List operations like access and iteration.
import 'dart:collection'; void main() { var fruits = ['apple', 'banana', 'orange']; var unmodifiableFruits = UnmodifiableListView(fruits); // Access elements print('First fruit: ${unmodifiableFruits[0]}'); print('Length: ${unmodifiableFruits.length}'); // Iteration for (var fruit in unmodifiableFruits) { print(fruit.toUpperCase()); } // Non-modifying methods print('Contains apple: ${unmodifiableFruits.contains('apple')}'); print('Index of banana: ${unmodifiableFruits.indexOf('banana')}'); }
We demonstrate read-only operations on an UnmodifiableListView. All standard List access methods work as expected without modification capabilities.
$ dart main.dart First fruit: apple Length: 3 APPLE BANANA ORANGE Contains apple: true Index of banana: 1
Protecting Internal Lists
UnmodifiableListView is commonly used to expose internal lists safely.
import 'dart:collection'; class Team { final List<String> _members = []; UnmodifiableListView<String> get members => UnmodifiableListView(_members); void addMember(String name) { _members.add(name); } } void main() { var team = Team(); team.addMember('Alice'); team.addMember('Bob'); print('Team members: ${team.members}'); try { team.members.add('Charlie'); // Will throw } catch (e) { print('Cannot modify: $e'); } }
The Team class exposes its members through an UnmodifiableListView. Clients can read but not modify the list directly. Modifications must go through addMember.
$ dart main.dart Team members: [Alice, Bob] Cannot modify: Unsupported operation: Cannot add to an unmodifiable list
UnmodifiableListView vs Unmodifiable List
UnmodifiableListView differs from creating a truly unmodifiable list.
import 'dart:collection'; void main() { var original = [1, 2, 3]; var view = UnmodifiableListView(original); var unmodifiableCopy = List.unmodifiable(original); original.add(4); // Modifies the original print('View: $view'); // Reflects changes print('Copy: $unmodifiableCopy'); // Doesn't change try { view.add(5); // Throws unmodifiableCopy.add(5); // Also throws } catch (e) { print('Both prevent modification'); } }
UnmodifiableListView is a live view that reflects changes to the original list. List.unmodifiable creates an independent copy that won't change.
$ dart main.dart View: [1, 2, 3, 4] Copy: [1, 2, 3] Both prevent modification
Combining with Other Collections
UnmodifiableListView can be combined with other collection operations.
import 'dart:collection'; void main() { var data = [10, 20, 30, 40, 50]; // Create filtered unmodifiable view var evenView = UnmodifiableListView( data.where((n) => n % 2 == 0).toList()); print('Even numbers: $evenView'); // Create transformed unmodifiable view var squaredView = UnmodifiableListView( data.map((n) => n * n).toList()); print('Squared numbers: $squaredView'); // Attempt modification try { evenView.removeLast(); } catch (e) { print('Cannot modify: $e'); } }
We create specialized unmodifiable views by combining filtering and mapping with UnmodifiableListView. The views remain immutable while showing transformed data.
$ dart main.dart Even numbers: [20, 40, 50] Squared numbers: [100, 400, 900, 1600, 2500] Cannot modify: Unsupported operation: Cannot remove from an unmodifiable list
Best Practices
- Defensive Programming: Use to prevent accidental modifications.
- Performance: Prefer over copying large lists when possible.
- Documentation: Clearly indicate when APIs return unmodifiable views.
- Alternatives: Consider List.unmodifiable for truly immutable snapshots.
Source
Dart UnmodifiableListView Documentation
This tutorial covered Dart's UnmodifiableListView with practical examples demonstrating its key features and usage patterns.
Author
List all Dart tutorials.