【黑马程序员】引用类型学习中的小问题解答

本文通过具体的C#代码示例,详细解释了值类型和引用类型在方法调用中的传递方式及其区别,帮助读者理解如何正确使用值传递和引用传递。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

------- WindowsPhone 7手机开发.Net培训、期待与您交流! -------

 

 

 

  public class XInt {
        //定义字段
        public int iField = 2;
    }
    public class Starter
    {
        /// <summary>
        /// 引用类型按引用传递会发生什么呢?函数接受局部引用而不是别名。首先,其中一个引用时按值传递的,在被调用函数中,该参数被赋予一个新实例。
        /// 然而,因为引用是按值传递的,所以函数退出后,该修改就被丢失了。因此,元是引用(obj)没有改变。
        /// </summary>
        /// <param name="alias"></param>
        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 MethodE(ref XInt alias)
        {
            XInt inner = new XInt();
            inner.iField = 5;
            alias = inner;
        }
        public static void Main()
        {

            
            XInt obj = new XInt();
            MethodA(obj);
            Console.WriteLine("引用传值{0}", obj.iField);//2

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

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

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

            XInt obj1 = new XInt();
            MethodA( ref obj1);
            Console.WriteLine("引用传值{0}", obj.iField);//5

            Console.ReadKey();
        }
    }


 

 

 

 

解决方案:

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

3 天前 上传
下载附件 (17.38 KB)


可以看到,他们的内存地址是不同的,栈里的内存会在方法退出时被自动释放。
回头看你的代码:

  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的内存被释放,好像下面的这个样子:
4.JPG

3 天前 上传
下载附件 (22.91 KB)


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

1.JPG

3 天前 上传
下载附件 (39.34 KB)


2.JPG

3 天前 上传
下载附件 (47.63 KB)




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值