如果我不想要类型安全怎么办?

时间:2014-11-05 03:33:30

标签: c# vba com-interop equality type-safety

我正在编写一个小的VBA IDE加载项,并且有一个名为AssertClass的COM可见C#类,其中AreEqual方法如下:

public void AreEqual(object value1, object value2, string message = null)
{
    if (value1.Equals(value2))
    {
        AssertHandler.OnAssertSucceeded();
    }
    else
    {
        AssertHandler.OnAssertFailed("AreEqual", message);
    }
}

当客户端VBA代码像这样调用它时,所有代码都按预期工作:

'@TestMethod
Public Sub TestMethod1()
    'compares two identical Integer (Int16) values:
    Assert.AreEqual 2, 2
End Sub

TestMethod1 passes

但是,当客户端VBA代码传递不同类型时,它会失败:

'@TestMethod
Public Sub TestMethod2()
    'compares identically-valued Long (Int32) and Integer (Int16) values:
    Assert.AreEqual CLng(2), 2
End Sub

TestMethod2 fails


TestMethod2调用Assert.AreEqual时,.NET代码会收到intshort - 这是正确的...但我不想把它放在客户端的VBA代码上以确保它传递相同的类型 - 我希望所有这些调用都能导致后续的断言:

Assert.AreEqual CByte(2), 2 'fails
Assert.AreEqual CInt(2), 2  'passes
Assert.AreEqual CLng(2), 2  'fails
Assert.AreEqual CSng(2), 2  'fails
Assert.AreEqual CDbl(2), 2  'fails
Assert.AreEqual CCur(2), 2  'fails

毕竟,在类型安全和相等检查方面,VBA并不像C#那样严格:

?CByte(2) = 2, CInt(2) = 2, CLng(2) = 2, CSng(2) = 2, CDbl(2) = 2, CCur(2) = 2
True          True          True          True          True          True

如何制定我的AreEqual C#函数以便...以某种方式避免强制类型安全进入VBA客户端代码?我不能假设VBA客户端代码将传递数值 - 该方法还需要使用StringDate值。

我很难过。我唯一的选择是记录类型重要的事实

在VS 2013 Express中使用C#4.5。

1 个答案:

答案 0 :(得分:3)

这是在黑暗中的一点点(没有使用VBA和C#组合),但尝试这个,看看它是否有效:

public void AreEqual(object value1, object value2, string message = null)
{
    bool convertedOk = true;
    object value2Converted;

    try
    {
         value2Converted = Convert.ChangeType(value2, value1.GetType());
    }
    catch 
    {
         convertedOk = false;
    }

    if (convertedOk && value1.Equals(value2Converted))
    {
        AssertHandler.OnAssertSucceeded();
    }
    else
    {
        AssertHandler.OnAssertFailed("AreEqual", message);
    }
}

想法是你改变了第一个值的类型,因此他们现在变得“更加兼容”以进行比较。

修改的:    根据评论的建议更新了try / catch处理的答案。谢谢!