【发布时间】:2013-04-22 16:06:23
【问题描述】:
这让我在 C# 中遇到过一两次。我可以写这样的代码
class Node
{
class Connection
{
public Connection(Node node, string label)
{
this.Node = node;
this.Label = label;
}
public Node Node { get; private set; }
public string Label { get; private set; }
};
IEnumerable<Connection> IncomingConnections() // ...
IEnumerable<Connection> OutgoingConnections() // ...
}
但是如果我写
interface INode
{
class Connection
{
public Connection(INode node, string label)
{
this.Node = node;
this.Label = label;
}
public INode Node { get; private set; }
public string Label { get; private set; }
};
IEnumerable<Connection> IncomingConnections();
IEnumerable<Connection> OutgoingConnections();
}
我得到编译错误
错误 CS0524:“连接”:接口无法声明类型
我了解限制,但我感兴趣的是为什么。我当然可以在 C++“接口”中拥有嵌套类型(这只是一个具有抽象成员的类,所以不足为奇),而且显然在 Java 中也是可能的,请参阅Interfaces Cannot Declare Type Issue C#。那么既然 C# 从 Java 中学到了一些东西,为什么它在这方面缺乏(如果确实缺乏的话)?
(抱歉,如果这已在其他地方解决。我还找到了 Interfaces cannot declare types 和 Why can't I put a delegate in an interface?,但他们似乎没有直接解决我的问题。)
编辑
我想我只是添加一个注释,说明在 Java 世界中,乍一看似乎是一个悬而未决的问题,即是否可以在接口中嵌套一个类。见https://stackoverflow.com/a/9098321/834521。我不认为我在问为什么同样不能适用于 C# 是愚蠢的。
编辑
来自Framework Design Guidelines, 2ed, section 4.9 pp115-117 的简要总结/引述。
- 请使用嵌套类型,例如嵌套类型需要访问封闭类型的私有成员。
- 不要使用公共嵌套类型进行分组;为此使用命名空间。
- 避免公开嵌套类型,除非您真的知道自己在做什么。 (主要动机:显式创建嵌套类型会使技术水平较低的开发人员感到困惑。但是隐式创建,例如通过集合枚举器,是可以的。)
- 如果嵌套类型将在包含类型之外使用或实例化,则不要使用嵌套类型(这两者都主张嵌套类型与包含类型的独立性)。李>
- 不要用作接口的成员。
【问题讨论】:
-
因为接口是......好吧,它是一个接口,而不是一个实现。如果你想要一个实现,让它成为一个类,而不是一个接口。您可以在接口上声明
Connection类型的成员或属性,但该类型的实现将在别处描述。想象一下,如果您每次需要创建Connection类型的对象时都必须引用该特定接口。那会很尴尬,不是吗? -
C++ 没有接口...
-
@TooTone 您错过了界面的全部要点。您需要查看 C# 中接口的用途并了解它们的用途。一旦你理解了它们在 C# 中的含义,你就会发现在接口中嵌套一个类是没有意义的。设计师甚至不必问“我们应该允许吗?”你听起来像个疯子:“语言 X 有一个特性,人们用 Y 来表示这个特性。为什么名为 Y 的特性在语言 Z 中不像在语言 X 中那样起作用?”
-
@TooTone 这根本不是一件坏事。您可以使用命名空间来防止智能感知混乱并传达它们类型“属于”在一起。
-
@TooTone:一般来说,这样的组织是通过命名空间来完成的。
标签: c#