zoukankan      html  css  js  c++  java
  • C#中的静态与非静态成员入门

     

    静态和非静态成员虽然是非常基本的知识,但对于编程入门者而言确又不易理解。虽然我也是新手,但也希望写下一点咚咚给新新手门参考. 下面对C#中的静态和非静态成员的用法做了一点简单介绍,为了便于理解,没有提到底层编译的运作过程,只对其用法做一些介绍。

    关于静态成员变量和非静态成员变量 

    静态成员变量从属于一个类而非某个具体的对象,它的值被该类的所有对象所共享.对于public的静态成员变量而言,它既可以由类名直接通过 “.” 操作符引用,也可以由对象名通过“.”操作符来引用,并且两者效果相同. 静态成员按照它们在类中声明的顺序进行初始化,并且此过程先于Main函数执行。
    非静态成员变量则为独个对象所拥有,而不被各个对象所共享.因此不能用类名来直接引用.
    例如: 

     1 using System;
     2 
     3 class MyClass
     4 {
     5     public int nsMember;    //非静态成员变量
     6     public static int sMember;    //静态成员变量
     7     
     8     public MyClass(int i, int j)
     9     { //成员的初始化
    10         nsMember = i;    
    11         sMember = j;
    12     }    
    13 }
    14 
    15 class Test
    16 {
    17     static void Main()
    18     {
    19         MyClass mc1 = new MyClass(50100); //创建一个MyClass实例,并初始化.
    20         
    21         Console.WriteLine(MyClass.sMember); //ok, sMember是MyClass类的静态成员,可以由类名直接引用. 此行输出100        
    22         Console.WriteLine(MyClass.nsMember);//出错!nsMember是非静态成员,不能由类名直接引用        
    23         Console.WriteLine(mc1.nsMember);    //ok, mc是一个已成功创建的对象,它拥有自己的非静态成员nsMember                                                                 
    24                                             //此行输出50;        
    25         MyClass mc2 = new MyClass(1020);     //创建一个新的实例,并初始化.
    26         
    27         Console.WriteLine(MyClass.sMember);    //ok,由于在mc2初始化时已更改sMember为20,而sMember为所有MyClass类对象所共享,                                                                                                                                  
    28                                             //故此行输出20.
    29         Console.WriteLine(MyClass.nsMember);//同样出错!
    30         
    31         Console.WriteLine(mc2.nsMember);     //ok, 此行输出10;        
    32         
    33         Console.WriteLine(mc1.nsMember);    //此行输出50,因为mc1和mc2的非静态成员nsMember是互相独立的                                                                     
    34                                                                      
    35     }
    36 }
    37 

     在内存上的关系如下图所示(并不准确,仅用于理解) ,其中两个对象中的sMember均引用顶端的类的sMember,而nsMember则为各自所独有。

    。。。 。。。

    sMember

    。。。 。。。

    mc1

    nsMember(50)

    sMember

    mc2

    nsMember(10)

    sMember

     

    关于静态方法和非静态方法 

    类似静态成员变量,静态方法为一个类所拥有.但静态方法中只能使用静态成员,而不能使用非静态成员.
    非静态方法中既能使用静态成员,也能使用非静态成员. 

    例如,为上面的MyClass类添加一个静态方法StaticFun()和一个非静态方法UStaticFun() 

     1 class MyClass
     2 {
     3      
     4     static void StaticFun()
     5     {
     6         nsMember += nsMember;     //出错!因为nsMember是非静态成员
     7         sMember += sMember;    //ok,因为sMember是静态成员
     8     }
     9     
    10     void UStaticFun()
    11     {
    12         nsMember += nsMember;     //ok
    13         sMember += sMember;    //ok
    14     }
    15 }
    16 


    关于静态构造函数
     

    静态构造函数的执行发生在类的静态成员初始化之后和类的第一个实例创建之前.一个类只能定义一个静态构造函数,并且不能带有参数.

    例如:

     1 class InitOrder
     2 {
     3     static int sMember1 = 1// 1
     4     static int sMember2 = 2// 2    
     5     
     6     InitOrder()
     7     {
     8         Console.WriteLine("unstatic ctor initialized"); // 4
     9     }
    10 
    11     static InitOrder()
    12     {
    13         Console.WriteLine("static ctor initialized"); // 3
    14     }
    15 }
    16 
    17 class Test
    18 {
    19     static void Main()
    20     {
    21         InitOrder io = new InitOrder(); 
    22     }
    23 }
    24 


     

    执行顺序如注释所标注. 

    静态构造函数不能被显式调用,且各个类中静态构造函数的调用顺序是不确定的.

    例如:

     1 class Test1
     2 {
     3     public static void Print()
     4     {
     5         Console.WriteLine("Print1 is called");
     6     }
     7     static Test1()
     8     {
     9         Console.WriteLine("Test1 Initialized");
    10     }
    11 }
    12 
    13 class Test2
    14 {
    15     public static void Print()
    16     {
    17         Console.WriteLine("Print2 is called");
    18     }
    19     static Test2()
    20     {
    21         Console.WriteLine("Test2 Initialized");
    22     }
    23 }
    24 
    25 class Test
    26 {
    27     static void Main()
    28     {
    29         Test1.Print();
    30         Test2.Print();
    31     }
    32 }
    33 

     

    有可能"Test2 Initialized"会在"Test1 Initialized"之前输出.

  • 相关阅读:
    169. Majority Element
    283. Move Zeroes
    1331. Rank Transform of an Array
    566. Reshape the Matrix
    985. Sum of Even Numbers After Queries
    1185. Day of the Week
    867. Transpose Matrix
    1217. Play with Chips
    766. Toeplitz Matrix
    1413. Minimum Value to Get Positive Step by Step Sum
  • 原文地址:https://www.cnblogs.com/dudu837/p/1499381.html
Copyright © 2011-2022 走看看