在ByRef和ByVal之间进行选择时需要考虑的事项。

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

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

有帮助吗?

解决方案

关于此,有很多错误信息。主要的是你了解价值类型和参考类型之间的差异,以及按价值传递和传递参考之间的差异。

你几乎总是希望通过价值来传递。通过引用传递几乎总是针对<!>引用;我想返回多个结果,而不仅仅是通过向传入的列表添加内容。<!> quot;使用pass-by-reference的方法的典型示例是 Int32.TryParse 返回值为成功/失败的地方,解析后的值为<!>“;返回<!>”;通过out参数。

其他提示

对于所有类型,默认值为byValue,但重要的是要了解这两个选项对于<!>引用类型<!>引用的含义。 (一个类)而不是一个值类型。 (结构)。

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

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

  myVar = new object();

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

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

ByVal应该是您的<!> quot;默认<!>“;除非您有特殊原因要使用ByRef

,否则请使用它

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

使用<!>“ByRef <!>”;仅当参数为<!> quot; output <!> quot;参数。否则使用<!>“ByVal <!>”;使用<!>“ByRef <!>”;对于明确不应返回值的参数是危险的,并且很容易产生错误。

我认为不应该使用ByRef - 这是一种不好的做法。我会将其应用于允许函数返回多个值的典型用例(通过ByRef参数)。函数返回包含多个返回值的结构化响应会更好。如果函数仅通过其return语句返回值,则更清晰,更明显。

将某些参数标记为ByRef会向您的函数用户显示分配给该参数**的变量将被修改。****

如果对所有args使用ByRef ,则无法确定哪些变量被函数修改,哪些变量只是被它读取。 (除了在功能源内窥视!)

根据Microsoft的说法,选择ByVal或ByRef可能会影响足够大的值的性能(参见按值和参考(Visual Basic)传递参数):

  

性能。虽然传递机制可以影响性能   你的代码,差异通常是微不足道的。一个例外   这是一个传递ByVal的值类型。在这种情况下,Visual Basic   复制参数的全部数据内容。因此,表示   大值类型如结构,可以更高效传递   它ByRef。

[强调补充]。

Sub last_column_process()
Dim last_column As Integer

last_column = 234
MsgBox last_column

trying_byref x:=last_column
MsgBox last_column

trying_byval v:=last_column
MsgBox last_column

End Sub

Sub trying_byref(ByRef x)
x = 345
End Sub

Sub trying_byval(ByRef v)
v = 555
End Sub

我会尝试简化很多混乱。你基本上有4个选择:

  1. 传递值类型byVal
  2. 传递值类型byRef
  3. 传递对象byVal
  4. 传递对象byRef
  5. 有些人说你应该从不使用byRef。虽然它们在技术上是正确的,但有一件事是肯定的。你应该从不使用 never 这个词。如果您从头开始设计系统,则应不惜一切代价避免使用byRef。使用它暴露了设计缺陷。但是,在现有系统上工作可能无法提供实现良好设计的灵活性。有时你必须做出结论,即使用byRef。例如,如果您可以使用byRef在2天内完成修复,则可以优先重新发明轮子并花一周的时间来获得相同的修复,以避免使用byRef。

    要点:

    1. 在值类型上使用byVal:将值传递给函数。这是首选方式 设计功能。
    2. 对值类型使用byRef:用于从函数返回多个值。如果你 正在创建一个需要返回多个值的函数 一个现有的系统,这可能比创建一个对象(以及设置属性和处理)更好 一个功能。
    3. 在对象上使用byVal:将对象的指针传递给函数。功能可以 修改对象。
    4. 在对象上使用byRef:将指向对象指针的指针传递给函数。允许 更改调用者指向的对象。这可能会导致一些 很难找到错误,我想不出任何有理由使用它。 不是说没有一个,但如果有的话很少 而且很远。
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top