Domanda

Ho pensato che questo metodo era valido, ma mi sbagliavo:

static void Equals<T>(T x, T y)
{
    return x == y;    //operator == can't be applied to type T
}

Dopo aver letto la specifiation (§7.2.4 in v3.0 e §7.3.4 in v4.0):

7.2.4 Binary risoluzione di sovraccarico operatore

Un'operazione della forma x y op, dove op è un sovraccaricabile operatore binario, x è un'espressione tipo X, e Y è un'espressione di tipo Y, viene elaborato come segue:

  • L'insieme dei candidati operatori definiti dall'utente fornito da X e Y per l'operazione operatore OP (x, y) è determinata. Il set è composto dall'unione del gli operatori candidati forniti da X e gli operatori candidati fornite da Y, ciascuno determinato utilizzando le regole di §7.2.5. Se X e Y sono dello stesso tipo, o se X e Y sono derivati ??da una tipo di base comune, allora condivisa gli operatori candidati si verificano solo nel insieme composito una volta.

  • Se l'insieme di candidati operatori definiti dall'utente è non vuota, allora questo diventa il set degli operatori candidati per la operazione. In caso contrario, il predefinito binari implementazioni operatore OP, incluse le forme sollevato, diventano l'insieme di operatori candidati per la operazione. il predefinito implementazioni di un determinato operatore sono specificate nella descrizione l'operatore (§7.7 attraverso §7.11).

  • Le regole di risoluzione del sovraccarico di §7.4.3 sono applicati al set di operatori candidati di selezionare la migliore dell'operatore rispetto alla lista di argomenti (x, y), e questo vettore sia il risultato della risoluzione di sovraccarico processi. Se la risoluzione di sovraccarico non riesce a selezionare un singolo miglior operatore, si verifica un errore di compilazione.

Nel passaggio 2 Penso che questa implementazione predefinita dovrebbe essere applicato:

bool operator ==(object x, object y);
bool operator !=(object x, object y);

dal momento che tutto in C # deriva da Object. Come può un errore di compilazione si verifica nella fase 3? Non credo sia possibile che "la risoluzione di sovraccarico non riesce a selezionare" in questo caso.

Modifica La domanda mi è venuta in mente quando ho stava realizzando qualcosa di simile:

class EnumComparer<TEnum> : IEqualityComparer<TEnum>
{
    public bool Equals(TEnum x, TEnum y)
    {
        return x == y;
    }
    public int GetHashCode(TEnum obj)
    {
        return (int)obj;
    }
}

Sono io necessità paura di costruire un'espressione e di invocare lo dynamicly nel metodo Equals.

È stato utile?

Soluzione

Buon per voi per la lettura le specifiche, ma è stata interrotta la lettura troppo presto. Avevi letto più si sarebbe ottenuto a questo bit:


Gli operatori di uguaglianza del tipo di riferimento predefinite richiedono uno dei seguenti:

  • Entrambi gli operandi sono un valore di tipo noto per essere un riferimento di tipo o nullo letterale. Inoltre, una conversione riferimento esplicito esiste dal tipo di uno degli operandi al tipo dell'altro operando.

  • Un operando è un valore di tipo T, dove T è un tipo di parametro e l'altro operando è nullo letterale. Inoltre T non ha il vincolo tipo di valore.

A meno che una di queste condizioni sono vere, si verifica un errore di tempo vincolanti. (*)


L'errore non è da risoluzione sovraccarico; l'errore è che la risoluzione di sovraccarico avrebbe scelto il tipo di riferimento operatore di uguaglianza predefinito, e non si dispone di tipi di riferimento.

Si consideri il codice. Ciò che si ferma T dall'essere un tipo di valore senza operatore di uguaglianza definita su di esso? Niente. Supponiamo di ricadde alla versione oggetto; entrambi gli operandi sarebbero casella in posizioni diverse e quindi di riferimento disuguale, anche se avevano lo stesso contenuto. Dal momento che è lento, confuso e sbagliato, è illegale per provare ancora.

Perché stai cercando di fare questa cosa, in primo luogo? Se il metodo ha funzionato, che non lo fa, allora il vostro metodo sarebbe peggio che semplicemente utilizzando ==, in primo luogo. Qual è il valore che si intende aggiungere al mondo con questo metodo?


(*) Ho segnalato l'errore grammaticale in questa frase per i manutentori spec.

Altri suggerimenti

che avrebbe potuto funzionare se sapesse che where T : class, facendo un confronto di riferimento. Gli operatori hanno in genere molto poco sostegno con i generici, ma ci sono soluzioni alternative. MiscUtil offerte sostegno indiretto per gli operatori sui farmaci generici, altrimenti è un EqualityComparer<T>.Default.Equals(x,y) buona scelta.

Mi piace usare EqualityComparer<T>.Default per questo.

Si basa sul metodo Equals override, ma usi IEquatable<T> quando disponibile, evitando boxe sui tipi di valori di attuazione.

EqualityComparer<T>.Default.Equals(x, y)

utilizzare il metodo .Equals() ed essere sicuri che il T implementare IComparable

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