C# 当从泛型类型继承时,为什么必须使父类型符合使用嵌套类型的条件?

C# 当从泛型类型继承时,为什么必须使父类型符合使用嵌套类型的条件?,c#,C#,考虑这一点: [SomeAttr(typeof(Bar))] class Foo { class Bar { } } …这是: class Foo : ISomething<Bar> { class Bar { } } 类Foo:ISomething{ 分类栏{ } } 第一个示例编译,第二个示例不编译。若要在从泛型类型继承时使用嵌套类型引用,我必须使用父类型名限定它: class Foo : ISomething<Foo.Bar>

考虑这一点:

[SomeAttr(typeof(Bar))]
class Foo {

   class Bar {

   }
}
…这是:

class Foo : ISomething<Bar> {

   class Bar {

   }
}
类Foo:ISomething{
分类栏{
}
}
第一个示例编译,第二个示例不编译。若要在从泛型类型继承时使用嵌套类型引用,我必须使用父类型名限定它:

class Foo : ISomething<Foo.Bar> {

   class Bar {

   }
}
类Foo:ISomething{
分类栏{
}
}
我的问题是,为什么?为什么从父类型中的属性引用时不应用此限制(第一个示例)?

这都是关于声明的范围。考虑下面的代码:

namespace FooSpace
{
    class Foo : ISomething<Bar> 
    {
        class Bar { }
    }
 }
如果没有限定符,您指的是哪个
Bar
?编译器将无法判断。因此,编译器不去尝试猜测,而是坚持使用明确限定的类名,这会更加一致

对于属性情况,尽管在类声明上方声明了类目标属性,如下所示:

 [SomeAttr(typeof(Bar))]
 class Foo { ...
class public auto ansi beforefieldinit FooSpace.Foo extends [mscorlib]System.Object
{
    .custom instance void FooSpace.SomeAttr::.ctor ... etc.
实际上,编译器会将其转换为类似以下内容:

 [SomeAttr(typeof(Bar))]
 class Foo { ...
class public auto ansi beforefieldinit FooSpace.Foo extends [mscorlib]System.Object
{
    .custom instance void FooSpace.SomeAttr::.ctor ... etc.
换句话说,实际的
SomeAttr
属性对象是使用您提供的参数在类内部创建的。这个参数
typeof(Bar)
当然是有效的,因为它存在于
Foo
的类范围内

相关问题也讨论了这个案例


有趣的是,同样的规则和行为也适用于访问常量或静态类成员的类属性-您不需要指定类名,因为该属性实际上是在类内部创建的。

我猜想编译器在编译类之后处理类属性?但我对编译器内部的了解还不够,甚至不知道如何找到/证明这个答案。不过这个问题很有趣!以这种方式使用公共嵌套子类的实际示例是什么?为什么父类依赖于子类而不是仅仅使其成为与父类位于同一命名空间中的类时,要使用嵌套类?是否可以在顶部添加“using YourNamespace.Foo;”,在这种情况下,它会使用非属性选项进行编译?我猜这不会起作用,但我现在不在电脑前检查。顺便说一句,有趣的是VB.NET在这里选择了相反的作用域(没有调整可用的名称空间):
需要
测试。
但是
实现了IProgress(子类)
没有。@MarkHurd这很有趣,我得以证实。我认为VB的行为更直观。这个答案有道理,但没有回答为什么父类上的属性引用了类“bar”编译成功。请注意,当在IL中查看时,您挥手示意该属性实际上放置在类中,这并不能真正解释为什么C#的作用域不同。@MarkHurd:同意。不幸的是,C#spec在这方面没有什么可说的。我似乎很清楚,这个属性的范围是在类中的——但至于为什么(比如在设计动机中),如果有人能用这些信息改进我的答案,我会很高兴。