如果我運行此C#代碼爲什麼Int32.TryParse在無法轉換時重置out參數?
int realInt = 3;
string foo = "bar";
Int32.TryParse(foo, out realInt);
Console.WriteLine(realInt);
Console.Read();
我得到0。而且我想知道爲什麼!因爲我找不到任何原因。這迫使我爲每個解析創建臨時變量。所以,請!偉大的宇宙編碼者,賜教!
如果我運行此C#代碼爲什麼Int32.TryParse在無法轉換時重置out參數?
int realInt = 3;
string foo = "bar";
Int32.TryParse(foo, out realInt);
Console.WriteLine(realInt);
Console.Read();
我得到0。而且我想知道爲什麼!因爲我找不到任何原因。這迫使我爲每個解析創建臨時變量。所以,請!偉大的宇宙編碼者,賜教!
它是「out」,而不是「ref」。在該方法內部,具有來分配它(不先讀取它)以滿足「out」的含義。
實際上,「out」是一個語言問題(不是框架之一) - 所以託管的C++實現可能會忽略這個......但是它更符合它的要求。
實際上,如果該方法返回false,則不應該查看該值;將其視爲垃圾直到下一次分配。它聲明返回0,但這是很少有用的。
此外 - 如果它沒有這樣做(即如果它保存了值);這個打印:
int i;
int.TryParse("gibber", out i);
Console.WriteLine(i);
這是完全有效的C#...所以它打印什麼?
*爲什麼*它是這樣的解釋,以便您可以斷言在TryParse調用後的任何代碼中變量* always *都已設置,即使變量在代碼的前面沒有初始化(所以編譯器在`TryParse`調用之後使用該變量時不會引發錯誤;嘗試對使用`ref`關鍵字的函數執行相同操作。) – Blixt 2009-07-17 08:16:42
The Int32.TryParse Method (String, Int32) doc說:
一個數字的字符串表示形式轉換爲它的32位帶符號整數等效。返回值指示轉換是否成功。
結果
類型:System.Int32
此方法返回時,包含32位帶符號整數的值等效於包含在S中的號碼,如果轉換成功,或者零,如果轉換失敗。如果s參數爲空引用(在Visual Basic中爲Nothing),格式不正確,或者表示小於MinValue或大於MaxValue的數字,則轉換將失敗。此參數未經初始化傳遞。
@Luke - look以粗體顯示... – 2009-07-17 08:08:02
因爲(至少在C#中)帶有一個或多個輸出參數的方法必須保證它們回寫給它們。這樣,在將方法作爲參數傳遞給方法之前,您不需要在方法中初始化本地字段。
我的猜測是,這是在C#規範的一部分:
10.5.1.3輸出參數 ... 在方法內部,就像一個局部變量,輸出參數最初考慮>未分配必須在使用其值之前明確分配。
在方法返回之前,方法的每個輸出參數都必須明確賦值。
如果是這種情況,您不應該依賴結果值。
由於TryParse
的第二個參數是out
參數,因此TryParse
方法被強制初始化參數。如果參數是ref
而不是out
,您將得到您想要的行爲。但是,由於TryParse
方法只需要輸出一個數字,並且不會獲得任何數字,因此輸入out
是參數的正確選擇。
因爲這是'out'合同的工作方式。每當你將一個out
參數傳遞給一個函數時,它的函數的責任就是初始化它。
爲Int32.TryParse MSDN文檔指出,如果轉換失敗,結果將始終返回0
你通常應該要麼使用一個臨時結果變量即
int value;
bool succeeded = Int32.TryParse("astring", out value);
if (succeeded)
{
// use value in some way
}
,或者你只是包裹在if語句中完整的方法
int value;
if (Int32.TryParse("astring", out value))
{
// use value in some way
}
我個人認爲後者是更好的選擇。
由於該參數是一個輸出參數,所以當您聲明它時,您不必初始化realInt,因爲編譯器可以看到您將它傳遞給一個保證將其設置爲某事的方法(因爲的「出」)。
現在,因爲它是一個輸出參數,所以需要TryParse將其設置爲某個值。它將它設置爲0,因爲這是C#中大多數情況下int的默認值。
你可以寫爲:
int realInt;
string foo="bar";
if(int.TryParse(foo,out realInt)==false)
{
realInt=3;
}
public static class IntHelper
{
public static bool TryParse(string s, ref int outValue)
{
int newValue;
bool ret = int.TryParse(s, out newValue);
if (ret) outValue = newValue;
return ret;
}
}
我格式化代碼爲您服務。下一次,如果您不確定如何在MarkDown編輯器中設置格式,請使用文本區域上方的小工具欄。有一個代碼格式化選項。 – OregonGhost 2009-07-17 08:31:40
感謝您的幫助=) – 2009-07-17 08:49:00