空接口有什么用?

时间:2019-04-19 12:12:24

标签: c# oop interface

我正在使用的代码具有一个空接口:

public interface ICube {}

它没有方法或属性。

某些类实现ICube,而其他接口则继承自ICube
请有人告诉我该ICube接口可能有什么好处?

2 个答案:

答案 0 :(得分:5)

您应该从MSDN阅读有关Interface Design

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

✓如果需要包含值类型的一组类型所支持的一些通用API,请务必定义一个接口。

✓考虑是否需要在已经从某些其他类型继承的类型上支持其功能的接口中定义接口。

使用标记接口(没有成员的接口)X AVOID。

如果您需要将一个类标记为具有特定特征(标记),通常使用自定义属性而不是接口。

✓必须提供至少一种类型的接口实现。

这样做有助于验证界面的设计。例如,List是IList接口的实现。

✓必须提供至少一个API,该API会使用您定义的每个接口(一种将接口作为参数或将属性键入为接口的方法)。

这样做有助于验证界面设计。例如,List.Sort使用System.Collections.Generic.IComparer接口。

X请勿将成员添加到先前提供的接口中。

更多参考: 空界面Are empty interfaces code smell?

标记界面 What is the purpose of a marker interface?

答案 1 :(得分:4)

这称为“标记界面”。有时,它们用来表示类是出于特定目的的。这不是理想的做法。

虽然我使用了标记器界面,但以下是它们所产生的问题的说明。假设我有一个List<ICube>。也许我将其作为方法参数接收。

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

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

您可以看到我被卡住的地方。 ICube只是一个标记接口,因此它没有自己的方法或属性。我对此无能为力。这很可能导致我将每个多维数据集转换为其他类型,以便我可以对其进行处理。

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

但是如果我强制转换,则会引发运行时错误,因为我可能不确定每个对象的实际运行时类型是什么。如果我知道运行时类型是什么,那么我应该这样做:

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

我们并不是绝对确定会出现此问题,但是使用标记器接口会引起问题。它正在将接口用于其预期目的之外的其他目的。它更像是一个属性,甚至是一条注释。

一个接口有两个用途,可以一起工作:首先,它描述了一个类实现的成员。其次,它允许我们转换一个实现接口 as 的类。标记接口都不起作用。它们允许我们将对象强制转换为没有成员的类型。充其量是没有用的,而在最坏的情况下则是有害的,因为它会导致更可疑的转换。