[英]LINQ new instance when SingleOrDefault returns null
我有这个简单的方法:
#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
返回一个结果。 我的问题是,如果SingleOrDefault
返回null
,我希望链接表达式创建一个Address()
的新实例。 我对 linq 真的很SingleOrDefault
,所以我不确定SingleOrDefault
是否是我应该使用的正确表达式。
您可以使用DefaultIfEmpty
并将该实例用作默认值:
return _addresses.Where(x => x.TypeId == AddressType.Delivery)
.DefaultIfEmpty(new Adress())
.Single();
使用空合并运算符:
return _addresses
.SingleOrDefault(x => x.TypeId == AddressType.Delivery) ?? new Address();
表达方式
x ?? y
如果x
不为null
,则产生x
,否则产生y
。 您可以链接运营商
x ?? y ?? z ?? t
这将返回第一个非 null 值或null
如果它们都是null
。
更新
请注意,如果序列具有多个元素,则SingleOrDefault
会引发异常。 如果您需要序列的第一个元素可能没有或多个元素,请改用FirstOrDefault
。
您可以创建自己的扩展方法,如下所示:
public static T NewIfNull<T>(this T obj) where T: class, new()
{
return obj ?? new T();
}
...然后在 SingleOrDefault 的末尾添加一个用法:
var singleResult = myCollection.SingleOrDefault().NewIfNull();
...或者因为逻辑如此简单,就像其他答案所说的那样将其内联。
代替
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;
我倾向于将这两个都写为IEnumerable<Address>
上的扩展方法。 如果SingleOrDefault()
调用返回null
您可以使用空合并运算符返回一个新实例。
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();
}
}
除了其他答案中的替代方案,您还可以创建自己的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);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.