Interfaces with no members at all, inherited or otherwise, are sometimes used to represent information about a type. For example, you might create a marker IObsolete interface to indicate that a type has been replaced by another type. This is generally considered to be an abuse of the interface mechanism: Interfaces should be used to represent which functions a type can perform, not to indicate facts about particular types. Instead of marker interfaces, use attributes for this purpose. See Chapter 18 for more details.
Interfaces are a key element of object-oriented programming in C#. They provide polymorphic capabilities like abstract classes without using up the single-inheritance option, because classes can implement multiple interfaces. Starting with C# 8.0/.NET Core 3.0, interfaces can include implementation via the use of default interface members, almost giving them a superset of the capabilities of abstract classes if backward compatibility is not required.
In C#, the implementation of interfaces can be either explicit or implicit, depending on whether the implementing class is used to expose an interface member directly or only via a conversion to the interface. Furthermore, the granularity of whether the implementation is explicit or implicit is determined at the member level: One member may be implicitly implemented, while another member of the same interface is explicitly implemented.
Chapter 9 looks at value types and discusses the importance of defining custom value types. In addition, it points out the subtle problems that such types can introduce.