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

时间:2011-03-09 15:46:26

标签: c# linq

是否有更短的方式来编写以下内容? (在不明确写!= null)的情况下检查null的东西

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

8 个答案:

答案 0 :(得分:56)

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

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

我会建议不要这样做。如果你想选择非空值,那么可能比你想要“列表中的非属性的MyProperties”更明确吗?

答案 1 :(得分:33)

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

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的值是无用的。

使用此方法,您的代码变为:

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

答案 2 :(得分:11)

我倾向于为这样的情况创建一个包含基本函数的静态类。他们允许我写像

这样的表达式
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;
    }
}

答案 3 :(得分:4)

如果存在,则无法跳过检查。

答案 4 :(得分:1)

//如果你需要检查所有项目'MyProperty是否没有空

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

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

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

但你总是要检查空

答案 5 :(得分:1)

这是从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);
    }

答案 6 :(得分:1)

在唯一选择中获取一列,并忽略空值:

tidyr::extract(df, Address, c("Address", "City", "State", "Zip"), 
                   regex = "(.+) (\\w+) (\\w+) (\\w+)")

#                        Address    City State   Zip
#1 101 Marietta Street NorthWest Atlanta    GA 30303

答案 7 :(得分:1)

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

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

就像一个魅力。