为什么我们要使用无成员接口?

7

写一个没有成员的接口有什么意义?

INamingContainer是.NET Framework中的一个例子。在MSDN中描述为:

标识一个容器控件,在Page对象的控件层次结构中创建一个新的ID命名空间。这只是一个标记接口。

它仅用于这种类型的块吗:

if (myControl is INamingContainer)
{
    // do something
}

或者它还有其他的优点吗?
编辑:它被称为 标记接口模式(感谢 Preet)。
4个回答

10

无成员接口在C#中被用来提供类似于mixin的能力。因此,考虑一个类A:

class A : B { ... }

你可以通过定义一个接口IStuff来为它提供额外的功能(类似于多重继承):

interface IStuff {}

然后在A中“实现”它:

class A : B, IStuff { ... }

然后添加额外的特性

class Methods {
  public static void Something(this IStuff stuff) {
    // some functionality here
  }
}

1
非常好的想法。以前没有看到过这种可能性,但现在会寻找机会。 - Steve Cooper
我不明白这有什么用。如果该扩展方法不是通用的,那么在没有强制转换的情况下,你几乎无法使用它。如果你将其变成通用的,你就不需要空接口了。 - Ufuk Hacıoğulları

8

这是为了确保您可以将对象集合视为相同类型并对该类型执行一些操作(您知道它必须从object继承)。

就像属性一样,它是类型元数据。

您可能还想对已知类型(例如System.Web.UI.Control)执行操作,但仅在该类型从特定接口(例如INamingContainer)继承时执行该操作。

foreach(var ctrl in this.Controls)
{
    if (ctrl is INamingContainer)
    {
        // Do something on the control
    }
}

事实上,这就是我在C++中应用“属性”的方式,因为你没有反射,但你有RTTI。 - Dave Van den Eynde
非常好的一点 - 我已经近8年没有做过C++,我忘记了这样的东西。 - Preet Sangha
这似乎不是回答问题的方法。他问的是没有成员的接口——那些没有共同操作或属性的接口。尽管如此,它被接受了... - Steve Cooper
该接口没有通用操作,但您仍然可以在该接口的类型上执行通用操作。 - Jonathan Parker

8

它是一个标记接口。可以用来修饰类型,从而在运行时无需使用反射就能确定类型是否正确。我们使用它来确保调用方中通用类型的正确性。


3
为了让认为鸭子类型很酷的Python程序员感到困惑。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接