A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 郑丹丹1990 中级黑马   /  2013-4-20 21:40  /  2156 人查看  /  9 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 郑丹丹1990 于 2013-4-24 08:56 编辑

public class Starter {
        public static void MethodA(XInt alias) {
            XInt inner = new XInt();
            inner.iField = 5;
            alias = inner;
        }
        public static void MethodB(int paremeter) {
            paremeter += 5;
        }
        public static void MethodC(ref int i) {
            i += 5;
        }
        public static void MethodD(XInt xint){
            xint.iField += 5;
        }
        public static void Main() {
            XInt obj = new XInt();
            MethodA(obj);
            Console.WriteLine("引用传值{0}",obj.iField);//2为何是2?????

            int local = 2;
            MethodB(local);
            Console.WriteLine("值传递{0}",local);//2

            int var = 2;
            MethodC(ref var);
            Console.WriteLine("引用传值{0}", var);//7

            XInt xint = new XInt();
            MethodD(xint);
            Console.WriteLine("引用传值{0}", xint.iField);//7
            Console.ReadKey();
        }

评分

参与人数 1技术分 +1 收起 理由
苏波 + 1

查看全部评分

9 个回复

倒序浏览
本帖最后由 崔宏奎 于 2013-4-20 21:58 编辑

C#中分为值传递和引用传递:
1.值类型包括基本类型(数值类型,bool类型等)、结构和枚举,
2.引用类型包括类、委托、数组等。
------------------------------------------------------------------------------------------
  1. A:  public static void MethodB(int paremeter);
复制代码
这个方法的参数 int parermeter,因为是int类型,C#传递参数时,会采用值传递方式,把parermeter的值复制一下,在内存中开辟一片区域保存这个值,所以你在主函数中操作的int local 和方法中操作的int paremeter实际是两片内存区域,改变了函数中的paremeter += 5,是不影响主函数中的int local = 2;
  1. B:  public static void MethodA(XInt alias);
复制代码
这个方法的参数是一个类,C#中采用的引用传递,就是传入了alias的地址,这个时候你在方法内操作这个变量,实际上是改变的同一片内存区域,主函数的变量也会随之改变!
  1. C:  public static void MethodB(ref int paremeter);
复制代码
如果你加上ref关键字,这时候传入的是引用,在方法内改变这个变量的值,主函数的变量值也会随之改变啦~~

评分

参与人数 1技术分 +1 收起 理由
苏波 + 1

查看全部评分

回复 使用道具 举报
  1. Console.WriteLine("引用传值{0}",obj.iField);//结果是2???为什么???
复制代码
之所以obj.ifield = 2,是因为你没有把它的值改,虽然你在methodA()方法里面有重新给赋值,
但是你没有把你赋的新值返回来,所以就跟没改的一样,只是多了一步操作,但没有意义;
能明白我的意思么

评分

参与人数 1技术分 +1 收起 理由
苏波 + 1

查看全部评分

回复 使用道具 举报
崔宏奎 发表于 2013-4-20 21:56
C#中分为值传递和引用传递:
1.值类型包括基本类型(数值类型,bool类型等)、结构和枚举,
2.引用类型包括 ...
  1.   public static void MethodA(XInt alias) {
  2.             XInt inner = new XInt();
  3.             inner.iField = 5;
  4.             alias = inner;
  5.         }
复制代码
但是这里我把 inner.iField 的值改变了。
比较
  1. public static void MethodD(XInt xint){
  2.             xint.iField += 5;
  3.         }
复制代码
两者的异同呢?
回复 使用道具 举报
林东枫 发表于 2013-4-20 21:56
之所以obj.ifield = 2,是因为你没有把它的值改,虽然你在methodA()方法里面有重新给赋值,
但是你没有把你 ...

同时请看我的
  1. public static void MethodD(XInt xint){
  2.             xint.iField += 5;
  3.         }
复制代码

  1.             XInt xint = new XInt();
  2.             MethodD(xint);
  3.             Console.WriteLine("引用传值{0}", xint.iField);//7
复制代码
结果是7
回复 使用道具 举报
引用类型按引用传递会发生什么呢?函数接受局部引用而不是别名。首先,其中一个引用时按值传递的,在被调用函数中,该参数被赋予一个新实例。
  然而,因为引用是按值传递的,所以函数退出后,该修改就被丢失了。因此,元是引用(obj)没有改变。
这是书上的原话。
回复 使用道具 举报
本帖最后由 崔宏奎 于 2013-4-21 00:04 编辑
郑丹丹1990 发表于 2013-4-20 21:59
但是这里我把 inner.iField 的值改变了。
比较两者的异同呢?

参数分为: 1. 值参数 2.引用参数
A.值参数在传递时,首先把参数中的值复制一份,存储在栈中。(int类型其实应该不在堆中的,这里不用管)
    如下:

可以看到,他们的内存地址是不同的,栈里的内存会在方法退出时被自动释放。
回头看你的代码:
  1. XInt obj = new XInt();
复制代码
虽然 obj 是一个引用类型变量,你用new Xint()创建一个类时,obj中保存了这个类在内存中的地址,但调用 public static void MethodA(XInt alias) 时,obj保存的“地址” 将复制给了 alias 变量!!!!(注意obj和alias)
这个时候如果这样操作:alias.iField+= 5 确实是修改的主函数的 obj 。
但如果执行如下代码:
  1. XInt inner = new XInt();
  2. inner.iField = 5;
  3. alias = inner;
复制代码
虽然修改了 alias  指向 inner  ,而且这时假设不退出,访问alias.iField的值,也确实是5, 但别忘记,alias是值参数,是复制而来的,是在栈中开辟的一块内存保存,方法结束时alias的内存被释放,好像下面的这个样子:

MethodA
{
}
执行到大括号结束时,系统会释放横线上面的内存区域。
---------------------------------------------------------------------------------------------------
假设采用引用传递,这时候,C#将不会复制obj的值,而会直接使用的原来的地址。现在修改了obj中的"地址",就相当于让obj指向了新的地方~!!!





评分

参与人数 1技术分 +1 收起 理由
苏波 + 1

查看全部评分

回复 使用道具 举报
崔宏奎 发表于 2013-4-20 23:24
参数分为: 1. 值参数 2.引用参数
A.值参数在传递时,首先把参数中的值复制一份,存储在栈中。(int类型其 ...

拜谢!解释真给力
回复 使用道具 举报
{:soso_e129:}这个肯定要学习下!
回复 使用道具 举报
学习学习
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马