Skip to content

Commit 3d7a7c5

Browse files
committed
UnitKey: renamed the UnitType and UnitValue to UnitEnumType and UnitEnumValue
1 parent 49a8657 commit 3d7a7c5

File tree

6 files changed

+98
-45
lines changed

6 files changed

+98
-45
lines changed

UnitsNet.Benchmark/Enums/UnitKeyEqualsBenchmarks.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ public class UnitKeyEqualsBenchmarks
1616

1717
private static readonly UnitKey UnitKey = UnitKey.ForUnit(VolumeUnit.CubicMeter);
1818
private static readonly UnitKey OtherUnitKey = UnitKey.ForUnit(VolumeUnit.AcreFoot);
19-
private readonly Type OtherUnitType = UnitKey.UnitType;
20-
private readonly int OtherUnitValue = UnitKey.UnitValue;
19+
private readonly Type OtherUnitType = UnitKey.UnitEnumType;
20+
private readonly int OtherUnitValue = UnitKey.UnitEnumValue;
2121

22-
private readonly Type UnitType = UnitKey.UnitType;
23-
private readonly int UnitValue = UnitKey.UnitValue;
22+
private readonly Type UnitType = UnitKey.UnitEnumType;
23+
private readonly int UnitValue = UnitKey.UnitEnumValue;
2424

2525
[Benchmark(Baseline = true)]
2626
public bool EqualsRecord()

UnitsNet.Benchmark/Enums/UnitKeyHashCodeBenchmarks.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ public class UnitKeyHashCodeBenchmarks
1717

1818
private static readonly UnitKey UnitKey = UnitKey.ForUnit(VolumeUnit.CubicMeter);
1919

20-
private readonly Type UnitType = UnitKey.UnitType;
21-
private readonly int UnitValue = UnitKey.UnitValue;
20+
private readonly Type UnitType = UnitKey.UnitEnumType;
21+
private readonly int UnitValue = UnitKey.UnitEnumValue;
2222

2323
[Benchmark(Baseline = true)]
2424
public int GetHashCodeRecord()

