是否应在功能中使用ByRef?

时间:2018-12-03 18:47:57

标签: vb.net function

当应该使用ByRef和ByVal时,我真的很困惑。有人告诉我,函数应该始终返回一个值,而Sub不必/可以返回多个值。但是,我真的在何时应该使用ByRef和ByVal上停留。

   Function Check(ByRef valid As Boolean, ByVal prize As Integer) As Boolean

    If prize < 1000000 Or prize > 4000000 Then valid = False

    Return valid

End Function

例如,在上面,我需要由Function进行更改,但是如果我使用ByVal,则不会更改它,因为ByVal不会保留值的更改并将其传递回去。 tyvm,请帮忙。

2 个答案:

答案 0 :(得分:3)

可以正确地说Function总是返回一个值(即使该值是Nothing),而Sub则不会。在C#中,所有方法都是函数,与VB Sub等效的C#是返回类型为void

的函数。

VB中参数的默认值为ByVal,几乎每次都应使用该参数。很少需要使用ByRef。以下是一些需要遵循的良好准则:

  1. 如果您的方法未产生任何输出,则应为Sub
  2. 如果您的方法产生一个输出,则应为Function返回该输出。
  3. 如果您的方法产生多个输出,则需要确定是否存在自然的“主要”输出,例如Integer.TryParse总是产生Boolean输出,并且仅当IntegerBoolean时才产生True输出,因此Boolean是自然的主要产出。
  4. 如果存在自然的主输出,则您的方法应该是Function,它返回主输出,其余部分使用ByRef参数。
  5. 如果没有自然的主输出,例如一种输出圆的周长和面积的方法,那么您的方法应该是一个Sub且所有输出都使用ByRef参数的方法。

请注意,您唯一需要声明参数ByRef的情况如下:

  1. 该参数是引用类型,您想为该方法内的参数分配一个新对象,并使该更改影响传递给方法调用的原始变量。
  2. 参数是一个值类型,您想为方法中的参数分配一个新值,并使该更改影响传递给方法调用的原始变量。
  3. 参数是一个值类型,您想在方法中设置参数的字段或属性,并使该更改影响传递给方法调用的原始变量。

没有其他理由声明参数ByRef。来自VB6的人们经常认为他们需要声明引用类型参数ByRef,以避免复制大对象,但事实并非如此。引用类型变量已经包含对对象的引用,而不是对象本身。按值传递参数会复制一个变量,因此,如果变量包含引用,则复制就是将引用复制到对象而不是对象。

答案 1 :(得分:0)

“ ByRef”做一件事:它修改作为参数传入的局部变量或属性。如果您不想这样做,并且很少这样做,则不应使用它。

在您的示例中,可能会提出一种方案,其中该代码具有某种意义,但永远不会很清楚。它既修改了调用方法中变量的值,又返回了可能修改的值。

“ ByRef”的两个用例是条件初始化和多次返回。您对sorta进行编码都可以做到。但这是以一种不常见且没有实际用处的方式进行的。通常,初始化值来自方法内部,在这种情况下,必须首先进行初始化。

该函数的核心是检查价格是否在一定范围内,但是由于“有效”可能已经设置为false,即使“价格”的值超出了不可接受的范围,它也可能仍然返回false。

Dim valid As Boolean = true
...
valid=valid AndAlso Check(price)

将做同样的事情,并且容易理解得多。