.net FirstOrDefault:非null的默认值
据我所知,在Linq中,方法.net FirstOrDefault:非null的默认值,.net,linq,.net,Linq,据我所知,在Linq中,方法FirstOrDefault()可以返回一个Default值,而不是null。我还没有弄清楚的是,当查询结果中没有项时,这个(和类似的)方法可以返回除null以外的其他什么类型的内容。是否有任何特定的方法可以设置该查询,以便在特定查询没有值时,将某个预定义值作为默认值返回 据我所知,在Linq中,FirstOrDefault()方法可以返回非null的默认值 否。或者更确切地说,它总是返回元素类型的默认值。。。它可以是null引用、可为null的值类型的null值,也
FirstOrDefault()
可以返回一个Default
值,而不是null。我还没有弄清楚的是,当查询结果中没有项时,这个(和类似的)方法可以返回除null以外的其他什么类型的内容。是否有任何特定的方法可以设置该查询,以便在特定查询没有值时,将某个预定义值作为默认值返回
据我所知,在Linq中,FirstOrDefault()方法可以返回非null的默认值
否。或者更确切地说,它总是返回元素类型的默认值。。。它可以是null引用、可为null的值类型的null值,也可以是不可为null的值类型的自然“全零”值 是否有任何特定的方法可以设置该查询,以便在特定查询没有值时,将某个预定义值作为默认值返回 对于引用类型,您可以只使用:
var result = query.FirstOrDefault() ?? otherDefaultValue;
当然,如果第一个值存在,但为空引用,则这也将为您提供“其他默认值”… 如果源为空,[返回]默认值(TSource)
从以下文件中: 默认关键字,对于引用类型将返回null,对于数值类型将返回零。对于结构,它将返回初始化为零或null的结构的每个成员,具体取决于它们是值类型还是引用类型。对于可为Null的值类型,默认值返回System.nullable,它与任何结构一样初始化
因此,根据类型是引用类型还是值类型,默认值可以为null或0,但您无法控制默认行为。一般情况,而不仅仅是值类型:
static class ExtensionsThatWillAppearOnEverything
{
public static T IfDefaultGiveMe<T>(this T value, T alternate)
{
if (value.Equals(default(T))) return alternate;
return value;
}
}
var result = query.FirstOrDefault().IfDefaultGiveMe(otherDefaultValue);
尽管正如Steak先生指出的那样,这也可以通过.DefaultIfEmpty(…).First()
来完成。您可以使用,然后是:
T自定义默认值=。。。;
IEnumerable mySequence=。。。;
mySequence.DefaultIfEmpty(customDefault.First();
您也可以这样做
Band[] objects = { new Band { Name = "Iron Maiden" } };
first = objects.Where(o => o.Name == "Slayer")
.DefaultIfEmpty(new Band { Name = "Black Sabbath" })
.FirstOrDefault(); // returns "Black Sabbath"
这只使用linq-yipee 从@sloth的评论中复制过来
例如,可以使用
YourCollection.DefaultIfEmpty(yourdault).First()
,而不是YourCollection.FirstOrDefault()
例如:
var viewModel = new CustomerDetailsViewModel
{
MainResidenceAddressSection = (MainResidenceAddressSection)addresses.DefaultIfEmpty(new MainResidenceAddressSection()).FirstOrDefault( o => o is MainResidenceAddressSection),
RiskAddressSection = addresses.DefaultIfEmpty(new RiskAddressSection()).FirstOrDefault(o => !(o is MainResidenceAddressSection)),
};
static class MyClass
{
public enum Level { Low, Medium, High }
public static void Dosomething()
{
var levels = Enum.GetValues<Level>();
var myLevel = levels.Select(x => (Level?)x).FirstOrDefault() ?? Level.Medium; // The Default value other than null
}
}
使用
DefaultIfEmpty()
而不是FirstOrDefault()
而不是YourCollection.FirstOrDefault()
,您可以使用YourCollection.DefaultIfEmpty(YourDefault.First()
例如。实际上,我在处理集合时使用两种方法来避免NullReferenceException
:
公共类Foo
{
公共字符串条{get;set;}
}
void Main()
{
var list=新列表();
//在C#6.0之前
string barCSharp5=list.DefaultIfEmpty(new Foo()).FirstOrDefault().Bar;
//C#6.0或更高版本
var barCSharp6=list.FirstOrDefault()?.Bar;
}
对于C#6.0或更高版本:
在执行成员访问之前,使用?。
或?[
测试是否为null
例如:
var barCSharp6=list.FirstOrDefault()?.Bar;
C#旧版本:
如果序列为空,请使用DefaultIfEmpty()
检索默认值
例如:
string barCSharp5=list.DefaultIfEmpty(new Foo()).FirstOrDefault().Bar;
我也遇到过类似的情况,我正在寻找一种解决方案,允许我在每次需要时返回一个可选的默认值,而不必在调用方处理它。如果Linq不支持我们想要的,我们通常会做的是编写一个新的扩展来处理它。这就是我所做的。下面是我要做的我提出了(但未经测试):
公共静态类EnumerableExtensions
{
公共静态T FirstOrDefault(此IEnumerable items,T defaultValue)
{
foreach(项目中的var项目)
{
退货项目;
}
返回默认值;
}
公共静态T FirstOrDefault(此IEnumerable项、Func谓词、T defaultValue)
{
返回项.Where(谓词).FirstOrDefault(默认值);
}
公共静态T LastOrDefault(此IEnumerable items,T defaultValue)
{
return items.Reverse().FirstOrDefault(默认值);
}
公共静态T LastOrDefault(此IEnumerable项、Func谓词、T defaultValue)
{
返回项.Where(谓词).LastOrDefault(默认值);
}
}
我知道这已经有一段时间了,但我会根据最流行的答案补充一下,不过有一点扩展,我想分享以下内容:
static class ExtensionsThatWillAppearOnIEnumerables
{
public static T FirstOr<T>(this IEnumerable<T> source, Func<T, bool> predicate, Func<T> alternate)
{
var thing = source.FirstOrDefault(predicate);
if (thing != null)
return thing;
return alternate();
}
}
对我来说,我只需要一个默认的分解器来使用内联,我可以做我平常的检查,然后在一个函数中传递,这样一个类即使没有被使用也不会被实例化,它是一个在需要时执行的函数。这是您想要的默认值 例如:
var viewModel = new CustomerDetailsViewModel
{
MainResidenceAddressSection = (MainResidenceAddressSection)addresses.DefaultIfEmpty(new MainResidenceAddressSection()).FirstOrDefault( o => o is MainResidenceAddressSection),
RiskAddressSection = addresses.DefaultIfEmpty(new RiskAddressSection()).FirstOrDefault(o => !(o is MainResidenceAddressSection)),
};
static class MyClass
{
public enum Level { Low, Medium, High }
public static void Dosomething()
{
var levels = Enum.GetValues<Level>();
var myLevel = levels.Select(x => (Level?)x).FirstOrDefault() ?? Level.Medium; // The Default value other than null
}
}
静态类MyClass
{
公共枚举级别{低、中、高}
公共静态无效剂量测定法()
{
var levels=Enum.GetValues();
var myLevel=levels.Select(x=>(Level?)x.FirstOrDefault()???Level.Medium;//非null的默认值
}
}
这对我们很有效
int valueOrDefault = myList.Find(x => x.Id == 1)?.Value ?? -1;
您可以使用
YourCollection.DefaultIfEmpty(yourlefault.FirstOrDefault())而不是YourCollection.FirstOrDefault()
例如,我一直在寻找类似上述注释的内容,很有帮助。这应该是公认的答案。上述注释是最好的答案。在我的例子中,当返回的值可为null且分配给不可为null的值时,@sloth answer不起作用。我使用了MyCollection.Last().GetValuerDefault(0)
。否则@Jon Skeet下面的答案在我看来是正确的。您的通用方法需要
static class ExtensionsThatWillAppearOnIEnumerables
{
public static T FirstOr<T>(this IEnumerable<T> source, Func<T, bool> predicate, Func<T> alternate)
{
var thing = source.FirstOrDefault(predicate);
if (thing != null)
return thing;
return alternate();
}
}
_controlDataResolvers.FirstOr(x => x.AppliesTo(item.Key), () => newDefaultResolver()).GetDataAsync(conn, item.ToList())
static class MyClass
{
public enum Level { Low, Medium, High }
public static void Dosomething()
{
var levels = Enum.GetValues<Level>();
var myLevel = levels.Select(x => (Level?)x).FirstOrDefault() ?? Level.Medium; // The Default value other than null
}
}
int valueOrDefault = myList.Find(x => x.Id == 1)?.Value ?? -1;