Domanda

O mi manca qualcosa o .NET non supporta ciò che fa Java. Vorrei poter evitare di creare una piccola classe solo per implementare una piccola interfaccia. Ad esempio, il metodo di Linq si aspetta IEqualityComparer. Quindi ho dovuto scrivere una piccola classe che implementa l'interfaccia. Tuttavia in Java posso semplicemente fare un new IEqualityComparer() { //interface declarations } e sii fatto con esso. Allora, qual'è il problema?

Questo è in qualche modo correlato a questo post:

Una classe C# Anonymous può implementare un'interfaccia?.

Aggiunta: al momento ho aggiunto sovrascrivi Equals e GetHashCode.

È stato utile?

Soluzione

Hai ragione, C# A differenza di Java, non supporta la nozione di classi interne anonime che possono implementare interfacce. Ho riscontrato lo stesso identico problema con IEqualityComparer e alla fine è arrivato alla seguente soluzione.

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

Ora in luoghi in cui voglio un fly IEqualityComparer<T> Posso solo fare quanto segue

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

Altri suggerimenti

La risposta breve è che questo non è supportato in C #NET

Devo ammettere che sembra abbastanza pulito, ma normalmente non è davvero necessario. I metodi di confronto in LINQ sembrano essere l'eccezione, la maggior parte degli altri metodi LINQ accetta sovraccarichi che eseguono la stessa cosa usando i delegati, che possono essere implementati "sul posto" tramite espressioni Lambda.

Per questo esempio specifico ci sono una dispersione di post sul blog che hanno un'implementazione per a LambdaComparer (o simile) che ti consente di fare proprio questo, anche se usando una sintassi un po 'meno elegante. Vedere Passare un'espressione Lambda al posto di ICOMparer o IEqualityComparer o qualsiasi interfaccia a metodo singolo? per un esempio.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top