Detailed explanation of C implicit and display implementation interface method

  • 2021-09-12 01:51:16
  • OfStack

The interface defines a series of behavioral specifications, defining one Can-Do function for the type. For example, the implementation of the IEnumerable interface defines the GetEnumerator method to get an enumerator that supports iteration over a collection, commonly known as foreach. Interface only defines behavior, and the specific implementation needs to be responsible for specific types. The methods of implementing interface can be divided into implicit implementation and explicit implementation.

1. Implicit/explicit implementation interface method

To put it simply, we usually use implicit implementation by default. For example:


interface ILog
{
  void Log();
}
 
public class FileLogger : ILog
{
  public void Log()
  {
    Console.WriteLine(" Record to file! ");
  }
}

Implicit implementation is very simple. Usually, we agree that the interface name begins with I, which is convenient to read. The method in the interface does not need public, and the compiler will automatically add it. A method in a type that implements an interface can only be public or can be defined as a virtual method overridden by a subclass. Now look at how to show the implementation:


public class EventLogger : ILog
{
  void ILog.Log()
  {
    Console.WriteLine(" Log system events! ");
  }
}

Unlike above, the method is specified with ILog, and there is no (and cannot be) public or private modifier.

In addition to the syntax difference, the calling method is also different, and the display implementation can only be called with variables of interface type, such as:


FileLogger fileLogger = new FileLogger();
fileLogger.Log(); // Correct 
EventLogger eventLogger = new EventLogger();      
eventLogger.Log(); // Report an error 
ILog log = new EventLogger();
log.Log(); // Correct 

2. When to use

1. c # allows multiple interfaces to be implemented. If multiple interfaces define the same method, they can be distinguished by showing the implementation, for example:


interface ISendable
{
  void Log();
}
 
public class EmailLogger : ILog, ISendable
{
  void ILog.Log()
  {
    Console.WriteLine("ILog");
  }
 
  void ISendable.Log()
  {
    Console.WriteLine("ISendable");
  }
}

2. Enhance compile-time type safety and avoid value type boxing

With generics, we can naturally achieve compile-time type safety and avoid value type boxing. But sometimes there may not be a corresponding generic version. For example: IComparable (here is just an example, there is actually IComparable < T > ). Such as:


interface IComparable
{
  int CompareTo(object obj);
}
 
struct ValueType : IComparable
{
  private int x;
  public ValueType(int x)
  {
    this.x = x;
  }
 
  public int CompareTo(object obj)
  {
    return this.x - ((ValueType)obj).x;
  }
} 

Call:


ValueType vt1 = new ValueType(1);
ValueType vt2 = new ValueType(2);
Console.WriteLine(vt1.CompareTo(vt2));

Since the formal parameter is object, the above CompareTo will be boxed; Moreover, we can't get the type safety at compile time. For example, we can pass an string at will, and the compilation will not report an error. Only when the runtime throws InvalidCastException. Use the method of displaying the implementation interface, such as:


public int CompareTo(ValueType vt)
{
  return this.x - vt.x;
}
 
int IComparable.CompareTo(object obj)
{
  return CompareTo((ValueType)obj);
} 

If you execute the above code again, the boxing operation will not occur, and you can get compile-time type safety. But if we call with an interface variable, boxing happens again and compile-time type-safety detection is lost.


IComparable vt1 = new ValueType(1); // Packing 
ValueType vt2 = new ValueType(2);
Console.WriteLine(vt1.CompareTo(vt2)); // Packing again 

3. Disadvantages

1. The display implementation can only be called with an interface type variable, which gives the impression that a type implements the interface but cannot call the methods in the interface. In particular, when written as a class library to be called by others, the interface method displayed will not be displayed by pressing f12 in vs. (This has been asked in csdn why a type can not implement an interface method.)

2. For value types, a boxing operation occurs to invoke the method that displays the implementation.

3. Cannot be inherited by subclasses.

The above is the C # display implementation interface of the entire content, hope to help everyone's learning.


Related articles: