所以我有一个集合struct
S(它实际上是一个WCF datacontract但我假定这这里没有轴承)。
List<OptionalExtra> OptionalExtras;
OptionalExtra
是一个struct
。
public partial struct OptionalExtra
现在我运行下面的语句:
OptionalExtra multiOptExtra = OptionalExtras.Where(w => w.Code == optExtra.Code).FirstOrDefault();
if (multiOptExtra != null)
{
}
现在,这不会编译:
操作者!=不能被应用于类型OptionalExtra的opperands和'<null>'
一点点的谷歌搜索后,我意识到这是因为OptionalExtra
是一个struct
。 除非定义为可空类型,我相信是不可为空?
所以我的问题是,如果我where
语句返回任何结果会是怎样的结果FirstOrDefault
电话吗? 它会抛出一个异常?
顺便说一句这不应该发生,但有备无患。
如果您收藏是空的, FirstOrDefault
将返回default(OptionalExtras)
一个结构的默认值是与它反过来缺省初始化所有的值(即,零,空等)的结构。
如果您认为会有一个元素,您的代码不会用空的收集, 利用工作First()
代替 ,因为当你的集合为空,将抛出异常。 它通常是更好地快速失败,而不是返回错误的数据。
如果你不能假设会有一个元素,也不能与结构缺省初始化处理,你可能使该结构可空,举例如下:
OptionalExtras
.Where(w => w.Code == optExtra.Code)
.Cast<OptionalExtras?>()
.FirstOrDefault();
这样,您就可以得到,即使是结构返回null。 这里的关键思想是扩展可能值的集合,包括比其他东西OptionalExtras
允许空列表的检测。 如果你不喜欢nullables,你也可以使用一个Maybe<>
实现(而不是.NET内置),或使用空或单例列表(例如.Take(1).ToArray()
然而,一个可空结构可能是你最好的选择。
TL; DR;
-
.FirstOrDefault<T>()
返回default(T)
如果该序列为空 - 使用
.First()
代替如果假设该列表非空。 - 投放到可为空,然后使用
.FirstOrDefault<T>()
时,不能假设该列表不为空。
正如其他人所说,你的代码的时候没有元素匹配的结果将是:
default( OptionalExtra )
如果你想有一个空回来,你可以投你的列表OptionalExtra?
OptionalExtra? multiOptExtra = OptionalExtras.Cast<OptionalExtra?>().Where( ...
然后,您可以测试null
如果default(OptionExtra)
仍然是一个有效的价值,这是更好地更改您的代码此
var results = OptionalExtras.Where(w => w.Code == optExtra.Code).Take(1).ToList();
if (results.Any()) {
multiOptExtra = results[0]
}
其结果将是你的结构的默认值,例如default(OptionalExtras)
而对于引用类型的默认值是null
。
它提供您的结构defualt值一样,如下
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);
如果你想检查空,使用System.Nullable集合:
var OptionalExtras = new List<OptionalExtra?>();
/* Add some values */
var extras = OptionalExtras.FirstOrDefault(oe => oe.Value.Code == "code");
if (extras != null)
{
Console.WriteLine(extras.Value.Code);
}
请注意,您必须使用值来访问元素。
假设代码是我的回答的目的的字符串,你应该能够只是为了测试值默认值。
OptionalExtra multiOptExtra = OptionalExtras.Where(w => w.Code == optExtra.Code).FirstOrDefault();
if (multiOptExtra.Code != null)
{
}