A bug report drifted into my muddled field of vision today that would make for a wonderful blog posting. The reporter was wondering what was so ambiguous about the following code:
Sub Test( foo as ListBox, bar() as String )
Sub Test( foo as ListBox, bar as Variant )
dim s() as String
dim v as Variant
Test( Nil, s )
Test( Nil, v )
If you compile this sort of a project, you'll notice that the compiler barks at you about ambiguous method overloading. That's because Nil counts as a conversion -- we have to convert Nil into an Object that represents a ListBox. And the compiler deals with ambiguities in a very straightforward method when it comes to picking a method variant to call. To the compiler, there's either "no" conversion steps, or "many" conversion steps. It doesn't try to pick the one with the least amount of steps as that caused many problems when we tried it. Instead, it picks the one with no conversion steps, and if it cannot find one with no conversion steps -- it bails out. So in the user's case, both calls need to do the conversion from Nil to ListBox that is Nil -- that means it's ambiguous as to which one is "better" for the compiler to call.
It's a bit obtuse, but when we tried to pick a better variant based on the number of conversions steps, we broke a whole bunch of code (from what I recall). It appears that there is a reliance on the current behavior, and changing that reliance (while possibly a logical thing to do) has practical implications that prevent us from doing it.
So if you ever run into an ambiguous overloading error in your own projects, take a look at each version's signature and see if you can count the number of conversion steps it would take with your usage, and be more explicit about the types. For instance, the user could fix their code by saying:
Sub Test( foo as ListBox, bar() as String )
Sub Test( foo as ListBox, bar as Variant )
dim s() as String
dim v as Variant
Test( ListBox( Nil ), s )
Test( ListBox( Nil ), v )
Fun stuff !
While I'm sure you would rather not do this, would it not make sense to special case the NIL to specific object type conversion so it does not count as a conversion in signature determination?
I doubt that would break any code (or very very little) and would be more intuitive.
- Karen
@Karen -- But... Nil *is* a conversion step... You could make the same argument against any conversion step, really (such as from a value to a variant). Simply ignoring conversion steps doesn't make it any more intuitive, it simply makes the logic harder to explain when you do run into ambiguity (since you'd have to say "except for this case, or that case).