假设这个dll链引用
Tests.dll >> Automation.dll >> White.Core.dll
Run Code Online (Sandbox Code Playgroud)
使用Tests.dll中的以下代码行构建所有内容
result.MissingPaths
Run Code Online (Sandbox Code Playgroud)
现在我把它改成了
result.MissingPaths.Count()
Run Code Online (Sandbox Code Playgroud)
我得到Tests.dll的以下构建错误"White.UIItem未在未引用的程序集中定义.您必须添加对White.Core.dll的引用." 我不想这样做,因为它打破了我的分层.
以下是结果的类型定义,它位于Automation.dll中
public class HasResult
{
public HasResult(IEnumerable<string> missingPaths )
{ MissingPaths = missingPaths; }
public IEnumerable<string> MissingPaths { get; set; }
public bool AllExist
{
get { return !MissingPaths.Any(); }
}
}
Run Code Online (Sandbox Code Playgroud)
在调用链下面,通过(TreeNode类在White.Core.dll中)创建此ctor的输入参数.
assetPaths.Where(assetPath => !FindTreeNodeUsingCache(treeHandle, assetPath));
Run Code Online (Sandbox Code Playgroud)
为什么在IEnumerable上调用Count()时这个依赖项会泄漏?然后我怀疑懒惰的评估导致了这个(由于某种原因) - 所以我在上面的一行中插入了一个ToArray()但是没有用.
更新2011 01 07: Curiouser和Curiouser!在添加White.Core引用之前,它不会构建.所以我添加一个引用并构建它(为了找到难以捉摸的依赖源).在Reflector中打开它,列出的唯一引用是Automation,mscorlib,System.core和NUnit.所以编译器丢弃了White引用,因为它不需要.ILDASM还确认没有White AssemblyRef条目.
关于如何深入了解这件事的任何想法(主要是'现在我想知道为什么'的原因)?这是VS2010/MSBuild错误的可能性有多大?
更新2011 01 07#2 根据Shimmy的建议,尝试将explcitly方法称为扩展方法
Enumerable.Count(result.MissingPaths)
Run Code Online (Sandbox Code Playgroud)
它停止了抄袭(不知道为什么).
但是之后我移动了一些代码,现在我使用IEnumerable在不同的位置获得相同的问题 - 这次是从磁盘上的文件读取和过滤行(完全与白色无关).似乎它是一个'症状修复'.
var lines = File.ReadLines(aFilePath).ToArray();
再次,如果我删除ToArray()它再次编译 - 似乎导致可枚举的任何方法(ToArray,Count,ToList等)导致这种情况.让我尝试一个工作的小应用程序来演示这个问题......
更新2011 01 07#3 P!更多信息..事实证明问题只在一个源文件中 - 这个文件是LINQ-phobic.必须显式调用对Enumerable扩展方法的任何调用.我做的重构导致一个新的方法被移动到这个源文件,它有一些LINQ :)仍然没有线索为什么这个类不喜欢LINQ.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using G.S.OurAutomation.Constants;
using G.S.OurAutomation.Framework;
using NUnit.Framework;
namespace G.S.AcceptanceTests
{
public abstract class ConfigureThingBase : OurTestFixture
{
....
private static IEnumerable<string> GetExpectedThingsFor(string param)
{
// even this won't compile - although it compiles fine in an adjoining source file in the same assembly
//IEnumerable<string> s = new string[0];
//Console.WriteLine(s.Count());
// this is the line that is now causing a build failure
// var expectedInfo = File.ReadLines(someCsvFilePath))
// .Where(line => !line.StartsWith("REM", StringComparison.InvariantCultureIgnoreCase))
// .Select(line => line.Replace("%PLACEHOLDER%", param))
// .ToArray();
// Unrolling the LINQ above removes the build error
var expectedInfo =
Enumerable.ToArray(
Enumerable.Select(
Enumerable.Where(
File.ReadLines(someCsvFilePath)),
line => !line.StartsWith("REM", StringComparison.InvariantCultureIgnoreCase)),
line => line.Replace("%PLACEHOLDER%", param)));
Run Code Online (Sandbox Code Playgroud)
更新2011 01 11#4将
它缩小到似乎是perp但没有动机:)
在周末恢复了任务......并且使用常绿的消除过程,能够在有问题的位上划分.问题是Tests.dll源文件中的以下using指令
using G.S.OurAutomation.Framework;
Run Code Online (Sandbox Code Playgroud)
接下来,我追踪了这个命名空间中最可能的嫌疑人,并且我将WhiteExtensions置于聚光灯下.
namespace G.S.OurAutomation.Framework
{
public static class WhiteExtensions
{
public static T PollAndGet<T>(this Window parentWindow, string automationId) where T : UIItem ...
public static Window WaitForWindowWithTitle(this Application application, string windowTitle) ...
public static bool HasTreeNode(this Tree treeHandle, string assetPath) ...
public static HasTreeNodesResult HasTreeNodes(this Tree treeHandle, IEnumerable<string> assetPaths)...
}
}
Run Code Online (Sandbox Code Playgroud)
这导致3个修复,两个都有效.
G.S.OurAutomation.Framework.White虽然我的具体实例已修复,但此更新是否可以帮助某人解释原因?如果不是摆动得到滴答:)指向正确的方向.
改变一下怎么样
public HasResult(IEnumerable<string> missingPaths )
{ MissingPaths = missingPaths; }
Run Code Online (Sandbox Code Playgroud)
到
public HasResult(IEnumerable<string> missingPaths )
{ MissingPaths = missingPaths.ToArray(); }
Run Code Online (Sandbox Code Playgroud)
应消除使用结果的所有情况下的延迟加载场景。