[你必须知道的.NET]第十回:品味类型---值类型与引用类型(下)-应用征途

本文将介绍以下内容:

  • 类型的基本概念 
  • 值类型深入
  • 引用类型深入
  • 值类型与引用类型的比较及应用

[下载]:[类型示例代码]

 

1. 引言

值类型与引用类型的话题经过了两个回合([第八回:品味类型---值类型与引用类型(上)-内存有理]和[第九回:品味类型---值类型与引用类型(中)-规则无边])的讨论和切磋,我们就基本的理解层面来说已经差不多了,但是对这一部分的进一步把握和更深刻的理解还要继续和深化,因为我自己就在两篇发布之际,我就得到装配脑袋兄的不倦指导,之后又查阅了很多的资料发现类型在.NET或者说语言基础中何其重要的内涵和深度,因此关于这个话题的讨论还没有停止,以后我将继续分享自己的所得与所感。

不过作为一个阶段,本文将值类型和引用类型的讨论从应用示例角度来进一步做以延伸,可以看作是对前两回的补充性探讨。我们从类型定义、实例创建、参数传递、类型判等、垃圾回收等几个方面来简要的对上两回的内容做以剖析,并以一定的IL语言和内存机制来说明,期望进一步加深我们的理解和分析。 

2. 以代码剖析

下面,我们以一个经典的值类型和引用类型对比的示例来剖析,其区别和实质。在剖析的过程中,我们主要以执行分析(主要是代码注释)、内存分析(主要是图例说明)和IL分析(主要是IL代码简析)三个方面来逐知识点解析,最后再做以总结描述,这样就可以有更深的理解。

2.1 类型定义

定义简单的值类型MyStruct和引用类型MyClass,在后面的示例中将逐渐完善,完整的代码可以点击下载[类型示例代码]。我们的讨论现在开始,

  • 代码演示
    // 01 定义值类型
    public struct MyStruct
    {
        
private int _myNo;

        
public int MyNo
        {
            
get { return _myNo; }
            
set { _myNo = value; }
        }

        
public MyStruct(int myNo)
        {
            _myNo 
= myNo;
        }

        
public void ShowNo()
        {
            Console.WriteLine(_myNo);
        }

    }

 

    // 02 定义引用类型
    public class MyClass
    {
        
private int _myNo;

        
public int MyNo
        {
            
get { return _myNo; }
            
set { _myNo = value; }
        }

        
public MyClass()
        {
            _myNo 
= 0;
        }

        
public MyClass(int myNo)
        {
            _myNo 
= myNo;
        }


        
public void ShowNo()
        {
            Console.WriteLine(_myNo);
        }
    }
  •  IL分析

 

分析IL代码可知,静态方法.ctor用来表示实现构造方法的定义,其中该段IL代码表示将0赋给字段_myNo。

2.2 创建实例、初始化及赋值

接下来,我们完成实例创建和初始化,和简单的赋值操作,然后在内存和IL分析中发现其实质。

  • 代码演示
创建实例、初始化及赋值
  • 内存实况

首先是值类型和引用类型的定义,这是一切面向对象的开始,

  

 然后是初始化过程,

 

 简单的赋值和拷贝,是最基本的内存操作,不妨看看,

  

2.3 参数传递

  • 代码演示

 

 

参数传递

 

不必多说,就是一个简要阐释,对于参数的传递作者将计划以更多的笔墨来在后面的系列中做以澄清和深入。

2.4 类型转换

类型转换的演示,包括很多个方面,在此我们只以自定义类型转换为例来做以说明,更详细的类型转换可以参考[第九回:品味类型---值类型与引用类型(中)-规则无边]的[再论类型转换部分]。

  • 代码演示

首先是值类型的自定义类型转换,

 

    public struct MyStruct
    {        
        
// 01.2 自定义类型转:整形->MyStruct型
        static public explicit operator MyStruct(int myNo)
        {
            
return new MyStruct(myNo);
        }

    }


然后是引用类型的自定义类型转换,

 

    public class MyClass
    {
        
// 02.2 自定义类型转换:MyClass->string型
        static public implicit operator string(MyClass mc)
        {
            
return mc.ToString();
        }

        
public override string ToString()
        {
            
return _myNo.ToString();
        }
    }


最后,我们对自定义的类型做以测试,

        public static void Main(string[] args)
        {          
            
#region 03. 类型转换
            MyStruct MyNum;
            
int i = 100;
            MyNum 
= (MyStruct)i;
            Console.WriteLine(
"整形显式转换为MyStruct型---");
            Console.WriteLine(i);

            MyClass MyCls 
= new MyClass(200);
            
string str = MyCls;
            Console.WriteLine(
"MyClass型隐式转换为string型---");
            Console.WriteLine(str);
            
#endregion                   
                   }       

2.5 类型判等

类型判等主要包括:ReferenceEquals()、Equals()虚方法和静态方法、==操作符等方面,同时注意在值类型和引用类型判等时的不同之处,可以参考[第九回:品味类型---值类型与引用类型(中)-规则无边]的[4. 再论类型判等]的简述。

 

  • 代码演示 

// 01 定义值类型
public struct MyStruct
{

// 01.1 值类型的类型判等
public override bool Equals(object obj)
{
return base.Equals(obj);
}

}  

public class MyClass
{

// 02.1 引用类型的类型判等
public override bool Equals(object obj)
{
return base.Equals(obj);
}

public static void Main(string[] args)

{

#region 05 类型判等
Console.WriteLine("类型判等---");
// 05.1 ReferenceEquals判等
//值类型总是返回false,经过两次装箱的myStruct不可能指向同一地址
Console.WriteLine(ReferenceEquals(myStruct, myStruct));
//同一引用类型对象,将指向同样的内存地址
Console.WriteLine(ReferenceEquals(myClass, myClass));
//RefenceEquals认为null等于null,因此返回true
Console.WriteLine(ReferenceEquals(null, null));

// 05.2 Equals判等
//重载的值类型判等方法,成员大小不同
Console.WriteLine(myStruct.Equals(myStruct2)) ;

//重载的引用类型判等方法,指向引用相同
Console.WriteLine(myClass.Equals(myClass2));

#endregion

}  

2.6 垃圾回收  

首先,垃圾回收机制,绝对不是三言两语就能交代清楚,分析明白的。因此,本示例只是从最简单的说明出发,对垃圾回收机制做以简单的分析,目的是有始有终的交代实例由创建到消亡的全过程。

  • 代码演示

public static void Main(string[] args)
{

#region 06 垃圾回收的简单阐释
//实例定义及初始化
MyClass mc1 = new MyClass();
//声明但不实体化
MyClass mc2;
//拷贝引用,mc2和mc1指向同一托管地址
mc2 = mc1;
//定义另一实例,并完成初始化
MyClass mc3 = new MyClass();
//引用拷贝,mc1、mc2指向了新的托管地址
//那么原来的地址成为GC回收的对象,在
mc1 = mc3;
mc2 = mc3;
#endregion

}  

