diff options
Diffstat (limited to 'src/mscorlib/src/System/Globalization/CultureInfo.cs')
-rw-r--r-- | src/mscorlib/src/System/Globalization/CultureInfo.cs | 167 |
1 files changed, 45 insertions, 122 deletions
diff --git a/src/mscorlib/src/System/Globalization/CultureInfo.cs b/src/mscorlib/src/System/Globalization/CultureInfo.cs index d620d2dc24..9f306c3c99 100644 --- a/src/mscorlib/src/System/Globalization/CultureInfo.cs +++ b/src/mscorlib/src/System/Globalization/CultureInfo.cs @@ -39,6 +39,7 @@ namespace System.Globalization { using System.Security.Permissions; using System.Reflection; using Microsoft.Win32; + using System.Diagnostics; using System.Diagnostics.Contracts; using System.Resources; @@ -66,10 +67,6 @@ namespace System.Globalization { internal bool m_isReadOnly; internal CompareInfo compareInfo; internal TextInfo textInfo; - // Not serialized for now since we only build it privately for use in the CARIB (so rebuilding is OK) -#if !FEATURE_CORECLR - [NonSerialized]internal RegionInfo regionInfo; -#endif internal NumberFormatInfo numInfo; internal DateTimeFormatInfo dateTimeInfo; internal Calendar calendar; @@ -88,10 +85,8 @@ namespace System.Globalization { #if FEATURE_LEAK_CULTURE_INFO [NonSerialized]private bool m_isSafeCrossDomain; [NonSerialized]private int m_createdDomainID; -#endif // !FEATURE_CORECLR -#if !FEATURE_CORECLR +#endif // !FEATURE_LEAK_CULTURE_INFO [NonSerialized]private CultureInfo m_consoleFallbackCulture; -#endif // !FEATURE_CORECLR // Names are confusing. Here are 3 names we have: // @@ -152,7 +147,6 @@ namespace System.Globalization { #if FEATURE_APPX // When running under AppX, we use this to get some information about the language list - [SecurityCritical] private static volatile WindowsRuntimeResourceManagerBase s_WindowsRuntimeResourceManager; [ThreadStatic] @@ -197,7 +191,6 @@ namespace System.Globalization { return true; } - [System.Security.SecuritySafeCritical] // auto-generated static CultureInfo InitUserDefaultCulture() { String strDefault = GetDefaultLocaleName(LOCALE_USER_DEFAULT); @@ -241,7 +234,6 @@ namespace System.Globalization { } #if FEATURE_APPX - [SecuritySafeCritical] internal static CultureInfo GetCultureInfoForUserPreferredLanguageInAppX() { // If a call to GetCultureInfoForUserPreferredLanguageInAppX() generated a recursive @@ -287,7 +279,6 @@ namespace System.Globalization { return toReturn; } - [SecuritySafeCritical] internal static bool SetCultureInfoForUserPreferredLanguageInAppX(CultureInfo ci) { // If running within a compilation process (mscorsvw.exe, for example), it is illegal to @@ -323,7 +314,7 @@ namespace System.Globalization { public CultureInfo(String name, bool useUserOverride) { if (name==null) { - throw new ArgumentNullException("name", + throw new ArgumentNullException(nameof(name), Environment.GetResourceString("ArgumentNull_String")); } Contract.EndContractBlock(); @@ -332,7 +323,7 @@ namespace System.Globalization { this.m_cultureData = CultureData.GetCultureData(name, useUserOverride); if (this.m_cultureData == null) { - throw new CultureNotFoundException("name", name, Environment.GetResourceString("Argument_CultureNotSupported")); + throw new CultureNotFoundException(nameof(name), name, Environment.GetResourceString("Argument_CultureNotSupported")); } this.m_name = this.m_cultureData.CultureName; @@ -347,7 +338,7 @@ namespace System.Globalization { public CultureInfo(int culture, bool useUserOverride) { // We don't check for other invalid LCIDS here... if (culture < 0) { - throw new ArgumentOutOfRangeException("culture", + throw new ArgumentOutOfRangeException(nameof(culture), Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum")); } Contract.EndContractBlock(); @@ -367,7 +358,7 @@ namespace System.Globalization { // Can't support unknown custom cultures and we do not support neutral or // non-custom user locales. throw new CultureNotFoundException( - "culture", culture, Environment.GetResourceString("Argument_CultureNotSupported")); + nameof(culture), culture, Environment.GetResourceString("Argument_CultureNotSupported")); default: // Now see if this LCID is supported in the system default CultureData table. @@ -413,18 +404,18 @@ namespace System.Globalization { // e.g. for es-ES_tradnl: v2 puts es-ES in m_name; v4 puts es-ES_tradnl if (m_name == null || IsAlternateSortLcid(cultureID)) { - Contract.Assert(cultureID >=0, "[CultureInfo.OnDeserialized] cultureID >= 0"); + Debug.Assert(cultureID >=0, "[CultureInfo.OnDeserialized] cultureID >= 0"); InitializeFromCultureId(cultureID, m_useUserOverride); } else { #endif - Contract.Assert(m_name != null, "[CultureInfo.OnDeserialized] m_name != null"); + Debug.Assert(m_name != null, "[CultureInfo.OnDeserialized] m_name != null"); this.m_cultureData = CultureData.GetCultureData(m_name, m_useUserOverride); if (this.m_cultureData == null) throw new CultureNotFoundException( - "m_name", m_name, Environment.GetResourceString("Argument_CultureNotSupported")); + nameof(m_name), m_name, Environment.GetResourceString("Argument_CultureNotSupported")); #if FEATURE_USE_LCID } @@ -486,14 +477,14 @@ namespace System.Globalization { // For Silverlight, the answer is always no. internal bool IsSafeCrossDomain { get { - Contract.Assert(m_createdDomainID != 0, "[CultureInfo.IsSafeCrossDomain] m_createdDomainID != 0"); + Debug.Assert(m_createdDomainID != 0, "[CultureInfo.IsSafeCrossDomain] m_createdDomainID != 0"); return m_isSafeCrossDomain; } } internal int CreatedDomainID { get { - Contract.Assert(m_createdDomainID != 0, "[CultureInfo.CreatedDomain] m_createdDomainID != 0"); + Debug.Assert(m_createdDomainID != 0, "[CultureInfo.CreatedDomain] m_createdDomainID != 0"); return m_createdDomainID; } } @@ -540,7 +531,7 @@ namespace System.Globalization { internal CultureInfo(String cultureName, String textAndCompareCultureName) { if (cultureName==null) { - throw new ArgumentNullException("cultureName", + throw new ArgumentNullException(nameof(cultureName), Environment.GetResourceString("ArgumentNull_String")); } Contract.EndContractBlock(); @@ -548,7 +539,7 @@ namespace System.Globalization { this.m_cultureData = CultureData.GetCultureData(cultureName, false); if (this.m_cultureData == null) throw new CultureNotFoundException( - "cultureName", cultureName, Environment.GetResourceString("Argument_CultureNotSupported")); + nameof(cultureName), cultureName, Environment.GetResourceString("Argument_CultureNotSupported")); this.m_name = this.m_cultureData.CultureName; @@ -644,7 +635,7 @@ namespace System.Globalization { } internal static bool VerifyCultureName(CultureInfo culture, bool throwException) { - Contract.Assert(culture!=null, "[CultureInfo.VerifyCultureName]culture!=null"); + Debug.Assert(culture!=null, "[CultureInfo.VerifyCultureName]culture!=null"); //If we have an instance of one of our CultureInfos, the user can't have changed the //name and we know that all names are valid in files. @@ -672,9 +663,6 @@ namespace System.Globalization { get { Contract.Ensures(Contract.Result<CultureInfo>() != null); -#if !FEATURE_CORECLR - return Thread.CurrentThread.CurrentCulture; -#else // In the case of CoreCLR, Thread.m_CurrentCulture and // Thread.m_CurrentUICulture are thread static so as not to let // CultureInfo objects leak across AppDomain boundaries. The @@ -695,13 +683,12 @@ namespace System.Globalization { s_DefaultThreadCurrentCulture ?? s_userDefaultCulture ?? UserDefaultCulture; -#endif } set { #if FEATURE_APPX if (value == null) { - throw new ArgumentNullException("value"); + throw new ArgumentNullException(nameof(value)); } if (AppDomain.IsAppXModel()) { @@ -770,9 +757,6 @@ namespace System.Globalization { get { Contract.Ensures(Contract.Result<CultureInfo>() != null); -#if !FEATURE_CORECLR - return Thread.CurrentThread.CurrentUICulture; -#else // In the case of CoreCLR, Thread.m_CurrentCulture and // Thread.m_CurrentUICulture are thread static so as not to let // CultureInfo objects leak across AppDomain boundaries. The @@ -793,13 +777,12 @@ namespace System.Globalization { s_DefaultThreadCurrentUICulture ?? s_userDefaultUICulture ?? UserDefaultUICulture; -#endif } set { #if FEATURE_APPX if (value == null) { - throw new ArgumentNullException("value"); + throw new ArgumentNullException(nameof(value)); } if (AppDomain.IsAppXModel()) { @@ -843,10 +826,6 @@ namespace System.Globalization { return s_DefaultThreadCurrentCulture; } - [System.Security.SecuritySafeCritical] // auto-generated -#pragma warning disable 618 - [SecurityPermission(SecurityAction.Demand, ControlThread = true)] -#pragma warning restore 618 set { // If you add pre-conditions to this method, check to see if you also need to @@ -861,10 +840,6 @@ namespace System.Globalization { return s_DefaultThreadCurrentUICulture; } - [System.Security.SecuritySafeCritical] // auto-generated -#pragma warning disable 618 - [SecurityPermission(SecurityAction.Demand, ControlThread = true)] -#pragma warning restore 618 set { //If they're trying to use a Culture with a name that we can't use in resource lookup, @@ -915,24 +890,23 @@ namespace System.Globalization { public virtual CultureInfo Parent { - [System.Security.SecuritySafeCritical] // auto-generated get { Contract.Ensures(Contract.Result<CultureInfo>() != null); + CultureInfo culture = null; if (null == m_parent) { try { string parentName = this.m_cultureData.SPARENT; - if (String.IsNullOrEmpty(parentName)) { - m_parent = InvariantCulture; + culture = InvariantCulture; } else { - m_parent = new CultureInfo(parentName, this.m_cultureData.UseUserOverride); + culture = new CultureInfo(parentName, this.m_cultureData.UseUserOverride); } } catch (ArgumentException) @@ -940,8 +914,10 @@ namespace System.Globalization { // For whatever reason our IPARENT or SPARENT wasn't correct, so use invariant // We can't allow ourselves to fail. In case of custom cultures the parent of the // current custom culture isn't installed. - m_parent = InvariantCulture; + culture = InvariantCulture; } + + Interlocked.CompareExchange<CultureInfo>(ref m_parent, culture, null); } return m_parent; } @@ -1034,7 +1010,6 @@ namespace System.Globalization { } } -#if !FEATURE_CORECLR [System.Runtime.InteropServices.ComVisible(false)] public String IetfLanguageTag { @@ -1054,7 +1029,6 @@ namespace System.Globalization { } } } -#endif //////////////////////////////////////////////////////////////////////// // @@ -1067,11 +1041,10 @@ namespace System.Globalization { //////////////////////////////////////////////////////////////////////// public virtual String DisplayName { - [System.Security.SecuritySafeCritical] // auto-generated get { Contract.Ensures(Contract.Result<String>() != null); - Contract.Assert(m_name != null, "[CultureInfo.DisplayName]Always expect m_name to be set"); + Debug.Assert(m_name != null, "[CultureInfo.DisplayName]Always expect m_name to be set"); return m_cultureData.SLOCALIZEDDISPLAYNAME; } @@ -1087,7 +1060,6 @@ namespace System.Globalization { // //////////////////////////////////////////////////////////////////////// public virtual String NativeName { - [System.Security.SecuritySafeCritical] // auto-generated get { Contract.Ensures(Contract.Result<String>() != null); return (this.m_cultureData.SNATIVEDISPLAYNAME); @@ -1104,7 +1076,6 @@ namespace System.Globalization { // //////////////////////////////////////////////////////////////////////// public virtual String EnglishName { - [System.Security.SecuritySafeCritical] // auto-generated get { Contract.Ensures(Contract.Result<String>() != null); return (this.m_cultureData.SENGDISPLAYNAME); @@ -1113,7 +1084,6 @@ namespace System.Globalization { // ie: en public virtual String TwoLetterISOLanguageName { - [System.Security.SecuritySafeCritical] // auto-generated get { Contract.Ensures(Contract.Result<String>() != null); return (this.m_cultureData.SISO639LANGNAME); @@ -1122,7 +1092,6 @@ namespace System.Globalization { // ie: eng public virtual String ThreeLetterISOLanguageName { - [System.Security.SecuritySafeCritical] // auto-generated get { Contract.Ensures(Contract.Result<String>() != null); return (this.m_cultureData.SISO639LANGNAME2); @@ -1138,7 +1107,6 @@ namespace System.Globalization { // //////////////////////////////////////////////////////////////////////// public virtual String ThreeLetterWindowsLanguageName { - [System.Security.SecuritySafeCritical] // auto-generated get { Contract.Ensures(Contract.Result<String>() != null); return (this.m_cultureData.SABBREVLANGNAME); @@ -1178,31 +1146,6 @@ namespace System.Globalization { } } -#if !FEATURE_CORECLR - //////////////////////////////////////////////////////////////////////// - // - // RegionInfo - // - // Gets the RegionInfo for this culture. - // - //////////////////////////////////////////////////////////////////////// - private RegionInfo Region - { - get - { - if (regionInfo==null) - { - // Make a new regionInfo - RegionInfo tempRegionInfo = new RegionInfo(this.m_cultureData); - regionInfo = tempRegionInfo; - } - return (regionInfo); - } - } -#endif // FEATURE_CORECLR - - - //////////////////////////////////////////////////////////////////////// // // TextInfo @@ -1294,7 +1237,7 @@ namespace System.Globalization { { Contract.Ensures(Contract.Result<String>() != null); - Contract.Assert(m_name != null, "[CultureInfo.ToString]Always expect m_name to be set"); + Debug.Assert(m_name != null, "[CultureInfo.ToString]Always expect m_name to be set"); return m_name; } @@ -1315,7 +1258,6 @@ namespace System.Globalization { } } -#if !FEATURE_CORECLR [System.Runtime.InteropServices.ComVisible(false)] public CultureTypes CultureTypes { @@ -1333,15 +1275,14 @@ namespace System.Globalization { // Disable warning 618: System.Globalization.CultureTypes.FrameworkCultures' is obsolete #pragma warning disable 618 types |= m_cultureData.IsFramework ? CultureTypes.FrameworkCultures : 0; - #pragma warning restore 618 + types |= m_cultureData.IsSupplementalCustomCulture ? CultureTypes.UserCustomCulture : 0; types |= m_cultureData.IsReplacementCulture ? CultureTypes.ReplacementCultures | CultureTypes.UserCustomCulture : 0; return types; } } -#endif public virtual NumberFormatInfo NumberFormat { get @@ -1351,13 +1292,13 @@ namespace System.Globalization { if (numInfo == null) { NumberFormatInfo temp = new NumberFormatInfo(this.m_cultureData); temp.isReadOnly = m_isReadOnly; - numInfo = temp; + Interlocked.CompareExchange(ref numInfo, temp, null); } return (numInfo); } set { if (value == null) { - throw new ArgumentNullException("value", + throw new ArgumentNullException(nameof(value), Environment.GetResourceString("ArgumentNull_Obj")); } Contract.EndContractBlock(); @@ -1385,15 +1326,14 @@ namespace System.Globalization { DateTimeFormatInfo temp = new DateTimeFormatInfo( this.m_cultureData, this.Calendar); temp.m_isReadOnly = m_isReadOnly; - System.Threading.Thread.MemoryBarrier(); - dateTimeInfo = temp; + Interlocked.CompareExchange(ref dateTimeInfo, temp, null); } return (dateTimeInfo); } set { if (value == null) { - throw new ArgumentNullException("value", + throw new ArgumentNullException(nameof(value), Environment.GetResourceString("ArgumentNull_Obj")); } Contract.EndContractBlock(); @@ -1402,17 +1342,16 @@ namespace System.Globalization { } } - - public void ClearCachedData() { s_userDefaultUICulture = null; s_userDefaultCulture = null; RegionInfo.s_currentRegionInfo = null; -#if !FEATURE_CORECLR // System.TimeZone does not exist in CoreCLR +#pragma warning disable CS0618 TimeZone.ResetTimeZone(); -#endif // FEATURE_CORECLR +#pragma warning restore CS0618 TimeZoneInfo.ClearCachedData(); + // Delete the cached cultures. s_LcidCachedCultures = null; s_NameCachedCultures = null; @@ -1438,7 +1377,7 @@ namespace System.Globalization { //This function exists as a shortcut to prevent us from loading all of the non-gregorian //calendars unless they're required. internal static Calendar GetCalendarInstanceRare(int calType) { - Contract.Assert(calType!=Calendar.CAL_GREGORIAN, "calType!=Calendar.CAL_GREGORIAN"); + Debug.Assert(calType!=Calendar.CAL_GREGORIAN, "calType!=Calendar.CAL_GREGORIAN"); switch (calType) { case Calendar.CAL_GREGORIAN_US: // Gregorian (U.S.) calendar @@ -1490,7 +1429,7 @@ namespace System.Globalization { get { Contract.Ensures(Contract.Result<Calendar>() != null); if (calendar == null) { - Contract.Assert(this.m_cultureData.CalendarIds.Length > 0, "this.m_cultureData.CalendarIds.Length > 0"); + Debug.Assert(this.m_cultureData.CalendarIds.Length > 0, "this.m_cultureData.CalendarIds.Length > 0"); // Get the default calendar for this culture. Note that the value can be // from registry if this is a user default culture. Calendar newObj = this.m_cultureData.DefaultCalendar; @@ -1534,8 +1473,6 @@ namespace System.Globalization { } } -#if !FEATURE_CORECLR - [System.Security.SecuritySafeCritical] // auto-generated [System.Runtime.InteropServices.ComVisible(false)] public CultureInfo GetConsoleFallbackUICulture() { @@ -1550,7 +1487,6 @@ namespace System.Globalization { } return (temp); } -#endif public virtual Object Clone() { @@ -1595,7 +1531,7 @@ namespace System.Globalization { public static CultureInfo ReadOnly(CultureInfo ci) { if (ci == null) { - throw new ArgumentNullException("ci"); + throw new ArgumentNullException(nameof(ci)); } Contract.Ensures(Contract.Result<CultureInfo>() != null); Contract.EndContractBlock(); @@ -1827,7 +1763,7 @@ namespace System.Globalization { // the altCulture code path for SQL Server. // Also check for zero as this would fail trying to add as a key to the hash. if (culture <= 0) { - throw new ArgumentOutOfRangeException("culture", + throw new ArgumentOutOfRangeException(nameof(culture), Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum")); } Contract.Ensures(Contract.Result<CultureInfo>() != null); @@ -1836,7 +1772,7 @@ namespace System.Globalization { if (null == retval) { throw new CultureNotFoundException( - "culture", culture, Environment.GetResourceString("Argument_CultureNotSupported")); + nameof(culture), culture, Environment.GetResourceString("Argument_CultureNotSupported")); } return retval; } @@ -1849,7 +1785,7 @@ namespace System.Globalization { // Make sure we have a valid, non-zero length string as name if (name == null) { - throw new ArgumentNullException("name"); + throw new ArgumentNullException(nameof(name)); } Contract.Ensures(Contract.Result<CultureInfo>() != null); Contract.EndContractBlock(); @@ -1858,7 +1794,7 @@ namespace System.Globalization { if (retval == null) { throw new CultureNotFoundException( - "name", name, Environment.GetResourceString("Argument_CultureNotSupported")); + nameof(name), name, Environment.GetResourceString("Argument_CultureNotSupported")); } return retval; @@ -1871,12 +1807,12 @@ namespace System.Globalization { // Make sure we have a valid, non-zero length string as name if (null == name) { - throw new ArgumentNullException("name"); + throw new ArgumentNullException(nameof(name)); } if (null == altName) { - throw new ArgumentNullException("altName"); + throw new ArgumentNullException(nameof(altName)); } Contract.Ensures(Contract.Result<CultureInfo>() != null); Contract.EndContractBlock(); @@ -1884,7 +1820,7 @@ namespace System.Globalization { CultureInfo retval = GetCultureInfoHelper(-1, name, altName); if (retval == null) { - throw new CultureNotFoundException("name or altName", + throw new CultureNotFoundException(nameof(name) + " or " + nameof(altName), String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString("Argument_OneOfCulturesNotSupported"), @@ -1904,7 +1840,7 @@ namespace System.Globalization { if (name == "zh-CHT" || name == "zh-CHS") { throw new CultureNotFoundException( - "name", + nameof(name), String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Argument_CultureIetfNotSupported"), name) ); } @@ -1915,7 +1851,7 @@ namespace System.Globalization { if (ci.LCID > 0xffff || ci.LCID == 0x040a) { throw new CultureNotFoundException( - "name", + nameof(name), String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Argument_CultureIetfNotSupported"), name) ); } @@ -1943,22 +1879,18 @@ namespace System.Globalization { // // Get Locale Info Ex calls. So we don't have to muck with the different int/string return types we declared two of these: - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern String nativeGetLocaleInfoEx(String localeName, uint field); - [System.Security.SecuritySafeCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern int nativeGetLocaleInfoExInt(String localeName, uint field); - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern bool nativeSetThreadLocale(String localeName); - [System.Security.SecurityCritical] private static String GetDefaultLocaleName(int localeType) { - Contract.Assert(localeType == LOCALE_USER_DEFAULT || localeType == LOCALE_SYSTEM_DEFAULT, "[CultureInfo.GetDefaultLocaleName] localeType must be LOCALE_USER_DEFAULT or LOCALE_SYSTEM_DEFAULT"); + Debug.Assert(localeType == LOCALE_USER_DEFAULT || localeType == LOCALE_SYSTEM_DEFAULT, "[CultureInfo.GetDefaultLocaleName] localeType must be LOCALE_USER_DEFAULT or LOCALE_SYSTEM_DEFAULT"); string localeName = null; if(InternalGetDefaultLocaleName(localeType, JitHelpers.GetStringHandleOnStack(ref localeName))) @@ -1969,13 +1901,11 @@ namespace System.Globalization { } // Get the default locale name - [System.Security.SecurityCritical] // auto-generated [SuppressUnmanagedCodeSecurity] [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool InternalGetDefaultLocaleName(int localetype, StringHandleOnStack localeString); - [System.Security.SecuritySafeCritical] // auto-generated private static String GetUserDefaultUILanguage() { string userDefaultUiLanguage = null; @@ -1987,13 +1917,11 @@ namespace System.Globalization { } // Get the user's default UI language, return locale name - [System.Security.SecurityCritical] // auto-generated [SuppressUnmanagedCodeSecurity] [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool InternalGetUserDefaultUILanguage(StringHandleOnStack userDefaultUiLanguage); - [System.Security.SecuritySafeCritical] // auto-generated private static String GetSystemDefaultUILanguage() { string systemDefaultUiLanguage = null; @@ -2005,19 +1933,14 @@ namespace System.Globalization { } - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] [SuppressUnmanagedCodeSecurity] [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool InternalGetSystemDefaultUILanguage(StringHandleOnStack systemDefaultUiLanguage); -// Added but disabled from desktop in .NET 4.0, stayed disabled in .NET 4.5 -#if FEATURE_CORECLR - [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern String[] nativeGetResourceFallbackArray(); -#endif } } |