闪电龟龟--笔记

万物寻其根,通其堵,便能解其困。
  博客园  :: 新随笔  :: 管理

C# 值传参和引用传参

Posted on 2019-01-12 23:30  闪电龟龟  阅读(381)  评论(0编辑  收藏  举报

值传递:对于个人理解,值传递就像是python中的深拷贝,值传递的内容和原来的内容是两份不同的东西,相互不影响。

引用传递:对于个人理解,引用传递就是python中的复杂多维list的浅拷贝,它传递的只是一个内存空间的一种映射,如果你更改引用进来的值,那么将会影响到被引用的值。

Class1.cs

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

namespace ConsoleApplication1
{
    class Class1
    {
        private int age;
        public Class1(int age)
        {
            this.age = age;
        }
        // age接口
        public int Age
        {
            get
            {
                return age;
            }

            set
            {
                age = value;
            }
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Class1 age = new Class1(3);
            //Growth(age);  // 调用静态方法,对象的++,会使对象年龄变为4
            Growth(age.Age);  // 整型的++,年龄虽然加到了4,但是没有输出使用,对象的年龄仍然为3
            Console.WriteLine(age.Age);  // 重新输出年龄的大小
        }
        // 定义静态方法,访问的时候不需要进行实例化
        // 该static使用的是对象类型的++,相当于引用类型
        static void Growth(Class1 child)
        {
            child.Age++;
            Console.WriteLine("又长大一岁!!!");
        }
        // 该static是int类型的++,相当于值类型
        static void Growth(int age)
        {
            age++;
            Console.WriteLine("int又长大一岁!!!");
        }
    }
}

 

值类型有byte,short,int,long,float,double,decimal,char,bool,enum和struct。值类型的值会直接存放在栈中;

引用类型有array,interface,string和object。引用类型在栈中存放的是引用,而引用的指向实际存放的堆。

相同的是值类型和引用类型继承的都是System.Object类,而不相同的是值类型继承System.Object类的子类System.ValueType类。

(详细可以看:https://blog.csdn.net/qiaoquan3/article/details/51202926#comments)

(练习可以看:https://www.oschina.net/code/snippet_188227_9009#14426)

值类型总是一个值;引用类型可以是null,表示不包含值。但是,值类型可以使用可空类型(泛型的一种),使值类型在这个方面可以像引用类型一样使其为null。

 

AddBy 2020-06-28

如果想要看更加详细的关于“C# 深浅复制 MemberwiseClone”可以跳转连接https://www.cnblogs.com/chenwolong/p/MemberwiseClone.html,我这里只是突然学习到了这个知识点所以做了个笔记,唯一想要纠正的是向上文我这里提到的string为引用类型这是毋庸置疑的。

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

namespace ConsoleApplication1
{
    /// <summary>
    /// 测试类
    /// </summary>
    public class CModel {
        public int ID;  // 值类型
        public string IDName;  // 引用类型
        public ObjectName OName; // 引用类型
        /// <summary>
        /// 进行浅复制
        /// </summary>
        /// <returns></returns>
        public CModel CopyDeal()
        {
            // 在进行浅复制的过程中,值类型都会创建新的变量
            // string是引用类型,但是也会创建新的变量,原因是因为string类型本身虽然是引用类型,但是一旦创建其长度和值便无法修改。
            return (CModel)this.MemberwiseClone();
        }
    }
    public class ObjectName
    {
        public string OName;
        public ObjectName(string _OName) {
            this.OName = _OName;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            CModel P1 = new CModel();
            P1.ID = 1;
            P1.IDName = "IDName1";
            P1.OName = new ObjectName("OName1");
            Console.WriteLine("P1的属性:");
            CResult(P1);
            CModel P2 = P1.CopyDeal();  // 进行浅复制
            P1.ID = 2;  // 值类型,不会影响P2的ID
            P1.IDName = "IDName2";  // string引用类型,不会影响P2的IDName
            P1.OName.OName = "OName2";  // 引用类型,会影响P2的OName
            Console.WriteLine("P2的属性:");
            CResult(P2);
            Console.ReadKey();
        }
        public static void CResult(CModel model) {
            Console.WriteLine("ID:" + model.ID + ",IDName:" + model.IDName + ",OName:" + model.OName.OName);
        }
    }
}

运行结果:

EndBy 2020-06-28