2014-11-05 29 views
2

我正在寫一個小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。

+0

不要帶走你想要完成的任何事情,也許這對你的設計完全不起作用,但爲什麼不用像'Assert.IsTrue()'這樣更通用的方法呢?然後你的VBA示例應該可以工作:'Assert.IsTrue(CByte(2)= 2)' – TyCobb 2014-11-05 03:47:17

+0

@TyCobb AssertClass具有AreEqual,AreNotEqual,AreNotSame,AreSame,Fail,InConclusive ','IsFalse','IsNothing','IsNotNothing'和'IsTrue'方法。只有'AreEqual'(和'AreNotEqual')是有問題的;我忽略了其他的方法,以便brievety;) – 2014-11-05 03:49:33

回答

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處理更新答案。謝謝!

+0

當然,將其轉換! (facepalm)......現在,實際的修復需要一個「try/catch」塊來確保轉換確實是可能的,但是這個答案肯定會讓我走上正確的軌道。謝謝! http://i.stack.imgur.com/IH72b。png – 2014-11-05 03:57:08

+0

有趣的答案。這可能需要包含在一個try塊中,以防二值轉換。 – RubberDuck 2014-11-05 03:57:28

+0

注意:在給它更多思想之後,我會保持類型安全的'AssertClass'方法。更簡單得多,沒有副作用,也沒有邊緣情況。考慮一下'AreEqual 300,CByte(30)'和'AreEqual CByte(30),300'--其中一個會爆炸,其他的通過。而且我甚至沒有提及轉換布爾值會發生什麼。 – 2014-11-05 11:34:04