所以我收到了struct
的集合(它实际上是一个WCF数据合同,但我认为这与此无关)。
List<OptionalExtra> OptionalExtras;
OptionalExtra
是struct
。
public partial struct OptionalExtra
现在我正在运行以下声明:
OptionalExtra multiOptExtra = OptionalExtras.Where(w => w.Code == optExtra.Code).FirstOrDefault();
if (multiOptExtra != null)
{
}
现在这不会编译:
operator!=不能应用于OptionalExtra类型的opperands 和
'<null>'
经过一番谷歌搜索后,我意识到这一点,因为OptionalExtra
是struct
。除非定义为可空类型,否则我认为不可为空?
所以我的问题是,如果我的where
语句没有返回结果FirstOrDefault
调用的结果是什么?它会引发异常吗?
这个应该永远不会发生,但比抱歉更安全。
答案 0 :(得分:48)
如果您的收藏集为空,FirstOrDefault
将返回default(OptionalExtras)
。 struct的默认值是struct,其所有值依次默认初始化(即零,null等)。
如果您认为会有一个元素并且您的代码无法使用空集合,使用First()
而不是,因为当您的集合为空时,这将引发异常。快速失败通常比返回错误数据更好。
如果你不能假设会有一个元素,但也不能处理struct default初始化,你可以使struct可以为空,例如如下:
OptionalExtras
.Where(w => w.Code == optExtra.Code)
.Cast<OptionalExtras?>()
.FirstOrDefault();
这样即使对于struct也可以获得null返回。这里的关键思想是扩展可能值的集合以包括除OptionalExtras
之外的其他内容以允许检测空列表。如果你不喜欢nullables,你可以使用Maybe<>
实现(不是.NET内置),或者使用空或单例列表(例如.Take(1).ToArray()
。但是,可以为空的结构是可能是你最好的选择。
.FirstOrDefault<T>()
会返回default(T)
.First()
。.FirstOrDefault<T>()
。答案 1 :(得分:6)
正如其他人所说,没有元素匹配时代码的结果将是:
default( OptionalExtra )
如果要返回null,可以将列表转换为OptionalExtra?
OptionalExtra? multiOptExtra = OptionalExtras.Cast<OptionalExtra?>().Where( ...
然后,您可以测试null
答案 2 :(得分:3)
结果将是您的结构的默认值,例如default(OptionalExtras)
。
对于参考类型,默认值为null
。
答案 3 :(得分:2)
int[] numbers = { };
int first = numbers.FirstOrDefault();
Console.WriteLine(first);//this print 0 as output
要处理的其他选项是使用默认值,如下所示
List<int> months = new List<int> { };
// Setting the default value to 1 by using DefaultIfEmpty() in the query.
int firstMonth2 = months.DefaultIfEmpty(1).First();
Console.WriteLine("The value of the firstMonth2 variable is {0}", firstMonth2);
答案 4 :(得分:2)
如果default(OptionExtra)
仍然是有效值,最好将代码更改为
var results = OptionalExtras.Where(w => w.Code == optExtra.Code).Take(1).ToList();
if (results.Any()) {
multiOptExtra = results[0]
}
答案 5 :(得分:0)
如果要检查null,请使用System.Nullable collection:
private void playSong() {
try {
mp.reset();
mp.setDataSource(context, Uri.parse(url));
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
mp.prepareAsync();
// Log.d("*** AUDIO DURATION ***", mp.getDuration() + " " + " ");
} catch (IOException e) {
e.printStackTrace();
}
}
请注意,您必须使用Value来访问元素。
答案 6 :(得分:-1)
假设Code是一个字符串,用于我的答案,你应该只能测试该值的默认值。
OptionalExtra multiOptExtra = OptionalExtras.Where(w => w.Code == optExtra.Code).FirstOrDefault();
if (multiOptExtra.Code != null)
{
}