在 LINQ 中,选择属性 X 的所有值,其中 X != null

发布于 2024-10-20 22:54:58 字数 160 浏览 1 评论 0原文

有没有更简短的写法? (无需显式写入 != null 即可检查 null 的内容)

from item in list 
where item.MyProperty != null 
select item.MyProperty

Is there a shorter way to write the following? (Something that would check for null without explicitly writing != null)

from item in list 
where item.MyProperty != null 
select item.MyProperty

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

旧梦荧光笔 2024-10-27 22:54:58

您可以使用 OfType 运算符。它忽略源序列中的空值。只需使用与 MyProperty 相同的类型,它就不会过滤掉其他任何内容。

// given:
// public T MyProperty { get; }
var nonNullItems = list.Select(x => x.MyProperty).OfType<T>();

不过我建议不要这样做。如果您想选择非空值,还有什么比说您想要“列表中不为空的 MyProperties”更明确的呢?

You can use the OfType operator. It ignores null values in the source sequence. Just use the same type as MyProperty and it won't filter out anything else.

// given:
// public T MyProperty { get; }
var nonNullItems = list.Select(x => x.MyProperty).OfType<T>();

I would advise against this though. If you want to pick non-null values, what can be more explicit than saying you want "the MyProperties from the list that are not null"?

冰魂雪魄 2024-10-27 22:54:58

您可以定义自己的扩展方法,但我不建议这样做。

public static IEnumerable<TResult> SelectNonNull<T, TResult>(this IEnumerable<T> sequence,Func<T, TResult> projection)
{
   return sequence.Select(projection).Where(e => e != null);
}

我不喜欢这个,因为它混合了两个问题。使用 Select 进行投影和过滤 null 值是单独的操作,不应合并为一种方法。


我宁愿定义一个扩展方法,仅检查该项目是否为空:

public static IEnumerable<T> WhereNotNull<T>(this IEnumerable<T> sequence)
{
   return sequence.Where(e => e != null);
}

public static IEnumerable<T> WhereNotNull<T>(this IEnumerable<T?> sequence)
    where T : struct
{
   return sequence.Where(e => e != null).Select(e => e.Value);
}

这只有一个目的,检查是否为空。对于可为 null 的值类型,它会转换为不可为 null 的等效类型,因为为不能为 null 的值保留可为 null 的包装器是没有用的。

使用这种方法,您的代码将变为:

list.Select(item => item.MyProperty).WhereNotNull()

You could define your own extension method, but I wouldn't recommend that.

public static IEnumerable<TResult> SelectNonNull<T, TResult>(this IEnumerable<T> sequence,Func<T, TResult> projection)
{
   return sequence.Select(projection).Where(e => e != null);
}

I don't like this one because it mixes two concerns. Projecting with Select and filtering your null values are separate operations and should not be combined into one method.


I'd rather define an extension method that only checks if the item isn't null:

public static IEnumerable<T> WhereNotNull<T>(this IEnumerable<T> sequence)
{
   return sequence.Where(e => e != null);
}

public static IEnumerable<T> WhereNotNull<T>(this IEnumerable<T?> sequence)
    where T : struct
{
   return sequence.Where(e => e != null).Select(e => e.Value);
}

This has only a single purpose, checking for null. For nullable value types it converts to the non nullable equivalent, since it's useless to preserve the nullable wrapper for values which cannot be null.

With this method, your code becomes:

list.Select(item => item.MyProperty).WhereNotNull()
脸赞 2024-10-27 22:54:58

我倾向于创建一个包含此类情况基本函数的静态类。它们允许我编写类似于

var myValues myItems.Select(x => x.Value).Where(Predicates.IsNotNull);

谓词函数集合的表达式:

public static class Predicates
{
    public static bool IsNull<T>(T value) where T : class
    {
        return value == null;
    }

    public static bool IsNotNull<T>(T value) where T : class
    {
        return value != null;
    }

    public static bool IsNull<T>(T? nullableValue) where T : struct
    {
        return !nullableValue.HasValue;
    }

    public static bool IsNotNull<T>(T? nullableValue) where T : struct
    {
        return nullableValue.HasValue;
    }

