【问题标题】:c# Can I prevent my constructor arguments clashing with VBA instantiation?c# 我可以防止我的构造函数参数与 VBA 实例化冲突吗?
【发布时间】:2018-12-31 12:35:26
【问题描述】:

对于在 VBA 环境中使用类时如何覆盖需要参数的构造函数,我有点困惑。

什么有效?

我在一个库中创建了几个类,每个类都有一个接口,以便在 VBA 中使用这个库时实现完全的智能感知兼容性

无论有没有构造函数,这些类对我来说都可以正常工作,例如

[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("JamHeadArt.ClassEX")]
[Guid("XYZ")]
public partial class ClassEX : IClassEX
{

    public ClassEX()
    {
        // Empty constructor here, some of mine have processes, all work well
    }  

    // Methods/ Properties as outlined by the interface below
}

[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
[Guid("ABC")]
public interface IClassEx
{
    // Various methods / fields / properties to be implemented by ClassEX
}

然后我添加对我的库的引用并在 VBA 中编写简单的代码行来实例化和访问我的类:

Sub Test()
Dim t As JamHeadArt.ClassEX
Set t = New JamHeadArt.ClassEX
' Using t.dot then provides all the methods needed '
End Sub

出了什么问题?

当我在一个类中创建带有参数(即使是可选的)的构造函数时,VBA 将停止允许我创建这些类的实例,它告诉我“New”关键字无效并且实际上不允许我选择如果我直接使用Dim t As New JamHeadArt.ClassEx,则从我的库中的对象的智能感知列表中提取类,即使参数设置为可选(因此并不真正需要)

这里令人讨厌的是 - 我实际上并不想要我的 VBA 实例通过构造函数接受参数,它们主要用于单元测试并且它们是可选字符串,因此默认为“ " ...所以我想我的问题是这样的

是否可以覆盖任何构造函数参数,以便在 VBA 环境中引用时忽略它们?

例如我真的希望我的构造函数看起来像这样:

public ClassEX(string s = "")
{

} 

在 VBA 中它应该像以前一样工作 Dim t As New JamHeadArt.ClassEX - 但它不会在那里有那个可选字符串!

【问题讨论】:

  • 你不能只添加一个额外的构造函数吗?即:一个无参数,另一个带有单元测试参数
  • 我没有使用过 VBA,但是在 c# 中你可以有一个 internal 构造函数和一个 public 构造函数。内部的可以用于单元测试,而公共的可以用于 VBA。使用InternalsVisibleToAttribute,这样只有单元测试应用才能看到该构造函数。这是一个可能的解决方案,但我不喜欢仅为单元测试编写代码。大多数情况下,这是一个设计缺陷,但有时没有其他方法。很难说,因为我对您的情况了解有限,但至少这是一种解决方案。
  • @Stefan 我没有尝试过 - 我想我非常关注参数是可选的这一事实,但给我五个,我会看看它是否有效
  • @CodingYoshi 如果可行的话,这听起来像是一个很好的解决方案 - 是的,代码的设置很糟糕,一些白痴(大约一年前的我)写了所有这些可怕的东西,这个可选参数是最少的实现单元测试的复杂方式。
  • @Stefan - 有效。老实说,有时只见树木不见森林。如此简单,看看我在我的问题中写了多少废话!!!这一切都是因为我专注于“可选”参数......这意味着我必须弄湿一点我的代码,但谢谢!

标签: c# vba


【解决方案1】:

你可以添加一个额外的构造函数,例如:

[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("JamHeadArt.ClassEX")]
[Guid("XYZ")]
public partial class ClassEX : IClassEX
{
    public ClassEX()
    {
        // Empty constructor here, some of mine have processes, all work well
    }  

    public ClassEX(string foo)
    {
        // additional constructor, can be used for unit testing etc.
    }  

    // Methods/ Properties as outlined by the interface below
}

【讨论】:

  • 感谢 Stefan,这对我来说是最好的解决方案 - 这并不理想,因为我基本上必须将所有内容从一个复制粘贴到另一个,但这是由于糟糕的代码编写设置了一个糟糕的框架前一阵子!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多