vblang
vblang copied to clipboard
Proposal: Allow ByRef overloading in VB
Overloading between in parameters and out or ref parameters is supported in C#. But in VB, if you want to call one of an overload method which differ only by ByVal and ByRef, the compiler will report error BC31429 . This feature was used in some C# class libraries such as CocosSharp, made them incompatible with VB.
C# signature:
public void TestA(int param);
public void TestA(ref int param);
public void TestB(int param);
public void TestB(out int param);
public void TestC(int param);
C# call:
int i = 0;
TestA(i);
TestA(ref i);
TestB(i);
TestB(out i);
TestC(i);
Suggested new VB syntax to distinguish between ByVal and ByRef:
Dim i = 0
TestA(i) ' TestA(i);
TestA(ByRef i) ' TestA(ref i);
TestB(i) ' TestB(i);
TestB(ByRef i) ' TestB(out i);
TestC(i) ' TestC(i);
ByVal is the default, why not have it the other way around?
Dim i = 0
TestA(i) ' TestA(i);
TestA(ByRef i) ' TestA(ref i);
TestB(i) ' TestB(i);
TestB(ByRef i) ' TestB(out i);
TestC(i) ' TestC(i);
This has the advantage of allowing ByRef to be optional for ref/out parameters in all cases. I found this issue while looking for that as a suggestion: I think it would make sense, as it makes the code more explicit and understandable.
@jrmoreno1 Your suggestion is more sensible. I'll edit the code to your version.
First of all, I'm wondering why anyone would overload a method where the only difference was ByVal vs By Ref... I guess the obvious answer would be so that SOMETIMES they could modify the parameter and SOMETIMES they couldn't. Using the same method name in that case wouldn't seem the best programming practice IMHO... but that's just my opinion. If we're going to add new syntax to parameters, then I would suggest going all the way and implementing In, Out, as well as ByRef. Although I don't like the C# implementation of "In". To me, if I specify "In" the parameter shouldn't be allowed to be changed, regardless of whether I passed it by Val or Ref.
Hi @Nukepayload2 , Did you try to create a delegate for it ?
Delegate Sub Arg_in(Arg As Int)
Delegate Sub Arg_out(ByRef Arg As Int)
Dim Call_in = New Arg_in(AddressOf TestA)
Dim Call_out = New Arg_out(AddressOf TestA)
This is not possible as VB has no difference in the call to a ByVal or ByRef parameter. I wouldn't like to have to type ByRef on all ByRef call's (this is not C#) And as @WolvenRA said: who uses this and how often? This would be a once in a million usages.
So the simple solution is just to use another name for the Sub or Function. Don't make it more difficult than it is.
In and Out are great, but also without overloading on this.
The problem with the " is that it is visually equal to double single quotes '' which makes some sequences very confusing especially when adding the escaping ". So, I sometimes use another tricks to avoid escaping the " such as using a double single quotes then replace them:
Dim X = "Hello ''Adam''".
Replace ("''", Chr(34))
Hi @VBAndCs , Do you mean to answer #503 issue ?
Yes, sorry.
So this is a suggestion to change a language because the choices of another language allow the developers to write nonsensical code - code that shouldn't exist in a public API? If there was only a mechanism that was in place that said something like "if you are going to build public API's on this platform, you should adhere to these restrictions". If only such a thing were to exist and that thing could evolve over time as what was common upon languages evolves. If only. And if only the producer of said guidelines would ACTUALLY FOLLOW THEM. If only. In any case, just because someone can write bad API's in another language doesn't mean other languages should follow the crowd.
I started to believe that vb should show any sign that the argument is ByRef or Out to make the code more readable and easy to understand, either by allowing adding optional those two keywords in front of the argument (like c#), or at least by showing the argument with special color in the editor.
VB Supports
Warning BC42030 it does not seem like it was ever fixed
Don't see it in .NET Core 5 console app. Edit: Yes it exists for ref types that can through a null exception in runtime.
Adding to Argument would be a better solution
This suggests to consider ByRef and Out as a Dim statement also, so:
Call Foo(ByRef x)
Will be lowered to:
Dim X as [Type of the param of Foo] = Nothing
Call Foo(x)
And if x already declared, the Dim statement will be dropped.