微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c# – Linq选择哪里

我经常发现自己写的是这样的:
var fields = _type.GetProperties()
            .Select(prop => new { Prop = prop,Attrib = prop.GetCustomAttribute<ColumnAttribute>() })
            .Where(t => t.Attrib != null)
            .ToList();

我感到困扰的是,在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);

有没有更好的模式/扩展方法我错过了?或者LINQ是否可以在封面下进行优化?

非常感激!

更新:

我想这是我的意思,但我期待已经存在的东西已经存在,而我只是在寻找不好的东西:

public static IEnumerable<TResult> SelectWhereNotNull<TSource,TValue,TResult>(this IEnumerable<TSource> source,Func<TSource,TValue> valueSelector,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);

解决方法

对于您正在执行的查询类型,您无法真正解决它.您将希望有一个位置将该属性放在某处.无论是将其隐藏在单独的方法中还是对结果对象进行操作,都必须完成.担心它会适得其反.但是有一些方法可以让它更具可读性.

如果您在查询语法中重写了查询,则可以隐藏它正在完成的事实

var fields =
    from prop in _type.GetProperties()
    let attr = prop.GetCustomAttribute<ColumnAttribute>()
    where attr != null
    select new
    {
        Prop = prop,Attrib = attr,};

然而,对于这个,我可能会将它打包在一台发电机中.它不需要用LINQ编写,如果你尝试的话,你会严重限制自己.

public static IEnumerable<TResult> SelectWhere<TSource,TResult>(
        this IEnumerable<TSource> source,bool> predicate,TResult> resultSelector)
{
    foreach (var item in source)
    {
        var value = valueSelector(item);
        if (predicate(item,value))
            yield return resultSelector(item,value);
    }
}

您的查询变为:

var fields = _type.GetProperties()
    .SelectWhere(
        p => p.GetCustomAttribute<ColumnAttribute>(),(p,a) => a != null,a) => new { Prop = p,Attrib = a }
    )
    .ToList();

原文地址:https://www.jb51.cc/csharp/100687.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