The Labs \ Source Viewer \ SSCLI \ System.Globalization \ NumberFormatInfo

  1. // ==++==
  2. //
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. //
  14. // ==--==
  15. namespace System.Globalization
  16. {
  17.     using System.Security.Permissions;
  18.     using System.Runtime.Serialization;
  19.     using System.Text;
  20.     using System;
  21.     //
  22.     // Property Default Description
  23.     // PositiveSign '+' Character used to indicate positive values.
  24.     // NegativeSign '-' Character used to indicate negative values.
  25.     // NumberDecimalSeparator '.' The character used as the decimal separator.
  26.     // NumberGroupSeparator ',' The character used to separate groups of
  27.     // digits to the left of the decimal point.
  28.     // NumberDecimalDigits 2 The default number of decimal places.
  29.     // NumberGroupSizes 3 The number of digits in each group to the
  30.     // left of the decimal point.
  31.     // NaNSymbol "NaN" The string used to represent NaN values.
  32.     // PositiveInfinitySymbol"Infinity" The string used to represent positive
  33.     // infinities.
  34.     // NegativeInfinitySymbol"-Infinity" The string used to represent negative
  35.     // infinities.
  36.     //
  37.     //
  38.     //
  39.     // Property Default Description
  40.     // CurrencyDecimalSeparator '.' The character used as the decimal
  41.     // separator.
  42.     // CurrencyGroupSeparator ',' The character used to separate groups
  43.     // of digits to the left of the decimal
  44.     // point.
  45.     // CurrencyDecimalDigits 2 The default number of decimal places.
  46.     // CurrencyGroupSizes 3 The number of digits in each group to
  47.     // the left of the decimal point.
  48.     // CurrencyPositivePattern 0 The format of positive values.
  49.     // CurrencyNegativePattern 0 The format of negative values.
  50.     // CurrencySymbol "$" String used as local monetary symbol.
  51.     //
  52.    
  53.     [Serializable()]
  54.     [System.Runtime.InteropServices.ComVisible(true)]
  55.     public sealed class NumberFormatInfo : ICloneable, IFormatProvider
  56.     {
  57.         // invariantInfo is constant irrespective of your current culture.
  58.         private static NumberFormatInfo invariantInfo;
  59.        
  60.         // READTHIS READTHIS READTHIS
  61.         // This class has an exact mapping onto a native structure defined in COMNumber.cpp
  62.         // DO NOT UPDATE THIS WITHOUT UPDATING THAT STRUCTURE. IF YOU ADD BOOL, ADD THEM AT THE END.
  63.         // ALSO MAKE SURE TO UPDATE mscorlib.h in the VM directory to check field offsets.
  64.         // READTHIS READTHIS READTHIS
  65.         internal int[] numberGroupSizes = new int[] {3};
  66.         internal int[] currencyGroupSizes = new int[] {3};
  67.         internal int[] percentGroupSizes = new int[] {3};
  68.         internal string positiveSign = "+";
  69.         internal string negativeSign = "-";
  70.         internal string numberDecimalSeparator = ".";
  71.         internal string numberGroupSeparator = ",";
  72.         internal string currencyGroupSeparator = ",";
  73.         internal string currencyDecimalSeparator = ".";
  74.         internal string currencySymbol = "¤";
  75.         // U+00a4 is the symbol for International Monetary Fund.
  76.         // The alternative currency symbol used in Win9x ANSI codepage, that can not roundtrip between ANSI and Unicode.
  77.         // Currently, only ja-JP and ko-KR has non-null values (which is U+005c, backslash)
  78.         internal string ansiCurrencySymbol = null;
  79.         internal string nanSymbol = "NaN";
  80.         internal string positiveInfinitySymbol = "Infinity";
  81.         internal string negativeInfinitySymbol = "-Infinity";
  82.         internal string percentDecimalSeparator = ".";
  83.         internal string percentGroupSeparator = ",";
  84.         internal string percentSymbol = "%";
  85.         internal string perMilleSymbol = "‰";
  86.        
  87.         [OptionalField(VersionAdded = 2)]
  88.         internal string[] nativeDigits = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"
  89.         };
  90.        
  91.         // an index which points to a record in Culture Data Table.
  92.         // We shouldn't be persisting dataItem (since its useless & we weren't using it),
  93.         // but since COMNumber.cpp uses it and since serialization isn't implimented, its stuck for now.
  94.         internal int m_dataItem = 0;
  95.        
  96.         internal int numberDecimalDigits = 2;
  97.         internal int currencyDecimalDigits = 2;
  98.         internal int currencyPositivePattern = 0;
  99.         internal int currencyNegativePattern = 0;
  100.         internal int numberNegativePattern = 1;
  101.         internal int percentPositivePattern = 0;
  102.         internal int percentNegativePattern = 0;
  103.         internal int percentDecimalDigits = 2;
  104.        
  105.         [OptionalField(VersionAdded = 2)]
  106.         internal int digitSubstitution = 1;
  107.         // DigitShapes.None
  108.         internal bool isReadOnly = false;
  109.         // We shouldn't be persisting m_useUserOverride (since its useless & we weren't using it),
  110.         // but since COMNumber.cpp uses it and since serialization isn't implimented, its stuck for now.
  111.         internal bool m_useUserOverride = false;
  112.        
  113.         public NumberFormatInfo() : this(null)
  114.         {
  115.         }
  116.        
  117.         #region Serialization
  118.         internal bool validForParseAsNumber = true;
  119.         internal bool validForParseAsCurrency = true;
  120.        
  121.         [OnSerializing()]
  122.         private void OnSerializing(StreamingContext ctx)
  123.         {
  124.             if (numberDecimalSeparator != numberGroupSeparator) {
  125.                 validForParseAsNumber = true;
  126.             }
  127.             else {
  128.                 validForParseAsNumber = false;
  129.             }
  130.            
  131.             if ((numberDecimalSeparator != numberGroupSeparator) && (numberDecimalSeparator != currencyGroupSeparator) && (currencyDecimalSeparator != numberGroupSeparator) && (currencyDecimalSeparator != currencyGroupSeparator)) {
  132.                 validForParseAsCurrency = true;
  133.             }
  134.             else {
  135.                 validForParseAsCurrency = false;
  136.             }
  137.         }
  138.        
  139.        
  140.         [OnDeserializing()]
  141.         private void OnDeserializing(StreamingContext ctx)
  142.         {
  143.             nativeDigits = null;
  144.             digitSubstitution = -1;
  145.         }
  146.        
  147.         [OnDeserialized()]
  148.         private void OnDeserialized(StreamingContext ctx)
  149.         {
  150.             if (nativeDigits == null) {
  151.                 nativeDigits = new string[] {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"
  152.                 };
  153.             }
  154.            
  155.             if (digitSubstitution < 0) {
  156.                 digitSubstitution = 1;
  157.             }
  158.         }
  159.        
  160.         #endregion Serialization
  161.        
  162.         private void VerifyDecimalSeparator(string decSep, string propertyName)
  163.         {
  164.             if (decSep == null) {
  165.                 throw new ArgumentNullException(propertyName, Environment.GetResourceString("ArgumentNull_String"));
  166.             }
  167.            
  168.             if (decSep.Length == 0) {
  169.                 throw new ArgumentException(Environment.GetResourceString("Argument_EmptyDecString"));
  170.             }
  171.            
  172.         }
  173.        
  174.         private void VerifyGroupSeparator(string groupSep, string propertyName)
  175.         {
  176.             if (groupSep == null) {
  177.                 throw new ArgumentNullException(propertyName, Environment.GetResourceString("ArgumentNull_String"));
  178.             }
  179.         }
  180.        
  181.         private void VerifyNativeDigits(string[] nativeDig, string propertyName)
  182.         {
  183.             if (nativeDig == null) {
  184.                 throw new ArgumentNullException(propertyName, Environment.GetResourceString("ArgumentNull_Array"));
  185.             }
  186.            
  187.             if (nativeDig.Length != 10) {
  188.                 throw new ArgumentException(propertyName, Environment.GetResourceString("Argument_InvalidNativeDigitCount"));
  189.             }
  190.            
  191.             for (int i = 0; i < nativeDig.Length; i++) {
  192.                 if (nativeDig[i] == null) {
  193.                     throw new ArgumentNullException(propertyName, Environment.GetResourceString("ArgumentNull_ArrayValue"));
  194.                 }
  195.                
  196.                
  197.                 if (nativeDig[i].Length != 1) {
  198.                     if (nativeDig[i].Length != 2) {
  199.                         // Not 1 or 2 UTF-16 code points
  200.                         throw new ArgumentException(propertyName, Environment.GetResourceString("Argument_InvalidNativeDigitValue"));
  201.                     }
  202.                     else if (!char.IsSurrogatePair(nativeDig[i][0], nativeDig[i][1])) {
  203.                         // 2 UTF-6 code points, but not a surrogate pair
  204.                         throw new ArgumentException(propertyName, Environment.GetResourceString("Argument_InvalidNativeDigitValue"));
  205.                     }
  206.                 }
  207.                
  208.                 if (CharUnicodeInfo.GetDecimalDigitValue(nativeDig[i], 0) != i) {
  209.                     // Not the appropriate digit according to the Unicode data properties
  210.                     // (Digit 0 must be a 0, etc.).
  211.                     throw new ArgumentException(propertyName, Environment.GetResourceString("Argument_InvalidNativeDigitValue"));
  212.                 }
  213.             }
  214.         }
  215.        
  216.         private void VerifyDigitSubstitution(DigitShapes digitSub, string propertyName)
  217.         {
  218.             switch (digitSub) {
  219.                 case DigitShapes.Context:
  220.                 case DigitShapes.None:
  221.                 case DigitShapes.NativeNational:
  222.                     // Success.
  223.                     break;
  224.                 default:
  225.                    
  226.                     throw new ArgumentException(propertyName, Environment.GetResourceString("Argument_InvalidDigitSubstitution"));
  227.                     break;
  228.             }
  229.         }
  230.        
  231.        
  232.         // We aren't persisting dataItem any more (since its useless & we weren't using it),
  233.         // Ditto with m_useUserOverride. Don't use them, we use a local copy of everything.
  234.         internal NumberFormatInfo(CultureTableRecord cultureTableRecord)
  235.         {
  236.             if (cultureTableRecord != null) {
  237.                 /*
  238.                 We don't have information for the following four.  All cultures use
  239.                 the same value set in the ctor of NumberFormatInfo.
  240.                 PercentGroupSize
  241.                 PercentDecimalDigits
  242.                 PercentGroupSeparator
  243.                 PerMilleSymbol
  244.                 */               
  245.                
  246.                 // We directly use fields here since these data is coming from data table or Win32, so we
  247.                 // don't need to verify their values (except for invalid parsing situations).
  248.                
  249. cultureTableRecord.GetNFIOverrideValues(this);
  250.                
  251.                 if ((932 == cultureTableRecord.IDEFAULTANSICODEPAGE) || (949 == cultureTableRecord.IDEFAULTANSICODEPAGE)) {
  252.                     // Legacy behavior for cultures that use Japaanese/Korean default ANSI code pages
  253.                     this.ansiCurrencySymbol = "\\";
  254.                 }
  255.                 this.negativeInfinitySymbol = cultureTableRecord.SNEGINFINITY;
  256.                 this.positiveInfinitySymbol = cultureTableRecord.SPOSINFINITY;
  257.                 this.nanSymbol = cultureTableRecord.SNAN;
  258.             }
  259.         }
  260.        
  261.         private void VerifyWritable()
  262.         {
  263.             if (isReadOnly) {
  264.                 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
  265.             }
  266.         }
  267.        
  268.         // Returns a default NumberFormatInfo that will be universally
  269.         // supported and constant irrespective of the current culture.
  270.         // Used by FromString methods.
  271.         //
  272.        
  273.         public static NumberFormatInfo InvariantInfo {
  274.             get {
  275.                 if (invariantInfo == null) {
  276.                     // Lazy create the invariant info. This cannot be done in a .cctor because exceptions can
  277.                     // be thrown out of a .cctor stack that will need this.
  278.                     invariantInfo = ReadOnly(new NumberFormatInfo());
  279.                 }
  280.                 return invariantInfo;
  281.             }
  282.         }
  283.        
  284.        
  285.         public static NumberFormatInfo GetInstance(IFormatProvider formatProvider)
  286.         {
  287.             // Fast case for a regular CultureInfo
  288.             NumberFormatInfo info;
  289.             CultureInfo cultureProvider = formatProvider as CultureInfo;
  290.             if (cultureProvider != null && !cultureProvider.m_isInherited) {
  291.                 info = cultureProvider.numInfo;
  292.                 if (info != null) {
  293.                     return info;
  294.                 }
  295.                 else {
  296.                     return cultureProvider.NumberFormat;
  297.                 }
  298.             }
  299.             // Fast case for an NFI;
  300.             info = formatProvider as NumberFormatInfo;
  301.             if (info != null) {
  302.                 return info;
  303.             }
  304.             if (formatProvider != null) {
  305.                 info = formatProvider.GetFormat(typeof(NumberFormatInfo)) as NumberFormatInfo;
  306.                 if (info != null) {
  307.                     return info;
  308.                 }
  309.             }
  310.             return CurrentInfo;
  311.         }
  312.        
  313.        
  314.        
  315.         public object Clone()
  316.         {
  317.             NumberFormatInfo n = (NumberFormatInfo)MemberwiseClone();
  318.             n.isReadOnly = false;
  319.             return n;
  320.         }
  321.        
  322.        
  323.         public int CurrencyDecimalDigits {
  324.             get { return currencyDecimalDigits; }
  325.             set {
  326.                 VerifyWritable();
  327.                 if (value < 0 || value > 99) {
  328.                     throw new ArgumentOutOfRangeException("CurrencyDecimalDigits", String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("ArgumentOutOfRange_Range"), 0, 99));
  329.                 }
  330.                 currencyDecimalDigits = value;
  331.             }
  332.         }
  333.        
  334.        
  335.         public string CurrencyDecimalSeparator {
  336.             get { return currencyDecimalSeparator; }
  337.             set {
  338.                 VerifyWritable();
  339.                 VerifyDecimalSeparator(value, "CurrencyDecimalSeparator");
  340.                 currencyDecimalSeparator = value;
  341.             }
  342.         }
  343.        
  344.        
  345.         public bool IsReadOnly {
  346.             get { return isReadOnly; }
  347.         }
  348.        
  349.         //
  350.         // Check the values of the groupSize array.
  351.         //
  352.         // Every element in the groupSize array should be between 1 and 9
  353.         // excpet the last element could be zero.
  354.         //
  355.         internal void CheckGroupSize(string propName, int[] groupSize)
  356.         {
  357.             if (groupSize == null) {
  358.                 throw new ArgumentNullException(propName, Environment.GetResourceString("ArgumentNull_Obj"));
  359.             }
  360.            
  361.             for (int i = 0; i < groupSize.Length; i++) {
  362.                 if (groupSize[i] < 1) {
  363.                     if (i == groupSize.Length - 1 && groupSize[i] == 0)
  364.                         return;
  365.                     throw new ArgumentException(propName, Environment.GetResourceString("Argument_InvalidGroupSize"));
  366.                 }
  367.                 else if (groupSize[i] > 9) {
  368.                     throw new ArgumentException(propName, Environment.GetResourceString("Argument_InvalidGroupSize"));
  369.                 }
  370.             }
  371.         }
  372.        
  373.        
  374.         public int[] CurrencyGroupSizes {
  375.             get { return ((int[])currencyGroupSizes.Clone()); }
  376.             set {
  377.                 VerifyWritable();
  378.                 CheckGroupSize("CurrencyGroupSizes", value);
  379.                 currencyGroupSizes = value;
  380.             }
  381.         }
  382.        
  383.        
  384.        
  385.        
  386.         public int[] NumberGroupSizes {
  387.             get { return ((int[])numberGroupSizes.Clone()); }
  388.             set {
  389.                 VerifyWritable();
  390.                 CheckGroupSize("NumberGroupSizes", value);
  391.                 numberGroupSizes = value;
  392.             }
  393.         }
  394.        
  395.        
  396.         public int[] PercentGroupSizes {
  397.             get { return ((int[])percentGroupSizes.Clone()); }
  398.             set {
  399.                 VerifyWritable();
  400.                 CheckGroupSize("PercentGroupSizes", value);
  401.                 percentGroupSizes = value;
  402.             }
  403.         }
  404.        
  405.        
  406.        
  407.         public string CurrencyGroupSeparator {
  408.             get { return currencyGroupSeparator; }
  409.             set {
  410.                 VerifyWritable();
  411.                 VerifyGroupSeparator(value, "CurrencyGroupSeparator");
  412.                 currencyGroupSeparator = value;
  413.             }
  414.         }
  415.        
  416.        
  417.         public string CurrencySymbol {
  418.             get { return currencySymbol; }
  419.             set {
  420.                 VerifyWritable();
  421.                 if (value == null) {
  422.                     throw new ArgumentNullException("CurrencySymbol", Environment.GetResourceString("ArgumentNull_String"));
  423.                 }
  424.                 currencySymbol = value;
  425.             }
  426.         }
  427.        
  428.         // Returns the current culture's NumberFormatInfo. Used by Parse methods.
  429.         //
  430.        
  431.         public static NumberFormatInfo CurrentInfo {
  432.             get {
  433.                 System.Globalization.CultureInfo culture = System.Threading.Thread.CurrentThread.CurrentCulture;
  434.                 if (!culture.m_isInherited) {
  435.                     NumberFormatInfo info = culture.numInfo;
  436.                     if (info != null) {
  437.                         return info;
  438.                     }
  439.                 }
  440.                 return ((NumberFormatInfo)culture.GetFormat(typeof(NumberFormatInfo)));
  441.             }
  442.         }
  443.        
  444.        
  445.         public string NaNSymbol {
  446.             get { return nanSymbol; }
  447.             set {
  448.                 VerifyWritable();
  449.                 if (value == null) {
  450.                     throw new ArgumentNullException("NaNSymbol", Environment.GetResourceString("ArgumentNull_String"));
  451.                 }
  452.                 nanSymbol = value;
  453.             }
  454.         }
  455.        
  456.        
  457.        
  458.         public int CurrencyNegativePattern {
  459.             get { return currencyNegativePattern; }
  460.             set {
  461.                 VerifyWritable();
  462.                 if (value < 0 || value > 15) {
  463.                     throw new ArgumentOutOfRangeException("CurrencyNegativePattern", String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("ArgumentOutOfRange_Range"), 0, 15));
  464.                 }
  465.                 currencyNegativePattern = value;
  466.             }
  467.         }
  468.        
  469.        
  470.         public int NumberNegativePattern {
  471.             get { return numberNegativePattern; }
  472.             set {
  473.                 VerifyWritable();
  474.                 if (value < 0 || value > 4) {
  475.                     throw new ArgumentOutOfRangeException("NumberNegativePattern", String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("ArgumentOutOfRange_Range"), 0, 4));
  476.                 }
  477.                 numberNegativePattern = value;
  478.             }
  479.         }
  480.        
  481.        
  482.         public int PercentPositivePattern {
  483.             get { return percentPositivePattern; }
  484.             set {
  485.                 VerifyWritable();
  486.                 if (value < 0 || value > 3) {
  487.                     throw new ArgumentOutOfRangeException("PercentPositivePattern", String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("ArgumentOutOfRange_Range"), 0, 3));
  488.                 }
  489.                 percentPositivePattern = value;
  490.             }
  491.         }
  492.        
  493.        
  494.         public int PercentNegativePattern {
  495.             get { return percentNegativePattern; }
  496.             set {
  497.                 VerifyWritable();
  498.                 if (value < 0 || value > 11) {
  499.                     throw new ArgumentOutOfRangeException("PercentNegativePattern", String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("ArgumentOutOfRange_Range"), 0, 11));
  500.                 }
  501.                 percentNegativePattern = value;
  502.             }
  503.         }
  504.        
  505.        
  506.         public string NegativeInfinitySymbol {
  507.             get { return negativeInfinitySymbol; }
  508.             set {
  509.                 VerifyWritable();
  510.                 if (value == null) {
  511.                     throw new ArgumentNullException("NegativeInfinitySymbol", Environment.GetResourceString("ArgumentNull_String"));
  512.                 }
  513.                 negativeInfinitySymbol = value;
  514.             }
  515.         }
  516.        
  517.        
  518.         public string NegativeSign {
  519.             get { return negativeSign; }
  520.             set {
  521.                 VerifyWritable();
  522.                 if (value == null) {
  523.                     throw new ArgumentNullException("NegativeSign", Environment.GetResourceString("ArgumentNull_String"));
  524.                 }
  525.                 negativeSign = value;
  526.             }
  527.         }
  528.        
  529.        
  530.         public int NumberDecimalDigits {
  531.             get { return numberDecimalDigits; }
  532.             set {
  533.                 VerifyWritable();
  534.                 if (value < 0 || value > 99) {
  535.                     throw new ArgumentOutOfRangeException("NumberDecimalDigits", String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("ArgumentOutOfRange_Range"), 0, 99));
  536.                 }
  537.                 numberDecimalDigits = value;
  538.             }
  539.         }
  540.        
  541.        
  542.         public string NumberDecimalSeparator {
  543.             get { return numberDecimalSeparator; }
  544.             set {
  545.                 VerifyWritable();
  546.                 VerifyDecimalSeparator(value, "NumberDecimalSeparator");
  547.                 numberDecimalSeparator = value;
  548.             }
  549.         }
  550.        
  551.        
  552.         public string NumberGroupSeparator {
  553.             get { return numberGroupSeparator; }
  554.             set {
  555.                 VerifyWritable();
  556.                 VerifyGroupSeparator(value, "NumberGroupSeparator");
  557.                 numberGroupSeparator = value;
  558.             }
  559.         }
  560.        
  561.        
  562.         public int CurrencyPositivePattern {
  563.             get { return currencyPositivePattern; }
  564.             set {
  565.                 VerifyWritable();
  566.                 if (value < 0 || value > 3) {
  567.                     throw new ArgumentOutOfRangeException("CurrencyPositivePattern", String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("ArgumentOutOfRange_Range"), 0, 3));
  568.                 }
  569.                 currencyPositivePattern = value;
  570.             }
  571.         }
  572.        
  573.        
  574.         public string PositiveInfinitySymbol {
  575.             get { return positiveInfinitySymbol; }
  576.             set {
  577.                 VerifyWritable();
  578.                 if (value == null) {
  579.                     throw new ArgumentNullException("PositiveInfinitySymbol", Environment.GetResourceString("ArgumentNull_String"));
  580.                 }
  581.                 positiveInfinitySymbol = value;
  582.             }
  583.         }
  584.        
  585.        
  586.         public string PositiveSign {
  587.             get { return positiveSign; }
  588.             set {
  589.                 VerifyWritable();
  590.                 if (value == null) {
  591.                     throw new ArgumentNullException("PositiveSign", Environment.GetResourceString("ArgumentNull_String"));
  592.                 }
  593.                 positiveSign = value;
  594.             }
  595.         }
  596.        
  597.        
  598.         public int PercentDecimalDigits {
  599.             get { return percentDecimalDigits; }
  600.             set {
  601.                 VerifyWritable();
  602.                 if (value < 0 || value > 99) {
  603.                     throw new ArgumentOutOfRangeException("PercentDecimalDigits", String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("ArgumentOutOfRange_Range"), 0, 99));
  604.                 }
  605.                 percentDecimalDigits = value;
  606.             }
  607.         }
  608.        
  609.        
  610.         public string PercentDecimalSeparator {
  611.             get { return percentDecimalSeparator; }
  612.             set {
  613.                 VerifyWritable();
  614.                 VerifyDecimalSeparator(value, "PercentDecimalSeparator");
  615.                 percentDecimalSeparator = value;
  616.             }
  617.         }
  618.        
  619.        
  620.         public string PercentGroupSeparator {
  621.             get { return percentGroupSeparator; }
  622.             set {
  623.                 VerifyWritable();
  624.                 VerifyGroupSeparator(value, "PercentGroupSeparator");
  625.                 percentGroupSeparator = value;
  626.             }
  627.         }
  628.        
  629.        
  630.         public string PercentSymbol {
  631.             get { return percentSymbol; }
  632.             set {
  633.                 VerifyWritable();
  634.                 if (value == null) {
  635.                     throw new ArgumentNullException("PercentSymbol", Environment.GetResourceString("ArgumentNull_String"));
  636.                 }
  637.                 percentSymbol = value;
  638.             }
  639.         }
  640.        
  641.        
  642.         public string PerMilleSymbol {
  643.             get { return perMilleSymbol; }
  644.             set {
  645.                 VerifyWritable();
  646.                 if (value == null) {
  647.                     throw new ArgumentNullException("PerMilleSymbol", Environment.GetResourceString("ArgumentNull_String"));
  648.                 }
  649.                 perMilleSymbol = value;
  650.             }
  651.         }
  652.        
  653.        
  654.         [System.Runtime.InteropServices.ComVisible(false)]
  655.         public string[] NativeDigits {
  656.             get { return nativeDigits; }
  657.             set {
  658.                 VerifyWritable();
  659.                 VerifyNativeDigits(value, "NativeDigits");
  660.                 nativeDigits = value;
  661.             }
  662.         }
  663.        
  664.        
  665.         [System.Runtime.InteropServices.ComVisible(false)]
  666.         public DigitShapes DigitSubstitution {
  667.             get { return (DigitShapes)digitSubstitution; }
  668.             set {
  669.                 VerifyWritable();
  670.                 VerifyDigitSubstitution(value, "DigitSubstitution");
  671.                 digitSubstitution = (int)value;
  672.             }
  673.         }
  674.        
  675.        
  676.         public object GetFormat(Type formatType)
  677.         {
  678.             return formatType == typeof(NumberFormatInfo) ? this : null;
  679.         }
  680.        
  681.        
  682.         public static NumberFormatInfo ReadOnly(NumberFormatInfo nfi)
  683.         {
  684.             if (nfi == null) {
  685.                 throw new ArgumentNullException("nfi");
  686.             }
  687.             if (nfi.IsReadOnly) {
  688.                 return (nfi);
  689.             }
  690.             NumberFormatInfo info = (NumberFormatInfo)(nfi.MemberwiseClone());
  691.             info.isReadOnly = true;
  692.             return info;
  693.         }
  694.        
  695.         // private const NumberStyles InvalidNumberStyles = unchecked((NumberStyles) 0xFFFFFC00);
  696.         private const NumberStyles InvalidNumberStyles = ~(NumberStyles.AllowLeadingWhite | NumberStyles.AllowTrailingWhite | NumberStyles.AllowLeadingSign | NumberStyles.AllowTrailingSign | NumberStyles.AllowParentheses | NumberStyles.AllowDecimalPoint | NumberStyles.AllowThousands | NumberStyles.AllowExponent | NumberStyles.AllowCurrencySymbol | NumberStyles.AllowHexSpecifier);
  697.        
  698.         static internal void ValidateParseStyleInteger(NumberStyles style)
  699.         {
  700.             // Check for undefined flags
  701.             if ((style & InvalidNumberStyles) != 0) {
  702.                 throw new ArgumentException(Environment.GetResourceString("Argument_InvalidNumberStyles"), "style");
  703.             }
  704.             if ((style & NumberStyles.AllowHexSpecifier) != 0) {
  705.                 // Check for hex number
  706.                 if ((style & ~NumberStyles.HexNumber) != 0) {
  707.                     throw new ArgumentException(Environment.GetResourceString("Arg_InvalidHexStyle"));
  708.                 }
  709.             }
  710.         }
  711.        
  712.         static internal void ValidateParseStyleFloatingPoint(NumberStyles style)
  713.         {
  714.             // Check for undefined flags
  715.             if ((style & InvalidNumberStyles) != 0) {
  716.                 throw new ArgumentException(Environment.GetResourceString("Argument_InvalidNumberStyles"), "style");
  717.             }
  718.             if ((style & NumberStyles.AllowHexSpecifier) != 0) {
  719.                 // Check for hex number
  720.                 throw new ArgumentException(Environment.GetResourceString("Arg_HexStyleNotSupported"));
  721.             }
  722.         }
  723.     }
  724.     // NumberFormatInfo
  725. }

Developer Fusion