【问题标题】:What is an empty interface used for?空接口有什么用?
【发布时间】:2019-04-19 12:12:24
【问题描述】:

我正在使用的代码有一个空界面:

public interface ICube {}

它没有方法或属性。

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

【问题讨论】:

标签: c# oop interface


【解决方案1】:

您应该从 MSDN 阅读有关 Interface Design 的信息

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

✓ 如果您需要一些通用 API 被包括值类型的一组类型支持,请定义一个接口。

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

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

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

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

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

✓ 务必提供至少一个 API 来使用您定义的每个接口(将接口作为参数的方法或类型化为接口的属性)。

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

X 不要将成员添加到以前发布的接口。

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

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

【讨论】:

    【解决方案2】:

    这称为“标记界面”。有时它们被用来表示一个类是为了某种目的。这不是一种可取的做法。

    虽然我使用了标记接口,但这里是它们产生的问题的说明。假设我有一个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 该接口。标记接口两者都不做。它们允许我们将对象转换为没有成员的类型。这充其量是无用的,最坏的情况是有害的,因为它会导致更可疑的选角。

    【讨论】:

    • 那么有什么选择呢?因为即使是微软也在这样做。例如:IAuthorizationRequirement
    猜你喜欢
    • 2010-09-27
    • 2011-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-16
    • 1970-01-01
    相关资源
    最近更新 更多