You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Unlike C#, VB doesn't use a keyword at the call-site to denote whether an argument is being passed ByRef or not. That's pretty reasonable given that ByRef was the default in VB6 and even C# drops the requirement to use ref when inter-operating with COM.
All that said, despite not being CLS-compliant from time to time one sees an API which includes overloads which differ only by the refness of one or more arguments. I'm not sure why they do this; perhaps it's a versioning thing--an initial version is published with a ByVal argument and later a ByRef one is added for performance.
This puts VB users in a bad spot if they encounter one of these bad-actors because VB can't distinguish these overloads at the call-site. I've run into it myself when using the Managed DirectX library and have seen at least one customer report about it.
Note: This proposal does NOT include allowing Visual Basic to define such overloads.
Proposal
Given two methods M and N of equal specificity, and a pair of parameters Mj and Nj that match argument Aj,
If Aj is classified as a variable or property access and Mj is a reference (ByRef) parameter and Nj is not, Mj is more specific than Nj.
If Aj is classified as a value and Mj is a value (ByVal) parameter and Nj is not, Mj is more specific than Nj.
If at least one Mj is more specific Nj and no Nj is more specific than Mj, M is more specific than N.
Note: This does not take into account whether the variable or property being accessed is read-only.
More plainly, prefer ByRef parameters when passing "r-values" (things that can be assigned to) and ByVal parameters when passing l-values (things which aren't storage locations).
This means given these overloads:
SubM(ByValpAsInteger)SubM(ByRefpAsInteger)
A user can force the compiler to pick the first overload by forcing the argument to be classified as a value (e.g. parenthesizing the expression).
A user can force the compiler to pick the second overload by manually copying the value into a local variable (which is what the compiler would have done anyway).
And without user intervention the compiler will pick the overload whose argument passing convention is most appropriate for the class of expression being passed.
Alternatives
Add a ByRef modifier at the call-site. This has been requested before but was rejected due to concerns that some code would use it and some wouldn't and without strict enforcement (breaking change) it would cause more confusion than good as readers would erroneously assume code without the modifier wasn't passing ByRef.
The text was updated successfully, but these errors were encountered:
That's a whole lot of machinery for an edge case. We shouldn't rush into burdening the entire world with new syntax just to unblock a handful of customers inter-operating with poorly designed libraries.
Update: The 12/6/2017 LDM approved this idea in principle. We decided against any new syntax for ByRef but think we're going to need this tie-breaker anyway as new libraries written in C# take advantage of the in (formally ref readonly) feature.
Scenario
Unlike C#, VB doesn't use a keyword at the call-site to denote whether an argument is being passed
ByRef
or not. That's pretty reasonable given that ByRef was the default in VB6 and even C# drops the requirement to useref
when inter-operating with COM.All that said, despite not being CLS-compliant from time to time one sees an API which includes overloads which differ only by the refness of one or more arguments. I'm not sure why they do this; perhaps it's a versioning thing--an initial version is published with a ByVal argument and later a ByRef one is added for performance.
This puts VB users in a bad spot if they encounter one of these bad-actors because VB can't distinguish these overloads at the call-site. I've run into it myself when using the Managed DirectX library and have seen at least one customer report about it.
Note: This proposal does NOT include allowing Visual Basic to define such overloads.
Proposal
Given two methods
M
andN
of equal specificity, and a pair of parametersMj
andNj
that match argumentAj
,Aj
is classified as a variable or property access andMj
is a reference (ByRef
) parameter andNj
is not,Mj
is more specific thanNj
.Aj
is classified as a value andMj
is a value (ByVal
) parameter andNj
is not,Mj
is more specific thanNj
.Mj
is more specificNj
and noNj
is more specific thanMj
,M
is more specific thanN
.Note: This does not take into account whether the variable or property being accessed is read-only.
More plainly, prefer
ByRef
parameters when passing "r-values" (things that can be assigned to) andByVal
parameters when passingl-values
(things which aren't storage locations).This means given these overloads:
A user can force the compiler to pick the first overload by forcing the argument to be classified as a value (e.g. parenthesizing the expression).
A user can force the compiler to pick the second overload by manually copying the value into a local variable (which is what the compiler would have done anyway).
And without user intervention the compiler will pick the overload whose argument passing convention is most appropriate for the class of expression being passed.
Alternatives
Add a
ByRef
modifier at the call-site. This has been requested before but was rejected due to concerns that some code would use it and some wouldn't and without strict enforcement (breaking change) it would cause more confusion than good as readers would erroneously assume code without the modifier wasn't passingByRef
.The text was updated successfully, but these errors were encountered: