一、分类
C#的值类型包括:结构体(数值类型,bool型,用户定义的结构体),枚举,可空类型。
C#的引用类型包括:数组,用户定义的类、接口、委托,object,字符串。
二。参数传递
对于引用类型,不管是将其作为值参数传递还是引用参数传递,都可以在方法成员内部修改其内容。而值类型则不能修改。首先举一个简单的例子
(1)引用类型和值类型作为参数传递的区别:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace 引用类型问题 { class Program { static void test1(ref int val1,int val2) { val1 = 10; val2 = 20; Console.WriteLine("val1={0},val2={1}", val1, val2); } static void Main(string[] args) { myclass mc = new myclass(); test1(ref mc.val1, mc.val2); Console.WriteLine("函数调用后:val1={0},val2={1}", mc.val1, mc.val2); Console.ReadKey(); } } class myclass { public int val1 = 0; public int val2 = 0; } }
输出结果是: val1=10,val2=20
函数调用后:val1=10,val2=0
引用类型中,如果在方法内创建新对象并赋值给形参会产生什么结果呢?
(1)引用类型作为值参数传递时,如果在方法内创建对象并赋值给形参,将切断形参与实参之间的联系,并在方法调用结束后,新对象也不复存在
class myclass { public int val1 = 10; } class Program { static void test1(myclass f1) { f1.val1 = 60; Console.WriteLine("创建新对象前:val1={0}", f1.val1); f1 = new myclass(); Console.WriteLine("创建新对象后:val1={0}", f1.val1); } static void Main(string[] args) { myclass mc = new myclass(); Console.WriteLine("函数调用..."); test1(mc); Console.WriteLine("函数调用后:val1={0}", mc.val1); Console.ReadKey(); } }
输出结果为: 函数调用...
创建新对象前:val1=60
创建新对象后:val1=10
函数调用后:val1=60
值得注意的是,函数调用结束后并没有改变val1的值,因为在方法调用结束后新对象已经不存在了。
(2)引用类型对象作为引用参数传递时,如果在方法内创建对象并赋值给形参,在方法结束后该对象依然存在,并且是实参所引用的值
class myclass { public int val1 = 10; } class Program { static void test1(ref myclass f1) { f1.val1 = 60; Console.WriteLine("创建新对象前:val1={0}", f1.val1); f1 = new myclass(); Console.WriteLine("创建新对象后:val1={0}", f1.val1); } static void Main(string[] args) { myclass mc = new myclass(); Console.WriteLine("函数调用..."); test1(ref mc); Console.WriteLine("函数调用后:val1={0}", mc.val1); Console.ReadKey(); } }
这段代码和上面几乎没区别,只是在引用参数调用的时候添加了ref关键字,但结果却不一样
输出结果为: 函数调用...
创建新对象前:val1=60
创建新对象后:val1=10
函数调用后:val1=10
函数调用后val1的值也变成了10.