Skip to content

Commit da9f7dc

Browse files
authored
♻️Move extension methods to UnitInfo (#1579)
Extension methods on collections of a specific item type is not always easy to read or reason about. - Convert to static utility methods and move to `UnitInfo`, the type of item the methods take. - Change to `internal`
1 parent d21e526 commit da9f7dc

File tree

3 files changed

+88
-89
lines changed

3 files changed

+88
-89
lines changed

UnitsNet/CustomCode/QuantityInfo/QuantityInfoExtensions.cs

Lines changed: 0 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -26,62 +26,6 @@ public static IEnumerable<QuantityInfo> GetQuantitiesWithBaseDimensions(this IEn
2626
return quantityInfos.Where(info => info.BaseDimensions.Equals(baseDimensions));
2727
}
2828

29-
/// <summary>
30-
/// Filters a collection of unit information based on the specified base units.
31-
/// </summary>
32-
/// <typeparam name="TUnitInfo">The type of the unit information.</typeparam>
33-
/// <param name="unitInfos">The collection of unit information to filter.</param>
34-
/// <param name="baseUnits">The base units to filter by.</param>
35-
/// <returns>An <see cref="IEnumerable{T}" /> containing the unit information that matches the specified base units.</returns>
36-
/// <exception cref="ArgumentNullException">Thrown when <paramref name="baseUnits" /> is null.</exception>
37-
public static IEnumerable<TUnitInfo> GetUnitInfosFor<TUnitInfo>(this IEnumerable<TUnitInfo> unitInfos, BaseUnits baseUnits)
38-
where TUnitInfo : UnitInfo
39-
{
40-
if (baseUnits is null)
41-
{
42-
throw new ArgumentNullException(nameof(baseUnits));
43-
}
44-
45-
return unitInfos.Where(unitInfo => unitInfo.BaseUnits.IsSubsetOf(baseUnits));
46-
}
47-
48-
/// <summary>
49-
/// Gets the <see cref="UnitInfo" /> whose <see cref="BaseUnits" /> is a subset of <paramref name="baseUnits" />.
50-
/// </summary>
51-
/// <example>
52-
/// Length.Info.GetUnitInfoFor(unitSystemWithFootAsLengthUnit) returns <see cref="UnitInfo" /> for
53-
/// <see cref="LengthUnit.Foot" />.
54-
/// </example>
55-
/// <param name="unitInfos">The collection of unit information to filter.</param>
56-
/// <param name="baseUnits">The <see cref="BaseUnits" /> to check against.</param>
57-
/// <returns>
58-
/// The <see cref="UnitInfo" /> that has <see cref="BaseUnits" /> that is a subset of
59-
/// <paramref name="baseUnits" />.
60-
/// </returns>
61-
/// <exception cref="ArgumentNullException"><paramref name="baseUnits" /> is null.</exception>
62-
/// <exception cref="InvalidOperationException">No unit was found that is a subset of <paramref name="baseUnits" />.</exception>
63-
/// <exception cref="InvalidOperationException">
64-
/// More than one unit was found that is a subset of
65-
/// <paramref name="baseUnits" />.
66-
/// </exception>
67-
public static TUnitInfo GetUnitInfoFor<TUnitInfo>(this IEnumerable<TUnitInfo> unitInfos, BaseUnits baseUnits)
68-
where TUnitInfo : UnitInfo
69-
{
70-
using IEnumerator<TUnitInfo> enumerator = unitInfos.GetUnitInfosFor(baseUnits).GetEnumerator();
71-
if (!enumerator.MoveNext())
72-
{
73-
throw new InvalidOperationException($"No unit was found that is a subset of {nameof(baseUnits)}");
74-
}
75-
76-
TUnitInfo firstUnitInfo = enumerator.Current!;
77-
if (enumerator.MoveNext())
78-
{
79-
throw new InvalidOperationException($"More than one unit was found that is a subset of {nameof(baseUnits)}");
80-
}
81-
82-
return firstUnitInfo;
83-
}
84-
8529
/// <summary>
8630
/// Retrieves the default unit for a specified quantity and unit system.
8731
/// </summary>

UnitsNet/QuantityInfo.cs

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ public UnitInfo BaseUnitInfo
7070
{
7171
get => GetGenericBaseUnitInfo();
7272
}
73-
73+
7474
/// <inheritdoc cref="BaseUnitInfo" />
7575
protected internal abstract UnitInfo GetGenericBaseUnitInfo();
7676

@@ -93,13 +93,13 @@ public IReadOnlyList<UnitInfo> UnitInfos
9393
/// <inheritdoc />
9494
public UnitInfo GetUnitInfoFor(BaseUnits baseUnits)
9595
{
96-
return UnitInfos.GetUnitInfoFor(baseUnits);
96+
return UnitInfo.GetUnitWithBase(UnitInfos, baseUnits);
9797
}
9898

9999
/// <inheritdoc />
100100
public IEnumerable<UnitInfo> GetUnitInfosFor(BaseUnits baseUnits)
101101
{
102-
return UnitInfos.GetUnitInfosFor(baseUnits);
102+
return UnitInfo.GetUnitsWithBase(UnitInfos, baseUnits);
103103
}
104104

105105
/// <summary>
@@ -142,7 +142,7 @@ protected QuantityInfo(string name, Type quantityType, BaseDimensions baseDimens
142142
{
143143
get => GetBaseUnitInfo();
144144
}
145-
145+
146146
/// <inheritdoc cref="BaseUnitInfo" />
147147
protected internal abstract UnitInfo<TUnit> GetBaseUnitInfo();
148148

@@ -179,28 +179,28 @@ public UnitInfo<TUnit> this[TUnit unit]
179179
/// <returns>An <see cref="UnitInfo{TUnit}" /> instance containing information about the specified unit.</returns>
180180
/// <exception cref="ArgumentException">Thrown if the specified unit is not valid for this quantity.</exception>
181181
protected internal abstract UnitInfo<TUnit> GetUnitInfo(TUnit unit);
182-
182+
183183
// /// <inheritdoc cref="QuantityInfo.TryGetUnitInfo" />
184184
// public abstract bool TryGetUnitInfo(TUnit unit, [NotNullWhen(true)] out UnitInfo<TUnit>? unitInfo);
185-
185+
186186
/// <inheritdoc cref="QuantityInfo.GetUnitInfoFor" />
187187
public new UnitInfo<TUnit> GetUnitInfoFor(BaseUnits baseUnits)
188188
{
189-
return UnitInfos.GetUnitInfoFor(baseUnits);
189+
return UnitInfo.GetUnitWithBase(UnitInfos, baseUnits);
190190
}
191-
191+
192192
/// <inheritdoc cref="QuantityInfo.GetUnitInfosFor" />
193193
public new IEnumerable<UnitInfo<TUnit>> GetUnitInfosFor(BaseUnits baseUnits)
194194
{
195-
return UnitInfos.GetUnitInfosFor(baseUnits);
195+
return UnitInfo.GetUnitsWithBase(UnitInfos, baseUnits);
196196
}
197-
197+
198198
/// <inheritdoc cref="QuantityInfo.From" />
199199
public IQuantity<TUnit> From(double value, TUnit unit)
200200
{
201201
return CreateGenericQuantity(value, unit);
202202
}
203-
203+
204204
/// <inheritdoc cref="From(double,TUnit)" />
205205
protected internal abstract IQuantity<TUnit> CreateGenericQuantity(double value, TUnit unit);
206206

@@ -286,7 +286,7 @@ protected QuantityInfoBase(string name, TQuantity zero, BaseDimensions baseDimen
286286

287287
private QuantityFromDelegate<TQuantity, TUnit> FromDelegate { get; }
288288

289-
289+
290290
#region Implementation of IQuantityInfo<TQuantity, TUnit>
291291

292292
/// <inheritdoc cref="IQuantityInfo.Zero" />
@@ -307,13 +307,13 @@ protected QuantityInfoBase(string name, TQuantity zero, BaseDimensions baseDimen
307307
/// <inheritdoc cref="IQuantityInfo.GetUnitInfosFor" />
308308
public new IEnumerable<TUnitInfo> GetUnitInfosFor(BaseUnits baseUnits)
309309
{
310-
return UnitInfos.GetUnitInfosFor(baseUnits);
310+
return UnitInfo.GetUnitsWithBase(UnitInfos, baseUnits);
311311
}
312312

313313
/// <inheritdoc cref="IQuantityInfo.GetUnitInfoFor" />
314314
public new TUnitInfo GetUnitInfoFor(BaseUnits baseUnits)
315315
{
316-
return UnitInfos.GetUnitInfoFor(baseUnits);
316+
return UnitInfo.GetUnitWithBase(UnitInfos, baseUnits);
317317
}
318318

319319
/// <summary>
@@ -334,7 +334,7 @@ TQuantity IQuantityInstanceInfo<TQuantity>.Create(double value, UnitKey unitKey)
334334
}
335335

336336
#endregion
337-
337+
338338
#region Overrides of QuantityInfo<TUnit>
339339

340340
/// <inheritdoc />
@@ -393,9 +393,9 @@ public class QuantityInfo<TQuantity, TUnit> : QuantityInfoBase<TQuantity, TUnit,
393393

394394
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
395395
private readonly UnitInfo<TQuantity, TUnit>[] _unitInfos;
396-
396+
397397
#if NET
398-
398+
399399
/// <summary>
400400
/// Initializes a new instance of the <see cref="QuantityInfo{TQuantity, TUnit}" /> class using the default quantity name.
401401
/// </summary>
@@ -413,7 +413,7 @@ public QuantityInfo(TUnit baseUnit, IEnumerable<IUnitDefinition<TUnit>> unitMapp
413413
: this(typeof(TQuantity).Name, baseUnit, unitMappings, baseDimensions, TQuantity.From, unitAbbreviations)
414414
{
415415
}
416-
416+
417417
/// <summary>
418418
/// Initializes a new instance of the <see cref="QuantityInfo{TQuantity, TUnit}" /> class.
419419
/// </summary>
@@ -432,7 +432,7 @@ public QuantityInfo(string name, TUnit baseUnit, IEnumerable<IUnitDefinition<TUn
432432
: this(name, baseUnit, unitMappings, TQuantity.From(0, baseUnit), baseDimensions, TQuantity.From, unitAbbreviations)
433433
{
434434
}
435-
435+
436436
#endif
437437

438438
/// <summary>
@@ -454,7 +454,7 @@ public QuantityInfo(TUnit baseUnit, IEnumerable<IUnitDefinition<TUnit>> unitMapp
454454
: this(typeof(TQuantity).Name, baseUnit, unitMappings, baseDimensions, fromDelegate, unitAbbreviations)
455455
{
456456
}
457-
457+
458458
/// <summary>
459459
/// Initializes a new instance of the <see cref="QuantityInfo{TQuantity, TUnit}" /> class.
460460
/// </summary>
@@ -554,7 +554,7 @@ public sealed override IReadOnlyList<UnitInfo<TQuantity, TUnit>> UnitInfos
554554
#endregion
555555

556556
#region Explicit implementation of IQuantityInfo<TUnit>
557-
557+
558558
// [DebuggerBrowsable(DebuggerBrowsableState.Never)]
559559
// IReadOnlyCollection<UnitInfo<TUnit>> IQuantityInfo<TUnit>.UnitInfos
560560
// {
@@ -605,13 +605,13 @@ public sealed override IReadOnlyList<UnitInfo<TQuantity, TUnit>> UnitInfos
605605
// get => Zero;
606606
// }
607607

608-
608+
609609
// /// <inheritdoc />
610610
// TQuantity IQuantityInstanceInfo<TQuantity>.Create(QuantityValue value, UnitKey unitKey)
611611
// {
612612
// return From(value, unitKey.ToUnit<TUnit>());
613613
// }
614-
614+
615615
#endregion
616616

617617
#region Implementation of IQuantityInfo<TQuantity,TUnit>

UnitsNet/UnitInfo.cs

Lines changed: 65 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
// Licensed under MIT No Attribution, see LICENSE file at the root.
22
// Copyright 2013 Andreas Gullberg Larsen ([email protected]). Maintained at https://github.com/angularsen/UnitsNet.
33

4-
using System;
5-
using System.Diagnostics;
6-
using UnitsNet.Units;
4+
using System.Linq;
75

86
namespace UnitsNet;
97

@@ -37,13 +35,13 @@ protected internal UnitInfo(IUnitDefinition mapping)
3735
PluralName = mapping.PluralName;
3836
BaseUnits = mapping.BaseUnits;
3937
}
40-
38+
4139
/// <inheritdoc />
4240
public override string ToString()
4341
{
4442
return Name;
4543
}
46-
44+
4745
#region Implementation of IUnitDefinition
4846

4947
/// <inheritdoc />
@@ -70,7 +68,7 @@ public Enum Value
7068

7169
/// <inheritdoc cref="Value" />
7270
protected abstract Enum GetUnitValue();
73-
71+
7472
/// <summary>
7573
/// Get the parent quantity information.
7674
/// </summary>
@@ -84,10 +82,10 @@ public QuantityInfo QuantityInfo
8482
{
8583
get => GetGenericInfo();
8684
}
87-
85+
8886
/// <inheritdoc cref="QuantityInfo" />
8987
protected internal abstract QuantityInfo GetGenericInfo();
90-
88+
9189
/// <summary>
9290
/// Gets the unique key representing the unit type and its corresponding value.
9391
/// </summary>
@@ -96,7 +94,7 @@ public QuantityInfo QuantityInfo
9694
/// as it avoids the boxing that would normally occur when casting the enum to <see cref="Enum" />.
9795
/// </remarks>
9896
public abstract UnitKey UnitKey { get; }
99-
97+
10098
/// <summary>
10199
/// Name of the quantity this unit belongs to.
102100
/// </summary>
@@ -106,7 +104,7 @@ public string QuantityName
106104
{
107105
get => QuantityInfo.Name;
108106
}
109-
107+
110108
/// <summary>
111109
/// Creates an instance of <see cref="IQuantity" /> from the specified <paramref name="value" />.
112110
/// </summary>
@@ -124,6 +122,63 @@ public IQuantity From(double value)
124122
protected internal abstract IQuantity CreateGenericQuantity(double value);
125123

126124
#endregion
125+
126+
/// <summary>
127+
/// Filters a collection of unit information based on the specified base units.
128+
/// </summary>
129+
/// <typeparam name="TUnitInfo">The type of the unit information.</typeparam>
130+
/// <param name="unitInfos">The collection of unit information to filter.</param>
131+
/// <param name="baseUnits">The base units to filter by.</param>
132+
/// <returns>An <see cref="IEnumerable{T}" /> containing the unit information that matches the specified base units.</returns>
133+
/// <exception cref="ArgumentNullException">Thrown when <paramref name="baseUnits" /> is null.</exception>
134+
internal static IEnumerable<TUnitInfo> GetUnitsWithBase<TUnitInfo>(IEnumerable<TUnitInfo> unitInfos, BaseUnits baseUnits)
135+
where TUnitInfo : UnitInfo
136+
{
137+
if (baseUnits is null)
138+
{
139+
throw new ArgumentNullException(nameof(baseUnits));
140+
}
141+
142+
return unitInfos.Where(unitInfo => unitInfo.BaseUnits.IsSubsetOf(baseUnits));
143+
}
144+
145+
/// <summary>
146+
/// Gets the <see cref="UnitInfo" /> whose <see cref="UnitsNet.BaseUnits" /> is a subset of <paramref name="baseUnits" />.
147+
/// </summary>
148+
/// <example>
149+
/// Length.Info.GetUnitInfoFor(unitSystemWithFootAsLengthUnit) returns <see cref="UnitInfo" /> for
150+
/// <see cref="LengthUnit.Foot" />.
151+
/// </example>
152+
/// <param name="unitInfos">The collection of unit information to filter.</param>
153+
/// <param name="baseUnits">The <see cref="UnitsNet.BaseUnits" /> to check against.</param>
154+
/// <returns>
155+
/// The <see cref="UnitInfo" /> that has <see cref="UnitsNet.BaseUnits" /> that is a subset of
156+
/// <paramref name="baseUnits" />.
157+
/// </returns>
158+
/// <exception cref="ArgumentNullException"><paramref name="baseUnits" /> is null.</exception>
159+
/// <exception cref="InvalidOperationException">No unit was found that is a subset of <paramref name="baseUnits" />.</exception>
160+
/// <exception cref="InvalidOperationException">
161+
/// More than one unit was found that is a subset of
162+
/// <paramref name="baseUnits" />.
163+
/// </exception>
164+
internal static TUnitInfo GetUnitWithBase<TUnitInfo>(IEnumerable<TUnitInfo> unitInfos, BaseUnits baseUnits)
165+
where TUnitInfo : UnitInfo
166+
{
167+
using IEnumerator<TUnitInfo> enumerator = GetUnitsWithBase(unitInfos, baseUnits).GetEnumerator();
168+
169+
if (!enumerator.MoveNext())
170+
{
171+
throw new InvalidOperationException($"No unit was found that is a subset of {nameof(baseUnits)}");
172+
}
173+
174+
TUnitInfo firstUnitInfo = enumerator.Current!;
175+
if (enumerator.MoveNext())
176+
{
177+
throw new InvalidOperationException($"More than one unit was found that is a subset of {nameof(baseUnits)}");
178+
}
179+
180+
return firstUnitInfo;
181+
}
127182
}
128183

129184
/// <inheritdoc cref="UnitInfo"/> />

0 commit comments

Comments
 (0)