GOTCHA 31 Optional parameters break interoperability


GOTCHA #31 Optional parameters break interoperability

An optional parameter in VB.NET is a parameter that is given a value at the point of declaration. When you call a method that has optional parameters, you can choose not to provide a value for them. The compiler will substitute the default values. However, not all .NET languages support optional parameters. VB.NET allows you to declare trailing arguments as optional. C# does not. What happens to interoperability if you use optional parameters in VB.NET? Consider Example 4-1.

Example 4-1. Using optional parameters

C# and VB.NET (Optional)

   'SomeClass1.vb part of AVBDNLibrary.dll Public Class SomeClass1     Public Overridable Sub SomeMethod(ByVal val1 As Integer, _         Optional ByVal val2 As Double = 0.0)       End Sub End Class     //Test.cs part of CSUser.exe using System;   namespace CSUser {     class Test     {         [STAThread]         static void Main(string[] args)         {             AVBDNLibrary.SomeClass1 obj                 = new AVBDNLibrary.SomeClass1();             obj.SomeMethod(1, 2);         }     } } 

The VB.NET class SomeClass1 has a method SomeMethod() with two parameters, the second one marked Optional. You also have a C# class Test that, in its Main() method, creates an instance of the VB.NET class SomeClass1 and then calls its SomeMethod(). If you look at this example, there seems to be no problem in calling the method SomeMethod() of SomeClass1. In fact, IntelliSense displays the method signature in C# without showing any indication of default or optional arguments, as seen in Figure 4-1.

Figure 4-1. C# IntelliSense for a method with optional parameter


Well, there is no problem if this is the level of interoperability you are looking for. However, things get tricky if you go further. To illustrate what can happen, let's derive a C# class from SomeClass1. This is shown in Example 4-2.

Example 4-2. Deriving a C# class from the VB.NET class in Example 4-1

C# and VB.NET (Optional)

   //SomeClass2.cs part of CSLib.dll using System;   namespace CSLib {     public class SomeClass2 : AVBDNLibrary.SomeClass1     {         public override void SomeMethod(int val1, double val2)         {             base.SomeMethod (val1, val2);         }     } } 

Note that the overridden method SomeMethod() takes two parameters, int val1 and double val2. Since C# does not support optional parameters, both the parameters are specified.

So far so good, right? Now say you create a VB.NET class that derives from SomeClass2, as in Example 4-3.

Example 4-3. Deriving a VB.NET class from the C# class in Example 4-2

C# and VB.NET (Optional)

   'SomeClass3.vb part of AVBDNLibrary2.dll Public Class SomeClass3     Inherits CSLib.SomeClass2     Public Overrides Sub SomeMethod(ByVal val1 As Integer, _         ByVal val2 As Double)       End Sub End Class 

Now that SomeClass3 inherits from SomeClass2, the overridden method does not have any optional parameters. When you compile this code, you get the error shown in Figure 4-2.

Figure 4-2. Error compiling code in Example 4-3


The error message tells you that SomeClass3 cannot override SomeMethod() because the base version and the overridden version differ by the optional parameter. What if you try to fix this error by placing the Optional keyword in SomeClass3.SomeMethod(), as in Example 4-4?

Example 4-4. Placing the Optional keyword in the overriding method

C# and VB.NET (Optional)

   'SomeClass3.vb part of AVBDNLibrary2.dll Public Class SomeClass3     Inherits CSLib.SomeClass2     Public Overrides Sub SomeMethod(ByVal val1 As Integer, _         Optional ByVal val2 As Double = 0.0)       End Sub End Class 

No go. You get the same error (see Figure 4-3).

Figure 4-3. Error compiling code in Example 4-4


The compiler is still not happy. Why? It's because there's a conflict here. The first-level base-class method says it needs an optional parameter. The second-level immediate base class, however, says it does not have any optional parameters (being a C# class). If you look at the MSIL generated for each of these classes using ildasm.exe, you will notice that SomeClass1.SomeMethod() in the VB.NET base class has [opt] specified. However, the method in the C# class does not.

IN A NUTSHELL

Not all .NET languages support optional parameters. This may lead to interoperability problems. Consider using method overloading instead of optional parameters.

SEE ALSO

Gotcha #16, "Default of Option Strict (off) isn't good," Gotcha #30, "Common Language Specification Compliance isn't the default," Gotcha #32, "Mixing case between class members breaks interoperability," Gotcha #33, "Name collision with keywords breaks interoperability," and Gotcha #34, "Defining an array isn't consistent."



    .NET Gotachas
    .NET Gotachas
    ISBN: N/A
    EAN: N/A
    Year: 2005
    Pages: 126

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net