C#中的COM可以看到全局类实例吗?

时间:2016-04-29 04:39:42

标签: c# vba static com

我可以在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")

1 个答案:

答案 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