SingleOrDefault返回null时的LINQ新实例

时间:2012-12-30 18:55:16

标签: c# asp.net linq

另一个快速问题。 我有这个简单的方法:

    #region Fields

    private Collection<Address> _addresses;

    #endregion

    #region Public methods

    public Address DeliveryAddress()
    {
        if (_addresses == null)
            if (this.Id > 0)
                _addresses = Core.Data.Addresses.GetClient(this.Id);

        return _addresses.SingleOrDefault(x => x.TypeId == AddressType.Delivery);
    }

    public Address InvoiceAddress()
    {
        if (_addresses == null)
            if (this.Id > 0)
                _addresses = Core.Data.Addresses.GetClient(this.Id);

        return _addresses.SingleOrDefault(x => x.TypeId == AddressType.Invoice);
    }

    #endregion

正如您所看到的,我尝试为DeliveryAddress返回一个结果,为InvoiceAddress返回一个结果。我的问题是,如果Address()返回SingleOrDefault,我希望链接表达式创建null的新实例。 我对linq很新,所以我不确定SingleOrDefault是否是我应该使用的正确表达式。

6 个答案:

答案 0 :(得分:25)

您可以使用DefaultIfEmpty并将该实例用作默认值:

return _addresses.Where(x => x.TypeId == AddressType.Delivery)
                 .DefaultIfEmpty(new Adress())
                 .Single();

答案 1 :(得分:12)

使用null-coalescing operator

return _addresses
    .SingleOrDefault(x => x.TypeId == AddressType.Delivery) ?? new Address();

表达式

x ?? y
如果x不是x,则

产生null,否则为y。您可以链接运算符

x ?? y ?? z ?? t

如果所有值都为null,则返回第一个非空值或null


<强>更新

请注意,如果序列包含多个元素,SingleOrDefault将引发异常。如果您需要序列的第一个元素可能没有或多个元素,请改用FirstOrDefault

答案 2 :(得分:3)

您可以创建自己的扩展方法,如下所示:

public static T NewIfNull<T>(this T obj) where T: class, new()
{
   return obj ?? new T();
}

...然后将用法添加到SingleOrDefault的末尾:

var singleResult = myCollection.SingleOrDefault().NewIfNull();

...或者因为逻辑非常简单,只需像其他答案所说的那样内联。

答案 3 :(得分:1)

而不是

return _addresses.SingleOrDefault(x => x.TypeId == AddressType.Delivery);

做这样的事情:

var address = _addresses.SingleOrDefault(x => x.TypeId == AddressType.Delivery);

if(address == null)
    address = new Address();

return address;

答案 4 :(得分:0)

我倾向于将这两个作为IEnumerable<Address>的扩展方法。如果SingleOrDefault()调用返回null,您可以使用null-coalesing运算符返回新实例。

public static class AddressExtensions
{
    public static Address DeliveryAddress(this IEnumerable<Address> addresses)
    {
        return addresses.SingleOrDefault(x => x.TypeId == AddressType.Delivery) 
               ?? new Address();
    }

    public static Address InvoiceAddress(this IEnumerable<Address> addresses)
    {
        return addresses.SingleOrDefault(x => x.TypeId == AddressType.Invoice) 
               ?? new Address();
    }
}

答案 5 :(得分:0)

除了其他答案中的替代方法,您还可以创建自己的SingleOrNew扩展方法。

public static TSource SingleOrNew<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate ) where T:new()
{
     return source.SingleOrDefault(predicate) ?? new T();
}

可以用作

return _addresses.SingleOrNew(x => x.TypeId == AddressType.Delivery);