1+ using System . Globalization ;
2+
13namespace MetaObjects . Render . Recover ;
24
35/// <summary>
@@ -7,43 +9,88 @@ namespace MetaObjects.Render.Recover;
79public static class RecoverMap
810{
911 /// <summary>
10- /// Returns the string value for key <paramref name="k"/>, coercing non-strings via
11- /// <see cref="Convert.ToString(object)"/>. Returns <c>null</c> when the key is absent.
12+ /// Returns the string value for key <paramref name="k"/>, coercing non-strings via invariant-culture
13+ /// <see cref="Convert.ToString(object, IFormatProvider )"/>. Returns <c>null</c> when the key is absent.
1214 /// </summary>
15+ /// <remarks>
16+ /// Mirrors Java <c>String.valueOf</c>: locale-independent. The generated path only calls this on
17+ /// string-typed fields (value already a string), so the numeric fallback is defensive.
18+ /// </remarks>
1319 public static string ? AsString ( IReadOnlyDictionary < string , object ? > d , string k )
1420 {
1521 if ( ! d . TryGetValue ( k , out object ? v ) ) return null ;
16- return v == null ? null : ( v is string s ? s : Convert . ToString ( v ) ) ;
22+ return v switch
23+ {
24+ null => null ,
25+ string s => s ,
26+ _ => Convert . ToString ( v , CultureInfo . InvariantCulture ) ,
27+ } ;
1728 }
1829
1930 /// <summary>
2031 /// Returns the value narrowed to <see cref="int"/> for key <paramref name="k"/>.
21- /// Returns <c>null</c> when the key is absent or the value is not a <see cref="IConvertible"/> number.
32+ /// Returns <c>null</c> when the key is absent or the value is not a number.
2233 /// </summary>
34+ /// <remarks>
35+ /// Mirrors Java <c>Number.intValue()</c>: gates on actual numeric types (never throws on a string/bool,
36+ /// unlike <see cref="Convert"/>) and truncates floating values toward zero.
37+ /// </remarks>
2338 public static int ? AsInt ( IReadOnlyDictionary < string , object ? > d , string k )
2439 {
2540 if ( ! d . TryGetValue ( k , out object ? v ) ) return null ;
26- return v is IConvertible c ? ( int ? ) Convert . ToInt32 ( c ) : null ;
41+ return v switch
42+ {
43+ long l => ( int ) l ,
44+ int i => i ,
45+ double db => ( int ) db ,
46+ float f => ( int ) f ,
47+ decimal m => ( int ) m ,
48+ short s => s ,
49+ byte b => b ,
50+ _ => null ,
51+ } ;
2752 }
2853
2954 /// <summary>
3055 /// Returns the value as <see cref="long"/> for key <paramref name="k"/>.
31- /// Returns <c>null</c> when the key is absent or the value is not a <see cref="IConvertible"/> number.
56+ /// Returns <c>null</c> when the key is absent or the value is not a number.
3257 /// </summary>
58+ /// <remarks>Mirrors Java <c>Number.longValue()</c>: numeric-typed, never throws, truncates toward zero.</remarks>
3359 public static long ? AsLong ( IReadOnlyDictionary < string , object ? > d , string k )
3460 {
3561 if ( ! d . TryGetValue ( k , out object ? v ) ) return null ;
36- return v is IConvertible c ? ( long ? ) Convert . ToInt64 ( c ) : null ;
62+ return v switch
63+ {
64+ long l => l ,
65+ int i => i ,
66+ double db => ( long ) db ,
67+ float f => ( long ) f ,
68+ decimal m => ( long ) m ,
69+ short s => s ,
70+ byte b => b ,
71+ _ => null ,
72+ } ;
3773 }
3874
3975 /// <summary>
4076 /// Returns the value as <see cref="double"/> for key <paramref name="k"/>.
41- /// Returns <c>null</c> when the key is absent or the value is not a <see cref="IConvertible"/> number.
77+ /// Returns <c>null</c> when the key is absent or the value is not a number.
4278 /// </summary>
79+ /// <remarks>Mirrors Java <c>Number.doubleValue()</c>: numeric-typed, never throws.</remarks>
4380 public static double ? AsDouble ( IReadOnlyDictionary < string , object ? > d , string k )
4481 {
4582 if ( ! d . TryGetValue ( k , out object ? v ) ) return null ;
46- return v is IConvertible c ? ( double ? ) Convert . ToDouble ( c ) : null ;
83+ return v switch
84+ {
85+ long l => l ,
86+ int i => i ,
87+ double db => db ,
88+ float f => f ,
89+ decimal m => ( double ) m ,
90+ short s => s ,
91+ byte b => b ,
92+ _ => null ,
93+ } ;
4794 }
4895
4996 /// <summary>
@@ -67,7 +114,7 @@ public static class RecoverMap
67114 if ( v is not List < object ? > list ) return null ;
68115 var out_ = new List < string ? > ( list . Count ) ;
69116 foreach ( object ? e in list )
70- out_ . Add ( e == null ? null : Convert . ToString ( e ) ) ;
117+ out_ . Add ( e == null ? null : Convert . ToString ( e , CultureInfo . InvariantCulture ) ) ;
71118 return out_ . AsReadOnly ( ) ;
72119 }
73120}
0 commit comments