7

We have a VB.NET project which I am doing some refactoring in. A lot of current functions require a userId to be passed in as a parameter. For example:

Private Function Foo(userId As Integer) As String
    Return "Foo"
End Function

But now, I have made this userId paramater no longer needed in much of our code.

I was thinking I would just remove all the userId parameters from all of the functions that don't need them anymore, and try re-building the project to see what calling code needs to change. To my surprise though, the code built successfully.

I learned that you can call a function which returns a string and doesn't take any parameters, but still pass in an Integer value. VB.NET builds/executes this code as if you were trying to invoke the function and then get the character from the String at the specified index. For example:

Imports System

Public Module MyModule
    Private Function Foo() As String
        Return "Foo"
    End Function

    Public Sub Main()
        Console.WriteLine(Foo(0)) ' prints 'F'
        Console.WriteLine(Foo(1)) ' prints 'o'
    End Sub
End Module

(.NET Fiddle)

I want my build to fail in this case. I have tried using Option Strict On and Option Explicit On but neither seem to change this behaviour.

Is there anyway to make this kind of function invocation invalid in my VB.NET project?

9
  • 6
    The 'problem' is that VB uses parens for array indexing (a string is a char array) and for method parameters. c# would catch it because it uses [] for indexers and would know the (0) is for a non existent arg. Its built in, basic language functionality, so you cant force it not to not allow it Commented Jan 11, 2018 at 19:38
  • I found a related Q&A where a user got burned by this language "feature". But unfortunately, it doesn't say if it is possible to disable support for this feature. Commented Jan 11, 2018 at 19:41
  • c# allows string indexing as well - the problem is the syntax/symbology in VB that uses () for two quite different things. Commented Jan 11, 2018 at 19:47
  • @Plutonix Thanks for the info, it seems you are correct that it is not possible to disable this behavior in the VB.NET compiler. Feel free to post that as an answer and I will gladly accept it (while angrily shaking my fist at the VB language). Commented Jan 11, 2018 at 19:50
  • It seems this is only a problem because VB.NET doesn't require parentheses when invoking parameter-less functions. I searched to see if it was possible to disable that feature, and it isn't possible according to this other Q&A. Commented Jan 11, 2018 at 19:52

1 Answer 1

4

Create an overload with no parameters which is a copy of the original function in every other respect.

Public Function Foo() As String
    Return "Foo"
End Function

Now change the type of userId to something else (not Object or anything numeric etc.)

Public Function Foo(userId As DateTime) As String
    Return "Foo"
End Function

Since there is an overload with a parameter, the compiler thinks you mean to call that, instead of indexing the chararray. So you have compile errors. Fix the errors

Then delete the original function.

Sign up to request clarification or add additional context in comments.

1 Comment

I tried it out and it worked perfectly. Great work-around, thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.