13

何かが足りないか、.NETがJavaの機能をサポートしていません。小さなインターフェースを実装するためだけに、小さなクラスを作成することは避けたいと思います。たとえば、LINQのExceptメソッドはを期待しIEqualityComparerます。そのため、インターフェイスを実装する小さなクラスを作成する必要がありました。ただし、Javaでは、単純にanew IEqualityComparer() { //interface declarations }を実行してそれを実行できます。だから問題は何ですか?

これは、この投稿にいくらか関連しています。

C#匿名クラスはインターフェイスを実装できますか?

追加:現時点では、とのオーバーライドを追加しましEqualsGetHashCode

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メソッドは、デリゲートを使用して同じことを実行するオーバーロードを受け入れます。これは、ラムダ式を介して「インプレース」で実装できます。

LambdaComparerこの特定の例では、多少洗練されていない構文を使用していますが、これを実行できる(または同様の)実装を持つブログ投稿が散在しています。IComparer、IEqualityComparer、または任意のシングルメソッドインターフェイスの代わりにラムダ式を渡すを参照してください。例として。

于 2011-05-03T23:56:39.883 に答える