在c#中通过ref关键字调用类对象[重复]

Posted

技术标签:

【中文标题】在c#中通过ref关键字调用类对象[重复]【英文标题】:Call class object by ref keyword in c# [duplicate] 【发布时间】:2014-11-15 09:06:55 【问题描述】:
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 关键字,通过对象传递)。我从他们那里得到不同的输出。 但是默认情况下类对象通过引用传递,为什么我得到不同的输出。

【问题讨论】:

不。默认情况下,参数始终按值传递。问题是,对于引用类型,被复制和传递的值就是引用。 输出结果是什么? 这里有一篇关于该主题的精彩文章 - yoda.arachsys.com/csharp/parameters.html @mdebeus:应该是BCD,后跟System.NullReferenceException @Timothy - ABISHEK 仍应在问题中说明这一点。 【参考方案1】:

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

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

class A 
// or
struct A 

var a = new A();

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

你可以:

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

【讨论】:

【参考方案2】:
 /* 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++ 指针编程中获得一个想法,并搜索“Reference to a Pointer”

【讨论】:

谢谢,我喜欢你的回答【参考方案3】:

阅读Passing Reference-Type Parameters (MSDN)

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

【讨论】:

【参考方案4】:

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

【讨论】:

以上是关于在c#中通过ref关键字调用类对象[重复]的主要内容,如果未能解决你的问题,请参考以下文章

在 C# 中通过引用传递对象和对象列表

使用关键字“ref”传递类对象有啥用?默认情况下,它们是通过引用传递的[重复]

Java中通过method对象来调用方法

在 C# 中使用“ref”关键字 [重复]

Java基础知识—面向对象

类和对象