Make the Optional keyword optional
just porting my old vb.net suggestions from uservoice
Please allow
Private Sub Test(s As String = 1)
as in C# besides the current version:
Private Sub Test(Optional s As String = 1)
This removes redundancies (--> improves readability, accelerates writing code) and drives forward the co-evolution of VB/C#. I don't see any reason not to allow this.
@beppe9000 This removes redundancies...
Totally agree! It would also make it so much easier (and I would say more readable) to line up parameters across multiple lines:
Public Sub Foo(ArgBlah As Integer,
Optional ArgBleh As Integer = 2)
End Sub
Would now become:
Public Sub Foo(ArgBlah As Integer,
ArgBleh As Integer = 2)
End Sub
Once Optional is optional, creating the above alignment is just a matter of pressing enter near the comma (block indenting will align the identifier ArgBleh with ArgBlah rather than aligning the Optional keyword as it does now, forcing you to manually shift if back so the parameter names are aligned).
I didn't think about that... But hey this is two birds with a stone 👍
It is already optional, just that is a compile-time error.
In most case you just specify the parameter type's default value to appease the compiler. So makes more sense to make that part optional. Proposal: Default Optional Parameters
It is already optional, just that is a compile-time error.
That proposal seems to be about having a default value for optional arguments. What I am proposing here is to get rid of the ugly Optional keyword (by making it optional) and allowing optional parameters to be implicitly defined by the = "default" syntax.
Is there any reason not to allow the type to be inferred from the default value? e.g. this:
Private Sub Test(s = "")
would be the same as this:
Private Sub Test(s As String = "")
following the same rules for type inference when using Dim:
Dim s = ""
is equivalent to:
Dim s As String = ""
@AdamSpeight2008
I don't think this is accurate:
In most case you just specify the parameter type's default value to appease the compiler.
In my code I find myself specifying the default value as often as not, so I think both goals (not having the Optional keyword and not requiring a default value) are valid. However, I don't think both are achievable, unless both variants are allowed:
Sub Test(s = "", Optional b)
C# gets around this by forcing you to always specify a default value for an optional parameter, but this is not appropriate for VB.NET, which allows declaring variables without a type or a value:
Dim s 'typed as object
In short, I don't see any way that this can be done in VB.NET.
@zspitz Just to clarify, there are 3 proposals here. (@KathleenDollard Could you please rename this issue to "Clean up Optional parameter declarations" or the like?)
- Allow Optional to be omitted when a default value is specified (as in C#)
- Allow the type to be omitted and inferred when a default value is specified
- Allow the default value to be omitted, when it is Nothing (or whatever is default for that type)
I think all are valid and useful. More comments on each:
- IMHO, the
Optionalkeyword doesn't really add readability, it is just an artifact from when VB (Classic) did not support default values for optional parameters (which is no longer allowed). - Valid and clean, just as elsewhere around the language where type inference works.
- Not really important once we do number 1, because this removes the
= Nothingbut at the expense of having to add the keywordOptional.
In short, I don't see any way that this can be done in VB.NET.
@zspitz 1 and 2 (which are most useful) are certainly doable in VB.NET. 3 is doable only if we also support a syntax without a default value (as you wrote), but is not important after number 1 (as I wrote).
@bandleader So are you saying there should be multiple syntaxes for optional parameters:
-
Optional <Identifier> -
<Identifier> = <constant>
which is confusing?
Or are you saying that VB.NET should follow C#, and only allow the second form? That works for C#, but I suspect that isn't in the VB style, where you don't have to specify an initial value when declaring a variable.
Or are you saying that VB.NET should follow C#, and only allow the second form? That works for C#, but I suspect that isn't in the VB style, where you don't have to specify an initial value when declaring a variable.
@zspitz On the contrary, VB currently does not allow an optional parameter without a default value. I hear you that it's not consistent with variable declaration, but that's how it currently is and I'm fine with leaving it that way.
So are you saying there should be multiple syntaxes for optional parameters
@zspitz As detailed, I'm mainly saying your number 2 (my number 1) that since we (currently) require a default value anyway, we can omit the Optional keyword. Additionally I was saying (my number 2) that we should allow omitting the type and inferring it from the default value.
Separately, my number 3 referred to Adam's proposal of allowing you to omit the default value if you do specify Optional. However, I think this will be neither necessary nor advisable if we are doing the others.
The following F(Optional arg = 123) already has a meaning in vb F(Optional arg As Object = 123)
See #13
@AdamSpeight2008 Very true. It might still be worth doing type inference for the case in which Optional is omitted, even though it would be weird that Optional arg = 123 is typed as Object and arg = 123 is typed as Integer. Good point.
Wasn't there the same problem with Dim v = 123 before VB had type inference? It was fixed using Option Infer. It might be worth doing the same for Option Infer Arguments. Not sure.
Either way, this doesn't affect number 1: allowing Optional to be omitted. The syntax would just have to be arg As Integer = 123.
PS: Writing this out makes me really feel that allowing type inference is a must here. I strongly vote to allow arg = 123 to infer Integer, even if (worst case) the old Optional arg = 123 syntax has to remain non-inferred and typed as Object.
@bandleader @AdamSpeight2008 As an aside, there is another place where a declaration defaults to Object -- class members:
Class Foo
Dim bar = 123 ' typed as Object
End Class
AFAICT, type inference cannot be applied here, so VB.NET defaults to Object (unlike C# which requires the type in this case).
But I think that where type inference can be enabled, it should be enabled.
What about this proposal now? When will optional be optional?
I ran into this post because I was looking for a work-around for C# missing an equivalent to 'Optional ByRef'. I plan to figure out how it's implemented in VB.Net and do the same in C# (I find the arguments for it not existing lacking imagination), but I digress... The fact I must type "Optional" to mark an argument as optional in VB.Net is illogical.
When you use the Optional keyword but don't provide a default value, that code will not compile... The compiler is already smart enough to know the default value is a requirement. There is no other situation where I'd provide a default value other than when making an argument Optional , so the "Optional" keyword is a redundant feature (I call it "code noise"). Isn't it the same Roslyn behind this check in C#, where it automatically identifies optional parameters by the fact a default value was provided? Exactly the same idea can be reused in parsing VB.Net code.
Because some people see compiler "problems" with inference:
I always develop VB.net with "option strict on" so I always write "optional i as integer = 9", in this case there is no ambiguity when I write "i as integer = 9" instead.
So at least for "option strict on" please make "optional" optional.