1.在C#中有两个大的数据类型,值类型和引用类型。
1)任何的结构体(例如:struct Int32...)或者是枚举都是值类型。
2)能被称作"类"的,则为引用类型,比如你用如下关键字(class、interface、delegate、record),或者是使用C#内置的引用类型:dynamic、object、string。
引用类型和值类型。 引用类型的变量存储对其数据(对象)的引用,而值类型的变量直接包含其数据。 对于引用类型,两种变量可引用同一对象;因此,对一个变量执行的操作会影响另一个变量所引用的对象。 对于值类型,每个变量都具有其自己的数据副本,对一个变量执行的操作不会影响另一个变量(
in
、ref
和out
参数变量除外)-------- 引用类型 - C# 参考 | Microsoft Learn
3)值类型放在栈上的,而引用类型是放在堆上的(new过之后),栈上只保留一个指向该引用类型的指针。
2.值类型方法形参的传递
1)对于值类型,传递的是该值的一个副本,在方法内部改变该值,对原有的值没有影响。如下例-> p最终打印出来还是1;
1 static void Main(string[] args) 2 { 3 int p = 1; 4 5 Add(p); 6 7 Console.WriteLine(p); 8 Console.ReadLine(); 9 } 10 static void Add(int x) => x += 1;
2)如果需要p能被方法内部所修改,则可以加上ref关键字来传递,对于值类型ref关键字会把该变量的地址传入,也就是传递一个指向该值的指针。如下例->p最终打印出来的是2;
1 static void Main(string[] args) 2 { 3 int p = 1; 4 5 Add(ref p); 6 7 Console.WriteLine(p); 8 Console.ReadLine(); 9 } 10 static void Add(ref int x) => x += 1;
3.引用类型方法形参的传递
1)对于引用类型,引用类型的变量存储的是一个指向该变量值的指针。所以不用加ref关键字,就可以做到方法内部修改了值,传入的值也会变(但是无法改变传入值原有的引用)。下面打印出来的就是1\n2
static void Main(string[] args) { MyClass mc = new() { id = 1, Type = "a" }; Console.WriteLine(mc.id); Change(mc); Console.WriteLine(mc.id); Console.ReadLine(); } static void Change(MyClass mc) { mc.id = 2; }
2)引用类型加上ref关键字传递,调用方则可以改变引用类型参数的引用。对象的存储位置按引用参数的值传递到方法,更改参数存储位置中的值(指向新对象),还可以将存储位置更改为调用方所引用的位置。如下例1,在方法内部改变了参数的原有对象引用,但是输出结果还是1\n2。
1 static void Main(string[] args) 2 { 3 MyClass mc = new() 4 { 5 id = 1, 6 Type = "a" 7 }; 8 Console.WriteLine(mc.id); 9 Change(mc); 10 Console.WriteLine(mc.id); 11 Console.ReadLine(); 12 } 13 14 static void Change(MyClass mc) 15 { 16 mc.id = 2; 17 mc = new() 18 { 19 id = 3, 20 Type = "c" 21 }; 22 }
如果加上ref传递,如下例2:最终打印的结果就是1\n3
1 static void Main(string[] args) 2 { 3 MyClass mc = new() 4 { 5 id = 1, 6 Type = "a" 7 }; 8 Console.WriteLine(mc.id); 9 Change(ref mc); 10 Console.WriteLine(mc.id); 11 Console.ReadLine(); 12 } 13 14 static void Change(ref MyClass mc) 15 { 16 mc.id = 2; 17 mc = new() 18 { 19 id = 3, 20 Type = "c" 21 }; 22 }
总的来说如果参数是引用类型变量,内部可以操作该变量指向的内存的值(比如修改某个属性的值)但是无法修改该引用类型的原有对象引用(传递的),加上ref的传递则是把参数的指针传递了过来所以可以修改原对象引用。
eg:如果是方法的参数是引用类型,相当是有一个新的指针指向了该值内存空间。加上ref传递则是把原有的指针给传递了过来。
标签:Console,mc,C#,关键字,引用,类型,ref,id From: https://www.cnblogs.com/AnYanaha/p/17442259.html