为什么不允许在 .NET 中就地实现接口?

发布于 2024-11-04 21:43:11 字数 502 浏览 0 评论 0原文

要么我遗漏了一些东西,要么.NET 不支持 Java 的功能。我希望能够避免仅仅为了实现一个小接口而创建一个小类。例如,LINQ 的 except 方法需要 IEqualityComparer。所以我必须编写一个实现该接口的小类。然而,在 Java 中,我可以简单地执行一个 new IEqualityComparer() { //interface statements } 并完成它。那么问题出在哪里呢?

这与这篇文章有些相关:

Can a C# Anonymous Class Implement an Interface?< /a>.

添加: 目前,我添加了 EqualsGetHashCode 的重写。

Either I am missing something or .NET doesn't support what Java does. I'd like to be able to avoid creating a small class just for the sake of implementing a small interface. For example, LINQ's Except method expects IEqualityComparer. So I had to write a small class that implements the interface. However in Java I can simply do a new IEqualityComparer() { //interface declarations } and be done with it. So what's the problem?

This is somewhat related to this post:

Can a C# anonymous class implement an interface?.

ADDITION:
At the moment, I added overrides for Equals and GetHashCode.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

权谋诡计 2024-11-11 21:43:11

你是对的,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 的地方,我可以执行以下操作

var comparer = Utils.CreateEqualityComparer<Student>(
  (left, right) => left.Name == right.Name,
  value => value.Name.GetHashCode());

You're correct, C# unlike Java, does not support the notion of anonymous inner classes which can implement interfaces. I've run into the exact same problem with IEqualityComparer and eventually came to the following solution.

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);
  }
}

Now in places where I want an on the fly IEqualityComparer<T> i can just do the following

var comparer = Utils.CreateEqualityComparer<Student>(
  (left, right) => left.Name == right.Name,
  value => value.Name.GetHashCode());
美羊羊 2024-11-11 21:43:11

简短的回答是,C# .Net 不支持这一点,

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

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

The short answer is that this is not supported in C# .Net

I have to admit that sounds pretty neat, but normally this is not really needed. The comparison methods in Linq seem to be the exception, most other Linq method accept overloads that perform the same thing using delegates, which can be implemented "in-place" via lambda expressions.

For this specific example there are a scattering of blog posts around that have an implementation for a LambdaComparer (or similar) that lets you do just this, albeit using a somewhat less elegant syntax. See Pass a lambda expression in place of IComparer or IEqualityComparer or any single-method interface? for an example.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文