Reflection 'ambiguous match' error

Grayda

Member
Joined
May 20, 2010
Messages
16
Programming Experience
10+
For a bit of self education, I'm writing a game using XNA and using NLua for scripting. I've got three classes, clsBase (which defines the functions and subs all things in the game must be able to do), clsSprite (which is objects such as doors) and clsPlayer. The last two inherit from clsBase so that my codebase is rather nice and neat.

clsBase has a sub called move that does what it says on the tin, and clsPlayer has a sub of the same name that does things a little different (as it needs to work out stuff like orientation, object collision and such). clsBase (and therefore clsSprite and clsPlayer) has a variable called lua, which is a new NLua.Lua. They also have a sub, addLuaFunction(), which basically calls lua.RegisterFunction, and allows my Lua files to call real functions in my VB.NET app (such as a function to display a messagebox).

If the lua stuff is in it's own non-inheritable class, things work fine, but I can only have one Lua script loaded at a time, which isn't that great (?). But as soon as I add the Lua stuff to clsBase and run, I get this error:

An exception of type 'System.Reflection.AmbiguousMatchException' occurred in mscorlib.dll but was not handled in user code

Additional information: Ambiguous match found.

And VB.NET 2013 Preview stops here:

VB.NET:
Sub Main()
    Dim player as New clsPlayer
    Dim door as New clsObject
 
    player.registerLuaFunction("move")
    door.registerLuaFunction("move")
End Sub

' -------------------------------------------
' -------------------------------------------
' -------------------------------------------
' In clsBase:

Public Sub registerLuaFunction(functionName As String)
    ' Saves a bit of typing
    lua.RegisterFunction(functionName, Me, Me.GetType().GetMethod(functionName)) ' <---- Stops right here with the ambiguous match error
End Sub

The reason is fairly obvious to me -- I have a player and I have a door object -- both have a move sub, and VB.NET is not really sure which move() we're referring to, despite each move sub being in it's own class.

A Google search yielded nothing, but I did have some success by removing sub move() from all my derived classes, but that's not a good solution, as different things in the game move differently.

Any suggestions?
 
despite each move sub being in it's own class.
That is not really true, the inherited members are equally members of the inherited type as those declared.

Since your Move methods in base and inherited have different signatures you can specify the signature types for the method you actually want.
 
That is not really true, the inherited members are equally members of the inherited type as those declared.

Since your Move methods in base and inherited have different signatures you can specify the signature types for the method you actually want.

Never actually thought of classes like that.

But let's say the signature (I believe by this, you mean the name of the sub, in addition to the arguments the sub can take?) is the same as everything else -- that move(x as integer, y as integer) in base, just moves the sprite, but move(x as integer, y as integer) in the inherited class does some smoothing of movement and such -- do I need to stick a dummy argument on the end that does nothing (move(x as integer, y as integer, optional unique123 as boolean = false), in order to differentiate between the two?

And how does one go about specifying which signature type we're referring to when dealing with reflection?
 
let's say the signature is the same
That is only possible for Overrides or Shadows/Overloads methods, and GetMethod have no problem with that.
And how does one go about specifying which signature type
With the GetMethod overload where you can supply a Type array matching the signature parameters.
 
That is only possible for Overrides or Shadows/Overloads methods, and GetMethod have no problem with that.

With the GetMethod overload where you can supply a Type array matching the signature parameters.

Gotcha! After some tweaking, everything works as expected, and my new code looks like this:

VB.NET:
Sub registerLuaFunction(functionName As String, ParamArray params() As Type)
        ' Registers a VB.NET class function for use in our Lua script
        ' You have to specify the type, due to inheritance and ambiguous match issues
        ' Call it like so: registerLuaFunction("writeYourNameAndAge", GetType(String), GetType(Integer))
        lua.RegisterFunction(functionName, Me, Me.GetType().GetMethod(functionName, params))
    End Sub

' Elsewhere..
sub loadFuncions()
  registerLuaFunction("move", GetType(Integer), GetType(Integer))
end sub

sub move(x as integer, y as integer)
' move code here
end sub

And if I need to have two or more subs with the same signature, I use overrides in the class.

Now my code successfully loads Lua scripts, no matter how many scripts or classes I have.

Thanks for the help!
 
Last edited:
Back
Top