1

I am developing a .dll in C# that makes extensive use of DynamicObject.

The .dll in other C# projects works fine, however in VB.NET TryGetMember doesn't seem to be called. Instead TryInvokeMember is called even if the member is a property.

Here is an example class from my .dll

namespace MyNamespace
{
    class MyDynamicClass : DynamicObject
    {
        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            //Do stuff with property
        }

        public override bool TryInvokeMember(InvokeMemberBinder, object[] args, out object result)
        {
            //do stuff with function
        }
    }
}

In a C# project everything works as expected:

class Program
  {
    static void Main(string[] args)
    {
        dynamic myObj = new MyNamespace.MyDynamicClass();
        var getm = myObj.GetMember; //this will call TryGetMember
        var invokem = myObj.InvokeMember(); //this will call TryInvokeMember
    }
  }

In VB.NET, both lines result in call to TryInvokeMember

Sub Main()
    Dim myObj = New MyNamespace.MyDynamicClass()
    Dim getm = g.GetMember 'calls TryInvokeMember
    Dim invokem = g.InvokeMember() 'calls TryInvokeMember
End Sub

I can solve my problem by simply calling TryGetMember at the end of TryInvokeMember if it fails to call it as a function, however since I have never worked with VB.NET before, I wanted to make sure this workaround is necessary and I am not doing something wrong.

atsekoff
  • 11
  • 1
  • In VB, can't you call a sub (not a func - i.e. no return value) by using the member name without parentheses? i.e `obj.Foo` === `obj.Foo()` if `Foo` is a sub? perhaps just `return false` from the `TryInvokeMember` if it isn't a method, so it will try the next apprach, presumably `TryGetMember` ? – Marc Gravell May 13 '19 at 14:21
  • You are right, if TryInvokeMember returns false it goes on to TryGetMember. I didn't notice that because I was either returning true or throwing an exception when the member was not found. – atsekoff May 13 '19 at 14:48
  • "It is history" is the usual answer for vb.net. It has supported the equivalent of C#'s *dynamic* for a very long time. Called "late binding", which is what you are accidentally using. Put `Option Strict On` at the top of the vb.net source code file to get a decent diagnostic error from the compiler. Or in other words, as posted the vb.net compiler has no idea that the class has a GetMember() method so needs go looking for that one first. Your first TryInvokeMember invocation is for binder.Name = "GetMember". – Hans Passant May 13 '19 at 14:55

0 Answers0