![]() CATEGORIES: BiologyChemistryConstructionCultureEcologyEconomyElectronicsFinanceGeographyHistoryInformaticsLawMathematicsMechanicsMedicineOtherPedagogyPhilosophyPhysicsPolicyPsychologySociologySportTourism |
Nbsp; Generic InterfacesC#’s and the CLR’s support of generic interfaces offers many great features for developers. In this sec- tion, I’d like to discuss the benefits offered when using generic interfaces.
First, generic interfaces offer great compile-time type safety. Some interfaces (such as the non- generic IComparable interface) define methods that have Object parameters or return types. When code calls these interface methods, a reference to an instance of any type can be passed. But this is usually not desired. The following code demonstrates.
private void SomeMethod1() { Int32 x = 1, y = 2; IComparable c = x;
// CompareTo expects an Object; passing y (an Int32) is OK c.CompareTo(y); // y is boxed here
// CompareTo expects an Object; passing "2" (a String) compiles // but an ArgumentException is thrown at runtime c.CompareTo("2"); } Obviously, it is preferable to have the interface method strongly typed, and this is why the FCL includes a generic IComparable<in T> interface. Here is the new version of the code revised by using the generic interface.
private void SomeMethod2() { Int32 x = 1, y = 2; IComparable<Int32> c = x;
// CompareTo expects an Int32; passing y (an Int32) is OK c.CompareTo(y); // y is not boxed here
// CompareTo expects an Int32; passing "2" (a String) results // in a compiler error indicating that String cannot be cast to an Int32 c.CompareTo("2"); // Error }
you want to implement any of these interfaces, you should typically implement the generic versions of these interfaces. The non-generic versions are in the FCL for backward compat- ibility to work with code written before the .NET Framework supported generics. The non- generic versions also provide users a way of manipulating the data in a more general, less type-safe fashion. Some of the generic interfaces inherit the non-generic versions, so your class will have to implement both the generic and non-generic versions of the interfaces. For example, the generic IEnumerable<out T> interface inherits the non-generic IEnumerable inter- face. So if your class implements IEnumerable<out T>, your class must also implement IEnumerable. Sometimes when integrating with other code, you may have to implement a non-generic interface because a generic version of the interface simply doesn’t exist. In this case, if any of the interface’s methods take or return Object, you will lose compile-time type safety, and you will get boxing with value types. You can alleviate this situation to some extent by using a technique I describe in the “Improving Compile-Time Type Safety with Explicit Interface Method Implementations” section near the end of this chapter. The third benefit of generic interfaces is that a class can implement the same interface multiple times as long as different type parameters are used.
The following code shows an example of how useful this could be.
using System;
// This class implements the generic IComparable<T> interface twice public sealed class Number: IComparable<Int32>, IComparable<String> { private Int32 m_val = 5;
// This method implements IComparable<Int32>'s CompareTo public Int32 CompareTo(Int32 n) { return m_val.CompareTo(n); }
// This method implements IComparable<String>'s CompareTo public Int32 CompareTo(String s) { return m_val.CompareTo(Int32.Parse(s)); } }
public static class Program { public static void Main() { Number n = new Number();
// Here, I compare the value in n with an Int32 (5) IComparable<Int32> cInt32 = n; Int32 result = cInt32.CompareTo(5);
// Here, I compare the value in n with a String ("5") IComparable<String> cString = n; result = cString.CompareTo("5"); } }
An interface’s generic type parameters can also be marked as contra-variant and covariant, which allows even more flexibility for using generic interfaces. For more about contra-variance and covari- ance, see the “Delegate and Interface Contra-variant and Covariant Generic Type Arguments” section in Chapter 12.
Date: 2016-03-03; view: 644
|