7

The code I'm working with has an empty interface:

public interface ICube {}

It has no methods or properties.

Some classes implement ICube and other interfaces inherit from ICube.
Please someone tell me how that ICube interface could be beneficial?

Scott Hannen
  • 27,588
  • 3
  • 45
  • 62
kamran186
  • 111
  • 1
  • 5

2 Answers2

12

You should read from MSDN about Interface Design

https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/interface

✓ DO define an interface if you need some common API to be supported by a set of types that includes value types.

✓ CONSIDER defining an interface if you need to support its functionality on types that already inherit from some other type.

X AVOID using marker interfaces (interfaces with no members).

If you need to mark a class as having a specific characteristic (marker), in general, use a custom attribute rather than an interface.

✓ DO provide at least one type that is an implementation of an interface.

Doing this helps to validate the design of the interface. For example, List is an implementation of the IList interface.

✓ DO provide at least one API that consumes each interface you define (a method taking the interface as a parameter or a property typed as the interface).

Doing this helps to validate the interface design. For example, List.Sort consumes the System.Collections.Generic.IComparer interface.

X DO NOT add members to an interface that has previously shipped.

More reference: Empty interface Are empty interfaces code smell?

Marker interface What is the purpose of a marker interface?

Hien Nguyen
  • 24,551
  • 7
  • 52
  • 62
6

This is called a "marker interface." Sometimes they're used to indicate that a class is meant for a certain purpose. It's not a desirable practice.

While I have used marker interfaces, here's an illustration of the problem they create. Suppose I have a List<ICube>. Perhaps I receive it as a method argument.

public interface ICube {} // It's empty!

public void DoSomethingWithTheseCubes(List<ICube> cubes)
{
    foreach(var cube in cubes)
    {
        // what do I do with this cube?
    }
}

You can see where I get stuck. ICube is just a marker interface, so it has no methods or properties of its own. I can't do anything with it. That's likely to result in me casting each cube to some other type so I can do something with it.

public void DoSomethingWithTheseCubes(List<ICube> cubes)
{
    foreach(var cube in cubes)
    {
        (SomeOtherType)cube.DoSomething();
    }
}

But if I cast it I'm inviting a runtime error because I may not know for sure what the actual runtime type of each object is. If I know what the runtime type is, then I just should do this:

public void DoSomethingWithTheseCubes(List<SomeOtherType> things)
{
    foreach(var thing in things)
    {
        thing.DoSomething();
    }
}

We're not absolutely certain to have that problem, but using a marker interface invites it. It's using an interface for something other than its intended purpose. It's more like an attribute or even a comment.

An interface has two uses that work together: First, it describes the members that a class implements. Second, it allows us to cast a class that implements an interface as that interface. Marker interfaces do neither. They allow us to cast an object as a type with no members. That's useless at best, and at worst it's harmful because it leads to even more questionable casting.

Scott Hannen
  • 27,588
  • 3
  • 45
  • 62
  • So what is the alternative? Because even Microsoft is doing this. For example: IAuthorizationRequirement – mightycode Newton Jan 17 '22 at 11:00
  • Like with many things, I've softened my viewpoint a little. If the only thing we're doing with the interface is checking `if (thisThing is ISomeType)` but there's no other casting, it's not so bad. An attribute makes more sense to me. – Scott Hannen Jun 28 '22 at 17:07