zoukankan      html  css  js  c++  java
  • 使用接口更改已装箱的值类型中的字段

    先看下面一段代码

    namespace 使用接口更改已装箱值类型的字段
    { 
        //point是一个值类型
    
        internal struct Point
        {
            private Int32 m_x, m_y;
            public Point(Int32 x, Int32 y)
            {
                m_x = x;
                m_y = y;
            }
            public void Change(int x, int y)
            {
                m_x = x;
                m_y = y;
            }
            public override string ToString()
            {
                return string.Format("({0},{1})", m_x, m_y);
                //fromat返回指定字符串中一个或多个格式项替换为指定对象的字符串格式
            }
            class Program
        {
           
            }
            static void Main(string[] args)
            {

            Point p = new Point(1, 1);
            Console.WriteLine(p);//显示(1,1)
            p.Change(2, 2);
            Console.WriteLine(p);//显示(2,2)
            object o = p;
            Console.WriteLine(o);//显示(2,2)
            ((Point)o).Change(3, 3);
            Console.WriteLine(o);//显示(2,2)
            Console.ReadKey();

            }
        }
    }
    

      Main在栈上创建一个Point值类型对象并赋值(1,1),第一次调用writeline之前对p进行装箱,writeline会在已装箱的Point上调用ToString,像预期中结果为(1,1)

         p调用Change方法将数值改为2,第二次调用writeline时再次对p进行装箱,像预期结果为(2,2)

         现在p要进行第三次装箱,o将引用已装箱的Point对象,第三次调用writeline会显示(2,2)

      最后希望调用Change来更改已装箱的Point对象中的字段,但是Object o 对Change方法并不知情所以要先将o转型为Point。将o转型为Point要先将o拆箱,并将已装箱中的字段

    复制到线程栈上一个临时的Point中。这个临时的Point的m_x,m_y会变成3,3,但是已装箱的Point不受这个Change调用影响,所以第四次显示(2,2)

    用接口来更改已装箱值类型的字段

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace 使用接口更改已装箱值类型的字段
    {
    
        //接口定义一个Change方法
        internal interface IChageBoxedPoint
        {
            void Change(int x, int y);
        }
        //point是一个值类型
    
        internal struct Point: IChageBoxedPoint
        {
            private Int32 m_x, m_y;
            public Point(Int32 x, Int32 y)
            {
                m_x = x;
                m_y = y;
            }
            public void Change(int x, int y)
            {
                m_x = x;
                m_y = y;
            }
            public override string ToString()
            {
                return string.Format("({0},{1})", m_x, m_y);
                //fromat返回指定字符串中一个或多个格式项替换为指定对象的字符串格式
            }
            class Program
        {
           
            }
            static void Main(string[] args)
            {
                Point p = new Point(1, 1);
                Console.WriteLine(p);//显示(1,1)
                p.Change(2, 2);
                Console.WriteLine(p);//显示(2,2)
                object o = p;
                Console.WriteLine(o);//显示(2,2)
                ((Point)o).Change(3, 3);
                Console.WriteLine(o);//显示(2,2)
                //对p进行装箱,更改已装箱的对象,然后丢弃它;
                ((IChageBoxedPoint)p).Change(4, 4);
                Console.WriteLine(p);//显示(2,2)
    //更改已装箱的对象病显示他 ((IChageBoxedPoint)o).Change(5,5); Console.WriteLine(o);//显示(5,5)
    } } }

      

       这段代码与上边的主要区别是change方法由

    IChageBoxedPoint接口定义,Point类型实现了这个接口。
      //对p进行装箱,更改已装箱的对象,然后丢弃它;
                ((IChageBoxedPoint)p).Change(4, 4);
                Console.WriteLine(p);//显示(2,2)
    这里未装箱的Point p 转型为IChangeBoxedPoint,这个转型造成对p的值进行装箱,然后已装箱的值上调用Change,这确实让m_x,m_y变成了4,4,
    但是,在Change返回之后,已装箱的对象立即装备好进行垃圾回收,所以显示(2,2)
    最后的例子中,o引用已装箱Point要转型为一个IChageBoxedPoint。这里不需要进行装箱,因为o已经是一个装箱的Point。然后调用Change,他能正确
    修改已装箱的Point的m_x,m_y字段。接口方法允许更改一个已装箱的Point对象中的字段。
  • 相关阅读:
    如何搜索IP的地理位置
    Windows Sockets错误标识及对应解释
    【转】GDB中应该知道的几个调试方法
    手动安装OpenCV下的IPP加速库
    Ubuntu16.04调整屏幕分辨率至1920*1080
    win10家庭版删除文件提示没有权限最简单的方式
    Centos7 HyperLedger Fabric 1.4 生产环境部署
    解析key值不确定的json数据
    (转)Centos下,Docker部署Yapi接口管理平台
    (转)手工释放linux内存——/proc/sys/vm/drop_cache
  • 原文地址:https://www.cnblogs.com/lanrenqilanming/p/6265426.html
Copyright © 2011-2022 走看看