有ref object参数和没有ref object参数的方法有什么区别?

本文关键字:object 参数 ref 区别 什么 方法 | 更新日期: 2023-09-27 18:13:03

我想知道关于如何引用object参数的以下方法之间的区别:

public void DoSomething(object parameter){}

public void DoSomething(ref object parameter){}

如果我想改变对object的引用而不是覆盖同一引用中的对象,我应该使用ref object parameter吗?

有ref object参数和没有ref object参数的方法有什么区别?

public void DoSomething(object parameter)
{
  parameter = new Object(); // original object from the callee would be unaffected. 
}
public void DoSomething(ref object parameter)
{
  parameter = new Object(); // original object would be a new object 
}

参见Jon Skeet的文章:c#中的参数传递

在c#中,引用类型对象的地址是按值传递的,当使用ref关键字时,原始对象可以被分配一个新对象或null,没有ref关键字是不可能的。

考虑下面的例子:

class Program
{
    static void Main(string[] args)
    {
        Object obj1 = new object();
        obj1 = "Something";
        DoSomething(obj1);
        Console.WriteLine(obj1);
        DoSomethingCreateNew(ref obj1);
        Console.WriteLine(obj1);
        DoSomethingAssignNull(ref obj1);
        Console.WriteLine(obj1 == null);
        Console.ReadLine();
    }
    public static void DoSomething(object parameter)
    {
        parameter = new Object(); // original object from the callee would be unaffected. 
    }
    public static void DoSomethingCreateNew(ref object parameter)
    {
        parameter = new Object(); // original object would be a new object 
    }
    public static void DoSomethingAssignNull(ref object parameter)
    {
        parameter = null; // original object would be a null 
    }
}

输出将是:

Something
System.Object
True

通过ref传递变量允许函数将该变量重新指向另一个对象,或者实际上是null:例如

object parameter = new object();
FailedChangeRef(parameter); // parameter still points to the same object
ChangeRef(ref parameter); // parameter now points to null
public void FailedChangeRef(object parameter)
{
            parameter = null; // this has no effect on the calling variable
}
public void ChangeRef(ref object parameter)
{
            parameter = null;  
}

参数传递ByVal:描述按值传递参数,这意味着过程不能修改变量本身。

参数传递ByRef:描述通过引用传递参数,这意味着过程可以修改变量本身。

在c#中,方法参数的默认机制是按值传递。因此,如果您声明一个方法,如

public void DoSomething(object parameter){} // Pass by value

因此,创建了对象的新副本,因此对参数的更改不会影响传入的原始对象。

但是,当u通过ref传递形参时,它是通过引用传递

public void DoSomething(ref object parameter) // Pass by reference

现在,您正在操作最初传递的对象的地址。因此,您对方法内部参数所做的更改将影响原始对象。

当你看到ref object时,这意味着参数必须是object类型。

你可以在文档中阅读:

当形式参数是引用参数时,对应的方法调用中的参数必须包含关键字ref后接与。类型相同的变量引用(第5.3.3节)正式的参数。变量必须先明确赋值作为引用形参传递。