Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/tensorflow/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# RuntimeBinderException通过动态_C#_.net_Enums_Com - Fatal编程技术网

C# RuntimeBinderException通过动态

C# RuntimeBinderException通过动态,c#,.net,enums,com,C#,.net,Enums,Com,我有一个公开类和枚举的第一个c程序集 namespace TestComLibraryInCSharp { [Guid("A5AE3B4C-7788-4394-A949-98A9F78A8E00")] [ComVisible(true)] public enum ColorType { Red = 0, Green = 1, Blue = 2 } [Guid("EF5D9F9C-DAAB-472E-

我有一个公开类和枚举的第一个c程序集

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());
        }
    }

}
在另一个程序集中,我想使用动态

    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、 选择0可显示消息框

c、 选择1或除0以外的任何其他数字将生成此异常

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
在vba(后期绑定)中,一切都按预期进行

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

在c中用延迟绑定传递枚举值的正确方法是什么?

这是一个很好的例子,它表明在.NET中编写COM服务器测试代码实际上根本不会测试COM互操作性。为什么IDE反对向类型库添加引用是一个非常合理的抱怨。CLR并不是那么容易被愚弄的,它可以在运行时看到您创建了一个.NET对象,但它不会为它创建RCW。不要因为生活更有效率而让你的生活变得困难

这种例外在其他方面是完全正常的。DLR遵循C语言规则,只有默认值0可以隐式转换为枚举类型。它坚持要看到颜色类型,否则,您将在C程序中使用强制转换。在后期绑定的场景中,这是非常困难的,您不能给枚举类型一个ProgId。需要某种偷偷摸摸的后门反射代码,远远超出正常测试的合理范围


考虑到您实际上根本没有测试COM互操作性,您不妨解决这个问题并添加一个普通的.NET引用。现在它很简单。只有VBA测试代码可以执行COM互操作管道。

尽管Hans是正确的,但解决方案可能是这样的

public ColorType GetColorTypeFromInt(int colorTypeAsInt)
{
    return (ColorType) colorTypeAsInt;
}
也就是说,在COM库中,公开一些助手方法,该方法将int转换为正确的枚举类型,这可能就是Hans所说的“秘密后门”


很难看,但回答了我原来的问题。

我担心这就是答案——从你那里我担心这是正确的。我有强烈的理由反对不允许这样做是合法或合理的,但这不是重点。我确实对CLR优化有很多废话。好像我要为设计选择负责。我回答这个问题的唯一原因是,这是一个非常好的例子,它清楚地揭示了底层的实现细节。干得好。根据我之前的评论,我根本不想批评你的答案。我只是想指出,我认为这个.net设计决策是有问题的。不想暗示你有任何责任。谢谢你完整的回答。