Overbelaste sammenligningsoperatorer
Implementer operatorene ==, != og operatorer for sortering.
Overbelaste sammenligningsoperatorer er en gratis leksjon i C# Academy på CoddyKit. Dette er leksjon 2 av 4. Du kan lese hele leksjonen gratis nedenfor – og deretter øve praktisk i nettleseren med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i C# Academy, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i C# Academy inneholder totalt 4 leksjoner.
Sammenligningsoperatorer og likhet
Når du overlagrer ==, må du også overlagre !=, og du bør overstyre Equals og GetHashCode slik at alle former for likhet er konsistente. C# håndhever at operatorene defineres som et par, på kompileringstidspunktet.
Overlagre == og !=
Kompilatoren krever at == og != defineres sammen. Hver av dem returnerer en bool som beskriver om operandene regnes som like.
using System;
public struct Point
{
public int X, Y;
public Point(int x, int y) { X = x; Y = y; }
public static bool operator ==(Point a, Point b) => a.X == b.X && a.Y == b.Y;
public static bool operator !=(Point a, Point b) => !(a == b);
public override bool Equals(object obj) => obj is Point p && this == p;
public override int GetHashCode() => HashCode.Combine(X, Y);
}
public class Program
{
public static void Main()
{
Console.WriteLine(new Point(1, 2) == new Point(1, 2));
Console.WriteLine(new Point(1, 2) != new Point(3, 4));
}
}Overstyr alltid Equals også
Operatorer løses på kompileringstidspunktet ut fra den statiske typen, mens Equals er virtuell og brukes av samlinger. Overstyr Equals slik at ordbøker og List.Contains samsvarer med ==.
using System;
public struct Point
{
public int X, Y;
public Point(int x, int y) { X = x; Y = y; }
public static bool operator ==(Point a, Point b) => a.X == b.X && a.Y == b.Y;
public static bool operator !=(Point a, Point b) => !(a == b);
public override bool Equals(object obj) => obj is Point p && this == p;
public override int GetHashCode() => HashCode.Combine(X, Y);
}
public class Program
{
public static void Main()
{
object a = new Point(1, 2);
object b = new Point(1, 2);
Console.WriteLine(a.Equals(b));
}
}GetHashCode må samsvare med likhet
Hvis to verdier er like, må de returnere samme hashkode. Ellers vil hashbaserte samlinger som Dictionary og HashSet oppføre seg feil.
using System;
using System.Collections.Generic;
public struct Point
{
public int X, Y;
public Point(int x, int y) { X = x; Y = y; }
public static bool operator ==(Point a, Point b) => a.X == b.X && a.Y == b.Y;
public static bool operator !=(Point a, Point b) => !(a == b);
public override bool Equals(object obj) => obj is Point p && this == p;
public override int GetHashCode() => HashCode.Combine(X, Y);
}
public class Program
{
public static void Main()
{
var set = new HashSet<Point> { new Point(1, 2) };
Console.WriteLine(set.Contains(new Point(1, 2)));
}
}Sorteringsoperatorene < og >
Du kan også overlagre relasjonsoperatorene. Som med likhet må < og > defineres sammen, og det samme gjelder <= og >=.
using System;
public struct Weight
{
public int Grams;
public Weight(int g) { Grams = g; }
public static bool operator <(Weight a, Weight b) => a.Grams < b.Grams;
public static bool operator >(Weight a, Weight b) => a.Grams > b.Grams;
public override string ToString() => Grams + "g";
}
public class Program
{
public static void Main()
{
Console.WriteLine(new Weight(100) < new Weight(200));
Console.WriteLine(new Weight(300) > new Weight(200));
}
}Likhet for referansetyper
For klasser betyr verdilikhet at feltene sammenlignes i stedet for referansene. Håndter null nøye for å unngå å kaste et unntak inne i operatoren.
using System;
public class Person
{
public string Name;
public Person(string name) { Name = name; }
public static bool operator ==(Person a, Person b)
{
if (ReferenceEquals(a, b)) return true;
if (a is null || b is null) return false;
return a.Name == b.Name;
}
public static bool operator !=(Person a, Person b) => !(a == b);
public override bool Equals(object obj) => this == (obj as Person);
public override int GetHashCode() => Name?.GetHashCode() ?? 0;
}
public class Program
{
public static void Main()
{
Console.WriteLine(new Person("Ann") == new Person("Ann"));
}
}Konsistens på tvers av former
Alle likhetsmekanismer bør gi samme resultat: ==, Equals og hashkoden. Implementer == ved hjelp av Equals (eller omvendt), slik at det finnes én sannhetskilde.
using System;
public struct Id
{
public int Value;
public Id(int value) { Value = value; }
public bool Equals(Id other) => Value == other.Value;
public override bool Equals(object obj) => obj is Id other && Equals(other);
public override int GetHashCode() => Value;
public static bool operator ==(Id a, Id b) => a.Equals(b);
public static bool operator !=(Id a, Id b) => !a.Equals(b);
}
public class Program
{
public static void Main()
{
Console.WriteLine(new Id(7) == new Id(7));
Console.WriteLine(new Id(7).Equals(new Id(8)));
}
}Operatorer kontra Equals i samlinger
Søk i lister bruker Equals, ikke ==, fordi det fungerer med object-referanser. Hvis du bare overlagrer == og glemmer Equals, bruker søk referanseidentitet og kan mislykkes.
using System;
using System.Collections.Generic;
public struct Tag
{
public string Name;
public Tag(string name) { Name = name; }
public override bool Equals(object obj) => obj is Tag t && t.Name == Name;
public override int GetHashCode() => Name?.GetHashCode() ?? 0;
public static bool operator ==(Tag a, Tag b) => a.Equals(b);
public static bool operator !=(Tag a, Tag b) => !a.Equals(b);
}
public class Program
{
public static void Main()
{
var list = new List<Tag> { new Tag("red"), new Tag("blue") };
Console.WriteLine(list.Contains(new Tag("blue")));
}
}Undertrykke kompilatoradvarsler på riktig måte
Det å overstyre Equals og GetHashCode sammen med operatorene er ikke bare god praksis; kompilatoren advarer hvis du overlagrer == uten å overstyre Equals. Ved å gjøre begge deler fjernes advarselen, og du unngår feil.
using System;
public struct Cell
{
public int Row, Col;
public Cell(int r, int c) { Row = r; Col = c; }
public override bool Equals(object obj) => obj is Cell c && c.Row == Row && c.Col == Col;
public override int GetHashCode() => HashCode.Combine(Row, Col);
public static bool operator ==(Cell a, Cell b) => a.Equals(b);
public static bool operator !=(Cell a, Cell b) => !a.Equals(b);
}
public class Program
{
public static void Main()
{
Console.WriteLine(new Cell(0, 0) == new Cell(0, 0));
}
}Sette alt sammen
En velfungerende type med likhetsstøtte definerer == og !=, overstyrer Equals og GetHashCode, og lar alle bruke én og samme sammenligning. Dette er gullstandarden for verdilignende typer.
using System;
using System.Collections.Generic;
public struct Color
{
public int R, G, B;
public Color(int r, int g, int b) { R = r; G = g; B = b; }
public override bool Equals(object obj) => obj is Color c && c.R == R && c.G == G && c.B == B;
public override int GetHashCode() => HashCode.Combine(R, G, B);
public static bool operator ==(Color a, Color b) => a.Equals(b);
public static bool operator !=(Color a, Color b) => !a.Equals(b);
}
public class Program
{
public static void Main()
{
var dict = new Dictionary<Color, string> { [new Color(255, 0, 0)] = "red" };
Console.WriteLine(dict[new Color(255, 0, 0)]);
}
}Prøv det selv
Implementer en struct med fullt konsistent likhetsstøtte, og kontroller at den fungerer både som nøkkel i en ordbok og med operatoren ==.
using System;
using System.Collections.Generic;
public struct GridPos
{
public int Row, Col;
public GridPos(int r, int c) { Row = r; Col = c; }
public override bool Equals(object obj) => obj is GridPos p && p.Row == Row && p.Col == Col;
public override int GetHashCode() => HashCode.Combine(Row, Col);
public static bool operator ==(GridPos a, GridPos b) => a.Equals(b);
public static bool operator !=(GridPos a, GridPos b) => !a.Equals(b);
}
public class Program
{
public static void Main()
{
var grid = new Dictionary<GridPos, string> { [new GridPos(1, 1)] = "player" };
Console.WriteLine(new GridPos(1, 1) == new GridPos(1, 1));
Console.WriteLine(grid[new GridPos(1, 1)]);
}
}Hurtigsjekk
Husk reglene for overlagring av likhet.
Oppsummering
Overlagring av sammenligningsoperatorer krever konsistens.
==og!=må defineres sammen; det samme gjelder</>.- Overstyr
EqualsogGetHashCodeslik at de samsvarer med==. - Like verdier må ha samme hashkode.
- La all likhet gå gjennom én sammenligningsmetode for å unngå avvik.
Lær deg C# med en AI-veileder – gratis
Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.
- Kurs
- 93
- Leksjoner
- 346
Ofte stilte spørsmål
Er leksjonen «Overbelaste sammenligningsoperatorer» gratis?
Ja – hele teksten i «Overbelaste sammenligningsoperatorer» er gratis å lese her på nettet. For å øve interaktivt med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt, og for å låse opp resten av C# Academy-kurset, kan du oppgradere til CoddyKit PRO. Kurset i C# Academy inneholder totalt 4 leksjoner.
Hva lærer jeg i «Overbelaste sammenligningsoperatorer»?
Implementer operatorene ==, != og operatorer for sortering. Du øver på C# Academy med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.
Trenger jeg erfaring for å begynne med C# Academy?
Ingen tidligere erfaring er nødvendig. C# Academy på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 2 av 4.
Hvor lang tid tar leksjonen «Overbelaste sammenligningsoperatorer»?
De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.
Kan jeg skrive og kjøre kode i denne C# Academy-leksjonen?
Ja. Alle C# Academy-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.
Alle leksjonene i dette kurset
- Overbelaste aritmetiske operatorer
- Overbelaste sammenligningsoperatorer
- Brukerdefinerte konverteringer
- Beste praksis for operatoroverbelastning