什么是FormatException
參數格式無效或復合格式字符串不正確時引發的異常。
- 繼承
-
ObjectExceptionSystemExceptionFormatException
詳細說明
由於以下原因之一, 可能會引發異常:FormatException
-
在對將字符串轉換為其他數據類型的方法的調用中, 該字符串不符合所需模式。 這通常發生在調用Convert類的某些方法和某些類型的
ParseExact
Parse
和方法時。在大多數情況下, 特別是當要轉換的字符串是用戶輸入或從文件中讀取時, 應使用
try/catch
塊並FormatException處理異常 (如果轉換不成功)。 你還可以將對轉換方法的調用替換為對TryParse
或TryParseExact
方法的調用 (如果存在)。 但是, FormatException當你嘗試分析預定義或硬編碼字符串時引發的異常指示程序錯誤。 在這種情況下, 應更正此錯誤, 而不是處理異常。將字符串轉換為System命名空間中的以下類型可能會FormatException引發異常:
-
-
Boolean。 Boolean.Parse(String) 和Convert.ToBoolean(String)方法要求將字符串轉換為 "true"、"true"、"false" 或 "false"。 任何其他值都將FormatException引發異常。
-
DateTime 和 DateTimeOffset。 所有日期和時間數據都基於特定區域性的格式設置約定: 當前線程區域性 (或在某些情況下為當前應用程序域區域性)、固定區域性或指定的區域性。 在調用DateTime.ParseExact(String, String, IFormatProvider, DateTimeStyles) DateTimeOffset.ParseExact(String, String[], IFormatProvider, DateTimeStyles)和方法時, 日期和時間數據還必須完全符合由一個或多個標准格式字符串或自定義格式字符串(作為中的參數提供) 指定的模式方法調用。 如果它不符合預期的區域性特定模式, FormatException則會引發異常。 這意味着, 在一個系統上保存為特定於區域性的格式的日期和時間數據可能無法在其他系統上成功分析。
有關分析日期和時間的詳細信息, 請參閱分析日期和時間字符串和引發異常的方法的文檔。
-
Guid. GUID 的字符串表示形式必須包含32個十六進制數字 (0-F), 並且必須是由Guid.ToString方法輸出的五種格式中的一種。 有關更多信息,請參見 Guid.Parse 方法。
-
數值類型, 包括所有有符號整數、無符號整數和浮點類型。 要分析的字符串必須包含拉丁語位數0-9。 還可以允許使用正號或負號、小數點分隔符、組分隔符和貨幣符號。 嘗試分析包含任何其他字符的字符串始終會引發FormatException異常。
所有數字字符串都基於特定區域性的格式設置約定: 當前線程區域性 (或在某些情況下為當前應用程序域區域性)、固定區域性或指定的區域性。 因此, 使用另一種區域性的約定分析的數值字符串可能會失敗。
有關分析數值字符串的詳細信息, 請參閱分析數值字符串和引發異常的特定方法的文檔。
-
時間間隔。 要分析的字符串必須是采用不區分區域性的格式或由當前線程區域性定義的區分區域性的格式 (在某些情況下為當前應用程序域區域性)、固定區域性或指定的區域性。 如果字符串的格式不正確, 或者如果時間間隔的最小值、天數、小時數和分鍾數部分不存在, 分析方法將引發FormatException異常。 有關詳細信息, 請參閱引發異常的TimeSpan分析方法的文檔。
-
-
-
類型實現IFormattable接口, 該接口支持定義如何將對象轉換為其字符串表示形式, 並使用無效格式字符串的格式字符串。 這在格式設置操作中最常見。 在下面的示例中, 在復合格式字符串中使用 "Q" 標准格式字符串來設置數值的格式。 但是, "Q" 不是有效的標准格式字符串。
using System; public class Example { public static void Main() { decimal price = 169.32m; Console.WriteLine("The cost is {0:Q2}.", price); } } // The example displays the following output: // Unhandled Exception: System.FormatException: Format specifier was invalid. // at System.Number.FormatDecimal(Decimal value, String format, NumberFormatInfo info) // at System.Decimal.ToString(String format, IFormatProvider provider) // at System.Text.StringBuilder.AppendFormat(IFormatProvider provider, String format, Object[] args) // at System.IO.TextWriter.WriteLine(String format, Object arg0) // at System.IO.TextWriter.SyncTextWriter.WriteLine(String format, Object arg0) // at Example.Main()
此異常是由編碼錯誤引起的。 若要更正此錯誤, 請刪除格式字符串或替換有效的字符串。 下面的示例通過使用 "C" (貨幣) 格式字符串替換無效的格式字符串來糾正錯誤。
using System; public class Example { public static void Main() { decimal price = 169.32m; Console.WriteLine("The cost is {0:C2}.", price); } } // The example displays the following output: // The cost is $169.32.
還可以通過分析方法 ( DateTime.ParseExact如和Guid.ParseExact) 引發異常,這需要對字符串進行分析,使其符合格式字符串指定的模式。FormatException 在下面的示例中, GUID 的字符串表示形式應符合 "G" 標准格式字符串指定的模式。 但是, Guid結構的IFormattable實現不支持 "G" 格式字符串。
using System; public class Example { public static void Main() { string guidString = "ba748d5c-ae5f-4cca-84e5-1ac5291c38cb"; Console.WriteLine(Guid.ParseExact(guidString, "G")); } } // The example displays the following output: // Unhandled Exception: System.FormatException: // Format String can be only "D", "d", "N", "n", "P", "p", "B", "b", "X" or "x". // at System.Guid.ParseExact(String input, String format) // at Example.Main()
此異常也是由於編碼錯誤引起的。 若要更正此錯誤, 請調用不需要精確格式的分析方法 (如DateTime.Parse或Guid.Parse) 或替換有效的格式字符串。 下面的示例通過調用Guid.Parse方法來更正錯誤。
using System; public class Example { public static void Main() { string guidString = "ba748d5c-ae5f-4cca-84e5-1ac5291c38cb"; Console.WriteLine(Guid.Parse(guidString)); } } // The example displays the following output: // ba748d5c-ae5f-4cca-84e5-1ac5291c38cb
-
復合格式字符串中的格式項的一個或多個索引大於對象列表或參數數組中項的索引。 在下面的示例中, 格式字符串中的格式項的最大索引為3。 由於對象列表中項的索引是從零開始的, 因此此格式字符串要求對象列表具有四項。 相反, 它只有三個、
dat
temp
、和scale
, 因此, 代碼會在運行時FormatException導致異常:。using System; public class Example { public enum TemperatureScale { Celsius, Fahrenheit, Kelvin } public static void Main() { String info = GetCurrentTemperature(); Console.WriteLine(info); } private static String GetCurrentTemperature() { DateTime dat = DateTime.Now; Decimal temp = 20.6m; TemperatureScale scale = TemperatureScale.Celsius; String result; result = String.Format("At {0:t} on {1:D}, the temperature is {2:F1} {3:G}", dat, temp, scale); return result; } } // The example displays output like the following: // Unhandled Exception: System.FormatException: Format specifier was invalid. // at System.Number.FormatDecimal(Decimal value, String format, NumberFormatInfo info) // at System.Decimal.ToString(String format, IFormatProvider provider) // at System.Text.StringBuilder.AppendFormat(IFormatProvider provider, String format, Object[] args) // at System.String.Format(IFormatProvider provider, String format, Object[] args) // at Example.Main()
在這種情況下FormatException , 異常是由開發人員錯誤引起的。 應更正此情況, 而不是通過
try/catch
確保對象列表中的每個項對應於格式項的索引, 而不是在塊中進行處理。 若要更正此示例, 請將第二個格式項的索引改為dat
引用變量, 並將每個后續格式項的索引減一。using System; public class Example { public enum TemperatureScale { Celsius, Fahrenheit, Kelvin } public static void Main() { String info = GetCurrentTemperature(); Console.WriteLine(info); } private static String GetCurrentTemperature() { DateTime dat = DateTime.Now; Decimal temp = 20.6m; TemperatureScale scale = TemperatureScale.Celsius; String result; result = String.Format("At {0:t} on {0:D}, the temperature is {1:F1} {2:G}", dat, temp, scale); return result; } } // The example displays output like the following: // At 10:40 AM on Wednesday, June 04, 2014, the temperature is 20.6 Celsius
-
復合格式字符串的格式不正確。 發生這種情況時FormatException , 異常始終是由開發人員錯誤引起的。 應更正此情況, 而不是在
try/catch
塊中進行處理。如以下示例中所示, 嘗試在字符串中包含文本大括號會引發異常。
result = String.Format("The text has {0} '{' characters and {1} '}' characters.", nOpen, nClose);
string result; int nOpen = 1; int nClose = 2; result = String.Format("The text has {0} '{{' characters and {1} '}}' characters.", nOpen, nClose); Console.WriteLine(result);
int n1 = 10; int n2 = 20; String result = String.Format("{0 + {1] = {2}", n1, n2, n1 + n2);
若要更正此錯誤, 請確保所有左大括號和右大括號對應。
String result = String.Format("{0} + {1} = {2}", n1, n2, n1 + n2);
-
已提供復合格式設置方法中的對象列表作為強類型參數數組, 但該FormatException異常表示一個或多個格式項的索引超過對象列表中的參數數量。 出現這種情況的原因是, 數組類型之間沒有顯式轉換, 因此編譯器會將該數組視為單個參數, 而不是作為參數數組。 例如, 以下對Console.WriteLine(String, Object[])方法的調用將FormatException引發異常, 盡管格式項的最高索引為 3, 而類型Int32的參數數組具有四個元素。
using System; using System.Collections.Generic; public class Example { public static void Main() { Random rnd = new Random(); int[] numbers = new int[4]; int total = 0; for (int ctr = 0; ctr <= 2; ctr++) { int number = rnd.Next(1001); numbers[ctr] = number; total += number; } numbers[3] = total; Console.WriteLine("{0} + {1} + {2} = {3}", numbers); } } // The example displays the following output: // Unhandled Exception: // System.FormatException: // Index (zero based) must be greater than or equal to zero and less than the size of the argument list. // at System.Text.StringBuilder.AppendFormat(IFormatProvider provider, String format, Object[] args) // at System.IO.TextWriter.WriteLine(String format, Object arg0) // at System.IO.TextWriter.SyncTextWriter.WriteLine(String format, Object arg0) // at Example.Main()
應該消除其原因, 而不是處理此異常。 因為既不 Visual Basic C#也不能將整數數組轉換為對象數組, 所以必須在調用復合格式設置方法之前自行執行轉換。 下面的示例提供了一個實現。
using System; using System.Collections.Generic; public class Example { public static void Main() { Random rnd = new Random(); int[] numbers = new int[4]; int total = 0; for (int ctr = 0; ctr <= 2; ctr++) { int number = rnd.Next(1001); numbers[ctr] = number; total += number; } numbers[3] = total; object[] values = new object[numbers.Length]; numbers.CopyTo(values, 0); Console.WriteLine("{0} + {1} + {2} = {3}", values); } } // The example displays output like the following: // 477 + 956 + 901 = 2334
HRESULT
FormatException使用 COR_E_FORMAT 值為0x80131537 的 HRESULT。