【发布时间】:2014-03-26 18:31:15
【问题描述】:
我正在对 Linq 扩展方法的变体进行性能测试,遇到了一个奇怪的情况。
执行返回测试时,先调用Count()会返回1,后面的Any()为false。
先调用Any()时为真,后面的Count()为0。
调用任一方法之前的断点检查显示有 1 个项目符合预期,但在以这种方式或调用 Any() 或 Count() 枚举后,可枚举项为空。
有人可以解释这种行为吗?由于延迟执行的一些警告,我的实现中是否存在错误?
public class Thing
{
public Guid Id { get; set; }
}
[TestClass]
public class IEnumerableExtensionsTests
{
Guid[] thingKeys = new Guid[1] { Guid.Parse("11A1AA1A-1A11-A111-AA11-111111AA1A11") };
System.Collections.ObjectModel.Collection<Thing> things= new System.Collections.ObjectModel.Collection<Thing>();
int additionalThingCount = 100;
[TestMethod]
public void TestIntersect1()
{
DateTime start = DateTime.Now;
var exceptionsList = things.Intersect1(thingKeys, (e) => e.Id);
//int count1 = exceptionsList.Count();
//Assert.AreEqual<int>(thingKeys.Length, count1);
bool any1 = exceptionsList.Any();
int count2 = exceptionsList.Count();
bool any2 = exceptionsList.Any();
string key = thingKeys[0].ToString();
var first = exceptionsList.FirstOrDefault();
var result = exceptionsList.FirstOrDefault(e => e.Id.ToString() == key);
var duration = DateTime.Now - start;
Debug.WriteLine(string.Format("TestIntersect1 duration {0}", duration));
Assert.IsNotNull(result);
}
[TestInitialize]
public void TestInit()
{
foreach(var key in thingKeys)
{
things.Add(new Thing()
{
Id = key
});
};
for (int i1 = 0; i1 < additionalThingCount; i1++)
{
things.Add(new Thing()
{
Id = Guid.NewGuid()
});
}
}
}
public static class IEnumerableExtension
{
public static IEnumerable<T> Intersect1<T, Y>(this IEnumerable<T> items, IEnumerable<Y> keys, Func<T, Y> firstMemberSelector)
{
var hashset = new HashSet<Y>(keys);
var returnValue = items.Where(t => hashset.Remove(firstMemberSelector(t)));
return returnValue;
}
}
【问题讨论】:
-
这“修复”了它(我还没有在我的代码中寻找新的副作用):msmvps.com/blogs/jon_skeet/archive/2008/02/28/… var hashset = new HashSet
(keys); var returnValue = items.Where(t => hashset.Remove(firstMemberSelector(t))); foreach (var item in returnValue) { yield return item; }
标签: c# linq ienumerable deferred-execution