另一个快速问题。 我有这个简单的方法:
#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
是否是我应该使用的正确表达式。
答案 0 :(得分:25)
您可以使用DefaultIfEmpty
并将该实例用作默认值:
return _addresses.Where(x => x.TypeId == AddressType.Delivery)
.DefaultIfEmpty(new Adress())
.Single();
答案 1 :(得分:12)
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);