VB.NET and calling byval/byref C# overloads

522 Views Asked by At

We have a C# class, which includes two functions, whose parameters differ only by the parameter modifier:

bool DoSomething(Object obj){};
bool DoSomething(ref Object obj){};

Now we need to call this method (any of them, actually) from VB.NET. The problem is that the VB.NET compiler can't decide, which method to use.

The question is: is there a way to tell the compiler that we want the first variant (or the second one, it doesn't matter for the caller)?

Writing the call as DoSomething((myObj)) (i.e. adding parentheses) in VB.NET doesn't help.

2

There are 2 best solutions below

0
On BEST ANSWER

You could create a separate library written in C# that provides helper methods with distinct names to enable you to call the ambiguously defined DoSomething methods. You shouldn't have to do that, and people might wonder why you did, so you could fill it with scathing comments explaining why it was necessary.

Or you could use reflection, something roughly like this:

Dim methods = GetType(WhatEverTheType).GetMethods()
Dim doSomethingMethod = methods.Single(Function(method As MethodInfo)
        Return method.Name = "DoSomething" _
        And Not method.GetParameters()(0).ParameterType.IsByRef
    End Function)
doSomethingMethod.Invoke(instanceOfWhatEverTheType)
1
On

AFAIK, the only way would be to force the call to the API using Reflection. Although I am not completely sure if that would work.

The problem is that creating 2 overloads only differing by ref is not CLS compliant and therefore not guaranteed to work in all .NET languages. To prevent getting into this situation, you should add the CLSCompliantAttribute to your AssemblyInfo.cs file and then the compiler will warn you when you have broken CLS compatibility.

[assembly: System.CLSCompliant(true)]

A way you could fix this is by adding a wrapper function that can be called via VB.NET.

bool DoSomething(Object obj){};
bool DoSomething(ref Object obj){};

// Call this method from VB.NET
bool DoSomething2(ref Object obj)
{
    return DoSomething(ref obj);
}

There are a few different ways you could make this cleaner, such as making a separate assembly to wrap it as Scott Hannen mentioned, or simply by making the wrapper method for CLS compliance an extension method.