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