zoukankan      html  css  js  c++  java
  • static 还是readonly 还是static readonly

    一、   static 多对象共享一段空间,或者说没有对象概念,就是类的概念,不需要实例化,自动被创建。多用于长期共享。不会为对象的创建或销毁而消失。

      

      public class C
        {
    
            static A a =  new A("C 创建A",1111)
    
    
    
            public A Ci
            {
                get
                {
                    return a;
                }
    
    
            }
    
    
            public C(A b)
            {
                a = b;
                Console.WriteLine("构造" + a.Presentation);
            }
    
            //public static void Set()
            //{
            //    a = new A("", 11);
            //}
    
        }
    
    
    public class A
    {
         private string _presentation;
          private int _intvalue = -1;    
    
          public int A1
            {
                get
                {
                    return _intvalue;
                }
            }
    
            public string Presentation
            {
                get
                {
                    return _presentation;
                }
            }
       
            public A(string presentation, int intvalue)
            {
                _presentation = presentation;
                _intvalue = intvalue;
                Console.WriteLine("构造A类" + presentation + "," + intvalue);
            }
    }

    以上代码有几点说明
    1.在C类创建静态A时,虽然在字段中(实建C类会自动创建一个静态构造方法,它会把类中声明的字段初始化值全放在你定义的前面,也就是后面的值可以随时改变字  段的定义的值)

    2.Static A类也就是上面a,可以随时被定义成别的对象

    3.Static 是什么?就是在单个进程中仅仅保留一份。而它又可以随时被读写。

     static void Main(string[] args)
            {
                A a1 = new A("a1", 11);
                A a2 = new A("a2", 12);
                C c1 = new C(a1);
                C c2 = new C(a2);
                Console.WriteLine(object.ReferenceEquals(c1.Ci, c2.Ci));
                         
                Console.ReadKey();
    
            }

     
    二、readonly人们常常与const相比,我不解释值类型readonly的问题,只说明引用类型readonly,只读,不会被改变,最直接了解。

       

     public class C
        {
    
            readonly A a = new A("111",1111);
    
            public A Ci
            {
                get
                {
                    return a;
                }
                //set
                //{
                //    a = value;//别试图在类内部使用时改变它的引用
                //}
    
    
            }
    
            public C(A b)
            {
                a = b;//仅仅是在构方法内被初始化
                Console.WriteLine("构造" + a.Presentation);
            }
    
            //public static void Set()
            //{
            //    a = new A("改变", 10000);
            //}
        }

    说明:
    1.readonly仅仅可以在构造方法中初始化(字段中一样)

    2.readonly不可能在静态构造方法中初始化

    3.在类中的任何地方,都无法改变readonly的值(无论是值类型,还是引用类型)

    4.为了保证类内部中被调用的稳定性,不会被改变,readonly吧!

    5.在不同类中有不同的readonly指向不同地址。也就是多类中保留多份

    然而,第三点是有条件的它不能是IEnumerable(最后说明这一点)

     public class B
        {
            readonly IList<A> geta = new List<A>();
            public IList<A> GetA
            {
                get { return geta; }
    
            }
    
            public int B1
            {
                get;
                set;
            }
    
            public  B()
            {
                GetA.Add(new A("B内部创建", 111));
                Console.WriteLine(geta[0].Presentation);
            }
        }
    static void Main(string[] args)
            {
                A a1 = new A("a1", 11);
                A a2 = new A("a2", 12);
                B b = new B();
                b.GetA[0] = a1;
                Console.WriteLine(b.GetA[0].Presentation);
                Console.ReadKey();
    
            }

    被改变了,readonly面对IEnumerable时,一,虽然IList只读,同样会被改变,二、可以从外面很容易通过属性方法改变Ilist所引用的地址。虽然我给A类重载了
    Equals和GetHashCode,可依然改变了,看来IEnumerable.add不会判断这个。(这点我希望能给我指正原理性问题)

      (今天修改一下我的这个内容,readonly锁定的是IEnumerable,不是内部元素,也就是锁定的是IEnumerable本身地址不会改变)

    三、static readonly 根据上面的定义,做了以下假设,

    1,肯定需要构造方法中定义(静态的,还是默认的?)

    2 .进程中保留一份还是多份,?

    3。在类中可以改变吗?

      public class C
        {
    
           static readonly A a = new A("A1",1111);
    
            public A Ci
            {
                get
                {
                    return a;
                }
                //set
                //{
                //    a = value;//别试图在类内部使用时改变它的引用
                //}
            }
    
            public C()
            {
               // a = new A("A3", 333); 也不可以这里定义
                Console.WriteLine("构造C类" + a.Presentation);
            }
            static C()
            {
                a = new A("A2", 2222);
                Console.WriteLine("构造C静态类" + a.Presentation);
            }
    
            //public static void Set()
            //{
            //    a = new A("改变", 10000);//也不可以这里改变
            //}
        }
    static void Main(string[] args)
            {
                A a1 = new A("a1", 11);
                A a2 = new A("a2", 12);
                C c1 = new C();
                C c2 = new C();
                Console.WriteLine(object.ReferenceEquals(c1.Ci, c2.Ci));
            
                Console.ReadKey();
    
            }


    上面的结果

    构造A类a1,11
    构造A类a2,12
    构造A类A1,1111
    构造A类A2,2222
    构造C静态类A2
    构造C类A2
    构造C类A2
    True

    说明:

    1.如果一个静态构造方法与一个构造方法同时存在,首先静态构造方法执行,然后是构造方法

    2在任何一个构造方法中都会把字段的值重新被定义。

    以上是任一本原理书都可以找到的重点是回答上面问题

    1.只有静态构造方法可以初始化static readonly

    2.进程中仅保留一份

    3.类中不可以改原有的值。

    想想我们的单例为什么那样创建(上一篇说过http://www.cnblogs.com/shouhongxiao/p/3530091.html),我们单例就是想在一个进程中只保留一份,且不会被已经进入类中多线程改变已经创建的对象,当然是双重锁定了

     if (null == instance)
                    {
                        lock (threadSafeLocker)
                        {
                            if (null == instance)
                            {
                                instance = new VFactory;
                               
    
                            }
                        }
                    }

    第一个null = instance 解决效率问题(如果多线程进入对象被创建,就不需lock了)
    第二个就是防止已经进入多线程改变

    第三个肯定是一个单线程进入了(判断对象是否被创建)

    那我们就创建了一份且只有一份,而且不会被进入的多线程改变的单例。

     总结一下:static 是为了保证共性(多对象共享,一损具损),readonly是了了保持个性(每个单一对象有自己固定的特性),static readonly ?这世界上仅有我一个,有个性的我。

      

        

  • 相关阅读:
    svn忽略不需要同步的文件夹或文件
    Redis 字符串(String)
    Redis 数据类型
    Linux下安装rabbitMQ
    Windows平台下Git服务器搭建
    Linux下安装redis
    JVM调优总结
    Tomcat优化配置
    通过profile 用maven命令打不同配置的变量包
    Log4j日志配置说明
  • 原文地址:https://www.cnblogs.com/shouhongxiao/p/3532641.html
Copyright © 2011-2022 走看看