I have the code which can be considered as repetetive:
private IEnumerable<decimal?> GetWidth(IEnumerable<Rectangle> rectangles) =>
rectangles.Where(s => s.Width != null)
.Select(s => s.Width);
private IEnumerable<decimal?> GetHeight(IEnumerable<Rectangle> rectangles) =>
rectangles.Where(s => s.Height != null)
.Select(s => s.Height);
private IEnumerable<decimal?> GetDiameter(IEnumerable<Rectangle> rectangles) =>
rectangles.Where(s => s.Diameter != null)
.Select(s => s.Diameter);
private IEnumerable<decimal?> GetWeight(IEnumerable<Rectangle> rectangles) =>
rectangles.Where(s => s.Weight != null)
.Select(s => s.Weight);
The only difference between these methods is just field names such as Width, Height, Diameter, Weight
. Is it possible to replace these names with a string property name and create just one method without using any third party libraries?
You can create simple extension for that:
public static class EnumerableExtensions
{
public static IEnumerable<TValue> ExtractValues<TEntity, TValue>(
this IEnumerable<TEntity> items,
Func<TEntity, TValue?> selector)
{
return items.Where(i => selector(i) != null)
.Select(i => selector(i)!);
}
}
And use it like this:
var heights = items.ExtractValues(i => i.Height);
var diameters = items.ExtractValues(i => i.Diameter);