【问题标题】:Access .NET generic objects from VBA从 VBA 访问 .NET 通用对象
【发布时间】:2009-09-25 22:45:23
【问题描述】:

我的 .net 代码有一个具有许多通用属性的对象。该对象返回给 VBA 代码。所有非泛型属性都运行良好,但我还需要访问泛型值。有没有办法从 VBA 中做到这一点?

[ClassInterface(ClassInterfaceType.AutoDual)]
public class Obj
{
    public string GetProp1() {...}
    public IList<MyCustomType> GetProp2() {...}
}

VB代码:

Sub Test()
    Dim o As Program.Obj
    Set o = New Program.Obj
    Set p2 = hp.GetProp2()

    set p2_0 = p2(0) ' doesn't work

End Sub

【问题讨论】:

    标签: c# .net vba com interop


    【解决方案1】:

    您不能直接执行此操作(如果 VS 正在注册您的 COM,您应该会看到如下警告:Type library exporter warning processing 'NS.Obj.get_GetProp2(#1), Assy'。警告:Type library exporter在签名中遇到泛型类型实例。泛型代码可能无法导出到 COM。

    您需要做的是制作一个小非泛型包装器和一个向 COM 公开的接口(假设您想要强类型对象)。只要您在 VBA 中引用 typelib 并通过强类型 VBA refs 访问您的对象,您就可以执行以下操作:

    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.AutoDual)]
    public class Class1
    {
        public IMyListOfString Strings {get; set;}
        public Class1()
        {
            Strings = new MyListOfString() { "Foo", "Bar", "Baz" };
        }
    }
    
    [ComDefaultInterface(typeof(IMyListOfString))]
    public class MyListOfString : List<string>, IMyListOfString { }
    
    [ComVisible(true)]
    [InterfaceType(ComInterfaceType.InterfaceIsDual)]
    public interface IMyListOfString
    {
        [DispId(0)]
        string this[int idx] { get; set; }
    }
    

    在不引用 VBA 中的托管类型库(例如,后期绑定)的情况下,也有一个技巧可以让它工作,但我已经离开 COM 互操作世界太久了,不记得它是什么。

    【讨论】:

      【解决方案2】:

      我发现this article 描述了一个丑陋的黑客——通过反射调用一切。由于泛型值仍作为对象返回,因此反射应该可以工作,但会 1) 慢,2) 容易出错,以及 3) 调用非常不方便。

      如文章所示,我将使用具有以下签名的实用方法:

      public object GetProperty(object Instance, string Property)
      public object InvokeMethod(object Instance, string Method)
      public object InvokeMethod_OneParm(object Instance, string Method, object Parm1)
      public object InvokeMethod_TwoParms(object Instance, string Method, object Parm1, object Parm2)
      public void SetProperty(object Instance, string Property, object Value)
      

      丑陋,但可行。

      【讨论】:

      • 警告建议修复此问题,例如在@Matt Davis 的回答中
      猜你喜欢
      • 2017-11-17
      • 2011-01-15
      • 2018-07-11
      • 2014-01-07
      • 1970-01-01
      • 2020-09-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多