我有一个代码,可以被认为是重复的:
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);
字符串
这些方法之间的唯一区别只是字段名称,如Width, Height, Diameter, Weight
。有没有可能用一个字符串属性名替换这些名称,并在不使用任何第三方库的情况下只创建一个方法?
4条答案
按热度按时间ifmq2ha21#
您可以为此创建简单的扩展:
字符串
然后这样使用:
型
k10s72fa2#
因为你使用IEnumerable,参数只是选择和检查值,你可以 * 反转 * 操作来选择值并过滤空值。您仍然在执行相同的简单操作-检查所有值,但只允许非空值:
字符串
您可以将其转换为表达式方法:
型
oknwwptz3#
在这个特定的例子中,我将引入一个单独的方法来执行null检查。类似于:
字符串
368yc8dk4#
如果你真的想用一个字符串来指示要获取的属性,你可以构建一个动态选择作为扩展方法。
此外,通过将
Where().Select()
切换到Select().Where()
,您也只需要一个动态表达式。即字符串
那么,如何构建动态过滤器呢?
你可以这样做--基于我对类似问题的回答
型
然后可以在代码中使用它
型
UPDATE -完全通用版本
要使这个完全通用是相当容易的
Rectangle with
Tand
十进制替换?with TOut, of course you need to update the method signature a little with the generic type parameters to
<T,TOut>`注意从
.Where(x => x.HasValue)
变回`。其中(x => x!= null)型
这也需要稍微调整它的调用方式:
型