空接口有什么作用?

kam*_*186 3 c# oop interface

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

public interface ICube {}
Run Code Online (Sandbox Code Playgroud)

它没有方法或属性。

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

Hie*_*yen 7

您应该从MSDN阅读有关 Interface Design

https://docs.microsoft.com/zh-cn/dotnet/standard/design-guidelines/interface

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

?如果需要在已经从其他类型继承的类型上支持其功能,请考虑定义接口。

X使用标记接口(无成员的接口)避免。

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

?请提供至少一种类型的接口实现。

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

?务必提供至少一个API,该API会使用您定义的每个接口(一种以接口为参数或以属性类型作为接口的方法)。

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

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

更多参考:空接口空接口代码有异味吗?

标记界面标记界面 的目的是什么?


Sco*_*nen 5

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

虽然我使用了标记器界面,但是下面是它们所产生的问题的说明。假设我有一个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?
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

public void DoSomethingWithTheseCubes(List<SomeOtherType> things)
{
    foreach(var thing in things)
    {
        thing.DoSomething();
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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