I C #, hva er forskjellen mellom hvordan == operatøren fungerer med referansetyper kontra primitiver?


Svar 1:

Samme som i Java: == sammenstiller verdier for primitiver, sammenligner pekere for referanser. I utgangspunktet ==, med mindre overbelastning vil sammenligne verdier som er lagret på bunken, hvis du vil sammenligne referansedatatyper som String for likhet, må du bruke metoden. Equals () denne vil sammenligne ting som er lagret på denne.


Svar 2:

Alle referansetyper støtter == sammenligning: hvis ikke overbelastet, vil operatøren utføre en referanseklikhetskontroll. Hvis den er overbelastet for en type, vil den utføre en verdiklikhetskontroll som definert av den typen. For eksempel i C # (i motsetning til Java) utfører == på strenger en verdi-sammenligning; spesifikt utfører den en ordinær verdi-sammenligning, dvs. en saksensitiv, kulturensensitiv karakter-for-karakter-sammenligning.

For innebygde primitive verdityper == gjør den forventede (vær forsiktig med flottør og dobbel, spesielt NaN) likhet. Brukerdefinerte verdityper må definere == og! = Eller en slik sammenligning vil ikke støttes. For de fleste strukturer der det er fornuftig å ønske å sammenligne for likestilling, bør du generelt:

  • definere == og! = overstyre Lik (objekt) overstyre GetHashCode () implementere IEquatable og gjør alt det foregående slik at hver metode gir resultat i samsvar med de andre

Svar 3:

I C # vil sammenligning av primitiver sammenligne verdiene sine, og sammenligne referansetyper vil sammenligne rheir-referanser (som standard). For referansetype betyr dette at ved å sammenligne to objekter, med mindre de er en eksakt samme forekomst (samme referanse), vil de ikke være like:

klasse Person
{
  offentlig streng Navn {get;}
  
  offentlig person (strengnavn)
  {
    Navn = navn;
  }
}

Vi oppretter 2 personer med samme navn. Deres referanser vil være forskjellige, cparisom vil resultere i falske.

var a = new Person ("Tom");
var b = ny person ("Tom");

var areEqual = a == b; // falsk

Du kan imidlertid overstyre standardoppførselen ved å overstyre == operator:

klasse Person
{
  offentlig streng Navn {get;}
  
  offentlig person (strengnavn)
  {
    Navn = navn;
  }

  offentlig statisk booloperatør == (Person p1, Person p2)
  {
    if (Object.ReferenceEquals (p1, null)
    {
      if (Object.ReferenceEquals (p2, null)
      {
        return true;
      }
    }

    // Nå som vi vet at venstre ikke er null, kan vi sammenligne verdiene
    return this.Equals (p2);
  }

  offentlig statisk booloperatør! = (Person p1, Person p2) =>! (p1 == p2);

  offentlig bool lik (objekt p)
  {
    // Sjekk om høyre side har verdi.
    if (Object.ReferenceEquals (p, null)
    {
      return falsk;
    }

    // frem til dette punktet har vi standard == implementering.

    // Begge referanser er like, betyr at det er det samme objektet med de samme verdiene.
    if (Object.ReferenceEquals (dette, p)
    {
      return true;
    }
    
    // Typer må samsvare nøyaktig.
    if (this.GetType ()! = p.GetType ())
    {
      return falsk;
    }
    
    // Til slutt kan vi sammenligne innholdet i hvert objekt.
    return this.Equals (p.Name);
  }
}

Hvis vi sammenligner de to igjen, vil resultatet være sant.

var a = new Person ("Tom");
var b = ny person ("Tom");

var areEqual = a == b; // sant