When creating a new version of a component or application that other developers have programmed against, you should not change interfaces. Because interfaces define a contract between the implementing class and the class using the interface, changing the interface is changing the contract, which will possibly break any code written against the interface.

Changing or removing a particular interface member signature is obviously a code-breaking change, as any call to that member will no longer compile without modification. The same is true when changing public or protected member signatures on a class. However, unlike with classes, adding members to an interface could also prevent code from compiling without additional changes. The problem is that any class implementing the interface must do so entirely, and implementations for all members must be provided. With new interface members, the compiler will require that developers add new interface members to the class implementing the interface.

The creation of IDistributedSettingsProvider in Listing 7.11 serves as a good example of extending an interface in a version-compatible way. Imagine that at first, only the ISettingsProvider interface is defined (as it was in Listing 7.6). In the next version, however, it is determined that per-machine settings are required. To enable this, the IDistributedSettingsProvider interface is created, and it derives from ISettingsProvider.

Listing 7.11. Deriving One Interface from Another

 interface IDistributedSettingsProvider : ISettingsProvider {   /// <summary>   /// Get the settings for a particular machine.   /// </summary>   /// <param name="machineName">   /// The machine name the setting is related to</param>   /// <param name="name">The name of the setting</param>   /// <param name="defaultValue">   /// The value returned if the setting is not found.</param>   /// <returns>The specified setting</returns>   string GetSetting(       string machineName, string name, string defaultValue);   /// <summary>   /// Set the settings for a particular machine.   /// </summary>   /// <param name="machineName">   /// The machine name the setting is related to.</param>   /// <param name="name">The name of the setting.</param>   /// <param name="value">The value to be persisted.</param>   /// <returns>The specified setting</returns>   void SetSetting(       string machineName, string name, string value); } 

The important factor is that programmers with classes that implement ISettingsProvider can choose to upgrade the implementation to include IDistributedSettingsProvider, or they can ignore it.

If instead of creating a new interface, the machine-related methods are added to ISettingsProvider, then classes implementing this interface will no longer successfully compile with the new interface definition, and instead a version-breaking change will occur.

Changing interfaces during the development phase is obviously acceptable, although perhaps laborious if implemented extensively. However, once an interface is released, it should not be changed. Instead, a second interface should be created, possibly deriving from the original interface.

(Listing 7.11 includes XML comments describing the interface members, as discussed further in Chapter 9.)

Essential C# 2.0
Essential C# 2.0
ISBN: 0321150775
EAN: 2147483647
Year: 2007
Pages: 185 © 2008-2017.
If you may any questions please contact us: