奇妙的.NET程式庫版本參考錯誤
| | | 0 | |
遇到奇妙的.NET程式庫版本參考錯誤。
試用以下專案重現問題,主專案RefIssue參照類別程式庫Blah專案:

Blah專案有一個TextId列舉,一個TextRes類別,提供靜態方法將TextId列舉轉換成字串。
namespace Blah { public enum TextId
{ TextPattern,
MsgDismatch,
MsgAbout
}
public class TextRes
{ public static string GetText(TextId id)
{ switch (id) { case TextId.TextPattern: return "[0-9A-Za-z]{1,6}";
case TextId.MsgDismatch: return "不符要求";
case TextId.MsgAbout: return "別讓黑大不開心";
}
return string.Empty;
}
}
}
RefIssue程式很單純,將字串"abc123"與TextId.TextPattern對應字串"[0-9A-Za-z]{1,6}"進行Reqular Expression比對,若格式不符則輸出TextId.MsgDismatch對應字串,符合時則輸出"OK"。在正常狀況下,應該要看到OK字樣。
using System; using System.Text.RegularExpressions; using Blah; namespace RefIssue { class Program { static void Main(string[] args)
{ string pwd = "abc123";
if (!Regex.IsMatch(pwd, TextRes.GetText(TextId.TextPattern))) { Console.WriteLine(TextRes.GetText(TextId.MsgDismatch));
}
else { Console.WriteLine("OK"); }
Console.Read();
}
}
}
下一步來玩點小把戲:將整個bin/Debug的檔案複製到Test資料夾,接著修改TextId列舉,在最前方增加一個新項目NewValue:
namespace Blah { public enum TextId
{ NewValue, //在最前方插入資料 TextPattern,
MsgDismatch,
MsgAbout
}
public class TextRes
{ public static string GetText(TextId id)
{ switch (id) { case TextId.NewValue: return "新資料";
case TextId.TextPattern: return "[0-9A-Za-z]{1,6}";
case TextId.MsgDismatch: return "不符要求";
case TextId.MsgAbout: return "別讓黑大不開心";
}
return string.Empty;
}
}
}
重新編譯後,測試結果仍顯示OK,很合理。有趣的部分來了:將重新編譯的RefIssue.exe複製到Test資料夾覆寫舊檔,但Blah.dll不要更新,執行Test下的RefIssue.exe,猜猜會有什麼結果?

好笑吧? 程式顯示一段莫名其妙的訊息。
問題出在列舉編譯後會儲存成數值,當變更TextId列舉在前方插入新值,會使原本的第0個項目變成第1個,第1個變成第2個。重新編譯RefIssue.exe,TextId.TextPattern將等於1,TextId.MsgDismatch會存成2,此時配上舊版Blah.dll,TextId.TextPattern(1)被轉換成"不符要求",TextId.MsgDimatch(2)被轉換成"別讓黑大不開心",下場便是Regex比對失敗,傳回錯亂訊息。
原因不難理解,但第一次「遇到漏更新程式庫,系統沒當掉或產生Exception,而是跑出莫名其妙的結果」。很新鮮,筆記留念。
Comments
Be the first to post a comment