为什么不允许在.net中实现本地接口?

本文关键字:实现 本地接口 net 不允许 为什么 | 更新日期: 2023-09-27 17:54:25

要么是我遗漏了什么,要么是。net不支持Java的功能。我希望能够避免仅仅为了实现一个小接口而创建一个小类。例如,LINQ的Except方法期望IEqualityComparer。因此,我必须编写一个实现该接口的小类。然而,在Java中,我可以简单地做一个new IEqualityComparer() { //interface declarations }并完成它。那么问题是什么呢?

这与这篇文章有些关系:

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

添加:目前,我为EqualsGetHashCode添加了覆盖。

为什么不允许在.net中实现本地接口?

你是对的,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());

简短的回答是c# .Net不支持这个

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

对于这个特定的例子,有一些博客文章提供了LambdaComparer(或类似的)的实现,可以让您做到这一点,尽管使用的语法有些不那么优雅。参见传递lambda表达式代替IComparer或IEqualityComparer或任何单方法接口?例如: