本文将介绍以下内容:

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

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

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]

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

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

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

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

  1. [你必须知道的.NET]第二十回:学习方法论

    本文,源自我回答刚毕业朋友关于.NET学习疑惑的回复邮件. 本文,其实早计划在<你必须知道的.NET>写作之初的后记部分,但是因为个中原因未能如愿,算是补上本书的遗憾之一. 本文,作为[& ...

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

    摘要: 本文将值类型和引用类型的讨论从应用示例角度来进一步做以延伸,可以看作是对前两回的补充性探讨.我们从类型定义.实例创建.参数传递.类型判等.垃圾回收等几个方面来简要的对上两回的内容做以剖析,并以 ...

  3. [你必须知道的.NET]第二十四回:认识元数据和IL(上)

    说在,开篇之前 很早就有说说Metadata(元数据)和IL(中间语言)的想法了,一直在这篇开始才算脚踏实地的对这两个阶级兄弟投去些细关怀,虽然来得没有<第一回:恩怨情仇:is和as>那么 ...

  4. [你必须知道的.NET]第二十一回:认识全面的null

    <你必须知道的.NET>网站 | Anytao技术博客  [你必须知道的.NET]第二十一回:认识全面的null 发布日期:2008.7.31 作者:Anytao © 2008 Anyta ...

  5. [你必须知道的.NET]第二十七回:interface到底继承于object吗?

    <你必须知道的.NET>网站 | Anytao技术博客  [你必须知道的.NET]第二十七回:interface到底继承于object吗? 发布日期:2009.03.05 作者:Anyta ...

  6. [你必须知道的css系列]第一回:丰富的利器2:CSS选择符之子选择符、相邻选择符...

    对了,接下来要讲的属性选择符,相邻选择符,子对象选择符可能大家稍微有点陌生了,这当然也是有原因的,因为IE6及以下的浏览器并不支持这几个选择符,而 大多数从事这方面工作的技术人员,多数时候还是主要考虑 ...

  7. [你必须知道的.NET] 第五回:深入浅出关键字---把new说透(转载)

    [你必须知道的.NET] 第五回:深入浅出关键字---把new说透 作者:Anytao 本文将介绍以下内容: 面向对象基本概念 new关键字深入浅出 对象创建的内存管理 1. 引言 园子里好像没有或者 ...

  8. [你必须知道的.NET]第二十六回:认识元数据和IL(下)

    说在,开篇之前 书接上回:  第二十四回:认识元数据和IL(上), 第二十五回:认识元数据和IL(中) 我们继续. 终于到了,说说元数据和IL在JIT编译时的角色了,虽然两个回合的铺垫未免铺张,但是却 ...

  9. [你必须知道的.NET]第二十五回:认识元数据和IL(中)

    说在,开篇之前 书接上回[第二十四回:认识元数据和IL(上)],我们对PE文件.程序集.托管模块,这些概念与元数据.IL的关系进行了必要的铺垫,同时顺便熟悉了以ILDASM工具进行反编译的基本方法认知 ...

最新文章

  1. Kaggle Days首次落地中国,日本团队拿下冠军
  2. 大数据加入渗透实体,错过它你将错过一个时代!
  3. Android笔记三十三.BroadcastReceiver使用
  4. Simulink仿真教程6---对控制系统的阶跃响应进行仿真
  5. python图片内容长度识别_教你如何用几行Python代码识别图片文字--就是这么简单!...
  6. Lesson 13.2 模型拟合度概念介绍与欠拟合模型的结构调整策略
  7. Keras:基于Theano和TensorFlow的深度学习库
  8. 在 Windows上写 Python 代码的最佳组合!
  9. Windows2012中安装域控(DC) + SQL Server 2014 + TFS 2015
  10. php fizz,php 的 FizzBuzzWhizznbsp;nbsp;
  11. 辽宁师范大学海华学院计算机科学与技术,辽宁师范大学海华学院计算机科学与技术专业综合评价简况表.doc...
  12. linux7.0下mysql_CentOS 7.0下使用yum安装MySQL
  13. 如何下载sci论文?
  14. 非安装版 Python 安装 PIP
  15. Unity5 (5.0-5.2) Shader编译机制初探 - 小心,Shader在吞噬你的内存
  16. 写好软文标题的10个方式
  17. 小米摄像头上传云服务器,杜老师说群晖:小米云摄像头无法对接群晖存储解决方法...
  18. 网站上传服务器浏览器打不开,网站发布或自己上传程序后,网站打不开的原因有哪些?...
  19. 《数据结构(C语言版)》严巍敏课件~第一章:绪论
  20. SPSS数据拆分(分组)

热门文章

  1. Ipython\Jupyter数据分析工具
  2. day3-python学习笔记(二)list(数组)
  3. 深入理解C# 静态类与非静态类、静态成员的区别 [转载]
  4. [Leedcode][JAVA][第25题][K个一组反转链表][链表][递归]
  5. EXEJ4 生成的java exe文件更换电脑后出现闪退情况解决办法
  6. 数学和计算机的应用视频教学反思,数学多媒体教学反思.doc
  7. 根据时间戳生成编号_分布式系统的唯一ID生成算法对比
  8. 1-3 交换变量(算法竞赛入门经典)
  9. B. File List
  10. 江阳职高计算机应用教改实验,计算机应用课程教改模式