例如:
public class A : A.B
{
public class B { }
}
从编译器生成此错误:
循环基类依赖 涉及'A'和'A.B'
我总是认为嵌套类的行为与普通类一样,除了有关访问外部类的私有成员的特殊规则,但我猜这两个类之间是否存在一些隐式继承?
答案 0 :(得分:34)
据我所知,没有隐含的继承。我本以为这是好的 - 尽管如果A和B都是通用的,我可以想象很奇怪。
规范10.1.4节中规定了
当B类来自A类时, 这是A到的编译时错误 取决于B.一个班级直接依赖 在它的直接基类(如果有的话)和 直接取决于其中的类 它立即嵌套(如果 任何)。鉴于这个定义, 一套完整的课程 阶级取决于传递 关闭直接取决于 关系。
我已经强调了相关部分。
这解释了为什么编译器拒绝它,但不是为什么语言禁止它。我想知道是否存在CLI限制......
编辑:好的,我收到了Eric Lippert的回复。基本上,它在技术上是可行的(CLI中没有任何东西可以禁止它),但是:在电子邮件主题中也注意到它会使这种事情有效:
A.B x = new A.B.B.B.B.B.B.B.B.B.B.B.B();
......但如果B派生自A。
,那就已经(如Tinister所述)有效嵌套+继承=奇怪......
答案 1 :(得分:13)
这不是C#的东西,而是编译器的东西。编译器的一个工作是在内存中布置一个类,即一堆基本数据类型,指针,函数指针和其他类。
在知道B类的布局之前,它不能构造A类的布局。在完成A类布局之前,它无法知道B类的布局。循环依赖。
答案 2 :(得分:0)
我认为嵌套是为了表示嵌套类型是嵌套类型的定义的一部分。有了这种解释,这种限制是有道理的,因为当编译器达到A的定义时,A.B尚未定义,即使在A的末尾,它也已经用A.B来定义。
答案 3 :(得分:0)
关于我试图做的事情的问题:
基本上,我想创建一个与自身具有组合关系的类,但我不希望包含的对象包含其他对象,因此创建一个包含许多“A has-a A has-a”的链A has-a A has-a ......“的关系。所以我当时的想法是做这样的事情:
public class A : A.AA
{
public class AA
{
// All of the class's logic
}
private AA _containedObject;
}
当时看起来很漂亮,但回想起来我不太确定......
我在Google上翻找过,并没有找到任何好的讨论,所以我想我会在这里发布。
但是,在post at Eric Lippert's Blog的注释中,他给出了实现嵌套接口的类的示例,以及实现带有嵌套类作为类型参数的通用接口的类(不编译,并且在当前编译器中调用“bug”。这两个例子都涉及接口,所以我想知道是否有一些嵌套类的特殊规则。似乎有。
答案 4 :(得分:0)
通过从包含嵌套接口的单独类继承,我能够避免这种情况(至少使用接口)。 (在我的场景中,我也返回对这些接口的引用。)
而不是:
public class MyClass<T1, T2, T3> :
MyClass<T1, T2, T3>.Interface
where T1 : ...
where T2 : ...
where T3 : ... {
public interface Interface { Interface SomeMethod(); }
Interface Interface.SomeMethod() {
...
}
}
// compile error: Circular base class dependency
做这样的事情:
public sealed class MyClassInterfaces<T1, T2, T3>
where T1 : ...
where T2 : ...
where T3 : ... {
public interface Interface { Interface SomeMethod(); }
}
sealed class MyClass<T1, T2, T3> :
MyClassInterfaces<T1, T2, T3>.Interface
where T1 : ...
where T2 : ...
where T3 : ... {
MyClassInterfaces<T1, T2, T3>.Interface
MyClassInterfaces<T1, T2, T3>.Interface.SomeMethod() {
...
}
}
为了避免使用显式接口实现的丑陋,你也可以从其他类继承,但是如果你试图从嵌套类继承那样就行不通,因为你不能从这两个类继承。
public abstract class MyClassInterfaces<T1, T2, T3>
where T1 : ...
where T2 : ...
where T3 : ... {
public interface Interface { Interface SomeMethod(); }
}
sealed class MyClass<T1, T2, T3> :
MyClassInterfaces<T1, T2, T3>,
MyClassInterfaces<T1, T2, T3>.Interface
where T1 : ...
where T2 : ...
where T3 : ... {
Interface Interface.SomeMethod() {
...
}
}
答案 5 :(得分:-2)
这对我没有意义......你正试图扩展一些不存在的东西! B类只存在于A类的范围内,因此我认为存在某种继承。