解决扩展方法/ LINQ歧义

我正在为ReSharper 4编写一个加载项。为此,我需要引用几个ReSharper的程序集。 其中一个程序集(JetBrains.Platform.ReSharper.Util.dll)包含System.Linq命名空间,其中包含System.Core已提供的扩展方法的子集。

当我编辑代码时,它会在这些扩展之间产生歧义,因此我不能使用OrderBy 。 我该怎么解决这个问题? 我想使用核心LINQ扩展,而不是ReSharper的扩展。

尝试编译时出现以下错误:

以下方法或属性之间的调用不明确:’ System.Linq.Enumerable.OrderBy(System.Collections.Generic.IEnumerableSystem.Func)' and 'System.Linq.Enumerable.OrderBy(System.Collections.Generic.IEnumerable, System.Func )’

编辑:我尝试了下面的建议,遗憾的是没有运气。 同时,我通过删除对System.Core引用来“解决”问题。 这样我就可以使用ReSharper DLL文件提供的扩展。

我上传了一个示例程序 ,我刚刚导入了我需要的ReSharper DLL文件。 我将System.Core的别名更改为SystemCore ,添加了extern alias指令,但它仍然无法正常工作。 如果我错过了什么,请告诉我。 PS参考是安装在"C:\Program Files\JetBrains\ReSharper\v4.1\..."默认directroy中的ReSharper v4.1 DLL文件。

这可能是使用外部别名有意义的罕见情况之一。

在System.Core引用的属性页面中(即在References下,选择System.Core,右键单击并选择“Properties”),将“Aliases”值更改为“global,SystemCore”(或者只是“SystemCore”,如果这是空白的开始)。

然后在你的代码中写道:

 extern alias SystemCore; using SystemCore::System.Linq; 

这将使System.Core.dll的System.Linq命名空间中的所有相关类型等可用。 这里的名称“SystemCore”是任意的 – 您可以将其称为“DotNet”或其他东西,如果这样可以让您更清楚。

这不是一个真正的答案,但可以为其他人提供一种更容易的方式来重现问题(从命令行 – 如果需要,可以在Visual Studio中使用两个项目)。

1)创建BadLinq.cs并将其构建为BadLinq.dll:

 using System.Collections.Generic; namespace System.Linq { public static class Enumerable { public static IEnumerable Where(this IEnumerable source, Func predicate) { return null; } } } 

2)创建Test.cs:

 extern alias SystemCore; using System; using SystemCore::System.Linq; static class Test { static void Main() { var names = new[] { "Larry", "Curly", "Moe" }; var result = names.Where(x => x.Length > 1); } } 

3)编译指定extern别名的Test.cs:

 csc Test.cs /r:BadLinq.dll /r:SystemCore=System.Core.dll 

这失败了:

Test.cs(11,28):错误CS1061:’System.Array’不包含’Where’的定义,也没有扩展方法’where’接受类型’System.Array’的第一个参数可以找到(你是吗?)缺少using指令或程序集引用?)

如果你改为不尝试使用扩展方法(即Enumerable.Where),它可以使用extern别名。

我认为这可能是一个编译器错误。 我已经通过电子邮件发送了一个C#团队读取的私人邮件列表 – 我会在收到回复后更新此答案或添加新答案。

这不再是一个问题,因为我能够使用ReSharper DLL文件提供的LINQ扩展,即使在面向.NET 3.0时也是如此。

斯基特先生又说对了! 我可以使用完整的LINQ语法,同时在项目的属性中定位.NET 3.0,而不是引用System.Core!

为了使ReSharper与其使用的各种解决方案尽可能兼容,它是针对.NET 2.0构建的。 LINQ等在C#3.0中引入,因此它们在该版本的Framework中不可用。 所以,JetBrains在他们自己的版本中添加了。

解决方案是针对.NET 2.0构建您的插件。

我使用System.ComponentModel有一个模糊的引用问题。 Visual Studio抱怨v2和v4中都存在DLL文件。 我能够通过删除对系统DLL文件的引用并读取它来解决它。

一种解决方案是将所有代码移出到使用ReSharper代码的部分类。 在那里,您只导入ReSharper命名空间而不导入System.Core。

在部分类的其余部分中,您将导入所需的所有其他命名空间,包括System.Core,但不导入ReSharper命名空间。

我有同样的问题,即使有外部别名,我把它作为 Connect上的编译器错误提出。 目前的解决方法是放弃扩展方法语法。

该错误已修复Visual Studio 2010。

这确实是一个编译器错误。

我有同样的问题,我只是通过清理和重建项目来解决它。 之后问题就消失了。

我有类似的情况。 经过两个小时的努力,我意识到我的库中有重复的命名空间名称。 如果您使用的是Microsoft发布的Dynamic.cs文件,那么您唯一需要做的就是将当前命名空间重命名为其他名称,并且它将被修复。

 //Copyright (C) Microsoft Corporation. All rights reserved. using System; using System.Collections.Generic; using System.Text; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Reflection.Emit; using System.Threading; namespace System.Linq.Dynamic <- for example to Linq.Dynamic { 

我在MVC(.Net 4.5,MVC 5)中使用PagedList时发现了同样的歧义。 我发现如果我把对象用于不明确的参数并首先明确地转换它,问题就解决了。 如果歧义是在一个采用System.Linq.Enumerable的方法和一个采用System.Collections.Generic.IEnumerable作为参数的方法之间,并且源类型为System.Collections.Generic.IEnumerable,我不知道使用扩展方法。 我投了它。在这个例子中,我的存储库方法返回一个List:

 searchRequest.CaseSearchResults = csr.SelectMatchingCases(searchRequest); var results = searchRequest.CaseSearchResults.AsEnumerable(); int pageNum = (int)(ViewBag.PageNum ?? 1); var pageResults =results.ToPagedList(pageNum, 5); 

searchRequest.CaseSearchResults上调用扩展方法会导致歧义错误; 显式地转换为结果 ,然后调用该扩展名。