遇到奇妙的.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

Post a comment