28
28
29
29
// ReSharper disable once CheckNamespace
30
30
31
+
32
+
31
33
namespace UnitsNet
32
34
{
33
35
[ PublicAPI ]
@@ -41,7 +43,7 @@ public partial class UnitSystem
41
43
/// Per-unit-type dictionary of enum values by abbreviation. This is the inverse of
42
44
/// <see cref="_unitTypeToUnitValueToAbbrevs" />.
43
45
/// </summary>
44
- private readonly Dictionary < Type , Dictionary < string , int > > _unitTypeToAbbrevToUnitValue ;
46
+ private readonly Dictionary < Type , AbbreviationMap > _unitTypeToAbbrevToUnitValue ;
45
47
46
48
/// <summary>
47
49
/// Per-unit-type dictionary of abbreviations by enum value. This is the inverse of
@@ -71,7 +73,7 @@ public UnitSystem([CanBeNull] IFormatProvider cultureInfo = null)
71
73
72
74
Culture = cultureInfo ;
73
75
_unitTypeToUnitValueToAbbrevs = new Dictionary < Type , Dictionary < int , List < string > > > ( ) ;
74
- _unitTypeToAbbrevToUnitValue = new Dictionary < Type , Dictionary < string , int > > ( ) ;
76
+ _unitTypeToAbbrevToUnitValue = new Dictionary < Type , AbbreviationMap > ( ) ;
75
77
76
78
LoadDefaultAbbreviatons ( cultureInfo ) ;
77
79
}
@@ -122,17 +124,33 @@ public TUnit Parse<TUnit>(string unitAbbreviation)
122
124
where TUnit : /*Enum constraint hack*/ struct , IComparable , IFormattable
123
125
{
124
126
Type unitType = typeof ( TUnit ) ;
125
- Dictionary < string , int > abbrevToUnitValue ;
127
+ AbbreviationMap abbrevToUnitValue ;
126
128
if ( ! _unitTypeToAbbrevToUnitValue . TryGetValue ( unitType , out abbrevToUnitValue ) )
127
129
throw new NotImplementedException (
128
130
$ "No abbreviations defined for unit type [{ unitType } ] for culture [{ Culture } ].") ;
129
131
130
- int unitValue ;
131
- TUnit result = abbrevToUnitValue . TryGetValue ( unitAbbreviation , out unitValue )
132
- ? ( TUnit ) ( object ) unitValue
133
- : default ( TUnit ) ;
132
+ List < int > unitValues ;
133
+ List < TUnit > units ;
134
134
135
- return result ;
135
+ if ( abbrevToUnitValue . TryGetValue ( unitAbbreviation , out unitValues ) )
136
+ {
137
+ units = unitValues . Cast < TUnit > ( ) . Distinct ( ) . ToList ( ) ;
138
+ }
139
+ else
140
+ {
141
+ units = new List < TUnit > ( ) ;
142
+ }
143
+
144
+ switch ( units . Count )
145
+ {
146
+ case 1 :
147
+ return units [ 0 ] ;
148
+ case 0 :
149
+ return default ( TUnit ) ;
150
+ default :
151
+ var unitsCsv = String . Join ( ", " , units . Select ( x => x . ToString ( ) ) . ToArray ( ) ) ;
152
+ throw new AmbiguousUnitParseException ( $ "Cannot parse '{ unitAbbreviation } ' since it could be either of these: { unitsCsv } ") ;
153
+ }
136
154
}
137
155
138
156
[ PublicAPI ]
@@ -187,15 +205,17 @@ public void MapUnitToAbbreviation(Type unitType, int unitValue, [NotNull] params
187
205
unitValueToAbbrev [ unitValue ] = existingAbbreviations . Concat ( abbreviations ) . Distinct ( ) . ToList ( ) ;
188
206
foreach ( string abbreviation in abbreviations )
189
207
{
190
- Dictionary < string , int > abbrevToUnitValue ;
208
+ AbbreviationMap abbrevToUnitValue ;
191
209
if ( ! _unitTypeToAbbrevToUnitValue . TryGetValue ( unitType , out abbrevToUnitValue ) )
192
210
{
193
- abbrevToUnitValue = _unitTypeToAbbrevToUnitValue [ unitType ] =
194
- new Dictionary < string , int > ( ) ;
211
+ abbrevToUnitValue = _unitTypeToAbbrevToUnitValue [ unitType ] = new AbbreviationMap ( ) ;
195
212
}
196
213
197
214
if ( ! abbrevToUnitValue . ContainsKey ( abbreviation ) )
198
- abbrevToUnitValue [ abbreviation ] = unitValue ;
215
+ {
216
+ abbrevToUnitValue [ abbreviation ] = new List < int > ( ) ;
217
+ }
218
+ abbrevToUnitValue [ abbreviation ] . Add ( unitValue ) ;
199
219
}
200
220
}
201
221
@@ -205,11 +225,11 @@ public bool TryParse<TUnit>(string unitAbbreviation, out TUnit unit)
205
225
{
206
226
Type unitType = typeof ( TUnit ) ;
207
227
208
- Dictionary < string , int > abbrevToUnitValue ;
209
- int unitValue ;
228
+ AbbreviationMap abbrevToUnitValue ;
229
+ List < int > unitValues ;
210
230
211
231
if ( ! _unitTypeToAbbrevToUnitValue . TryGetValue ( unitType , out abbrevToUnitValue ) ||
212
- ! abbrevToUnitValue . TryGetValue ( unitAbbreviation , out unitValue ) )
232
+ ! abbrevToUnitValue . TryGetValue ( unitAbbreviation , out unitValues ) )
213
233
{
214
234
if ( IsDefaultCulture )
215
235
{
@@ -221,8 +241,16 @@ public bool TryParse<TUnit>(string unitAbbreviation, out TUnit unit)
221
241
return GetCached ( DefaultCulture ) . TryParse ( unitAbbreviation , out unit ) ;
222
242
}
223
243
224
- unit = ( TUnit ) ( object ) unitValue ;
225
- return true ;
244
+ var maps = ( List < TUnit > ) ( object ) unitValues ;
245
+
246
+ switch ( maps . Count )
247
+ {
248
+ case 1 : unit = maps [ 0 ] ;
249
+ return true ;
250
+ default :
251
+ unit = default ( TUnit ) ;
252
+ return false ;
253
+ }
226
254
}
227
255
228
256
/// <summary>
@@ -279,5 +307,13 @@ private void LoadDefaultAbbreviatons([NotNull] IFormatProvider culture)
279
307
}
280
308
}
281
309
}
310
+
311
+ /// <summary>
312
+ /// Avoids having too many nested generics for code clarity
313
+ /// </summary>
314
+ class AbbreviationMap : Dictionary < string , List < int > >
315
+ {
316
+
317
+ }
282
318
}
283
319
}
0 commit comments