Gen*_*ene 7 c# linq linq-to-objects
我经常发现自己写的是这样的:
var fields = _type.GetProperties()
.Select(prop => new { Prop = prop, Attrib = prop.GetCustomAttribute<ColumnAttribute>() })
.Where(t => t.Attrib != null)
.ToList();
Run Code Online (Sandbox Code Playgroud)
我感到困扰的是,在where子句失败的情况下,我不必要地创建对象.虽然开销很小,但我仍然更愿意保存分配,就像我只是简单地循环它或者做得更痛苦一样:
var fields = _type.GetProperties()
.Select(prop =>
{
var attrib = prop.GetCustomAttribute<ColumnAttribute>();
return attrib == null ? null : new {Prop = prop, Attrib = attrib};
})
.Where(t => t != null);
Run Code Online (Sandbox Code Playgroud)
我缺少更好的模式/扩展方法吗?或者LINQ可以在封面下进行优化吗?
非常感激!
更新:
我想这是我的意思,但我期待已经存在的东西已经存在,我只是在寻找不好的东西:
public static IEnumerable<TResult> SelectWhereNotNull<TSource, TValue, TResult>(this IEnumerable<TSource> source, Func<TSource, TValue> valueSelector, Func<TSource, TValue, TResult> selector)
where TValue:class
where TResult:class
{
return source
.Select(s =>
{
var val = valueSelector(s);
if (val == null)
{
return null;
}
return selector(s, val);
})
.Where(r => r != null);
}
var fields = _type.GetProperties()
.SelectWhereNotNull(prop => prop.GetCustomAttribute<ColumnAttribute>(), Tuple.Create);
Run Code Online (Sandbox Code Playgroud)
Jef*_*ado 10
对于您正在执行的查询类型,您无法真正解决它.您将希望有一个位置将该属性放在某处.无论是将其隐藏在单独的方法中还是对结果对象进行操作,都必须完成.担心它会产生反作用.但有一些方法可以让它更具可读性.
如果您在查询语法中重写了查询,则可以隐藏它正在完成的事实
var fields =
from prop in _type.GetProperties()
let attr = prop.GetCustomAttribute<ColumnAttribute>()
where attr != null
select new
{
Prop = prop,
Attrib = attr,
};
Run Code Online (Sandbox Code Playgroud)
然而,对于这个,我可能会将其打包在发电机中.它并不需要在LINQ的方面来写,你会受到严重限制自己,如果你尝试.
public static IEnumerable<TResult> SelectWhere<TSource, TValue, TResult>(
this IEnumerable<TSource> source,
Func<TSource, TValue> valueSelector,
Func<TSource, TValue, bool> predicate,
Func<TSource, TValue, TResult> resultSelector)
{
foreach (var item in source)
{
var value = valueSelector(item);
if (predicate(item, value))
yield return resultSelector(item, value);
}
}
Run Code Online (Sandbox Code Playgroud)
您的查询变为:
var fields = _type.GetProperties()
.SelectWhere(
p => p.GetCustomAttribute<ColumnAttribute>(),
(p, a) => a != null,
(p, a) => new { Prop = p, Attrib = a }
)
.ToList();
Run Code Online (Sandbox Code Playgroud)