Try   HackMD

Convert.ToInt32 / int32.Parse / int32.TryParse 該怎麼用?

tags: ASP.NET C#

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
資料來源放哪裡?

,真是麻煩的規則,各國幣別小數位都不相同,要怎麼設定這些資料阿?
這個不難阿,不就把規則寫好存放著就好了,至於放哪 你想怎麼做?
我是想寫類似Util的工具,包成一包帶著走,只是這樣到底搞不好維護呢
不如 放在資料庫當作做config檔設定如何?如此一來就不用進程式裡調整維護
好像是這樣,不用去看程式碼即使接手也很好維護,決定了!就用這種做法了!

上述的小故事經常發生在工程師coding過程,像是這種固定且有規範的東西

建議是集中放在某處管理,至於要放在哪?

  1. 放在DB端設定畫面供使用者直接修改?
  2. 存放在config檔讓資訊部門的人修改呢?
  3. 放在程式碼裡一直頻繁調整?

其實每種方法都可達成目的,只是後續的維護成本看誰比較低、比較方便而已

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
接下來將針對資料轉換過程,上述部分就請大家好好思考下,最後再跟大家討論各利弊問題


Ⅰ. Convert.ToInt32 V.S. Int32.Parse

兩者都是針對非Int型別做轉換的動作,以下為測試案例及結果

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

  • 測試代碼
public void numberParse (){
    var numberStrValue = "88";
    string numberStrNull = null;
    
    Console.WriteLine(Convert.ToInt32(numberStrValue));
    Console.WriteLine(Convert.ToInt32(numberStrNull));
    Console.WriteLine(Int32.Parse(numberStrValue));
    Console.WriteLine(Int32.Parse(numberStrNull));
}
  • 測試結果

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

上述兩者發現,當參數型別為null值時,Convert與Int轉換工具各有不同的產出







%0


cluster_a



cluster_b




pp1

88



a

Convert.ToInt32



pp1->a





b

Int.Parse



pp1->b





pp2

null



a1

Convert.ToInt32



pp2->a1





b2

Int.Parse



pp2->b2





pp1a

88



a->pp1a





pp1b

88



b->pp1b





pp2a1

0



a1->pp2a1





pp2b2

ArgumentNullException



b2->pp2b2





返回頭查詢了下兩邊各自的原始碼,發現了一些事情

  • Convert.ToInt32 原始碼
public static int ToInt32(string value)
{
    if (value == null)
    {
        return 0;
    }

    return int.Parse(value, CultureInfo.CurrentCulture);
}
  • Int32.Parse 原始碼
public static int Parse(string s)
{
    return Number.ParseInt32(s, NumberStyles.Integer, NumberFormatInfo.CurrentInfo);
}
  • Number.ParseInt32 原始碼
internal unsafe static Int32 ParseInt32(String s, NumberStyles style, NumberFormatInfo info) {

    Byte * numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
    NumberBuffer number = new NumberBuffer(numberBufferBytes);
    Int32 i = 0;

    StringToNumber(s, style, ref number, info, false);

    if ((style & NumberStyles.AllowHexSpecifier) != 0) {
        if (!HexNumberToInt32(ref number, ref i)) { 
            throw new OverflowException(Environment.GetResourceString("Overflow_Int32"));
        }
    }
    else {
        if (!NumberToInt32(ref number, ref i)) {
            throw new OverflowException(Environment.GetResourceString("Overflow_Int32"));
        }
    }
    return i;           
}

Convert.ToInt32 和 Int.Parse 差別只有在參數為null時
前者會判斷null值,而後者是產生Exception,其兩者基本上做的事情並無差多少

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
基本上兩者都使用同個function產出,差別在是否判斷null值


Ⅱ. Int32.Parse V.S. Int32.TryParse

以下為測試案例代碼的建構

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

  • 測試代碼
public void tryParseTest(){
	var numberStrFail = "8923ava";

	Console.WriteLine(Int32.TryParse(numberStrFail, out var result));
	Console.WriteLine(result);
	Console.WriteLine(result.GetType());
	Console.WriteLine(numberStrFail.GetType());

	Console.WriteLine();

	var numberStrSucces = "8999";
	Console.WriteLine(Int32.TryParse(numberStrSucces, out var resultOut));
	Console.WriteLine(resultOut);
	Console.WriteLine(resultOut.GetType());
	Console.WriteLine(numberStrSucces.GetType());
}
  • 測試結果

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

從上述結果圖可以看的出來,當String型別資料不可轉換成Int型別時

TryParse function會回傳False,並且會output一個參數型別為Int32,值為0

我們在近一步回頭去看TryParse的程式碼

internal unsafe static Boolean TryParseInt32(String s, NumberStyles style, NumberFormatInfo info, out Int32 result) {

    Byte * numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
    NumberBuffer number = new NumberBuffer(numberBufferBytes);
    result = 0;

    if (!TryStringToNumber(s, style, ref number, info, false)) {
        return false;
    }

    if ((style & NumberStyles.AllowHexSpecifier) != 0) {
        if (!HexNumberToInt32(ref number, ref result)) { 
            return false;
        }
    }
    else {
        if (!NumberToInt32(ref number, ref result)) {
            return false;
        }
    }
    return true;           
}

將其與Parse32比較後可以發現,差別分別為

  • StringToNumber / TryStringToNumber
  • HexNumerToInt32
  • NumberToInt32

以上function作動方式與原Parse32 function無差別,只是後續的function回傳資料有不一樣

  • Parse回傳Exception
  • TryParse回傳Boolean資料

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
結論

現在要來說說個人對於資料存放在哪比較妥當,從開頭的故事可以分成三個面向

  • DataBase : 開表格存放,並聯動前端畫面供使用者自行調整
  • Config檔 : 設定存放,透過更改後並再載入系統中
  • Constant陣列物件 : HardCode在程式碼裡並透過前端呼叫取得
優點 缺點
DataBase 只需要更動DB資料即可改變畫面
使用者可自行設定
開發時測試相較長
但若熟悉可以壓縮開發時間
Config 統一管理在properties檔案內
不必重新閱讀程式碼即可快速維護
當properties檔一旦變多不好管理
變更後須重新啟動伺服器
Constant Array 開發速度最快最方便
開發時期更改方便
日後維護需重新閱讀程式碼
後續須有人力了解當時開發方式

時程真得很緊湊,個人傾向第二種 遠大於 第三種

時間充裕DB有類似的資料儲存區域,第一種的靈活性 遠大於 其他兩種

第三種方案只有可能發生在接小型案子時程只有1-2個禮拜開發,又或者想要多要維護金額

不然沒有工程師想要害自己,結案後還要回來一直看程式碼

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →


Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
連結