    public static bool HasValue<T>(T? nullableValue) where T : struct
    {
        return nullableValue.HasValue;
    }

    public static bool HasNoValue<T>(T? nullableValue) where T : struct
    {
        return !nullableValue.HasValue;
    }
}

I tend to create a static class containing basic functions for cases like these. They allow me write expressions like

var myValues myItems.Select(x => x.Value).Where(Predicates.IsNotNull);

And the collection of predicate functions:

public static class Predicates
{
    public static bool IsNull<T>(T value) where T : class
    {
        return value == null;
    }

    public static bool IsNotNull<T>(T value) where T : class
    {
        return value != null;
    }

    public static bool IsNull<T>(T? nullableValue) where T : struct
    {
        return !nullableValue.HasValue;
    }

    public static bool IsNotNull<T>(T? nullableValue) where T : struct
    {
        return nullableValue.HasValue;
    }

    public static bool HasValue<T>(T? nullableValue) where T : struct
    {
        return nullableValue.HasValue;
    }

    public static bool HasNoValue<T>(T? nullableValue) where T : struct
    {
        return !nullableValue.HasValue;
    }
}
攒眉千度 2024-10-27 22:54:58

无法跳过检查是否存在。

There is no way to skip a check if it exists.

尾戒 2024-10-27 22:54:58

// 如果您需要检查所有项目的 MyProperty 是否不为 null

if (list.All(x => x.MyProperty != null))
// do something

// 或者如果您需要检查至少一个项目的属性是否不为 null

if (list.Any(x => x.MyProperty != null))
// do something

但您始终必须检查是否为 null

// if you need to check if all items' MyProperty doesn't have null

if (list.All(x => x.MyProperty != null))
// do something

// or if you need to check if at least one items' property has doesn't have null

if (list.Any(x => x.MyProperty != null))
// do something

But you always have to check for null

久而酒知 2024-10-27 22:54:58

在不同的选择中获取一列并忽略空值:

 var items = db.table.Where(p => p.id!=null).GroupBy(p => p.id)
                                .Select(grp => grp.First().id)
                                .ToList();

get one column in the distinct select and ignore null values:

 var items = db.table.Where(p => p.id!=null).GroupBy(p => p.id)
                                .Select(grp => grp.First().id)
                                .ToList();
银河中√捞星星 2024-10-27 22:54:58

这是改编自 CodesInChaos 的扩展方法。名称更短 (NotNull),更重要的是,将类型 (T) 限制为带有 where T : class 的引用类型。

    public static IEnumerable<T> NotNull<T>(this IEnumerable<T> source) where T : class
    {
        return source.Where(item => item != null);
    }

This is adapted from CodesInChaos's extension method. The name is shorter (NotNull) and more importantly, restricts the type (T) to reference types with where T : class.

    public static IEnumerable<T> NotNull<T>(this IEnumerable<T> source) where T : class
    {
        return source.Where(item => item != null);
    }
黑色毁心梦 2024-10-27 22:54:58

我知道我参加聚会有点晚了,但在我看来,我找到了一个非常优雅的解决方案来解决这个问题。我编写了一个扩展方法来链接到我的 LINQ 查询:

public static IEnumerable<T> DiscardNullValues<T>(this IEnumerable<T?> nullable)
    {
        foreach (var item in nullable)
        {
            if (item is not null) yield return item;
        }
    }

工作起来就像一个魅力。

I know i am a bit late to the party but I found a IMO very elegant sollution to this problem. I wrote an extension method to chain onto my LINQ queries:

public static IEnumerable<T> DiscardNullValues<T>(this IEnumerable<T?> nullable)
    {
        foreach (var item in nullable)
        {
            if (item is not null) yield return item;
        }
    }

Works like a charm.

风吹短裙飘 2024-10-27 22:54:58

这是已向 dotnet/runtime 问题跟踪器提出的一项功能。

请参阅此评论,其中提出了 SelectNotNull 函数:
https://github.com/dotnet/runtime/issues/30381#issuecomment- 806396119

This is a feature that have been proposed to the dotnet/runtime issue tracker.

See this comment that proposes a SelectNotNull function :
https://github.com/dotnet/runtime/issues/30381#issuecomment-806396119

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文