【问题标题】:Overloading a generic extension method重载泛型扩展方法
【发布时间】:2015-02-26 14:06:57
【问题描述】:

我在重载扩展方法时遇到问题。

我有两种扩展方法:

方法 A - 对于标准对象:

public static bool HasChanged<T>(this T obj1, T obj2, Func<T, T, bool> equalityExpression)

方法 B - 对于 IEnumerables:

public static bool HasChangedList<T>(this IEnumerable<T> obj1, IEnumerable<T> obj2, Func<T, T, bool> isEqualExpression)

但我想给它们两个相同的名称,这目前不起作用,因为 IEnumerables 也是对象,因此编译器无法决定是在 IEnumerable 上使用第一个还是第二个。

我确定,不可能让第一个方法获取除 IEnumerable 之外的所有对象,那么还有其他方法吗?

【问题讨论】:

  • 你可以检查第一个的主体,如果它是 IEnumerable 并调用第二个私有方法,那么你只需要一个。
  • 在两种方法上分配相同的名称对我来说效果很好。
  • 你说目前不工作。那是什么意思?你得到什么错误?或意外行为或什么?
  • 很抱歉,我认为犯了一个错误,它确实有效,Visual Studios IntelliSense 让我认为它不起作用。

标签: c# extension-methods


【解决方案1】:

(不是真正的解决方案,但评论太长了。希望有一位 C# 规范专家会出现并告诉我们为什么在这种特殊情况下重载解析会这样工作。)

如果

  • 您限定了equalExpression 的参数 if
  • IEnumerable 的内部类型可以从 lambda 表达式中推断出来,

它应该可以正常工作:

class Program
{
    static void Main(string[] args)
    {
        var array = new[] { 1, 2, 3 };

        // uses the IEnumerable overload -- prints false
        Console.WriteLine(array.HasChanged(array, (int x, int y) => x == y));

        // uses the IEnumerable overload -- prints false
        Console.WriteLine(array.HasChanged(array, (x, y) => x >= y));

        // uses the generic overload -- prints true
        Console.WriteLine(array.HasChanged(array, (x, y) => x == y));

        Console.ReadLine();
    }
}
static class Extensions
{
    public static bool HasChanged<T>(this IEnumerable<T> obj1, IEnumerable<T> obj2, Func<T, T, bool> isEqualExpression)
    { 
        return false; 
    }
    public static bool HasChanged<T>(this T obj1, T obj2, Func<T, T, bool> equalityExpression)
    { 
        return true; 
    }
}

【讨论】:

  • 这绝对是您在那里发现的意外行为。
  • @Andrew:确实,我预计在最后一种情况下会出现重载解析歧义错误。
  • 如果 arrayarrayList&lt;int&gt;,它会按照您的指定工作。但是,如果在任何一种情况下,变量被声明为IEnumerable&lt;int&gt; 而不是使用varList&lt;int&gt;,则会出现歧义错误。这真的令人困惑。
  • 这并不意外
  • 当您指定 var 时,编译器假定类型是 int[] 并且最好的重载是泛型,当您推送时 IEnumerable 是模棱两可的,因为它可以使用两种重载。当您指定 Func 时,它由 IEnumerable 重载决定。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-19
  • 2020-05-16
  • 2014-12-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多