解决方案 »
- sqlhelper是什么呀,好多人在说它,我看到好多版本,哪个是正宗的?
- foreach访问字符串数组顺序
- 请教关于C#结果集dataset中过滤记录的问题
- 数据导出至Excel后锁定某些列不允许修改
- 自动增长字段高手帮帮小弟吧
- 有没有办法实现简单类型的浅拷贝?没人知道吗?呜呜呜~~~~
- 问:asp.net(C#) 2.0控制窗口的大小,位置等外观,不仅仅是弹出窗口,怎么实现?
- 如何用.net操作word2003,功能包括可以获取word里面的内容,可以识别表格等?
- 请问谁有Antechinus C# Editor的注册码?
- 如何用C#拦截用net send发到我机器上的消息?
- 现在的数据库都是什么版本的?
- 频繁的访问数据库,sqlconnection可以一直open不close吗(2)
这两个函数.参数array是引用类型,a是值类型.但是他们传递时都是按值传递. 我们来举个例子说明下 按值传递参数: class Program { public static void ChangeInt(int num) { num = 123; } public static void ChangeArray(int[] array) { array[0] = 10; array = new int[] { 6, 7, 8, 9 }; } static void Main(string[] args) { int anum = 1; int[] aarray = { 1, 2, 3 }; ChangeInt(anum); ChangeArray(aarray); Console.WriteLine("value of num: " + anum); Console.Write("value of aarray: "); foreach (int i in aarray) Console.Write(i + " "); } } 结果是:value of anum : 1 value of aarray :10 2 3 可能看到结果会有点奇怪.我们一般认为值传递就是把值拷贝一份,然后不管在函数中对传入的参数做啥改变,参数之前的值不会受啥影响,所以anum没有变成123,仍然是1 但是aarray[0]为啥却变成10了呢? 前面我们有说到引用类型在内存中是保存为两个部分,一个是stack中的内存地址,另一个是heap中的实际值.用时我们只直接用stack中的值,我们假如stack中的值为0xabcdefgh
,就说是aaraay指向它吧. 那么我们按值传递时就是把这个stack的值拷贝成另一份就假如是array指向它吧.跟拷贝anum的值1一样. 但是我们操作内存地址这样的值时不会像整数一样直接操作它,而只会通过它去找heap中的实际值. 于是我们array[0] = 10.改变了实际上还是heap中数组的值了. 但array = new int []
{6,7,8,9}没有对之前传的aarray产生影响.这个操作的意义是在heap中重新开辟一块内存,保存着值6,7,8,9.
这这块内存的地址赋给array,于是它之前的值0xabcdefgh被改写了.但aarray指的值stack值仍没变,仍是0xabcdefgh 按引用传递参数 可以用out或ref显式指定.它们大部分时候可以通用,只是有一点细小区别. 先用ref 来举例吧,还用上面的例子,只是加个了关键字ref class Program { public static void ChangeInt(ref int num) { num = 123; } public static void ChangeArray(ref int[] array) { array[0] = 10; array = new int[] { 6, 7, 8, 9 }; } static void Main(string[] args) { int anum = 1; int[] aarray = { 1, 2, 3 }; ChangeInt(ref anum); ChangeArray(ref aarray); Console.WriteLine("value of num: " + anum); Console.Write("value of aarray: "); foreach (int i in aarray) Console.Write(i + " "); } } 结果是:value of anum : 123 value of aarray :6 7 8 9 跟按值传递的结果完全不同吧 num = 123我们是容易理解.我们再来说下aarray的值为啥变了吧 按引用传递时aarray指向的stack中的值不会复制一份,而是直接传过去.这样array[0]= 10这样赋值时也同样改变了heap中 1 2 3
的值,变为10 2 3,如果 没有array = new int [] {6,7,8,9}
这个语句,则它的结果跟上面按值传递是完全一样的.但有个这句话后就不一样,我们知道上面说了它的含义,在heap中开辟一块新内存 值是6 7 8 9,而aarray指向的stack的值被改写了,改为指向保存6 7 8 9的内存地址了.那含有10 2
3的那一块内存其实还继续存在,只是没有谁引用到它了.到时垃圾回收器会把它回收的. 补充: 说下out 和ref的细小区别 ref 传进来的参数必须要先赋值. 像上面 的例子中如果这样写 int num; ChangeInt(ref int num); 就会出错,必须先给num给个值1. 而且out传进来的参数可以不先赋值. out num; ChangeInt(out int num);是对的 另外还有个区别就是如果用out的时候ChangeInt函数中必须有某个地方给num赋值了,而用ref不一定需要在函数中给num赋值 其实这样做的目的很好理解.C#为了确保在任何情况下num必须有个值,不能为空. 因为用ref,在调用函数前必须保证参数有值,所以在函数中就不必要求它一定再赋值 而用out由于在调用函数前不用保证参数必须有值,所以在函数中必须保证给它个值 ChangeInt(ref int num)和ChangeInt(out int num)虽然不一样,但是不同共存,不能当作两个不同的函数 而ChangeInt(int num)和上面 的两个函数是完全不一样的,可以放到一起共存 这样的话调用的时候ref ,out这样的关键字不能省的.必须匹配
params关键字表示可变参数的意思,就是说你这个方法的参数是可以变化的。 ss("a","b"),ss("a","b","c"),ss("a","b","c","d")都可以。
值类型,引用类型的本质不理解的话也不急,慢慢来。
但是.net为性能做了妥协,引入了值类型。引用类型是对象,值类型的本质是“轻量的对象”。