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阐

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

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

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

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

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

相关推荐
初见无风21 小时前
3.4 Boost库intrusive_ptr智能指针的使用
开发语言·boost
程序猿202321 小时前
Python每日一练---第六天:罗马数字转整数
开发语言·python·算法
装不满的克莱因瓶21 小时前
【Java架构师】各个微服务之间有哪些调用方式?
java·开发语言·微服务·架构·dubbo·restful·springcloud
杨筱毅21 小时前
【穿越Effective C++】条款13:以对象管理资源——RAII原则的基石
开发语言·c++·effective c++
Zz_waiting.1 天前
统一服务入口-Gateway
java·开发语言·gateway
四维碎片1 天前
【Qt】大数据量表格刷新优化--只刷新可见区域
开发语言·qt
时光追逐者1 天前
【拾遗补漏】.NET 常见术语集
微软·c#·.net
薛慕昭1 天前
C语言核心技术深度解析:从内存管理到算法实现
c语言·开发语言·算法
火星数据-Tina1 天前
Python + WebSocket 实现实时体育比分系统(含数据库设计与前端演示)
开发语言·前端
秋雨雁南飞1 天前
c# 使用Memory实现Redis入队出队功能
redis·c#