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

时间:2014-09-21 06:28:54

标签: c#

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关键字,按对象传递)。我得到了不同的输出。 但是默认情况下类对象通过引用传递,为什么我得到不同的输出。

4 个答案:

答案 0 :(得分:3)

在您的情况下,对类对象的引用按值传递。

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

class A {}
// or
struct A {}

var a = new A();

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

你可以:

  • 按值传递引用类型:您可以更改变量引用的对象,您无法自行更改变量。
  • 通过引用传递引用类型:您可以更改变量引用的对象,您可以更改变量本身。
  • 按值传递值:您无法更改变量引用的对象,您无法自行更改变量。
  • 通过引用传递值类型:您可以更改变量引用的对象,您无法自行更改变量。

答案 1 :(得分:1)

阅读Passing Reference-Type Parameters (MSDN)

  

引用类型的变量不直接包含其数据;它包含对其数据的引用。按值传递reference-type参数时,可以更改引用指向的数据,例如类成员的值。但是,您无法更改引用本身的值;也就是说,您不能使用相同的引用为新类分配内存并使其在块外保留。为此,请使用ref或out关键字传递参数。

答案 2 :(得分:1)

 /* 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 ++指针编程中获得一个想法并搜索“引用指针”

答案 3 :(得分:0)

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