zoukankan      html  css  js  c++  java
  • 值类型和引用类型

    在C#中值类型的变量直接存储数据,而引用类型的变量持有的是数据的引用,数据存储在数据堆中。

    常见的值类型数据有:整值型(整形,浮点型,十进制型),布尔类型,枚举类型;

    引用类型有:接口,数组,Object类型,类,委托,字符串,null类型。

    在C#中每种类型的存储方式有两种:1)分配在托管栈中;2)分配在托管堆中;

    内存的分配有CLR管理(即公共语言运行时),这两种方法的区别是:

    1)分配在托管栈中的变量会在创建它们的方法返回时自动释放,例如在一个方法中声明Char型的变量UserInput=C,当实例化它的方法结束时,UserInput变量在栈上占用的内存就会自动释放;

    2)分配在托管堆中的变量并不会在创建它们的方法结束时释放内存,它们所占用的内存会被CLR中的垃圾回收机制释放。

    看下面的代码:

    1 static void Main(string[] args)
    2         {
    3             //当nStudent声明并赋值是,这时在托管栈上就会开辟一块内存来存储nStudent的值,当实例化nStudent的Main()方法结束时,
    4             //nStudent在托管栈上占用的内存会自动释放。
    5             int nStudent = 0;
    6             //当声明strStuName时,这个时候“小明”存储在托管堆中,而托管栈中存储的是strStuName指向的引用。
    7             string strStuName = "小明";

    9             Console.WriteLine("学生的总数是{0},五号的名字是{1}", nStudent, strStuName);
    10             Console.ReadKey();
    11         }

    装箱和拆箱

    当值类型的数据转换成引用类型时,CLR会先在托管堆配置一块内存,将值类型的数据复制到这块内存,然后再让托管栈上的引用类型的变量指向这块内存,这样的过程称为装箱。相反的话,有引用类型转换成值类型的话就称为拆箱。

    一般情况下,.NET会主动的帮我们完成装箱操作,但是拆箱并非主动,我们必须知道拆箱对象的实力类型,然后明确的去执行拆箱操作。

    1 int BirthdayNum = 1989;
    2             object BoxBirthdayNum = BirthdayNum;//系统自动装箱
    3             int nBirthdayNum = (int)BoxBirthdayNum;//明确数据类型的拆箱

    因为花费了更多的时间,所以装箱和拆箱对程序的性能有一定的影响。

    --------------------------------------------------------------------------------------------------------------------------------------

    类型推断

    在C#中有两种类型的数据,一种是值类型,另一种是引用类型。

    值类型包括:内置值类型、用户自定义值类型、和枚举,如 int,float bool 等,以及struct等。

    引用类型包括接口类型、用户自定义的类、委托等。如 string 、DateTime、数组等。

    值类型是存储在堆栈中,而引用类型是存储在托管堆上,C#程序首先被编译成IL程序,然后在托管执行。值类型直接从堆栈中里面取值,而引用类型必须要先从堆栈里面取出它的地址,再根据这个地址在堆里找到对应的值。


    值类型与饮用类型的本质区别有以下几点:

    1.内存分配: 值类型是分配在栈中的;而引用类型是分配在堆中。

    2.效率: 值类型效率高,不需要地址转换;引用类型效率较低,需要进行地址转换。

    3.内存回收: 值类型使用完后立即回收;引用类型使用完后不立即回收,而是交给GC处理回收。

    4.赋值操作: 值类型是创建一个新对象;引用类型创建一个引用。

    5.类型扩展: 值类型不易扩展,所有值类型都是密封(seal)的,所以无法派生出新的值类型;引用类型具有多态的特性方便扩展。

    这是别人的总结,我在这里拿来用下。

    下面我在说说它们在用法上的区别了,C#之所以要分这两种数据类型的原因是达到更好的性能,把一些基本类型如int、bool规定为值类型,而把包含许多字段的较大类型规定为引用类型,如用户自定义的类。值类型主要是负责存储数据,引用类更多是用在代码的重用性上。

    从C#3.0开始,C#引入了一个隐式类型推断的关键字var,编译器可以通过它的初始值来判断变量的具体类型。var只能用于局部变量的声明,不能用于字段级的变量声明。使用var关键字时,var必须得有初始值,这样编译器才能判断是否是真实变量。

    1 class Program
    2     {
    3         static void Main(string[] args)
    4         {
    5             var i = 10;//隐式类型
    6             int m = 10;//显示类型

    8             var Program=new Program();
    9             Program.nAge = 20;
    10             Program.SayHello();
    11         }
    12 
    13         private int nAge;
    14         public void SayHello()
    15         {
    16             var message = "my age is {0}";
    17             Console.WriteLine(message, nAge);
    18         }
    19     }

    message初始值的变量为字符串类型,因此编译器可以推断其类型为String类型

  • 相关阅读:
    MF干活——C#点灯神话
    开发板通用刷机教程
    如何找到并完成兼职项目
    如何获取最新的X组件及源码
    MF干活——C#数码管与跑马灯之舞(视频)
    MF前传——探索者一号简介
    .Net Micro Framework移植基础(包编译通过)
    Oracle免客户端For .Net(只为用NewLife.XCode开发Oracle的同学服务)
    XCode新增数据转换功能(导数据)
    MF前传——探索者二号简介
  • 原文地址:https://www.cnblogs.com/wuyuankun/p/3736749.html
Copyright © 2011-2022 走看看