我對LINQ方法SingleOrDefault
,FirstOrDefault
,LastOrDefault
和ElementAtOrDefault
方法的預期行爲或系列操作在數據庫上感到困惑。對於數據庫集合,應該FirstOrDefault返回null嗎?
他們是否應該返回:
- 空,或
- 填充了默認值的新對象?
我對LINQ方法SingleOrDefault
,FirstOrDefault
,LastOrDefault
和ElementAtOrDefault
方法的預期行爲或系列操作在數據庫上感到困惑。對於數據庫集合,應該FirstOrDefault返回null嗎?
他們是否應該返回:
它們返回的項目的順序或項目的default
值中,如果序列是空的(或「ElementAtOrDefault」的情況下,如果指定的索引超出範圍)。
的下面摘錄是從文檔default
:
的解決方案是使用默認的關鍵字,這將返回null爲數字值類型 引用類型和爲零。對於結構體, 將返回結構體的每個成員初始化爲零或空,具體取決於 關於它們是值類型還是引用類型。
鏈接到default
文檔:https://msdn.microsoft.com/en-us/library/xwth0h0d.aspx
默認(TSource)如果源是空的返回值部;否則,來源中的第一個元素。
default(T)
爲Reference Types爲null,在幾乎所有情況,但對於Value Types不爲空。例子:
int i; // 0
var j = default(int); // 0
var b = default(bool); // false
var s = default(string); // null
var s = default(object); // null
var i0 = (new int[] { }).FirstOrDefault(); // 0
var s0 = (new string[] { }).FirstOrDefault(); // null
var i1 = new int[] { }.DefaultIfEmpty(-1).ToArray(); // { -1 }
這裏有一些定義的使用反射鏡。
FirstOrDefault
public static TSource FirstOrDefault<TSource>(this IEnumerable<TSource> source)
{
if (source == null)
{
throw Error.ArgumentNull("source");
}
IList<TSource> list = source as IList<TSource>;
if (list != null)
{
if (list.Count > 0)
{
return list[0];
}
}
else
{
using (IEnumerator<TSource> enumerator = source.GetEnumerator())
{
if (enumerator.MoveNext())
{
return enumerator.Current;
}
}
}
return default(TSource);
}
的SingleOrDefault
public static TSource SingleOrDefault<TSource>(this IEnumerable<TSource> source)
{
if (source == null)
{
throw Error.ArgumentNull("source");
}
IList<TSource> list = source as IList<TSource>;
if (list != null)
{
switch (list.Count)
{
case 0:
return default(TSource);
case 1:
return list[0];
}
}
else
{
using (IEnumerator<TSource> enumerator = source.GetEnumerator())
{
if (!enumerator.MoveNext())
{
return default(TSource);
}
TSource current = enumerator.Current;
if (!enumerator.MoveNext())
{
return current;
}
}
}
throw Error.MoreThanOneElement();
}
LastOrDefault
public static TSource LastOrDefault<TSource>(this IEnumerable<TSource> source)
{
if (source == null)
{
throw Error.ArgumentNull("source");
}
IList<TSource> list = source as IList<TSource>;
if (list != null)
{
int count = list.Count;
if (count > 0)
{
return list[count - 1];
}
}
else
{
using (IEnumerator<TSource> enumerator = source.GetEnumerator())
{
if (enumerator.MoveNext())
{
TSource current;
do
{
current = enumerator.Current;
}
while (enumerator.MoveNext());
return current;
}
}
}
return default(TSource);
}
ElementAtOrDefault
public static TSource ElementAtOrDefault<TSource>(this IEnumerable<TSource> source, int index)
{
if (source == null)
{
throw Error.ArgumentNull("source");
}
if (index >= 0)
{
IList<TSource> list = source as IList<TSource>;
if (list != null)
{
if (index < list.Count)
{
return list[index];
}
}
else
{
using (IEnumerator<TSource> enumerator = source.GetEnumerator())
{
while (enumerator.MoveNext())
{
if (index == 0)
{
return enumerator.Current;
}
index--;
}
}
}
}
return default(TSource);
}
的源代碼也在這裏可用Enumerable:http://referencesource.microsoft.com/#System.Core/System/Linq/Enumerable.cs,這裏爲IQueryable:http://referencesource.microsoft.com/#System.Core/System/ LINQ/IQueryable.cs – astidham2003
它們返回['默認(T)'](http://stackoverflow.com/questions/2432909/what-does-defaultobject-do-in-c) –