【问题标题】:How to resolve ambiguous ZIP call between Enumerable and MoreLINQ?如何解决 Enumerable 和 MoreLINQ 之间的模糊 ZIP 调用?
【发布时间】:2013-01-18 10:31:11
【问题描述】:

我遇到了扩展方法解析的问题。 LINQ 和 MoreLINQ 包含 zip 方法,它从 4.0 版本开始存在于 .NET 中,并且始终位于 MoreLINQ 库中。但是您不能使用具有旧扩展方法语法的实现之一。所以这段代码不会编译

using MoreLinq;
using System.Linq;


var students = new [] { "Mark", "Bob", "David" };
var colors = new [] { "Pink", "Red", "Blue" };

students.Zip(colors, (s, c) => s + c );

错误:

The call is ambiguous between the following methods or properties: 
'MoreLinq.MoreEnumerable.Zip<string,string,string>
(System.Collections.Generic.IEnumerable<string>, 
System.Collections.Generic.IEnumerable<string>, System.Func<string,string,string>)' and 
'System.Linq.Enumerable.Zip<string,string,string>
(System.Collections.Generic.IEnumerable<string>, 
System.Collections.Generic.IEnumerable<string>, System.Func<string,string,string>)'

我在 string 上为 Jon Skeet 在 this post 制作的 MoreLINQ 找到了 Concat 方法的良好分辨率,但我不知道 zip 方法的良好分辨率。

注意:您始终可以使用静态方法调用语法,并且在

下一切正常
MoreEnumerable.Zip(students, colors, (s, c) => s + c )

但有点忽略了扩展语法糖的意义。如果您使用 LINQ 和 MoreLINQ 调用进行大量数据转换 - 您不想在中间使用静态方法调用。

有没有更好的方法来解决这种歧义?

【问题讨论】:

标签: c# .net linq ambiguous-call morelinq


【解决方案1】:

使其编译的方法是:

var students = new[] { "Mark", "Bob", "David", "test" }.AsQueryable();
var colors = new[] { "Pink", "Red", "Blue" };

students
    .Zip(colors, (s, c) => s + c)
    .Dump();

students 对象必须转换为 IQueryable 对象。

【讨论】:

  • dynamic 是干什么用的?那么AsQueryable()呢?
  • 这里不需要dynamic
  • 您可以删除数组声明中的括号并将其设为new [] { "..." }.AsQueryable(); 并仅在students 的第一个数组中调用它
【解决方案2】:

您可以使用相同的方法创建包装类,但名称不同。这有点脏,但如果你真的喜欢扩展语法,那是唯一的方法。

public static class MoreLinqWrapper
{
    public static IEnumerable<TResult> MlZip<TFirst, TSecond, TResult>(this IEnumerable<TFirst> first, IEnumerable<TSecond> second, Func<TFirst, TSecond, TResult> resultSelector)
    {
        return MoreLinq.Zip(first, second, resultSelector);
    }
}

【讨论】:

  • 是的,我也考虑过,写信给丹尼斯回答。但我不知道这是否是一个更好的方法
  • 在他有单个MoreLinq 呼叫之前没关系,否则他将使用这种假方法而不是Zip。第一种情况不适用 - 请参阅问题文本,第二种情况 - 好吧,我不羡慕必须支持此代码的人。我想,一两年后就很难解释了,为什么这里调用MlZip(以及它是什么)而不是Zip
  • Dennis,我通常通过“转到定义”来解决这个问题,在里面你会立即看到答案。当然,这不是一个好的解决方案。但是相比不得不替换大量对静态语法的调用,我会选择这个。
  • 伊利亚,在这里你应该选择两个邪恶中最小的一个。我将根据我必须更改的实际代码行数做出决定。我的用法数量很少,我会使用静态类语法。另外,您是否考虑过停止使用 MoreLinq?我正在评估它,发现它不是很好,而是弄脏了命名空间。我只使用了其中的 1-2 个函数。然后将它们复制到我自己的扩展类中。
  • Ilya,正如我所说,我发现只有几个函数有用,而其他所有函数都只是污染了命名空间。所以我将这 2-3 个函数移到了我自己的类中,并取消了对 MoreLinq 的引用。
【解决方案3】:

更新你的 morelinq,从现在开始

  • 对 .NET 4.0 Zip 使用 Zip
  • 对 MoreLinq Zip 使用 ZipShortest

问题已在88c573f7 中修复

【讨论】:

  • 截至 2014 年 11 月(1.1 版)MoreLinq 仍然包含 Zip;也就是说,这个补丁似乎没有被使用,问题仍然存在。
【解决方案4】:

不幸的是,静态方法调用语法是这里唯一的方法。

【讨论】:

  • 好吧,我能想到的另一种方法是克隆签名并使用Zipp 名称创建单独的方法,例如,将调用MoreEnumerable.Zip。但我认为这不是更好的方法
【解决方案5】:

我前几天遇到了这个问题,我只是直接调用了MoreLinq方法。

MoreLinq.MoreEnumerable.Zip(students, colors, (s, c) => s + c);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多