当前位置:  开发笔记 > 编程语言 > 正文

最佳实践:ByRef或ByVal?在.Net

如何解决《最佳实践:ByRef或ByVal?在.Net》经验,为你挑选了5个好方法。

在ByRef和ByVal之间进行选择时需要考虑的事项是什么.

我理解两者之间的区别,但我不完全理解ByRef是否节省了资源,或者我们是否需要在.Net环境中担心这一点.

如果在某种情况下功能无关紧要,您如何在两者之间做出决定?



1> Jon Skeet..:

关于这一点有很多错误的信息.主要的是你理解值类型和引用类型之间的区别,以及传递值和传递引用之间的区别.

你几乎总是希望通过价值来传递.通过引用传递几乎总是"我希望返回多个结果,而不仅仅是通过将内容添加到传入的列表中".使用pass-by-reference的方法的经典示例是Int32.TryParse,其中返回值是成功/失败,并且解析的值由out参数"返回".


许多开发人员仍然倾向于使用这种模式 - 可能是因为他们的背景是来自C++,或者是COM,其中rets总是错误代码,这种模式是必要的?
+1.通过引用传递并在一个返回void的方法内部进行更改是我脑海中常见的"错误" - 它误导了该方法正在做什么.

2> Charles Bret..:

对于所有类型,默认值为byValue,但重要的是要理解这两个选项对于"引用类型"(类)而不是值类型的含义.(结构).

对于引用类型,如果在方法中声明引用类型变量,则该变量是方法的堆栈帧中的内存位置.它不在堆上.初始化该变量时(使用new或factory,无论如何),您已在堆上创建了一个实际对象,该对象的地址存储在方法堆栈框架中声明的引用变量中.

当您将引用类型传递给另一个方法byVal时,您将创建存储在调用方法堆栈中的地址的副本,并将该值的副本(指针地址)传递给被调用的方法,并将其存储在新的内存中被调用方法堆栈中的槽.在被调用的方法中,新的克隆变量直接指向Heap上的同一个对象.因此,使用它可以更改同一对象的属性.但是您无法更改原始引用变量(在调用方法堆栈上)指向哪个堆对象.如果,在我写的被调用方法中

  myVar = new object();

调用方法中的原始变量不会更改为指向新对象.

如果我传递一个引用类型byRef,otoh,我传递一个指向调用方法堆栈中声明的变量的指针(它包含指向堆上对象的指针)因此它是指向该对象的指针.它指向调用方法堆栈上的内存位置,该堆栈指向堆上的对象.
所以现在,如果我在被调用方法中更改变量的值,通过将其设置为新对象(),如上所述,因为它是对调用方法中的变量的"引用",我实际上是在更改哪个对象调用方法中的变量指向.因此,在调用方法返回后,调用方法中的变量将不再指向堆上的同一原始对象.



3> Kevin..:

ByVal应该是你的"默认".除非您有特定原因要使用ByRef,否则请使用它



4> DancesWithBa..:

在.net中传递对象ByVal不会创建对象的副本,并且不会消耗更多的资源,然后ByRef,指针仍然传递给函数.运行时只是确保您不能修改函数中的指针并为其返回不同的值.您仍然可以更改对象中的值,您将在函数外部看到这些更改.这就是为什么ByRef很少使用的原因.只有当你想要一个函数来改变回来的实际对象时才需要它; 因此是输出参数.


这在技术上是正确的,但非常误导.传递对象byVal时,不复制"对象",但复制对象的地址,并传递给被调用的方法.传递byRef时,不会复制对象的地址,传递地址的地址.

5> TcKs..:

仅当参数为"output"参数时才使用"ByRef".否则使用"ByVal".对明确不应返回值的参数使用"ByRef"是危险的,并且很容易产生错误.


否.如果参数是"输出"参数,请使用"Out".如果参数是"参考"参数,请使用"ByRef".
推荐阅读
oDavid_仔o_880
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有