zoukankan      html  css  js  c++  java
  • c#静态成员和静态类

    说起静态类,你可能会联想到实例类。这两者并不难区分,前者(静态类)只在内存中创建一个,而后者(实例类)则是每次实例化后,就会再内存创建一份。今天来简单聊一下静态类的理解。

    代码情景: 

    class Program
    {
          static void Main(string[] args)
           {
               Person p1 = new Person();
                p1.Name = "zs";
                p1.LivePlanet = "earth";
    
                Person p2 = new Person();
                p1.Name = "ls";
                p1.LivePlanet = "earth";
           }     
    }
    
    
    public class Person
    {
    
            public string Name { get; set; }
            public int Age { get; set; }
            public string Phone { get; set; }
            public  string LivePlanet { get; set; }
    }

    根据以上的情景假如我需要实例化100个对象,而Person中的LivePlanet属性值都统一为earth,不就得反复重写100次? 这样妥吗?起码您应该知道违背了DRY原则。

    好吧,我们来实现一下通过static 来改善这个代码:

    class Program
    {
          static void Main(string[] args)
           {
               Person.LivePlanet = "earth"
               Person p1 = new Person();
                p1.Name = "zs";
                //p1.LivePlanet = "earth";
    
                Person p2 = new Person();
                p1.Name = "ls";
               //p1.LivePlanet = "earth";
           }     
    }
    
    
    public class Person
    {
    
            public string Name { get; set; }
            public int Age { get; set; }
            public string Phone { get; set; }
            public  static string LivePlanet { get; set; }
    }

    我们在Person类把LivePlanet改成static,这样我们直接可以不需要实例化可以直接Person.LivePlanet = "earth"。这样的好处不仅在于此,而且这解决了当所有对象都共享同一个信息的时候,不需要重复去实例化再去调用这个对象。

    请注意以下几点:

    1.存储在静态成员中的信息只有在应用程序退出的时候才会从内存里释放出来。

    2.静态成员不能通过对象访问,只能通过类名直接访问。

    3.静态成员(内容)在内存中只存储一份。

    4.静态成员,在整个应用程序中任何一个地方都可以访问的到,所以静态成员直到程序退出后才会释放内存。而实例成员,当没有变量使用就可以被垃圾回收,回收后内存就释放了.(可以把一些常用的工具函数,封装到一个静态类中,使用方便)


    现在请您再看这个简单的改动会有什么问题,我在Person中添加一个静态方法然后通过this来调用静态成员。

    public class Person
        {
            public static void Say()
            {
                this.Name = "你好";
            }
    
            public string Name { get; set; }
            public int Age { get; set; }
            public string Phone { get; set; }
            public static string LivePlanet { get; set; }
        }

    可能在脱离编译器的情况下,您可能觉得this 就是Person,所以这个调用不应该会存在问题。实际上这边请您注意我用的是静态static,而静态成员访问实例成员必须要new一个实例。并且this指的是当前的对象,在使用静态成员的时候因为还没实例化一个对象,所以这个时候this无法得知自己的身份。

    改动如下:

    public class Person
        {
            public static void Say()
            {
                Person p = new Person();
                p.Name = "你好";
                //this.Name = "你好";
            }
    
            public string Name { get; set; }
            public int Age { get; set; }
            public string Phone { get; set; }
            public static string LivePlanet { get; set; }
        }

    这才是我们想要的结果。

    那什么是静态类呢?请看如下代码:

     public static class MyStaticClass
        {
            public static string Name { get; set; }
    
            public static void SayHi()
            {
                Console.WriteLine("hi");
            }
            
        }

    观察以上代码可以看出静态类的几个特点:

    1.在静态类中只能有静态成员,不能有实例成员
    2.静态类不能创建对象,不能new对象

    使用静态类跟使用静态成员的情景其实是一样的,即在整个应用程序中要共享数据的时候可以使用静态类。所以对于那些类中包含有大量的方法,并且类不需要创建对象的时候,可以使用静态类。

  • 相关阅读:
    编译 netcat for lineage-17.1-20210303-UNOFFICIAL-dipper.zip (ARM)
    Mi8-Android-arm 中网络接口命名:wlan0 & rmnet_data 《========》 VB-Android-x86 中网络接口命名:eth1 & wifi_eth
    HOW TO CHANGE LINUX KERNEL DMESG BUFFER SIZE
    Calculation of RTO in tcp and related open source implementation (Linux kernel, unbound) --- rtt, rttvar, cwnd, ssthresh
    图解Linux网络包接收过程
    Tcpprobe 在网络中的使用 --- tcp_probe has been removed from the kernel. --- Using ip-tcp_metrics --- Using ss (socket statistics)
    全面的 iPerf3 Android平台移植编译、运行过程记录
    socket、sock、sk_buff、net_device 关系图
    tcp: Add TCP_FREEZE socket option
    ECNU 2031 绝对值排序
  • 原文地址:https://www.cnblogs.com/byvar/p/4311320.html
Copyright © 2011-2022 走看看