嵌套类型是否隐式静态?

时间:2016-02-04 13:03:12

标签: c# inner-classes

在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 
        {

        } 
        ...
    }

嵌套类型是否真的是一个静态类型,所有方法都隐式静态?

2 个答案:

答案 0 :(得分:15)

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

  

嵌套类型是否真的是一个静态类型,所有方法都隐式静态?

否 - 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 BA没有实例 public class Parent { private int field; public class Child { public void WriteFieldFromParent(Parent parent) { Console.WriteLine(parent.field); } } } 引用。

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

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

field

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

事实上,instance (i.e. not static) member(我不知道为什么我在第一次写这个答案时没有提及它)给出了一个类似于我的例子,并说:

  

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

答案 1 :(得分:0)

您的代码无法编译,因为public Task<string> DoSomething() { return SomeOtherFunctionThatReturnsATask(); } 超出了范围。你应该写这样的东西:

a

class A
{
   int a;

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