.Net【基础回顾】值类型与引用类型

值类型

直接存储数据
基础数据类型都是值类型
从类 System.ValueType 中派生的

  • 值类型存在上,自动释放,栈存小数据

  • 不能派生

  • 适合做存储数据的载体

容易误会的数据类型

  • enum
  • struct
  • datetime 值类型(struct)
  • Nullable 值类型(本质是一个结构)

引用类型

不包含存储在变量中的实际数据,但它们包含对变量的引用

  • 引用类型存在上,堆存大数据

  • 适合定义应用程序的行为

容易误会的数据类型

  • object
  • dynamic
  • string
  • 指针类型

装箱与拆箱

  • 装箱:值类型转成引用类型

  • 拆箱:引用类型转成值类型

值类型和引用类型的参数传递

值传递

  • 值类型:复制值传递,函数中修改不会影响原来的变量值

  • 引用类型:引用地址传递,函数中做修改会影响原来的变量

  • string:引用类型,但当做值类型处理

引用传递

  • 值类型:值类型的存储地址传递,函数中修改会影响原来的变量

  • 引用类型:引用地址传递,一样会修改

引用传递方式

  • ref:地址传递,必须先初始化,不能NULL

  • out:结果传出,在结果返回前必须先赋值

类型转化比较 is as typeof

  • is:判断类型,不会跑出异常,如果对象为null,则返回值永远为false

  • as:类型转化,不会抛出异常,转化失败返回null

  • typeof:返回System.Type对象,获取对象的具体类型信息


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Demo.ValueTypeTest
{
    class Program
    {
        static void Main(string[] args)
        {
            // 值传递
            int a = 1;
            int b = a;
            b = 0;
            Console.WriteLine($"a:{a}"); //1

            Person person1 = new Person() { Id = 1, Name = "Jack" };
            Person person2 = person1;

            person2.Id = 2;
            person2.Name = "Tom";
            Console.WriteLine($"person1.Id:{person1.Id},name:{person1.Name}"); //2,Tom

            string sta = "a";
            string stb = sta;
            stb = "b";
            Console.WriteLine($"sta:{sta}"); //a


            // 引用传递

            // out
            int cc = 1;
            ValueOutTest(out cc);
            Console.WriteLine($"cc:{cc}"); //2

            Person person = new Person() { Id = 1, Name = "Jack" };
            ObjectOutTest(out person);
            Console.WriteLine($"person.Id:{person1.Id},name:{person1.Name}"); //2,Tom

            string st = "1";
            StringOutTest(out st);
            Console.WriteLine($"st:{st}"); //2

            // ref
            int c = 1;
            RefTest(ref c);
            Console.WriteLine($"c:{c}"); //2

            person = new Person() { Id = 1, Name = "Jack" };
            RefTest(ref person);
            Console.WriteLine($"person.Id:{person1.Id},name:{person1.Name}"); //2,Tom


            string stt = "1";
            StringOutTest(out stt);
            Console.WriteLine($"stt:{stt}"); //2


            Console.ReadLine();

        }


        static void ValueOutTest(out int a)
        {
            //离开当前方法之前必须对 out 参数赋值
            a = 2;
        }

        static void StringOutTest(out string a)
        {
            //离开当前方法之前必须对 out 参数赋值
            a = "2";
        }

        static void ObjectOutTest(out Person person)
        {
            person = new Person()
            {
                Id = 2,
                Name = "Tom"
            };
        }

        static void RefTest(ref int a)
        {
            a = 2;
        }


        static void RefTest(ref Person person)
        {
            person.Id = 2;
            person.Name = "Tom";
        }
        static void RefTest(ref string str)
        {
            str = "2";
        }

    }

    class Person
    {
        public string Name { get; set; }
        public int Id { get; set; }
    }
}


源码

posted on 2020-04-18 11:25  杏村牧童  阅读(115)  评论(0编辑  收藏  举报