4

I have a C# program that calls a COM DLL that has a method called test with two parameters: the first parameter is passed ByVal, the second one is passed ByRef.

This is what the COM DLL does:

Public Sub test(ByVal a As String, ByRef b As String)
    a = "a"
    b = "b"
End Sub

This is what C# program does:

test.Class1 x = new test.Class1();
            string a = "1";
            string b = "2";
            x.test(a, ref b);

I notice that if I remove ref keyword, the compiler doesn't advice me that I missed the ref keyword and passes the parameter ByVal. This can be a big problem if I miss the ref keyword because I can't notice it until I know that it wants the ref. Do you know why the compiler exhibits this behavior?

Mr.C64
  • 41,637
  • 14
  • 86
  • 162
CRK
  • 337
  • 2
  • 10
  • @MartinVerjans there is no "Option Strict ON" in C# projects – CRK Nov 07 '16 at 15:05
  • @HansPassant I test the program without ref keyword, and it don't change the value of the string. So pass the string ByVal instead of ByRef if you don't tell him to do this. – CRK Nov 07 '16 at 15:16

1 Answers1

6

This is highly specific to COM interop code and C# language version 4 and up. Yes, it permits omitting ref in this specific case. C# version 4 had a lot of tweaks to make Office programming easier. The Office api was originally designed to work well with early VB versions, they used ByRef by default. Still the case for VBA. So the api has a lot of method parameters that are ByRef, even though they don't actually modify the passed argument.

The compiler will generate a temporary variable if necessary to make the call legal. With the consequence that your variable doesn't get updated. Something you'll have to watch out for. Two steps forward, one step back :)

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • If I have a big project and I want to check every missed "ref" keyword, how can I do this? Or something that advice me of the mistake? – CRK Nov 07 '16 at 15:31
  • Hmya, you have to use the obvious way to find bugs in code, you use a debugger. Don't panic, just because you got one wrong does not mean you got them all wrong. IntelliSense still helps you get it right. Do fix that COM code first, it should be a Function of course. – Hans Passant Nov 07 '16 at 15:36
  • Maybe you don't understand my problem. The problem is this: if I miss a ref keyword in a COM method signature, the compiler accept it telling me nothing even if actually the method want a ByRef parameter. In a big project I can't check every single method and they're signature (I can but it will take much time). I only want that the compiler advice me if I miss a ref keyword. – CRK Nov 07 '16 at 15:40
  • Pretty sure I understand your problem. Maybe you don't understand what "one step back" means. It means that a *new* potential problem got added in version 4. Never a hard one to debug, it is quite noticeable that the value doesn't change. Don't panic. – Hans Passant Nov 07 '16 at 15:42
  • Is noticeable if you have few var to check. What if you have to check thousands of variable? There is no way to notice me that a ref keyword is missed? – CRK Nov 07 '16 at 16:02
  • 4
    Sigh, you are not going to let up, are you? Fine, write a Roslyn code analyzer, you can compare the call with the method declaration and see the mismatch. Google "writing roslyn code analyzers" for good hits. – Hans Passant Nov 07 '16 at 16:13