C#教程

C#中类型的实例化

一、类型实例化的本质

在上一节课,我们定义了一个Person类型,这一节我们来学习如何使用它。对于非静态类,我们是不能直接使用的,必须先对其进行实例化。

举个例子,大米科技的老板突然想研发一款新产品,虽然该公司设有研发部长一职,但该职位空缺,老板是不能直接喊一句:研发部长,今年我们要开发一款新产品,就叫大米手机18,你赶紧组织人手干吧!

因为这个“研发部长”只是公司众多职位中的一种职位类型,并没有特指哪个具体的人,直到有一天,张三前来入职,担任了研发部长。这个时候老板再到公司扯一嗓子,那位叫张三的研发部长才会有回应。张三就是一个实实在在的对象,只有对象才能干活儿。

对应到C#代码中,Person只是我们设计的一种类型,由于它没有实例化,所以也不能直接使用,那么,什么是实例化?如何实例化一个类型呢?

首先,实例化的本质是程序通过“CLR运行时”转告操作系统,我这里要申请一些内存空间,用来存放Person,等我使用完内存中的这个Person对象后,C#的垃圾清理器会帮我把Person从内存中清理它,并把这部分内存还给操作系统。

二、堆内存与栈内存的区别

至于要申请多大的内存,CLR运行时会自动计算出Person占用内存空间的字节长度。计算机的内存分为堆和栈两种,这两种的区别是:

1.内存分配方式

栈(stack)和堆(heap)都是内存中的一段区域,但它们的内存分配方式是不同的。栈是由程序自动创建和释放的,通常用于存储函数调用时的临时变量、函数的返回地址等信息。而堆则是由程序员手动申请和释放的,通常用于存储程序中需要动态分配的内存(如动态数组、对象等)。

2.内存管理方式

栈的内存分配是按照“后进先出”的原则进行的,即最后一个进入栈的变量最先被释放。因此,栈中的内存管理是由系统自动完成的,程序员不需要过多考虑内存的分配和释放问题。堆的内存管理则需要程序员自行负责,使用完毕后必须手动释放,否则会导致内存泄漏或其他问题。

3.内存大小

栈的容量较小,一般只有几百KB到几MB的空间,具体容量由操作系统和编译器决定。相对而言,堆用于存储较大的数据结构,大小一般比栈要大得多,可以动态扩展内存空间。但是,因为堆需要手动管理内存,如果不及时释放,会导致内存泄漏,进而影响系统性能。

4.访问速度

因为栈的内存分配是系统自动完成的,所以访问速度相对堆更快。栈中的数据直接存放在系统内存中,而访问堆中的数据需要通过指针进行间接访问,会造成一定的时间损耗。此外,在多线程环境下,由于栈的线程独享,所以不会发生竞争问题。而堆则需要考虑多线程并发访问时的同步和互斥机制。

5.应用场景

栈适合用于存储局部变量和函数调用,主要用于内存的临时分配;而堆适合用于存储需要动态分配和管理的数据结构,如动态数组、字符串、对象等。在实际开发中,应该根据具体的应用场景选择合适的内存分配方式。

综上所述,堆大栈小,堆慢栈快。

在C#语言中,所有采用class声明的数据结构体称为引用类型,往往程序员在设计一个class时,随着业务的扩展,类型会越写越大,所以,引用类型在实例化时所分配的内存都是从堆上面拿到的;所有采用struct声明的数据结构体称为值类型,它们在实例化时会从栈中分配到内存空间

三、new关键字

new可以根据对象的类型来为其在堆上分配足够的空间,并且将这个对象的所有字段都设为默认值。也就是说,CLR会把该对象的所有引用类型字段设为null,而把值类型字段的所有底层二进制表示位设为 0(本质上来说,不论是将值类型或引用类型字段初始化为“默认值”,其实都是把他们底层的数据位设为0)。

那么,Person类的实例化就是下面这样子。

Person person = new Person();
person.Name = "杨过";
person.Age = 18;
person.Write();

我们可以把这段代码放在任何可以执行C#的地方,第一句代码表示将Person类型实例化,这个实例对象叫person;第二句代码表示给这个person对象的Name属性赋值为"杨过",第三句代码表示给person对象的Age属性赋值为整数18;第四句代码表示执行person的Write方法成员。

那我们把它们放到Helloworld项目中的Main函数里面。

namespace Helloworld
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Person person = new Person();
            person.Name = "杨过";
            person.Age = 18;
            person.Write();

            var v = Console.ReadKey();
        }
    }
}

然后按下F5运行,其效果如下。

OK,至此,通过前面这些课程的讲解,我们终于踏入编程的大门了,接下来,我们将从C#的基础学走,围绕类型的设计,编写不同的控制台应用程序,直到学完C#的所有基础知识。

当前课程源码下载:(注明:本站所有源代码请按标题搜索)

文件名:001-《C#中类型的实例化》源代码
链接:https://pan.baidu.com/s/1Bq2lX7cruUbklLwgjGggSw
提取码:byte

——重庆教主 2023年12月11日

copyright @重庆教主 C#中文网 联系站长:(QQ)23611316 (微信)movieclip (QQ群).NET小白课堂:864486030 | 本文由C#中文网原创发布,谢绝转载 渝ICP备2023009518号-1