通过c#中的ref关键字调用类对象


Call class object by ref keyword in c#

本问题已经有最佳答案,请猛点这里访问。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public class Test
{
    public string Name;

    public void CallFunctionByObjectRef(Test a)
    {
        a.Name ="BCD";
        a = null;
    }

    public void CallFunctionByObjectRefTORef(ref Test a)
    {
        a.Name ="BCD";
        a = null;
    }
}

class Program
{
    static void Main(string[] args)
    {

        Test test = new Test();
        test.Name ="ABC";
        test.CallFunctionByObjectRef(test);


        Test test1 = new Test();
        test1.Name ="ABC";
        test1.CallFunctionByObjectRefTORef(ref test1);

        Console.WriteLine(test.Name);
        Console.WriteLine(test1.Name);
        Console.Read();
    }
}

在上面调用了两个函数(使用ref关键字,pass-by-object)。我从他们那里得到了不同的产出。但是类对象在默认情况下通过引用传递,这就是为什么我得到不同的输出。


在您的例子中,对类对象的引用是按值传递的。

给定值或引用类型的变量a和方法,接受a作为值或引用:

1
2
3
4
5
6
7
8
9
class A {}
// or
struct A {}

var a = new A();

Foo(ref a);
// or
Foo(a);

你可以:

  • 按值传递引用类型:可以更改变量引用的对象,不能更改变量本身。
  • 通过引用传递引用类型:可以更改变量引用的对象,也可以更改变量本身。
  • 按值传递值类型:不能更改变量引用的对象,也不能更改变量本身。
  • 按引用传递值类型:可以更改变量引用的对象,不能更改变量本身。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
 /* Here you are passing pointer to the variable. For example variable test has got memory address
             * 0X200001.
             * When you pass test, you are saying that there are two variables that points to 0X200001 (one in main and another in CallFunctionByObjectRef i.e. variable a)
             * Thus when you are changing the value for a variable to null, you are changing the direction to link with null memory location.
             *
             * It is called  reference.
             * When you came back to Main, test variable is still pointing to the memory 0X200001
            */

            Test test = new Test();
            test.Name ="ABC";

            test.CallFunctionByObjectRef(test);

            /*
            * In this case you are saying that create a variable test1 that gives a memory as: 0X200002
            * Then you are passing a pointer to pointer i.e. you are sending an actual test1 variable.
             * so whatever you will change here will get impacted in Main.
            */

            Test test1 = new Test();
            test1.Name ="ABC";

            test1.CallFunctionByObjectRefTORef(ref test1);

            Console.WriteLine(test.Name);
            Console.WriteLine(test1.Name);
            Console.Read();

如果你想了解更多,那么你需要从C/C++指针编程中得到一个想法,并搜索"指针的引用"。


读取传递引用类型参数(msdn)

A variable of a reference type does not contain its data directly; it contains a reference to its data. When you pass a reference-type parameter by value, it is possible to change the data pointed to by the reference, such as the value of a class member. However, you cannot change the value of the reference itself; that is, you cannot use the same reference to allocate memory for a new class and have it persist outside the block. To do that, pass the parameter using the ref or out keyword.


当使用ref关键字时,您将实际内存位置传递给被调用的方法,而不是引用的副本,这是有意义的。