泛型和Com可见.NET库 [英] Generics and Com Visible .NET libraries
问题描述
我开发了一个VB.NET库(部分开发在C#上),这在很大程度上依赖于从一个抽象通用基类继承,我试图找出这个的最佳实践。我很遗憾必须使用框架3.5。
公共MustInherit类MyBaseClass(Of T)
公共
结束类
公共类MyDerivedClass
Inherits MyBaseClass(Of String)
私有_myProperty作为字符串
公共属性MyProperty As String
Get
返回_myProperty
结束Get
设置(值为字符串)
_myProperty =值
结束集
结束属性
结束类
我在VBA中使用.tlb文件作为参考我运行以下代码:
Dim m As New VBtoVBA.MyDerivedClass
m.MyProperty =foo
我收到错误运行时错误430:类不支持自动化或不支持预期的接口。
另一方面,我将第一行改为:
公共MustInherit类MyBaseClass
公共无关作为字符串
结束类
公共类MyDerivedClass
继承MyBaseClass
VBA脚本工作。因此,我认为问题是与泛型(也记录在其他来源)。然而,删除我的库的通用功能是不可能的。我可以想到的最好的解决方法是写一个第三个类,包括MyDerivedClass作为一个字段,并作为一个非通用接口:
公共类MyDerivedClassString
私人_innerObj作为新的MyDerivedClass
公共属性MyProperty作为字符串
获取
返回_innerObj.MyProperty
End Get
Set(value As String)
_innerObj.MyProperty = value
End Set
End Property
公共属性Whatever As String
Get
返回_innerObj.Whatever
结束Get
设置(值为字符串)
_innerObj.Whatever =值
结束集
结束属性
结束类
这样我就可以使用它, d喜欢在VBA:
m.Whatever =wha
MsgBox(m.Whatever)
顺便说一下,我认为可能有另一种(更好的)方式来实现相同的结果,我真的希望因为m库是由几十个类组成的。
非常感谢。
正如我在注释写入库(dll)MS Office应用程序是位...硬编码。这个dll必须暴露方法和属性,以便能够在COM自动化中使用它。为了能够实现这一点,你需要编写接口:
命名空间VBtoVBA
public Interface IMyDerivedClass
属性MyProperty as String
结束接口
结束命名空间
DerivedClass
Public Class MyDerivedClass
Inherits MyBaseClass(Of String)
实现IMyDerivedClass
Private _myProperty As String
公共属性MyProperty As String实现IMyDerivedClass.MyProperty
现在,转到项目属性
窗口
1)选择应用程序
选项卡 - 单击装配信息
按钮,在下一个窗口中选择使装配COM可见
复选框(使用 code>按钮),
2)选择编译
标签 - 选择注册COM interop
checkbox
3)保存项目和Build dll
4)现在,在Office应用程序中转到VBA代码编辑器 - > 引用
菜单。 参考窗口
添加对 yourDllName.tlb
现在,您可以在Office应用程序中使用您的dll;)
我测试的代码:
code>选项显式
Sub DoSomething()
Dim m As VBtoVBA.MyDerivedClass
设置m =新VBtoVBA.MyDerivedClass
m.MyProperty =Something
MsgBox m.MyProperty
End Sub
它的工作原理)
I've developed a VB.NET library (partially developed on C# as well) that heavily depends on inheriting from an abstract generic base class, and I'm trying to figure out the best practice for this. I Sadly have to do it using framework 3.5.
Public MustInherit Class MyBaseClass(Of T)
Public Whatever As T
End Class
Public Class MyDerivedClass
Inherits MyBaseClass(Of String)
Private _myProperty As String
Public Property MyProperty As String
Get
Return _myProperty
End Get
Set(value As String)
_myProperty = value
End Set
End Property
End Class
I attach the .tlb file as a reference in VBA (using Excel), and I run the following code:
Dim m As New VBtoVBA.MyDerivedClass
m.MyProperty = "foo"
And I get the error "Run-time error 430: Class does not support Automation or does not support expected interface".
On the other hand, I change the first lines to:
Public MustInherit Class MyBaseClass
Public Whatever As String
End Class
Public Class MyDerivedClass
Inherits MyBaseClass
The VBA script works. Hence I assume the issue is with generics (as documented in other sources as well). Dropping the generic feature of my library is not possible, though. The "best" workaround I can think of is to write a third class that includes MyDerivedClass as a field, and works as a non-generic interface to it:
Public Class MyDerivedClassString
Private _innerObj As New MyDerivedClass
Public Property MyProperty As String
Get
Return _innerObj.MyProperty
End Get
Set(value As String)
_innerObj.MyProperty = value
End Set
End Property
Public Property Whatever As String
Get
Return _innerObj.Whatever
End Get
Set(value As String)
_innerObj.Whatever = value
End Set
End Property
End Class
This way I can work with it pretty much as I'd like to in VBA:
m.Whatever = "wha"
MsgBox (m.Whatever)
By the way I think that there might be another (better) way to achieve the same result, and i really hope so since m library is made up of dozens of classes.
Many thanks.
As i mentioned in comment writing library (dll) for MS Office applications is bit... hard-coded. This dll must exposes methods and properties to be able to use it in COM automation. To be able to achieve that, you need to write interface(s):
Namespace VBtoVBA
Public Interface IMyDerivedClass
Property MyProperty As String
End Interface
End Namespace
then in DerivedClass
Public Class MyDerivedClass
Inherits MyBaseClass(Of String)
Implements IMyDerivedClass
Private _myProperty As String
Public Property MyProperty As String Implements IMyDerivedClass.MyProperty
Now, go to Project Properties
window
1) choose Application
tab - click on Assembly Information
button and in the next window select Make assembly COM visible
checkbox (apply setting using OK
button),
2) choose Compile
tab - select Register for COM interop
checkbox
3) Save project and Build dll
4) Now, go to VBA Code editor in Office application -> References
menu. In Reference window
add reference to yourDllName.tlb
Now, you can use your dll in Office application ;)
I tested code:
Option Explicit
Sub DoSomething()
Dim m As VBtoVBA.MyDerivedClass
Set m = New VBtoVBA.MyDerivedClass
m.MyProperty = "Something"
MsgBox m.MyProperty
End Sub
and it works as well ;)
这篇关于泛型和Com可见.NET库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!