Domanda

Alcuni codici per il contesto:

class a
{

}

class b
{
    public a a{get;set;}
    public static implicit operator a(b b)
    {
        return b.a;
    }
}

  a a=null;
  b b=null;
  a = b;

  //compiler: cannot apply operator '==' to operands of type tralala...
  bool c = a == b; 

È possibile utilizzare l'operatore == su istanze di tipo diverso, dove è possibile convertirlo implicitamente in un altro?Cosa mi sono perso?

Modificare:
Se i tipi devono essere gli stessi chiamando ==, allora perché

int a=1;
double b=1;
bool c=a==b; 

lavori?

È stato utile?

Soluzione

L'operatore implicit funziona solo per l'assegnazione.

Si vuole sovraccaricare l'operatore di uguaglianza (==), come ad esempio:

class a
{
    public static bool operator ==(a x, b y)
    {
        return x == y.a;
    }

    public static bool operator !=(a x, b y)
    {
        return !(x == y);
    }
}

class b
{
    public a a{get;set;}
    public static implicit operator a(b b)
    {
        return b.a;
    }
}

Questo dovrebbe quindi consentire di confrontare due oggetti di tipo a e b come suggerito nel tuo post.

var x = new a();
var y = new b();
bool c = (x == y); // compiles

Nota:

I caldamente semplicemente l'override del metodo GetHashCode e Equals, come il compilatore avverte, ma come ti sembra di voler sopprimere loro, si può fare come segue.

Cambia la dichiarazione di classe di a a:

#pragma warning disable 0660, 0661
class a
#pragma warning restore 0660, 0661
{
    // ...
}

Altri suggerimenti

  

E 'possibile utilizzare == operatore   le istanze di tipo diverso, quando uno   può convertire implicitamente ad un altro?

Sì.

  

Cosa mi sono perso?

Ecco la quota di competenza della specifica. Ti sei perso la parola evidenziata.

  

Il predefinito uguaglianza tipo di riferimento   operatori richiedono [che] entrambi gli operandi   sono valori di riferimento di tipo oi   nullo letterale. Inoltre, un standard   conversione implicita esiste dal   tipo di uno dei due operandi al tipo di   l'altro operando.

Una conversione definita dall'utente è per definizione una conversione standard. Questi sono i tipi di riferimento. Pertanto, il tipo di riferimento predefinito operatore di uguaglianza non è un candidato.

  

Se i tipi deve essere la stessa vocazione ==,   allora perché [doppio == int] funziona?

Il tuo supposizione che i tipi devono essere gli stessi non è corretto. V'è una conversione implicita da int standard di raddoppiare e non v'è un operatore di uguaglianza che prende due doppie, quindi questo funziona.

Credo che anche voi persi questo bit:

  

Si tratta di un errore di compilazione di utilizzare la   Tipo uguaglianza riferimento predeterminato   operatori per confrontare due riferimenti   che sono noti per essere differente a   compile-time. Ad esempio, se il   Tipi fase di compilazione degli operandi sono   due tipi di classe A e B, e se   né A né B deriva dal   altri, allora sarebbe impossibile per   i due operandi riferimento allo stesso   oggetto. Pertanto, l'operazione è   considerato un errore di compilazione.

Immagino che è necessario sostituire in realtà l'operatore == per i tipi a cui è interessato. Se la compilazione / runtime sarà ancora lamentano anche se i tipi sono implicitamente convertibile è qualcosa che si dovrà sperimentare.

public static bool operator ==(a a, b b)
    {
        //Need this check or we can't do obj == null in our Equals implementation
        if (((Object)a) == null)
        {
            return false;
        }
        else
        {
            return a.Equals(b);
        }
    }

In alternativa basta utilizzare Uguale implementazioni come ole6ka suggerisce e garantire che l'attuazione fa il casting di tipo è necessario.

http://msdn.microsoft.com/en-us/library /8edha89s.aspx

  

In ogni caso, un parametro deve essere   lo stesso tipo come la classe o struct   che dichiara l'operatore (...)

Usa questo

 bool c = a.Equals(b);
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top