Search code examples
c#.netenumscom

RuntimeBinderException passing Enum values other then 0 to a .Net Com Assembly via dynamic


I have a first c# assembly exposing a class and an enum

namespace TestComLibraryInCSharp
{
    [Guid("A5AE3B4C-7788-4394-A949-98A9F78A8E00")]
    [ComVisible(true)]
    public enum ColorType
    {
        Red = 0,
        Green = 1,
        Blue = 2
    }

    [Guid("EF5D9F9C-DAAB-472E-A418-114F0352F06E")]
    [InterfaceType(ComInterfaceType.InterfaceIsDual)]
    [ComVisible(true)]
    public interface IComClassUsingEnum
    {
        void Select(ColorType color);
    }

    [Guid("5EDE0D14-3A3B-41E7-93BC-40868BC68655")]
    [ClassInterface(ClassInterfaceType.None)]
    [ComVisible(true)]
    public class ComClassUsingEnum : IComClassUsingEnum
    {
        public void Select(ColorType color)
        {
            MessageBox.Show("you have selected " + color.ToString());
        }
    }

}

In another assembly I want to test the above interface using dynamic

    public void DoTestColor()
    {
        Type type = Type.GetTypeFromProgID("TestComLibraryInCSharp.ComClassUsingEnum");
        dynamic c = Activator.CreateInstance(type);

        c.Select(0); // this works
        c.Select(1); // this throws RuntimeBinderException
    }

c.Select(0) works showing the messagebox

c.Select(1) (or any other number except 0) will generate this exception

An unhandled exception of type 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' occurred in System.Core.dll
Additional information: The best overloaded method match for 'TestComLibraryInCSharp.ComClassUsingEnum.Select(TestComLibraryInCSharp.ColorType)' has some invalid arguments

in vba, late bound, everything works as expected

Dim c As Object
Set c = CreateObject("TestComLibraryInCSharp.ComClassUsingEnum")
c.Select 1

What is the correct way to pass enum values with late bound in c#?


Solution

  • As much as Hans is right, a solution could be this

    public ColorType GetColorTypeFromInt(int colorTypeAsInt)
    {
        return (ColorType) colorTypeAsInt;
    }
    

    that is, in the COM library, expose some helper method which casts from an int to the proper enum type (which maybe is what Hans referred to as 'sneaky backdoor').

    Quite ugly, but answers my original question.