C # implizite Konvertierungen und Operator ==
-
23-08-2019 - |
Frage
Einige Code für Kontext:
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;
Ist es möglich, Operator == auf andere Art Instanzen zu verwenden, wo man in einer anderen implizit umwandeln kann? Was habe ich verpasst?
Bearbeiten
Wenn Typen müssen die gleiche Berufung sein ==, warum dann
int a=1;
double b=1;
bool c=a==b;
funktioniert?
Lösung
Der implicit
Operator funktioniert nur für die Zuordnung.
Sie wollen die Gleichheit (==
) Betreiber zu überlasten, als solche:
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;
}
}
Dies sollte dann können Sie zwei Objekte vom Typ a
und b
vergleichen, wie in Ihrem Beitrag vorgeschlagen.
var x = new a();
var y = new b();
bool c = (x == y); // compiles
Hinweis:
I recommmend einfach die GetHashCode
und Equals
Methode überschrieben, wie der Compiler warnt, aber wie Sie scheinen zu wollen, um sie zu unterdrücken, können Sie tun, dass Sie wie folgt vor.
Ändern Sie Ihre Klassendeklaration von a
an:
#pragma warning disable 0660, 0661
class a
#pragma warning restore 0660, 0661
{
// ...
}
Andere Tipps
Ist es möglich, Operator == auf die Verwendung verschiedene Arten Fällen, in denen ein kann implizit in eine andere umwandeln?
Ja.
Was habe ich verpasst?
Hier ist der relevante Teil der Spezifikation. Sie verfehlten das markierte Wort.
Die vorgegebene Referenztyp Gleichheit Betreiber erfordern, [die] beide Operanden sind Werte Referenz-Typ oder die wörtliche null. Weiterhin ist ein Standard implizite Umwandlung besteht aus dem Art der beiden Operanden auf den Typ des der andere Operand.
Eine benutzerdefinierte Konvertierung ist per Definition nicht eine Standard-Konvertierung. Dies sind Referenztypen. Daher ist der vorgegebene Referenztyp Gleichheitsoperator kein Kandidat.
Wenn Typen müssen die gleiche Berufung sein ==, warum dann [double == int] funktioniert?
Ihre Vermutung, dass die Typen gleich sein müssen, ist falsch. Es gibt eine Standard-implizite Konvertierung von int zu verdoppeln, und es gibt einen Gleichheitsoperator, der zwei Doppelzimmer nimmt, so das funktioniert.
Ich glaube, Sie auch dieses Bit verpasst haben:
Es ist ein Fehler bei der Kompilierung zu verwenden, die vordefinierten Referenztyp Gleichheit Betreiber zwei Referenzen vergleichen dass, anders zu sein, sind bekannt bei Kompilierung der Zeit. Zum Beispiel, wenn die Kompilierung-Typen der Operanden zwei Klassentypen A und B, und wenn weder A noch B leitet sich von der andere, sein, dann wäre es unmöglich, die beiden Operanden die gleiche referenzieren Objekt. Somit ist der Betrieb als ein Fehler bei der Kompilierung.
Ich könnte mir vorstellen, dass Sie tatsächlich benötigen, um den Operator == außer Kraft für die Typen, die Sie interessieren. Ob die Kompilierung / Laufzeit noch einmal beschweren, wenn die Typen sind implicity konvertierbar ist etwas, das Sie mit experimentieren.
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);
}
}
Alternativ verwenden nur Equals Implementierungen wie ole6ka schlägt vor, und stellen Sie sicher, dass die Umsetzung der Art Casting macht Sie benötigen.
http://msdn.microsoft.com/en-us/library /8edha89s.aspx
In jedem Fall muss ein Parameter sein vom gleichen Typ wie die Klasse oder Struktur dass erklärt den Betreiber (...)
Verwenden Sie diese
bool c = a.Equals(b);