我正在编写一个小型 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。
最佳答案
这有点盲目(还没有使用 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 处理更新了答案。谢谢!
关于c# - 如果我不想要类型安全怎么办?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26749247/