我很惊讶,无论我是在前置还是附加LINQ扩展方法都没关系.
hugeList.Where(x => x.Text.Contains("10000")).FirstOrDefault();hugeList.FirstOrDefault(x => x.Text.Contains("10000"));
var hugeList = Enumerable.Range(1, 50000000)
.Select(i => new { ID = i, Text = "Item" + i });
var sw1 = new System.Diagnostics.Stopwatch();
var sw2 = new System.Diagnostics.Stopwatch();
sw1.Start();
for(int i=0;i<1000;i++)
hugeList.Where(x => x.Text.Contains("10000")).FirstOrDefault();
sw1.Stop();
sw2.Start();
for(int i=0;i<1000;i++)
hugeList.FirstOrDefault(x => x.Text.Contains("10000"));
sw2.Stop();
var result1 = String.Format("FirstOrDefault after: {0} FirstOrDefault before: {1}", sw1.Elapsed, sw2.Elapsed);
//result1: FirstOrDefault after: 00:00:03.3169683 FirstOrDefault before: 00:00:03.0463219
sw2.Restart();
for (int i = 0; i < 1000; i++) …Run Code Online (Sandbox Code Playgroud)var result = foo.FirstOrDefault(f => f.bar == barVal).someProperty
Run Code Online (Sandbox Code Playgroud)
如果没有匹配项(默认为 null),这将不起作用 - 尝试访问 null 对象上的属性。我们可以重写如下:
var result = foo.Where(f => f.bar == barVal)
.Select(f => f.someProperty).DefaultIfEmpty(0).First()
Run Code Online (Sandbox Code Playgroud)
虽然它有效,但这似乎不是最优雅的方法......有更好的方法吗?
当然,人们可以做一些事情,例如:
var result = 0;
var tmp = foo.FirstOrDefault(f => f.bar == barVal);
if(tmp != null) result = tmp.someProperty
Run Code Online (Sandbox Code Playgroud)
但在更复杂的查询中,这种方法看起来比 DefaultIfEmpty 方法更“混乱”
var tmpSet = dataSet.GroupBy(f => f.ID);
var newSet = tmp.Select(f => new {
ID = f.ID,
SomeProperty = f.Where(g => g.bar == barVal)
.Select(f => f.SomeProperty)
.DefaultIfEmpty(0).First()
});
Run Code Online (Sandbox Code Playgroud)