gpt4 book ai didi

c# - 为什么调用 IEnumerable.Count() 会创建额外的程序集依赖项?

转载 作者:太空狗 更新时间:2023-10-29 19:41:52 28 4
gpt4 key购买 nike

假设这个 dll 引用链

Tests.dll >> Automation.dll >> White.Core.dll

在 Tests.dll 中使用以下代码行,构建所有内容

result.MissingPaths 

现在当我把它改成

result.MissingPaths.Count()

我收到以下 Tests.dll 构建错误“White.UIItem 未在未引用的程序集中定义。您必须添加对 White.Core.dll 的引用。”我不想这样做,因为它会破坏我的层次感。

这是result的类型定义,在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(); }
}
}

在调用链中,通过(TreeNode 类在 White.Core.dll 中)创建此 ctor 的输入参数

assetPaths.Where(assetPath => !FindTreeNodeUsingCache(treeHandle, assetPath));

为什么在 IEnumerable 上调用 Count() 时会泄漏此依赖项?然后我怀疑是懒惰的评估导致了这个(出于某种原因) - 所以我在上面的行中插入了一个 ToArray() 但没有工作。

2011 年 01 月 7 日更新:越来越好奇!在我添加 White.Core 引用之前它不会构建。所以我添加了一个引用并构建它(为了找到难以捉摸的依赖源)。在 Reflector 中打开它,列出的唯一引用是 Automation、mscorlib、System.core 和 NUnit。所以编译器丢弃了 White 引用,因为它不需要。 ILDASM 还确认没有白色 AssemblyRef 条目。

关于如何深入了解这件事的任何想法(主要是出于“现在我想知道为什么”的原因)?这是 VS2010/MSBuild 错误的可能性有多大?

更新 2011 01 07 #2根据 Shimmy 的建议,尝试将该方法显式调用为扩展方法

Enumerable.Count(result.MissingPaths)

它停止抄袭(不知道为什么)。
然而,在那之后我移动了一些代码,现在我在不同的位置使用 IEnumerable 遇到了同样的问题——这次是从磁盘上的文件中读取和过滤行(与 White 完全无关)。这似乎是一个“症状修复”。
var lines = File.ReadLines(aFilePath).ToArray();再一次,如果我删除 ToArray() 它会再次编译 - 似乎任何导致计算可枚举的方法(ToArray、Count、ToList 等)都会导致这种情况。让我尝试获得一个可用的微型应用程序来演示此问题...

更新 2011 01 07 #3呸!更多信息.. 事实证明问题只出在一个源文件中——这个文件是 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)));

更新 2011 01 11 #4将范围缩小到看似犯罪但没有动机的范围:)
周末后恢复了任务……并使用常绿的消除过程,能够在有问题的位置上进行区域划分。问题是 Tests.dll 源文件中的以下 using 指令

using G.S.OurAutomation.Framework;

接下来,我追踪了这个命名空间中最有可能的嫌疑人,我在聚光灯下找到了 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)...
}
}

这导致了 3 个修复,都有效。

  1. 将扩展方法变成普通的静态方法。
  2. 将此类移动到子命名空间 G.S.OurAutomation.Framework.White
  3. 使它成为一个内部类(因为它是供内部使用的..再次选择最严格的访问修饰符的准则让我恼火。)

虽然我的具体实例是固定的,但此更新可以帮助某人解释这是什么原因吗?如果不是 shimmy 得到勾号 :) 指向正确的方向。

最佳答案

尝试调用 System.Linq.Enumerable.Count(result.MissingPaths)(有或没有完整的命名空间引用)。

Count是一个扩展方法,您可以显式调用它。

Gishu 更新#2 后的更新:

道理都是一样的,ToArrayCountToList等函数都是System.Linq.Enumerable中声明的扩展方法.

顺便说一句,重要:您是否仔细检查过命名空间 System.Linq 是否已导入(using System.Linq)到您的文件?这甚至可能会解决您所有的问题。

关于c# - 为什么调用 IEnumerable<string>.Count() 会创建额外的程序集依赖项?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4613600/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com