C#学习之值类型与饮用类型

新建控制台应用程序

示例1:值类型

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

namespace _07值类型传递
{
    class Program
    {

        #region 概念、定义
        //值类型:都派生自System.ValueType[System.ValueType又继承自Object
        //1.int、char、double、float、long、short、byte、bool、enum、struct、decimal
        //2.值类型不能继承,只能实现接口。
        //3.值类型变量赋值会拷贝一个副本。

        //引用类型:ref,都派生自:Object
        //1.string、数组、类(子定义数据类型)、接口、委托、
        //2.int[] n={1,2,3};//引用类型。
        //3.引用类型可以继承(类之间可以继承)
        //4.引用类型变量的赋值只复制对对象的引用。

        //枚举:
        //1.一组和数值有关的常量
        //2.enum Gender { Male,Female}
        //3.enum Weeks { 星期日=0,星期一,}
        //4.把字符串转换成枚举Gender g = (Gender)Enum.Parse(typeof(Gender), "Male");
        //结构:
        //1.就是小类,值类型
        //2.不能继承类
        //3.可以实现接口
        //4.不能有显示无参构造函数(隐式)
        //5.结构中不能给字段赋初始值
        #endregion

        static void Main(string[] args)
        {
            #region 测试一:值类型
            Console.WriteLine("测试一结果如下:");
            int n = 10;
            int m = n;
            m = m + 1;
            Console.WriteLine(m);//11
            Console.WriteLine(n);//10
            #endregion

            #region 测试二:参考截图“1-值类型引用类型”
            Console.WriteLine("测试二结果如下:");
            //说明:变量“pp”即截图“1-值类型引用类型”中的“p”,为了区分测试三种的变量,在此处修改了变量名
            Person pp = new Person();//在堆中开辟一块内存,并把存储地址赋值给pp(栈类型)
            pp.Name = "yzk";//在堆中给pp的Name属性赋值为“yzk”

            Person p1 = pp;//把p在堆中的存储地址赋值给p1(与pp指向堆的地址相同)
            Console.WriteLine(p1.Name);//yzk

            p1.Name = "jk";//修改堆中Name属性为“jk”
            Console.WriteLine(pp.Name);//jk
            #endregion

            #region 测试三:(值传递)值类型与引用类型作为参数传递时的注意事项,参考截图“2-M1M2M3”和“3-M4”
            Console.WriteLine("测试三结果如下:");
            //======================1======================
            int x = 10;
            M1(x);//通过M1调用后,n1的值+1,为11,x的值不变
            Console.WriteLine("M1:" + x);//10

            //======================2=====================
            Person p = new Person();//在堆中开辟一块内存,并把存储地址赋值给p(栈类型)
            p.Name = "yzk";//在堆中给p的Name属性赋值为“yzk”
            M2(p);//通过“M2”调用后,把p在堆中的存储地址赋值给p1(与p指向堆的地址相同),然后通过p1将Name属性修改为“jk”
            Console.WriteLine("M2:" + p.Name);//输出结果即为:jk

            //======================3=====================
            Person pp1 = new Person();
            pp1.Name = "科比";
            M3(pp1);
            Console.WriteLine("M3:" + pp1.Name);//输出“科比”

            //=========================4====================
            Person yzk = new Person();
            yzk.Name = "yzk";
            M4(yzk);
            Console.WriteLine("M4:" + yzk.Name);//输出"jk"

            //======================5======================
            Person p3 = new Person();
            p3.Name = "yzk";
            M5(p3);
            Console.WriteLine("M5:" + p3.Name);//输出yzk

            //======================6======================
            Person p4 = new Person();
            p4.Name = "yzk";
            M6(p4);
            Console.WriteLine("M6:" + p4.Name);//输出jk

            #endregion

            Console.ReadKey();
        }

        static void M1(int n1)
        {
            n1 = n1 + 1;
        }

        static void M2(Person p1)
        {
            p1.Name = "jk";
        }

        static void M3(Person px)
        {
            Person p2x = new Person();
            px = p2x;
            px.Name = "sk";
        }

        static void M4(Person per)
        {
            per.Name = "jk";
            Person p = new Person();
            per = p;
            per.Name = "sk";
        }

        static void M5(Person p1)
        {
            p1 = new Person();
            p1.Name = "jk";
        }

        static void M6(Person p1)
        {
            p1.Name = "jk";
            p1 = new Person();
            p1.Name = "sk";
        }
    }
    public class Person
    {
        public string Name
        {
            get;
            set;
        }
        public int Age
        {
            get;
            set;
        }
        public string Email
        {
            get;
            set;
        }

    }
}

图1:“1-值类型引用类型”


图2:“2-M1M2M3”


图3:“3-M4”

示例1输出结果:



示例2:ref引用类型

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

namespace _08引用类型
{
    class Program
    {
        static void Main(string[] args)
        {
            //ref表示引用传递
            //ref引用传递的是栈的地址,栈的内容不变
            //值传递:传递的是栈中的内容
            //按引用传递,传递的是值类型
            //参考截图“4-ref引用传递”
            int n = 10;
            M1(ref n);
            Console.WriteLine(n);//11

            Person p = new Person();
            p.Name = "jk";
            M2(ref p);
            Console.WriteLine(p.Name);//sk

            //总结:
            //ref引用传递:传递的是栈本身的地址
            //值传递:传递的是栈中的内容
            //对于值类型来说:栈中存储的就是直接使用的数据。
            //对于应用类型来说:栈中存储的就是堆中对象的地址
            //参数传递的时候:
            //1>值传递,传递的是栈中保存的数据
            //2>引用传递,传递的是栈的本身的地址
            Console.ReadKey();
        }

        static void M1(ref int a) 
        {
            a = a + 1;
        }

        static void M2(ref Person per) 
        {
            per = new Person();
            per.Name = "sk";
        }
    }

    public class Person
    {
        public string Name
        {
            get;
            set;
        }
        public int Age
        {
            get;
            set;
        }
        public string Email
        {
            get;
            set;
        }
    }
}


图4:“4-ref引用传递”
示例2输出结果如下:




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值