我可以在C#中创建一个可在COM上看到的类的全局实例吗?
原因:我将VBA类库移植到C#以使用COM,我想提供某种形式的非默认构造函数。
但是,COM不允许非默认构造函数,也不能直接访问静态类方法,我将用于非默认构造函数。它需要类的实例来调用方法。我对解决方法的最后一个想法是只提供该类的全局实例。这实际上是我通过设置Attribute VB_PredeclaredId = True
对原始VBA代码所做的。
但是,C#中的全局变量总是包含在无法通过COM访问的静态类中。
因此在VBA中,使用此策略的示例类是(Box.cls的原始代码)
VERSION 1.0 CLASS
BEGIN
MultiUse = -1 'True
END
Attribute VB_Name = "Box"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False ' prohibit `new Box` from outside project
Attribute VB_PredeclaredId = True ' creates object `Box`
Attribute VB_Exposed = True
Option Explicit
Private pStr As String
' "Constructor"
Public Function Make(ByVal x as String)
Dim result As New Box
result.Inject x
Set Make = result
End Function
Friend Sub Inject(ByVal x As String)
pStr = x
End Sub
Public Property Get Inside() As String
Inside = pStr
End Property
然后用法就像
Dim b As Box ' Box as a type
Set b = Box.Make("example") ' Box as a global instance
debug.assert b.Inside = "example"
debug.assert Box.Inside = "" ' side affect is you can do this.
我看的C#代码就像
public class Box {
private string _str;
public Box() {} // _str still empty
public Box(string str) { _str = str; } // Can't call from COM
public static Box nogood(string str) // Can't call from COM
{
return new Box(str);
}
public Box make(string str) //.Can call but I need an instance of Box first.
{
return new Box(str);
}
//...
}
我想使用VBA中的C#类,并且我希望避免这样做
Dim boxMaker as New Box
Dim b As Box
Set b = boxMaker.make("hello")
答案 0 :(得分:1)
这是不可能的,但是一种模拟全局实例的简单方法是使用全局函数来返回静态实例:
Public Function Box() As Box
Static instance As New Box
Set Box = instance
End Function
Sub Usage()
Dim b As Box
Set b = Box.make("hello")
End Sub