C# 方法(引用类型作为值参数顸引用参数)

本章内容:

方法的结构

方法体内部的代码执行

局部变量

局部常量

控制流

方法调用

返回值

返回语句和void方法

局部函数

参数

值参数

引用参数

引用类型作为值参数和引用参数

输出参数

参数数组

参数类型总结

方法重载

命名参数

可选参数

栈帧

递归

引用类型作为值参数顸引用参数

在前几节中我们看到了,对于一个引用类型对象,不管是将其作为值参数传递还是作为引用

参数传递,都可以在方法成员内部修改它的成员。不过,我们并没有在方法内部设置形参本身。

本节来看看在方法内设置引用类型形参时会发生什么。

将引用类型对象作为值参数传递如果在方法内创建一个新对象并赋值给形参,将切断

形参与实参之间的关联,并且在方法调用结束后,新对象也将不复存在。

将引用类型对象作为引用参数传递如果在方法内创建一个新对象并赋值给形参,在方

法结束后该对象依然存在,并且是实参所引用的值。

下面的代码展示了第一种情况----将引用类型对象作为值参数传递:

csharp 复制代码
class MyClass
{
    public int Val=20;
}

class Program
{
    static void RefAsParameter(MyClass f1)
    {
        f1.Val=50;
        Console.WriteLine($"After member assignment:{f1.Val}");
        f1=new MyClass();
        Console.WriteLine($"After new object creation:{f1.Val}");
    }

    static void Main()
    {
        MyClass a1=new MyClass();

        Console.WriteLine($"Before method call: {a1.Val}");
        RefAsParameter(a1);
        Console.WriteLine($"After method call:{a1.Val}");
    }
}

图6-9阐明了关于上述代码的以下几点

在方法开始时,实参和形参指向堆中相同的对象。

在为对象的成员赋值之后,它们仍指向堆中相同的对象。

当方法分配新的对象并赋值给形参时,(方法外部的)实参仍指向原始对象,而形参指向

的是新对象。

在方法调用之后,实参指向原始对象,形参和新对象都会消失。

下面的代码演示了将引用类型对象作为引用参数的情况。除了方法声明和方法调用时要使用

ref关键字外,与上面的代码完全相同。

csharp 复制代码
class MyClass
{
    public int Val=20;
}

class Program
{
    static void RefAsParameter(ref MyClass f1)
    {
        //设置对象成员
        f1.Val=50;

        ConSole.WriteLine($"After member assignment:{f1.Val}");

        //创建新对象并赋值给形参
        f1=new MyClass();
        ConSole.WriteLine($"After new object creation:{f1.Val}");
    }
}

static void Main(string[] args)
{
    MyClass a1=new MyClass();

    Console.WriteLine($"Before method call:{a1.Val}");
    RefAsParameter(ref a1);
    Console.WriteLine($"After method call:{a1.Val}");
}

你肯定还记得,引用参数充当形参的别名。这样一来上面的代码就很好解释了。图6-10阐

明了上述代码的以下几点。

在方法调用时,形参和实参指向堆中相同的对象。

对成员值的修改会同时影响到形参和实参。

当方法创建新的对象并赋值给形参时,形参和实参的引用都指向该新对象。

在方法结束后,实参指向在方法内创建的新对象。

相关推荐
非晓为骁4 分钟前
【Go】优化文件下载处理:从多级复制到零拷贝流式处理
开发语言·后端·性能优化·golang·零拷贝
北极象8 分钟前
Golang中集合相关的库
开发语言·后端·golang
小浪学编程20 分钟前
C#学习7_面向对象:类、方法、修饰符
开发语言·学习·c#
Q_Q196328847528 分钟前
python小说网站管理系统-小说阅读系统
开发语言·spring boot·python·django·flask·node.js·php
goTsHgo38 分钟前
Java的对象头:原理与源码详解
java·开发语言
yunbao00_1 小时前
C++ 复习(一)
开发语言·c++
冼紫菜1 小时前
如何使用责任链模式优雅实现功能(滴滴司机、家政服务、请假审批等)
java·开发语言·设计模式·责任链模式
小郝 小郝1 小时前
【C语言】五一回归,复习动脑
c语言·开发语言
程序员JerrySUN2 小时前
驱动开发硬核特训 · Day 30(上篇):深入理解 I2C 总线驱动模型(以 at24 EEPROM 为例)
linux·开发语言·驱动开发
石去皿2 小时前
C++ 中的 `it->second` 和 `it.second`:迭代器与对象访问的微妙区别
开发语言·c++·算法·leetcode