我正在编写一个小的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
但是,当客户端VBA代码传递不同类型时,它会失败:
'@TestMethod
Public Sub TestMethod2()
'compares identically-valued Long (Int32) and Integer (Int16) values:
Assert.AreEqual CLng(2), 2
End Sub
当TestMethod2
调用Assert.AreEqual
时,.NET代码会收到int
和short
- 这是正确的...但我不想把它放在客户端的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客户端代码将传递数值 - 该方法还需要使用String
和Date
值。
我很难过。我唯一的选择是记录类型重要的事实?
在VS 2013 Express中使用C#4.5。
答案 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处理的答案。谢谢!