Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#,是否需要通过引用传递对象?_C#_Pass By Reference - Fatal编程技术网

C#,是否需要通过引用传递对象?

C#,是否需要通过引用传递对象?,c#,pass-by-reference,C#,Pass By Reference,我正试图更新我对C#的理解。我以前使用过Java,通过引用传递是一个强大的工具,在Java中我真的很怀念它。但是,如果需要通过引用传递一个对象,以及是否存在这样的场景,我需要澄清一下?Stackoverflow已经有多个关于引用的问题,它们确实很有启发性,但是,我想知道是否有一个通过引用传递对象的场景。让我附上代码以更好地说明它 class Program { public static void Update(int x) { x++; } public

我正试图更新我对C#的理解。我以前使用过Java,通过引用传递是一个强大的工具,在Java中我真的很怀念它。但是,如果需要通过引用传递一个对象,以及是否存在这样的场景,我需要澄清一下?Stackoverflow已经有多个关于引用的问题,它们确实很有启发性,但是,我想知道是否有一个通过引用传递对象的场景。让我附上代码以更好地说明它

class Program
    {
        public static void Update(int x) { x++; }
        public static void Update(ref int x) { x++; }
        public static void Update(Employee x) { x.msalary += 2000; }
        public static void Update(ref Employee x) { x.msalary += 2000; } //Do we even need this method? Is there a scenario where we might need this?

        static void Main(string[] args)
        {

            int a = 0;

            Update(a);
            Console.WriteLine("T1  " + a.ToString()); //a is still 0

            Update(ref a);
            Console.WriteLine("T2  " + a.ToString());//a is 1

            Employee emp2 = new Employee("Brent", "1234", "Blue", 1000); //salary is 1000

            Update(emp2.msalary);
            Console.WriteLine("T3  " + emp2.msalary.ToString());//salary does not change.

            Update(ref emp2.msalary);
            Console.WriteLine("T4  "+emp2.msalary.ToString());//salary changes to 1001

            Update(emp2);
            Console.WriteLine("T5  " + emp2.msalary.ToString()); //This changes, as expected for objects.

            Update(ref emp2);
            Console.WriteLine("T6  " + emp2.msalary.ToString()); //This also changes. But is there a scenario where we might need this?


        }
    }
在我看来,称之为“ref”是一个错误;考虑此功能的正确方法是,它使局部参数或参数成为另一个变量的别名。也就是说,当您使用
ref
时,您刚刚为现有变量指定了另一个名称

那么问题是:在什么情况下修改其他人的变量是有意义的?在这些情况下,您应该使用
ref

回到历史时期,
ref
的主要用例类似于
bool-TryParse(string s,out-int-x)
,其中您希望有两个返回值:bool和int。但该方法是在泛型、空值和元组之前的1天在C#1中创建的。现在更好的做法是:如果需要返回一个可能无效的值类型,则返回一个可为null的值;如果需要返回两个值,则返回一个元组。(请记住,
out
只是
ref
需要在阅读之前先写。)

那么,在使用元组和可空值类型的新代码中,
ref
的当前用例是什么?有些算法可以通过直接读取和修改数据结构另一部分中的变量来获得少量性能,但需要传递需要读取和修改的变量。也就是说,
ref
应该用作某些数据类型的实现细节的性能优化。(请记住,不能永久存储引用;只能将局部变量作为另一个变量的别名,并且该局部变量的生存期不能延长!这大大限制了引用的使用情形。)

您还可以使用
ref
作为一种更干净、类型安全的方式,与使用指针作为变量别名的非托管代码进行互操作


就这样。我几乎从不在主流业务线代码中使用
ref
。当你需要它时,它就在那里,但你几乎从来没有这样做过。

你的
更新(ref Employee x)
方法可以做
x=new Employee()
,这种变化反映在调用者中。引用类型和值类型的情况都是一样的——当您需要在被调用函数中指定变量并使其在调用者中可见时。在您的
ref Employee
示例中,您没有分配
x
,因此它不是必需的。只有在您希望更改值并将其反映在scopre之外时,我才建议使用值类型。仅当您可能会将当前实例设为null或需要将新实例分配给引用时,才用于引用类型。在您的情况下,不会修改对Employee的引用。您只是在修改实际对象,而不是对它的引用。您认为为什么C#中的有用场景与Java有什么不同?谢谢您的澄清。我以前用C编写过代码,ref让我想起了C中的指针功能。我认为使用ref可能会提高代码性能,但根据每个人的反馈,我会避免使用它。@baleeghr00:IMHO,C语言没有上面提到的“通过变量共享传递”功能,但是C++是这样做的。指针不是变量的别名,是与C/C++中的类型指针的内存存储位置相关联的变量包含对象的地址(在c*中的引用)。它与C#中引用类型的变量相同。别名共享相同的内存存储位置。当然,但我的意思是,如果我们有
intx=123
int*p=&x
那么
*p
也是一个变量,而且是
x
的别名。我们不需要C++参考文献;它们只是一种甜点。