[英]LINQ new instance when SingleOrDefault returns null
I have this simple method:我有这个简单的方法:
#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
As you can see I trying to return one result for a DeliveryAddress
and one result for an InvoiceAddress
.如您所见,我尝试为DeliveryAddress
返回一个结果,为InvoiceAddress
返回一个结果。 My problem is that I would like the link expression to create a new instance of Address()
if SingleOrDefault
returns null
.我的问题是,如果SingleOrDefault
返回null
,我希望链接表达式创建一个Address()
的新实例。 I am really new to linq, so I am not sure whether SingleOrDefault
is the correct expression I should be using.我对 linq 真的很SingleOrDefault
,所以我不确定SingleOrDefault
是否是我应该使用的正确表达式。
You could use DefaultIfEmpty
and use that instance as default value:您可以使用DefaultIfEmpty
并将该实例用作默认值:
return _addresses.Where(x => x.TypeId == AddressType.Delivery)
.DefaultIfEmpty(new Adress())
.Single();
Use the null-coalescing operator :使用空合并运算符:
return _addresses
.SingleOrDefault(x => x.TypeId == AddressType.Delivery) ?? new Address();
The expression表达方式
x ?? y
yields x
if x
is not null
, otherwise y
.如果x
不为null
,则产生x
,否则产生y
。 You can chain the operator您可以链接运营商
x ?? y ?? z ?? t
This returns the first non-null value or null
if all of them are null
.这将返回第一个非 null 值或null
如果它们都是null
。
UPDATE更新
Note that SingleOrDefault
throws an exception if the sequence has more than one element.请注意,如果序列具有多个元素,则SingleOrDefault
会引发异常。 If you need the first element of a sequence possibly having no or more than one element, use FirstOrDefault
instead.如果您需要序列的第一个元素可能没有或多个元素,请改用FirstOrDefault
。
You could create your own extension method, like this:您可以创建自己的扩展方法,如下所示:
public static T NewIfNull<T>(this T obj) where T: class, new()
{
return obj ?? new T();
}
... then tack a usage onto the end of SingleOrDefault: ...然后在 SingleOrDefault 的末尾添加一个用法:
var singleResult = myCollection.SingleOrDefault().NewIfNull();
... or because the logic is so simple, just inline it as other answers have said. ...或者因为逻辑如此简单,就像其他答案所说的那样将其内联。
Instead of代替
return _addresses.SingleOrDefault(x => x.TypeId == AddressType.Delivery);
Do something like this:做这样的事情:
var address = _addresses.SingleOrDefault(x => x.TypeId == AddressType.Delivery);
if(address == null)
address = new Address();
return address;
I'd be inclined to write both of these as extension methods on IEnumerable<Address>
.我倾向于将这两个都写为IEnumerable<Address>
上的扩展方法。 You can use the null-coalesing operator to return a new instance if the SingleOrDefault()
call returns null
.如果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();
}
}
Apart from alternatives in other answers, you can also create your own SingleOrNew
Extension method.除了其他答案中的替代方案,您还可以创建自己的SingleOrNew
扩展方法。
public static TSource SingleOrNew<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate ) where T:new()
{
return source.SingleOrDefault(predicate) ?? new T();
}
It can be used as它可以用作
return _addresses.SingleOrNew(x => x.TypeId == AddressType.Delivery);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.