嵌套类型是否隐式静态

本文关键字:静态 是否 嵌套类型 | 更新日期: 2023-09-27 18:33:23

在C# 5.0语言规范中,它说:

请注意,常量和嵌套类型被归类为静态成员。

所以如果我写:

class A
{
   int a;
   class B
   {
       public void foo()
       {
           int j = a; // ERROR
       } 
   }
}

将 a 分配给 j 给了我一个 CS0120 错误

"非静态字段、方法或 财产'会员'">

所以我可以理解foo也是隐含的静态的。

但是,当我同时查看反编译代码和 IL 代码时,没有静态关键字的迹象!

internal class A
{
    private class B
    {
        public void foo()
        {
        }
    }
    private int a;
}

// Nested Types
    .class nested private auto ansi beforefieldinit B
        extends [mscorlib]System.Object
    {
        // Methods
        .method public hidebysig 
            instance void foo () cil managed 
        {
        } 
        ...
    }

嵌套类型真的是所有方法都隐式静态的静态类型吗?

嵌套类型是否隐式静态

"嵌套类型被归类为静态成员">

嵌套类型真的是所有方法都隐式静态的静态类型吗?

否 - Type 的定义是静态成员,但类型本身不是静态的。

当它说

请注意,常量和嵌套类型被归类为静态成员。

这意味着您可以创建嵌套类的实例,而无需父类的实例。

换句话说,使用代码

public class Parent
{
    public class Child
    {
    }
}

要拨打new Parent.Child(),您无需先拨打new Parent()或类似电话。


代码的问题

您的实际问题是嵌套类型的实例与父类型的实例是分开的 - 您的代码,

class A
{
   int a;
   class B
   {
       public void foo()
       {
           int j = a; // ERROR
       } 
   }
}

不编译,因为在A.B.foo()中,字段aA的实例(即非静态(成员,而B没有A的实例可以引用。


如何使用 使用嵌套类型的一种方式

您可以将类型嵌套视为将父级中私有成员的可访问性扩展到子级的一种方式,例如

public class Parent
{
    private int field;
    public class Child
    {
        public void WriteFieldFromParent(Parent parent)
        {
            Console.WriteLine(parent.field);
        }
    }
}

哪个编译!您可以从 Parent.Child 类中获取Parent私有字段field的值,因为它是嵌套的。请注意,我需要将Parent的实例传递给Parent.Child.WriteFieldFromParent

事实上,关于嵌套类型的 MSDN 页面(我不知道为什么我在第一次写这个答案时没有参考它(给出了一个类似于我的例子,并说:

嵌套类型有权访问其包含类型可访问的所有成员。它可以访问包含类型的私有成员和受保护成员,包括任何继承的受保护成员。

您的代码将无法编译,因为a超出范围。你应该写这样的东西:

class A
{
   int a;
   class B
   {
       public void foo()
       {
           int j = new A().a;
       } 
   }
}

class A
{
    static int a;
    class B
    {
        public void foo() {
            int j = a;
        }
    }
}