LINQ中的SingleOrNew()方法而不是SingleOrDefault()怎么样?

JC *_*bbs 10 c# linq

SingleOrDefault()方法很棒,因为如果您调用它的集合为空,它不会抛出异常.但是,有时我想要的是获取某种类型的新对象(如果不存在).例如,如果我能做到以下几点会很棒:

var client = db.Clients
    .Where(c => c.Name == "Some Client")
    .SingleOrNew<Client>();
Run Code Online (Sandbox Code Playgroud)

这样我就不必检查它null是否是创建一个新的,我总是知道我的client对象将是我可以立即使用的东西.

有任何想法吗?

Nol*_*rin 21

真的,你只想在这里使用null合并算子.例:

var client = db.Clients
    .Where(c => c.Name == "Some Client")
    .SingleOrDefault() ?? new Client();
Run Code Online (Sandbox Code Playgroud)

这将返回SingleOrDefault返回的任何内容,但如果SingleOrDefault返回null,则表达式返回新的Client().

编辑:正如John Skeet指出的那样,这个解决方案没有区分没有匹配的情况和找到空元素的情况,但显然在许多情况下这不一定是个问题.另一种方法是创建如下的扩展方法.

public static T SingleOrNew<T>(this IEnumerable<T> query) where T : new()
{
    try
    {
        return query.Single();
    }
    catch (InvalidOperationException)
    {
        return new T();
    }
}
Run Code Online (Sandbox Code Playgroud)

我想说这可能是一般案例中最优雅的解决方案.


Eri*_*ing 9

如果你想要完成的只是覆盖默认值(并返回一个新对象),你可以在调用SingleOrDefault()之前使用DefaultIfEmpty()方法.就像是:

var client = db.Clients
    .Where(c => c.Name == name)
    .DefaultIfEmpty(new Client { Name = name })
    .SingleOrDefault();
Run Code Online (Sandbox Code Playgroud)


Ana*_*tts 1

那么为什么不通过扩展方法添加它呢?听起来好像会很方便。