Eric Vogel covers some practical uses
for the long awaited interfaces, IReadOnlyList and IReadOnlyDictionary
in .NET Framework 4.5.
The Microsoft .NET Framework 4.5 includes the IReadOnlyList,
IReadOnlyDictionary and IReadOnlyCollection generic interfaces. The main
benefit is that the new interfaces are covariant, except for
IReadOnlyDictionary. This means that you can use a derived type as the
generic parameter, when passing in a collection into a method that's
defined for a base type. If you have a Dog class, for example, that
derives from Animal, you can have a method that accepts an
IReadOnlyListThe IReadOnlyCollection interface, which forms the base of the IReadOnlyList and IReadOnlyDictionary classes, is defined as IReadOnlyCollection
Prior to .NET 4.5, the primary covariant collection interface was IEnumerable
A common scenario you may run into, is storing a list of people or employees. The application may be a case or customer relationship management system. Either way, you're dealing with similar class representations. For example, if you have a Person class that contains FirstName and LastName properties (Listing 1), and an Employee subclass that adds EIN and Salary properties (Listing 2). This is a very simplified view of a business domain, but it gets the picture across.
You could then create a typed list of Employee objects and access them as a read-only collection using the new interfaces. In a real-world application, your employee list is likely to be quite large and retrieved from a database.
ListThe IReadOnlyCollection is the most basic read-only collection interface and provides a Count property on top of its inherent IEnumerable members. For example, you could store a read-only view of employees for a directory listing and easily retrieve the number of people.employees = new List () { new Employee() { EIN = 1, FirstName = "John", LastName = "Doe", Salary= 55000M }, new Employee() { EIN = 2, FirstName = "Jane", LastName = "Doe", Salary= 55000M }, new Employee() { EIN = 3, FirstName = "Don", LastName = "DeLuth", Salary= 55000M }, };
IReadOnlyCollectionThe IReadOnlyList interface is the same as IReadOnlyCollection with the addition of an item indexer.directory = employees; int numStaff = directory.Count;
IReadOnlyListThe IReadOnlyList would be well-suited for a read-only grid display of the needed items.staff = employees; Person firstHire = staff[0];
The IReadOnlyDictionary interface, as its name suggests, provides a read-only view of the Dictionary class. The accessible Dictionary class members include the Keys, Values and key indexer properties, in addition to the ContainsKey and TryGetValue methods.
DictionaryThe IReadOnlyDictionary interface could prove useful for validation, as you would not need to modify the items but may want to quickly access them via a key, such as a control identifier.einLookUp = employees.ToDictionary(x => x.EIN); IReadOnlyDictionary readOnlyStaff = einLookUp; var eins = readOnlyStaff.Keys; var allEmployees = readOnlyStaff.Values; var secondStaff = readOnlyStaff[2]; bool haveThirdEin = readOnlyStaff.ContainsKey(3); Employee test; bool fourthExists = readOnlyStaff.TryGetValue(4, out test);
As you can see, there are many uses for the new read-only collection interfaces. Primarily, they can be used to clean up your application's API to indicate that a method or class should not modify the contents of a collection that it is accessing. One caveat to note is that the interfaces do not provide an immutable copy of the collection but rather a read-only view of the source mutable collection.
Eric Vogel is a Software Developer at Red Cedar Solutions Group in Okemos, MI. He is the president of the Greater Lansing User Group for .NET. Eric enjoys learning about software architecture and craftsmanship and is always looking for ways to create more robust and testable applications. Contact him at eric.vogel@rcsg.net.
No comments:
Post a Comment