C# 引用类型作为值参数与引用参数的区别

发布于:2025-05-09 ⋅ 阅读:(16) ⋅ 点赞:(0)

在编程中,我们常常需要处理引用类型对象,而将引用类型对象作为参数传递给方法时,有值参数和引用参数这两种方式,它们在方法内部操作时会产生不同的结果。下面就来详细分析这两种情况。

引用类型对象作为值参数传递

当我们把引用类型对象作为值参数传递给方法时,如果在方法内部创建一个新对象并赋值给形参,会切断形参与实参之间的关联,并且在方法调用结束后,新对象也将不复存在。

下面是一段示例代码:

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}"); 
    } 
} 

从代码执行过程来看:

  • 方法开始时:实参和形参指向堆中相同的对象。
  • 为对象成员赋值后:它们仍指向堆中相同的对象。
  • 方法分配新对象并赋值给形参时:(方法外部的)实参仍指向原始对象,而形参指向的是新对象。
  • 方法调用之后:实参指向原始对象,形参和新对象都会消失。

引用类型对象作为引用参数传递

若将引用类型对象作为引用参数传递,除了在方法声明和方法调用时要使用 ref 关键字外,代码结构与值参数传递时类似。但在方法内部操作的结果却大不相同。如果在方法内创建一个新对象并赋值给形参,在方法结束后该对象依然存在,并且是实参所引用的值。

示例代码如下:

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}"); 
    } 
} 

这里代码的执行过程如下:

  • 方法调用时:形参和实参指向堆中相同的对象。
  • 对成员值修改时:会同时影响到形参和实参。
  • 方法创建新对象并赋值给形参时:形参和实参的引用都指向该新对象。
  • 方法结束后:实参指向在方法内创建的新对象。

综上所述,在使用引用类型对象作为参数传递时,我们需要根据具体的需求来选择使用值参数还是引用参数,避免出现意外的结果。掌握这两种参数传递方式的区别,有助于我们编写出更加健壮和高效的代码。


网站公告

今日签到

点亮在社区的每一天
去签到