13

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.

FreakyAli
  • 13,349
  • 3
  • 23
  • 63
Schultz9999
  • 8,717
  • 8
  • 48
  • 87
  • possible duplicate of [Can a C# anonymous class implement an interface?](http://stackoverflow.com/questions/191013/can-a-c-anonymous-class-implement-an-interface) – Dan J May 03 '11 at 23:55
  • 2
    @djacobson I think this is a different Q. The OP is asking if there is an equivalent to anonymous inner classes, not if the C# anonymous type feature can be used to implement interfaces. Subtle but different. – JaredPar May 03 '11 at 23:58

2 Answers2

14

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());
JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
  • Alternatively `Equals` and `GetHashCode` methods can be overridden. – Schultz9999 May 04 '11 at 00:03
  • @Schultz9999: JaredPar's answer is expressly for the situations where you cannot override those methods: either you don't own the class or you have your own definition of equality. They are the same situations your question applies to. – Rick Sladkey May 04 '11 at 00:21
  • @Rick Sladkey: absolutely. His answer is great. I own the code in my case so I can do that. – Schultz9999 May 04 '11 at 00:29
4

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.

Community
  • 1
  • 1
Justin
  • 84,773
  • 49
  • 224
  • 367
  • Well, if they would give me the `Func` type as in many other cases, I'd be more than happy with that. `Except` seems just overlooked, not loved :) – Schultz9999 May 04 '11 at 00:02