  • 内存实况

 

GC执行时,会遍历所有的托管堆对象,按照一定的递归遍历算法找出所有的可达对象和不可访问对象,显然本示例中的托管堆A对象没有被任何引用访问,属于不可访问对象,将被列入执行垃圾收集的目标。对象由newobj指令产生,到被GC回收是一个复杂的过程,我们期望在系列的后期对此做以深入浅出的理解。 

2.7 总结陈述

这些示例主要从从基础的方向入手来剖析前前两回中的探讨,不求能够全面而深邃,但求能够一点而及面的展开,技术的魅力正在于千变万化,技术追求者的力求却是从变化中寻求不变,不然我们实质太累了,我想这就是好方法,本系列希望的就是提供一个入口,打开一个方法。示例的详细分析可以下载[类型示例代码],简单的分析希望能带来丝丝惬意。 

3. 结论

值类型和引用类型,要说的,要做的,还有很多。此篇只是一个阶段,更多的深入和探讨我相信还在继续,同时广泛的关注技术力量的成长,是每个人应该进取的空间和道路。

品味类型,为应用之路开辟技术基础。

品味类型,继续探讨还会更多精彩。

 

参考文献

(USA)Jeffrey Richter, Applied Microsoft .NET Framework Programming

(USA)Jacquie Barker, Grant Palmer, Beginning C# Objects From Concepts to Code

广而告之

[下载]:[类型示例代码]

  

温故知新

[开篇有益]

[第一回:恩怨情仇:is和as]

[第二回:对抽象编程:接口和抽象类]

[第三回:历史纠葛:特性和属性]

[第四回:后来居上:class和struct]

[第五回:深入浅出关键字---把new说透]

[第六回:深入浅出关键字---base和this]

[第七回:品味类型---从通用类型系统开始]

[第八回:品味类型---值类型与引用类型(上)-内存有理]

[第九回:品味类型---值类型与引用类型(中)-规则无边]

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/438749.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

lfsr算法c语言,求助:如何用C语言实现LFSR加密

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼includevoidLFSR(unsigned char pzt[],unsigned char pjg[],int n){unsigned char t0;int c0,i;for(i0;it^(pzt[i]&pjg[i]);t^((t<<1)^(t<<2)^(t<<3)^(t<<4)^(t<<5)^(t<<6)^(t<<7))…

c语言提供了三种预处理命令,9、C语言之预处理命令

预处理命令基本概念&#xff1a;ANSI C标准规定可以在C源程序中加入一些“预处理命令”&#xff0c;以改进程序设计环境&#xff0c;提高编程效率。这些预处理命令是由ANSI C同一规定的&#xff0c;但是它们不是C语言本身的组成部分&#xff0c;不能直接对它们进行编译(因为编译…

[你必须知道的.NET]第十一回:参数之惑---传递的艺术(上)

本文将介绍以下内容&#xff1a; 按值传递与按引用传递深论ref和out比较 参数应用浅析 1. 引言 接上回《第九回&#xff1a;品味类型---值类型与引用类型&#xff08;中&#xff09;&#xff0d;规则无边》中&#xff0c;对值类型和引用类型的讨论&#xff0c;其中关于string…

[你必须知道的.NET]第十二回:参数之惑---传递的艺术(下)

本文将介绍以下内容&#xff1a; 按值传递与按引用传递深论ref和out比较 参数应用浅析 接上篇继续&#xff0c;『第十一回&#xff1a;参数之惑---传递的艺术&#xff08;上&#xff09;』 4.2 引用类型参数的按值传递 当传递的参数为引用类型时&#xff0c;传递和操作的是指…

android 自定义相机源码,Android 自定义相机及分析源码

Android 自定义相机及分析源码使用Android 系统相机的方法&#xff1a;要想让应用有相机的action&#xff0c;咱们就必须在清单文件中做一些声明&#xff0c;好让系统知道&#xff0c;如下action的作用就是声明action的类型&#xff0c;便于Intent的使用&#xff0c;category的…

[你必须知道的.NET]第十三回:从Hello, world开始认识IL

本文将介绍以下内容&#xff1a; IL代码分析方法 Hello, world历史 .NET学习方法论1. 引言 1988年Brian W. Kernighan和Dennis M. Ritchie合著了软件史上的经典巨著《The C programming Language》&#xff0c;我推荐所有的程序人都有机会重温这本历史上的经典之作。从那时起…

android服务器怎么做的,[Android]Android 制作一个HTTP服务器应用

上传文件开始想用apache的开源库获取文件&#xff0c;但是失败了&#xff0c;要么文件不全&#xff0c;要么就完全为空&#xff0c;还是自己写。文件上传请求头的部分内容contentType:multipart/form-data; boundary----WebKitFormBoundaryHpUAY0qCryu0Oc7o我们需要获取boundar…

[你必须知道的.NET]第十四回:认识IL代码---从开始到现在

本文将介绍以下内容&#xff1a; IL代码分析方法 IL命令解析 .NET学习方法论 1. 引言 自从『你必须知道.NET』系列开篇以来&#xff0c;受到大家很多的关注和支持&#xff0c;给予了anytao巨大的鼓励和动力。俱往昔&#xff0c;我发现很多的园友都把…

android 获取服务对象,android 如何取得正在运行的service对象

在写有关推送的代码&#xff0c;用的长连接的方式。具体逻辑&#xff1a;登录时 启service&#xff0c;service中启一个线程&#xff0c;线程中构建一个CommunicateManegr对象&#xff0c;此对象里面有一个BlockingDeque双端队列处理包的顺序问题&#xff0c; 还有若干线程分别…

[你必须知道的.NET]第十五回:继承本质论

本文将介绍以下内容&#xff1a; 什么是继承&#xff1f;继承的实现本质1. 引言 关于继承&#xff0c;你是否驾熟就轻&#xff0c;关于继承&#xff0c;你是否了如指掌。 本文不讨论继承的基本概念&#xff0c;我们回归本质&#xff0c;从编译器运行的角度来揭示.NET继承中的…

海岸鸿蒙2018年标准物质,海岸鸿蒙——20年权威的标准物质研制单位

摘要&#xff1a;海岸鸿蒙创办于1996年&#xff0c;是专业从事国家标准物质研发、生产、销售的高新技术企业。海岸鸿蒙创办于1996年&#xff0c;是专业从事国家标准物质研发、生产、销售的高新技术企业。海岸鸿蒙自创办以来&#xff0c;一直秉持“以市场为导向&#xff0c;以科…

[你必须知道的.NET]第十六回:深入浅出关键字---using全接触

本文将介绍以下内容&#xff1a; using指令的多种用法using语句在Dispose模式中的应用1. 引言 在.NET大家庭中&#xff0c;有不少的关键字承担了多种角色&#xff0c;例如new关键字就身兼数职&#xff0c;除了能够创建对象&#xff0c;在继承体系中隐藏基类成员&#xff0c;还在…

华为双系统是鸿蒙系统吗,华为p50pro是鸿蒙系统吗-华为p50pro有双系统吗

华为p50pro的外观基本上就是延续了上一代的风格&#xff0c;没有什么太大的变化&#xff0c;不过影像能力还是非常令人期待的&#xff0c;下面一起来了解华为p50pro的系统方面&#xff0c;看看有没有你暂所不知的消息。近日&#xff0c;有消息曝光了华为 P50 Pro将会有 Harmony…

[你必须知道的.NET]第十七回:貌合神离:覆写和重载

本文将介绍以下内容&#xff1a; 什么是覆写&#xff0c;什么是重载覆写与重载的区别覆写与重载在多态特性中的应用1. 引言 覆写&#xff08;override&#xff09;与重载&#xff08;overload&#xff09;&#xff0c;是成就.NET面向对象多态特性的基本技术之一&#xff0c;两…

鸿蒙系统正式开源,余承东:鸿蒙系统正式开源,友商也可以使用!

鸿蒙OS2.0正式开源&#xff1a;从PPT走向前台&#xff0c;该谁脸红了&#xff1f;在9月10日的开发者大会上&#xff0c;华为鸿蒙2.0发布&#xff0c;已经不再是某些人嘴中的PPT、又哄又蒙的鸿蒙了。说鸿蒙是PPT的言论&#xff0c;在前不久还能看到&#xff0c;如今鸿蒙已经发布…

[你必须知道的.NET]第十八回:对象创建始末(上)

本文将介绍以下内容&#xff1a; 对象的创建过程内存分配分析内存布局研究1. 引言 了解.NET的内存管理机制&#xff0c;首先应该从内存分配开始&#xff0c;也就是对象的创建环节。对象的创建&#xff0c;是个复杂的过程&#xff0c;主要包括内存分配和初始化两个环节。例如&…

viper4android fxifi,ViPer4android. FX顶级音效!

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼名称&#xff1a;OPPO X903 杜比音效脉冲反馈样本 For VIPER4Android FX v2.0样本数量&#xff1a;72适配V4A版本&#xff1a;ViPER4Android FX v2.2.0.1 或更高适用范围&#xff1a;耳机内放制作者&#xff1a;漫游因特网授权&…

[你必须知道的.NET]第十九回:对象创建始末(下)

本文将介绍以下内容&#xff1a; 对象的创建过程内存分配分析内存布局研究接上回[第十八回&#xff1a;对象创建始末&#xff08;上&#xff09;]&#xff0c;继续对对象创建话题的讨论>>> 2.2 托管堆的内存分配机制 引用类型的实例分配于托管堆上&#xff0c;而线…

android material 颜色值,Android Material Colors 谷歌 Material Design 标准颜色

Android Material Colors谷歌 Material Design 标准颜色。调色板资源文件通过 doc-getter 自动抓取生成。运行 Demo 来查看效果。UsageGradlecompile com.takwolf.android.materialdesign:color:0.0.1Stylecolor/material_indigo_500color/material_indigo_700color/material_p…

突然吐字不清_要注意说话吐字不清小心是脑中风前兆

任何疾病发病之前往往会有一些前兆出现&#xff0c;像是脑中风这种疾病在发作之前也是有前兆的&#xff0c;若是朋友们能够尽早的发现就能够在发病前进行治疗了。朋友们要注意的是说话吐字不清小心是脑中风前兆&#xff0c;这是脑中风发病前的典型前兆&#xff0c;还有头晕、呕…