在ByRef和ByVal之间进行选择时需要考虑的事项是什么.
我理解两者之间的区别,但我不完全理解ByRef是否节省了资源,或者我们是否需要在.Net环境中担心这一点.
如果在某种情况下功能无关紧要,您如何在两者之间做出决定?
关于这一点有很多错误的信息.主要的是你理解值类型和引用类型之间的区别,以及传递值和传递引用之间的区别.
你几乎总是希望通过价值来传递.通过引用传递几乎总是"我希望返回多个结果,而不仅仅是通过将内容添加到传入的列表中".使用pass-by-reference的方法的经典示例是Int32.TryParse,其中返回值是成功/失败,并且解析的值由out参数"返回".
对于所有类型,默认值为byValue,但重要的是要理解这两个选项对于"引用类型"(类)而不是值类型的含义.(结构).
对于引用类型,如果在方法中声明引用类型变量,则该变量是方法的堆栈帧中的内存位置.它不在堆上.初始化该变量时(使用new或factory,无论如何),您已在堆上创建了一个实际对象,该对象的地址存储在方法堆栈框架中声明的引用变量中.
当您将引用类型传递给另一个方法byVal时,您将创建存储在调用方法堆栈中的地址的副本,并将该值的副本(指针地址)传递给被调用的方法,并将其存储在新的内存中被调用方法堆栈中的槽.在被调用的方法中,新的克隆变量直接指向Heap上的同一个对象.因此,使用它可以更改同一对象的属性.但是您无法更改原始引用变量(在调用方法堆栈上)指向哪个堆对象.如果,在我写的被调用方法中
myVar = new object();
调用方法中的原始变量不会更改为指向新对象.
如果我传递一个引用类型byRef,otoh,我传递一个指向调用方法堆栈中声明的变量的指针(它包含指向堆上对象的指针)因此它是指向该对象的指针.它指向调用方法堆栈上的内存位置,该堆栈指向堆上的对象.
所以现在,如果我在被调用方法中更改变量的值,通过将其设置为新对象(),如上所述,因为它是对调用方法中的变量的"引用",我实际上是在更改哪个对象调用方法中的变量指向.因此,在调用方法返回后,调用方法中的变量将不再指向堆上的同一原始对象.
ByVal应该是你的"默认".除非您有特定原因要使用ByRef,否则请使用它
在.net中传递对象ByVal不会创建对象的副本,并且不会消耗更多的资源,然后ByRef,指针仍然传递给函数.运行时只是确保您不能修改函数中的指针并为其返回不同的值.您仍然可以更改对象中的值,您将在函数外部看到这些更改.这就是为什么ByRef很少使用的原因.只有当你想要一个函数来改变回来的实际对象时才需要它; 因此是输出参数.
仅当参数为"output"参数时才使用"ByRef".否则使用"ByVal".对明确不应返回值的参数使用"ByRef"是危险的,并且很容易产生错误.