UnitsNet.Benchmark/Enums/UnitKeyToEnumBenchmarks.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public int ManualCast()
2323
var total = 0;
2424
for (var i = 0; i < NbIterations; i++)
2525
{
26-
if ((MassUnit)unitKey.UnitValue == MassUnit.Gram)
26+
if ((MassUnit)unitKey.UnitEnumValue == MassUnit.Gram)
2727
{
2828
total++;
2929
}

UnitsNet.Tests/UnitKeyTest.cs

Lines changed: 37 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,16 @@ public enum TestUnit
2323
public void Constructor_ShouldCreateUnitKey(int unitValue)
2424
{
2525
var unitKey = new UnitKey(typeof(TestUnit), unitValue);
26-
Assert.Equal(typeof(TestUnit), unitKey.UnitType);
27-
Assert.Equal(unitValue, unitKey.UnitValue);
26+
Assert.Equal(typeof(TestUnit), unitKey.UnitEnumType);
27+
Assert.Equal(unitValue, unitKey.UnitEnumValue);
2828
}
2929

3030
[Fact]
3131
public void Constructor_WithNullType_ShouldNotThrow()
3232
{
3333
var unitKey = new UnitKey(null!, 0);
34-
Assert.Null(unitKey.UnitType);
35-
Assert.Equal(0, unitKey.UnitValue);
34+
Assert.Null(unitKey.UnitEnumType);
35+
Assert.Equal(0, unitKey.UnitEnumValue);
3636
}
3737

3838
[Theory]
@@ -42,8 +42,8 @@ public void Constructor_WithNullType_ShouldNotThrow()
4242
public void ForUnit_ShouldCreateUnitKey(TestUnit unit)
4343
{
4444
var unitKey = UnitKey.ForUnit(unit);
45-
Assert.Equal(typeof(TestUnit), unitKey.UnitType);
46-
Assert.Equal((int)unit, unitKey.UnitValue);
45+
Assert.Equal(typeof(TestUnit), unitKey.UnitEnumType);
46+
Assert.Equal((int)unit, unitKey.UnitEnumValue);
4747
}
4848

4949
[Theory]
@@ -53,8 +53,31 @@ public void ForUnit_ShouldCreateUnitKey(TestUnit unit)
5353
public void Create_ShouldCreateUnitKey(int unitValue)
5454
{
5555
var unitKey = UnitKey.Create<TestUnit>(unitValue);
56-
Assert.Equal(typeof(TestUnit), unitKey.UnitType);
57-
Assert.Equal(unitValue, unitKey.UnitValue);
56+
Assert.Equal(typeof(TestUnit), unitKey.UnitEnumType);
57+
Assert.Equal(unitValue, unitKey.UnitEnumValue);
58+
}
59+
60+
[Theory]
61+
[InlineData(typeof(TestUnit), 1)]
62+
[InlineData(typeof(TestUnit), 2)]
63+
[InlineData(typeof(TestUnit), 3)]
64+
public void Create_WithUnitTypeAndUnitValue_ShouldCreateUnitKey(Type unitType, int unitValue)
65+
{
66+
var unitKey = UnitKey.Create(unitType, unitValue);
67+
Assert.Equal(unitType, unitKey.UnitEnumType);
68+
Assert.Equal(unitValue, unitKey.UnitEnumValue);
69+
}
70+
71+
[Fact]
72+
public void Create_WithNullUnitType_ShouldThrowArgumentNullException()
73+
{
74+
Assert.Throws<ArgumentNullException>(() => UnitKey.Create(null!, 0));
75+
}
76+
77+
[Fact]
78+
public void Create_WithNonEnumType_ShouldThrowArgumentException()
79+
{
80+
Assert.Throws<ArgumentException>(() => UnitKey.Create(typeof(int), 1));
5881
}
5982

6083
[Theory]
@@ -64,8 +87,8 @@ public void Create_ShouldCreateUnitKey(int unitValue)
6487
public void ImplicitConversion_ShouldCreateUnitKey(TestUnit unit)
6588
{
6689
UnitKey unitKey = unit;
67-
Assert.Equal(typeof(TestUnit), unitKey.UnitType);
68-
Assert.Equal((int)unit, unitKey.UnitValue);
90+
Assert.Equal(typeof(TestUnit), unitKey.UnitEnumType);
91+
Assert.Equal((int)unit, unitKey.UnitEnumValue);
6992
}
7093

7194
[Theory]
@@ -94,8 +117,8 @@ public void ToUnit_ShouldReturnEnum(TestUnit unit)
94117
public void Default_InitializesWithoutAType()
95118
{
96119
var defaultUnitKey = default(UnitKey);
97-
Assert.Null(defaultUnitKey.UnitType);
98-
Assert.Equal(0, defaultUnitKey.UnitValue);
120+
Assert.Null(defaultUnitKey.UnitEnumType);
121+
Assert.Equal(0, defaultUnitKey.UnitEnumValue);
99122
}
100123

101124
[Fact]
@@ -139,7 +162,7 @@ public void Deconstruct_ShouldReturnTheUnitTypeAndUnitValue()
139162
[InlineData(TestUnit.Unit1, "TestUnit.Unit1")]
140163
[InlineData(TestUnit.Unit2, "TestUnit.Unit2")]
141164
[InlineData(TestUnit.Unit3, "TestUnit.Unit3")]
142-
[InlineData((TestUnit)(-1), "UnitType: UnitsNet.Tests.UnitKeyTest+TestUnit, UnitValue = -1")]
165+
[InlineData((TestUnit)(-1), "UnitEnumType: UnitsNet.Tests.UnitKeyTest+TestUnit, UnitEnumValue = -1")]
143166
public void GetDebuggerDisplay_ShouldReturnCorrectString(TestUnit unit, string expectedDisplay)
144167
{
145168
var unitKey = UnitKey.ForUnit(unit);
@@ -154,6 +177,6 @@ public void GetDebuggerDisplayWithDefault_ShouldReturnCorrectString()
154177
var defaultUnitKey = default(UnitKey);
155178
var display = defaultUnitKey.GetType().GetMethod("GetDebuggerDisplay", BindingFlags.NonPublic | BindingFlags.Instance)!
156179
.Invoke(defaultUnitKey, null);
157-
Assert.Equal("UnitType: , UnitValue = 0", display);
180+
Assert.Equal("UnitEnumType: , UnitEnumValue = 0", display);
158181
}
159182
}

