Home Random Page


CATEGORIES:

BiologyChemistryConstructionCultureEcologyEconomyElectronicsFinanceGeographyHistoryInformaticsLawMathematicsMechanicsMedicineOtherPedagogyPhilosophyPhysicsPolicyPsychologySociologySportTourism






Nbsp;   Improving Compile-Time Type Safety with Explicit Interface Method Implementations

Interfaces are great because they define a standard way for types to communicate with each other. Earlier, I talked about generic interfaces and how they improve compile-time type safety and reduce boxing. Unfortunately, there may be times when you need to implement a non-generic interface because a generic version doesn’t exist. If any of the interface’s method(s) accept parameters of type System.Object or return a value whose type is System.Object, you will lose compile-time type safety, and you will get boxing. In this section, I’ll show you how you can use EIMI to improve this situ- ation somewhat.

Look at the very common IComparable interface.

 

public interface IComparable { Int32 CompareTo(Object other);

}

 

This interface defines one method that accepts a parameter of type System.Object. If I define my own type that implements this interface, the type definition might look like the following.

 

internal struct SomeValueType : IComparable { private Int32 m_x;

public SomeValueType(Int32 x) { m_x = x; } public Int32 CompareTo(Object other) {

return(m_x ­ ((SomeValueType) other).m_x);

}

}

 

Using SomeValueType, I can now write the following code.

 

public static void Main() {

SomeValueType v = new SomeValueType(0); Object o = new Object();

Int32 n = v.CompareTo(v); // Undesired boxing

n = v.CompareTo(o); // InvalidCastException

}

 

There are two characteristics of this code that are not ideal.

 

Undesired boxingWhen v is passed as an argument to the CompareTo method, it must be boxed because CompareTo expects an Object.

The lack of type safetyThis code compiles, but an InvalidCastException is thrown inside the CompareTo method when it attempts to cast o to SomeValueType.

 

Both of these issues can be fixed by using EIMIs. Here’s a modified version of SomeValueType that has an EIMI added to it.

 

internal struct SomeValueType : IComparable { private Int32 m_x;

public SomeValueType(Int32 x) { m_x = x; }


public Int32 CompareTo(SomeValueType other) { return(m_x ­ other.m_x);

}

 

// NOTE: No public/private used on the next line Int32 IComparable.CompareTo(Object other) {

return CompareTo((SomeValueType) other);

}

}

 

Notice several changes in this new version. First, it now has two CompareTo methods. The first CompareTo method no longer takes an Object as a parameter; it now takes a SomeValueType instead. Because this parameter has changed, the code that casts other to SomeValueType is no longer necessary and has been removed. Second, changing the first CompareTo method to make it type-safe means that SomeValueType no longer adheres to the contract placed on it by implement- ing the IComparable interface. So SomeValueType must implement a CompareTo method that sat- isfies the IComparable contract. This is the job of the second IComparable.CompareTo method, which is an EIMI.

Having made these two changes means that we now get compile-time type safety and no boxing.



 

public static void Main() {

SomeValueType v = new SomeValueType(0); Object o = new Object();

Int32 n = v.CompareTo(v); // No boxing

n = v.CompareTo(o); // compile­time error

}

 

If, however, we define a variable of the interface type, we will lose compile-time type safety and

experience undesired boxing again.

 

public static void Main() {

SomeValueType v = new SomeValueType(0); IComparable c = v; // Boxing!

 

Object o = new Object();

Int32 n = c.CompareTo(v); // Undesired boxing

n = c.CompareTo(o); // InvalidCastException

}

 

In fact, as mentioned earlier in this chapter, when casting a value type instance to an interface type, the CLR must box the value type instance. Because of this fact, two boxings will occur in the previous Main method.

EIMIs are frequently used when implementing interfaces such as IConvertible, ICollection, IList, and IDictionary. They let you create type-safe versions of these interfaces’ methods, and they enable you to reduce boxing operations for value types.



Date: 2016-03-03; view: 673


<== previous page | next page ==>
Nbsp;   Generic Interfaces | Nbsp;   Be Careful with Explicit Interface Method Implementations
doclecture.net - lectures - 2014-2024 year. Copyright infringement or personal data (0.007 sec.)