Question

Soit il me manque quelque chose, soit .NET ne prend pas en charge ce que fait Java.J'aimerais pouvoir éviter de créer une petite classe juste pour implémenter une petite interface.Par exemple, la méthode Except de LINQ attend IEqualityComparer.J'ai donc dû écrire une petite classe qui implémente l'interface.Cependant, en Java, je peux simplement faire un new IEqualityComparer() { //interface declarations } et en finir avec.Donc quel est le problème?

Ceci est en quelque sorte lié à ce post:

Une classe anonyme C # peut-elle implémenter une interface? .

AJOUT: Pour le moment, j'ai ajouté des remplacements pour Equals et GetHashCode.

Était-ce utile?

La solution

Vous avez raison, C # contrairement à Java, ne supporte pas la notion de classes internes anonymes qui peuvent implémenter des interfaces.J'ai rencontré exactement le même problème avec IEqualityComparer et suis finalement arrivé à la solution suivante.

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

Maintenant, dans les endroits où je veux un code générique à la volée, je peux simplement faire ce qui suit

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

Autres conseils

La réponse courte est que cela n'est pas pris en charge dans C # .Net

Je dois admettre que cela semble assez soigné, mais normalement ce n'est pas vraiment nécessaire.Les méthodes de comparaison de Linq semblent être l'exception, la plupart des autres méthodes Linq acceptent les surcharges qui effectuent la même chose en utilisant des délégués, qui peuvent être implémentées "sur place" via des expressions lambda.

Pour cet exemple spécifique, il y a une dispersion d'articles de blog qui ont une implémentation pour un LambdaComparer (ou similaire) qui vous permet de faire exactement cela, bien qu'en utilisant une syntaxe un peu moins élégante.Voir Passer une expression lambda dansplace de IComparer ou IEqualityComparer ou de toute interface à méthode unique? pour un exemple.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top