UnitsNet/CustomCode/UnitAbbreviationsCache.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ public string GetDefaultAbbreviation(UnitKey unitKey, IFormatProvider? formatPro
267267
IReadOnlyList<string> abbreviations = GetUnitAbbreviations(unitKey, formatProvider);
268268
if (abbreviations.Count == 0)
269269
{
270-
throw new InvalidOperationException($"No abbreviations were found for {unitKey.UnitType.Name}.{(Enum)unitKey}. Make sure that the unit abbreviations are mapped.");
270+
throw new InvalidOperationException($"No abbreviations were found for {unitKey.UnitEnumType.Name}.{(Enum)unitKey}. Make sure that the unit abbreviations are mapped.");
271271
}
272272

273273
return abbreviations[0];
@@ -463,7 +463,7 @@ private static List<string> ReadAbbreviationsFromResourceFile(UnitInfo unitInfo,
463463
{
464464
var abbreviationsList = new List<string>();
465465
// we currently don't have any way of providing external resource dictionaries
466-
Assembly unitAssembly = unitInfo.UnitKey.UnitType.Assembly;
466+
Assembly unitAssembly = unitInfo.UnitKey.UnitEnumType.Assembly;
467467
if (unitAssembly != typeof(UnitAbbreviationsCache).Assembly)
468468
{
469469
return abbreviationsList;

UnitsNet/CustomCode/UnitKey.cs

Lines changed: 52 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ namespace UnitsNet;
1717
public readonly record struct UnitKey
1818
{
1919
// apparently, on netstandard, the use of auto-properties is significantly slower
20-
private readonly Type _unitType;
21-
private readonly int _unitValue;
20+
private readonly Type _unitEnumType;
21+
private readonly int _unitEnumValue;
2222

2323
/// <summary>
2424
/// Represents a unique key for a unit type and its corresponding value.
@@ -27,10 +27,10 @@ public readonly record struct UnitKey
2727
/// This key is particularly useful when using an enum-based unit in a hash-based collection,
2828
/// as it avoids the boxing that would normally occur when casting the enum to <see cref="Enum" />.
2929
/// </remarks>
30-
public UnitKey(Type UnitType, int UnitValue)
30+
internal UnitKey(Type UnitEnumType, int UnitEnumValue)
3131
{
32-
_unitType = UnitType;
33-
_unitValue = UnitValue;
32+
_unitEnumType = UnitEnumType;
33+
_unitEnumValue = UnitEnumValue;
3434
}
3535

3636
/// <summary>
@@ -40,9 +40,9 @@ public UnitKey(Type UnitType, int UnitValue)
4040
/// This property holds the <see cref="Type" /> of the unit enumeration associated with this key.
4141
/// It is particularly useful for identifying the unit type in scenarios where multiple unit types are used.
4242
/// </remarks>
43-
public Type UnitType
43+
public Type UnitEnumType
4444
{
45-
get => _unitType;
45+
get => _unitEnumType;
4646
}
4747

4848
/// <summary>
@@ -52,9 +52,9 @@ public Type UnitType
5252
/// This property represents the unique value of the unit within its type, typically corresponding to the underlying
5353
/// integer value of an enumeration.
5454
/// </remarks>
55-
public int UnitValue
55+
public int UnitEnumValue
5656
{
57-
get => _unitValue;
57+
get => _unitEnumValue;
5858
}
5959

6060
/// <summary>
@@ -81,6 +81,36 @@ public static UnitKey Create<TUnit>(int unitValue)
8181
return new UnitKey(typeof(TUnit), unitValue);
8282
}
8383

84+
/// <summary>
85+
/// Creates a new instance of the <see cref="UnitKey" /> struct for the specified unit type and value.
86+
/// </summary>
87+
/// <param name="unitType">The type of the unit, which must be an enumeration.</param>
88+
/// <param name="unitValue">The integer value representing the unit.</param>
89+
/// <returns>A new instance of the <see cref="UnitKey" /> struct.</returns>
90+
/// <exception cref="ArgumentNullException">
91+
/// Thrown if <paramref name="unitType" /> is <c>null</c>.
92+
/// </exception>
93+
/// <exception cref="ArgumentException">
94+
/// Thrown if <paramref name="unitType" /> is not an enumeration type.
95+
/// </exception>
96+
/// <remarks>
97+
/// This method is useful for creating a <see cref="UnitKey" /> when the unit type and value are known.
98+
/// </remarks>
99+
public static UnitKey Create(Type unitType, int unitValue)
100+
{
101+
if (unitType is null)
102+
{
103+
throw new ArgumentNullException(nameof(unitType));
104+
}
105+
106+
if (!unitType.IsEnum)
107+
{
108+
throw new ArgumentException($"Unit type must be an enumeration, but was {unitType.FullName}.");
109+
}
110+
111+
return new UnitKey(unitType, unitValue);
112+
}
113+
84114
/// <summary>
85115
/// Implicitly converts an enumeration value to a <see cref="UnitKey" />.
86116
/// </summary>
@@ -111,7 +141,7 @@ public static implicit operator UnitKey(Enum unit)
111141
/// </remarks>
112142
public static explicit operator Enum(UnitKey unitKey)
113143
{
114-
return (Enum)Enum.ToObject(unitKey._unitType, unitKey._unitValue);
144+
return (Enum)Enum.ToObject(unitKey._unitEnumType, unitKey._unitEnumValue);
115145
}
116146

117147
/// <summary>
@@ -129,25 +159,25 @@ public static explicit operator Enum(UnitKey unitKey)
129159
/// </remarks>
130160
public TUnit ToUnit<TUnit>() where TUnit : struct, Enum
131161
{
132-
if (typeof(TUnit) != _unitType)
162+
if (typeof(TUnit) != _unitEnumType)
133163
{
134-
throw new InvalidOperationException($"Cannot convert UnitKey of type {_unitType} to {typeof(TUnit)}.");
164+
throw new InvalidOperationException($"Cannot convert UnitKey of type {_unitEnumType} to {typeof(TUnit)}.");
135165
}
136166

137-
var unitValue = _unitValue;
167+
var unitValue = _unitEnumValue;
138168
return Unsafe.As<int, TUnit>(ref unitValue);
139169
}
140170

141171
private string GetDebuggerDisplay()
142172
{
143173
try
144174
{
145-
var unitName = Enum.GetName(_unitType, _unitValue);
146-
return string.IsNullOrEmpty(unitName) ? $"{nameof(UnitType)}: {_unitType}, {nameof(UnitValue)} = {_unitValue}" : $"{_unitType.Name}.{unitName}";
175+
var unitName = Enum.GetName(_unitEnumType, _unitEnumValue);
176+
return string.IsNullOrEmpty(unitName) ? $"{nameof(UnitEnumType)}: {_unitEnumType}, {nameof(UnitEnumValue)} = {_unitEnumValue}" : $"{_unitEnumType.Name}.{unitName}";
147177
}
148178
catch
149179
{
150-
return $"{nameof(UnitType)}: {_unitType}, {nameof(UnitValue)} = {_unitValue}";
180+
return $"{nameof(UnitEnumType)}: {_unitEnumType}, {nameof(UnitEnumValue)} = {_unitEnumValue}";
151181
}
152182
}
153183

@@ -162,8 +192,8 @@ private string GetDebuggerDisplay()
162192
/// </remarks>
163193
public void Deconstruct(out Type unitType, out int unitValue)
164194
{
165-
unitType = _unitType;
166-
unitValue = _unitValue;
195+
unitType = _unitEnumType;
196+
unitValue = _unitEnumValue;
167197
}
168198

169199
#region Equality members
@@ -172,21 +202,21 @@ public void Deconstruct(out Type unitType, out int unitValue)
172202
public bool Equals(UnitKey other)
173203
{
174204
// implementing the Equality members on net48 is 5x faster than the default
175-
return _unitType == other._unitType && _unitValue == other._unitValue;
205+
return _unitEnumType == other._unitEnumType && _unitEnumValue == other._unitEnumValue;
176206
}
177207

178208
/// <inheritdoc />
179209
public override int GetHashCode()
180210
{
181211
// implementing the Equality members on net48 is 5x faster than the default
182-
if (_unitType == null)
212+
if (_unitEnumType == null)
183213
{
184-
return _unitValue;
214+
return _unitEnumValue;
185215
}
186216

187217
unchecked
188218
{
189-
return (_unitType.GetHashCode() * 397) ^ _unitValue;
219+
return (_unitEnumType.GetHashCode() * 397) ^ _unitEnumValue;
190220
}
191221
}
192222

0 commit comments

Comments
 (0)