13

要么我遗漏了一些东西,要么.NET 不支持 Java 的功能。我希望能够避免仅仅为了实现一个小接口而创建一个小类。例如,LINQ 的 except 方法需要IEqualityComparer. 所以我不得不写一个实现接口的小类。但是在Java中我可以简单地做一个new IEqualityComparer() { //interface declarations }并完成它。所以有什么问题?

这与这篇文章有些相关:

C#匿名类可以实现接口吗?.

补充:目前,我为Equalsand添加了覆盖GetHashCode

4

2 回答 2

14

没错,C# 与 Java 不同,不支持可以实现接口的匿名内部类的概念。我遇到了完全相同的问题,IEqualityComparer并最终得出了以下解决方案。

public static class Utils {
  private sealed class EqualityComparer<T> : IEqualityComparer<T> {
    private readonly Func<T, T, bool> m_equals;
    private readonly Func<T, int> m_getHashCode;
    internal EqualityComparer(
      Func<T, T, bool> equals,
      Func<T, int> getHashCode) {
      m_equals = equals;
      m_getHashCode = getHashCode;
    }
    public bool Equals(T left, T right) {
      return m_equals(left, right);
    }
    public int GetHashCode(T value) {
      return m_getHasheCode(value);
    }
  }

  public static IEqualityComparer<T> CreateEqualityComparer<T>(
    Func<T, T, bool> equals, 
    Func<T, int> getHashCode) {
    return new EqualityComparer<T>(equals, getHashCode);
  }
}

现在在我想要即时运行的地方,我IEqualityComparer<T>可以执行以下操作

var comparer = Utils.CreateEqualityComparer<Student>(
  (left, right) => left.Name == right.Name,
  value => value.Name.GetHashCode());
于 2011-05-03T23:57:19.367 回答
4

简短的回答是这在 C# .Net 中不受支持

我不得不承认这听起来很整洁,但通常这并不是真正需要的。Linq 中的比较方法似乎是个例外,大多数其他 Linq 方法都接受使用委托执行相同操作的重载,这可以通过 lambda 表达式“就地”实现。

对于这个特定的示例,周围散布着一些博客文章,它们有一个LambdaComparer(或类似的)实现,可以让你做到这一点,尽管使用的语法不太优雅。请参阅传递 lambda 表达式代替 IComparer 或 IEqualityComparer 或任何单方法接口?例如。

于 2011-05-03T23:56:39.883 回答