Conversioni implicite C# e operatore ==
-
23-08-2019 - |
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?
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);