No one covered this important distinction: in some (common) situations, Call prevents parentheses around function (and sub) arguments from causing the arguments to be strictly interpreted as ByVal
.
The big takeaway for you is that if you DO use parentheses around arguments to a routine, perhaps by rote or habit, even though they are not required, then you SHOULD USE Call
to ensure that the routine's implicit or explicit ByRef
is not disregarded in favor of ByVal
; or, instead, you should use an "equal sign" assignment of the return value to prevent the disregard (in which case you would not use Call
).
Again, that is to protect you from unfavorably getting ByVal
from a routine. Conversely, of course, if you WANT ByVal
interpretation regardless of the routine's declaration, then LEAVE OFF the Call
(and use parentheses).
Rationale: summarizing "ByRef and ByVal Parameters"
If
1. there is an assignment of a function call retval, e. g.
iSum = myfunc(myArg)
or
2. "Call
" is used, e. g.
call myFunc(myArg)
or
call mySub(myArg)
then the parentheses strictly delineate the calling argument list; the routine declaration determines ByVal or ByRef. OTHERWISE the parentheses force ByVal to be used by the routine - even though ByVal was not specified in the routine. Thus,
mySub(myArg) 'uses ByVal regardless of the routine's declaration, whereas
Call mySub(myArg) 'uses ByRef, unless routine declares ByVal
Also note that Call syntactically mandates use of parentheses. You can go
mySub myArg
but you can't go
call mySub myArg
but you CAN go
call mySub(myArg)
(and parentheses are syntactically required for assignment of Function return value)
NOTE however that ByVal
on the routine declaration overrides all of this. And FYI, ByRef
is always implied in the declaration if you are silent; thus TMK ByRef
has no apparent value other than documentary.
Repeating from above: The big takeaway for you is that if you DO use parentheses around arguments to a routine, perhaps by rote or habit, even though they are not required, then you SHOULD USE Call
to ensure that the routine's implicit or explicit ByRef
is not disregarded in favor of ByVal
; or, instead, you should use an "equal sign" assignment of the return value to prevent the disregard (in which case you would not use Call
).
Again, that is to protect you from unfavorably getting ByVal
from a routine. Conversely, of course, if you WANT ByVal
interpretation regardless of the routine's declaration, then LEAVE OFF the Call
(and use parentheses).
Call New RNGCryptoServiceProvider().GetBytes(salt)
withoutCall
I would have had to a variable as anRNGCryptoServiceProvider
first – IsabelRNGCryptoServiceProvider
inheritsRandomNumberGenerator
, which implementsIDisposable
, so this "pretty useful" use ofCall
is actually allocating unmanaged resources, and leaves them dangling, sinceDispose
is never invoked. In some contexts, the consequences of this can be catastrophic. Bad, bad idea IMO. – Almonte