Ten artykuł został przetłumaczony przez maszynę. Aby wyświetlić jego treść w języku angielskim, zaznacz pole wyboru Angielski. Możesz też wyświetlić angielski tekst w okienku wyskakującym, przesuwając wskaźnik myszy nad konkretny tekst”.
Tłumaczenie
Angielski

Metoda Object.Equals — (Object)

.NET Framework (current version)
 

Data opublikowania: październik 2016

Sprawdza, czy podany obiekt jest równy aktualnemu obiektowi

Przestrzeń nazw:   System
Zestaw:  mscorlib (w mscorlib.dll)

public virtual bool Equals(
	object obj
)

Parametry

obj
Type: System.Object

Obiekt do porównania z bieżącym obiektem.

Wartość zwracana

Type: System.Boolean

trueJeśli określony obiekt jest taki sam jak bieżący obiekt; w przeciwnym razie false.

Typ porównania dla bieżącego wystąpienia i obj parametru zależy od tego, czy bieżące wystąpienie jest typem referencyjnym lub typem wartości.

  • Jeśli bieżące wystąpienie jest typem referencyjnym Equals(Object) testy metoda równości odwołań i wywołanie Equals(Object) jest odpowiednikiem wywołania metody ReferenceEquals metody. Równość odwołania oznacza, że zmienne obiektów, które są porównywane odwołują się do tego samego obiektu. Poniższy przykład przedstawia wynik takie porównanie. Definiuje Person klasy, która jest typem referencyjnym, i wywołania Person konstruktora klasy można utworzyć dwa nowe Person obiektów, person1a i person2, które mają taką samą wartość. Przypisuje także person1a innej zmiennej obiektu, person1b. Jako dane wyjściowe w przykładzie pokazano person1a i person1b są takie same, ponieważ odwołujących się do tego samego obiektu. Jednak person1a i person2 nie są takie same, mimo że mają one taką samą wartość.

    using System;
    
    // Define a reference type that does not override Equals.
    public class Person
    {
       private string personName;
    
       public Person(string name)
       {
          this.personName = name;
       }
    
       public override string ToString()
       {
          return this.personName;
       }
    }
    
    public class Example
    {
       public static void Main()
       {
          Person person1a = new Person("John");
          Person person1b = person1a;
          Person person2 = new Person(person1a.ToString());
    
          Console.WriteLine("Calling Equals:"); 
          Console.WriteLine("person1a and person1b: {0}", person1a.Equals(person1b));               
          Console.WriteLine("person1a and person2: {0}", person1a.Equals(person2));  
    
          Console.WriteLine("\nCasting to an Object and calling Equals:");
          Console.WriteLine("person1a and person1b: {0}", ((object) person1a).Equals((object) person1b));
          Console.WriteLine("person1a and person2: {0}", ((object) person1a).Equals((object) person2)); 
       }
    }
    // The example displays the following output:
    //       person1a and person1b: True
    //       person1a and person2: False
    //       
    //       Casting to an Object and calling Equals:
    //       person1a and person1b: True
    //       person1a and person2: False
    
  • Jeśli bieżące wystąpienie jest typem wartości Equals(Object) testy metoda równości wartości. Równość wartości oznacza, że następujące czynności:

    • Dwa obiekty są tego samego typu. Jak pokazano na poniższym przykładzie, Byte obiekt, który ma wartość 12 nie jest równa Int32 obiekt, który ma wartość 12, ponieważ te dwa obiekty mają różne typy środowiska wykonawczego.

      using System;
      
      public class Example
      {
         public static void Main()
         {
            byte value1 = 12;
            int value2 = 12;
      
            object object1 = value1;
            object object2 = value2;
      
            Console.WriteLine("{0} ({1}) = {2} ({3}): {4}",
                              object1, object1.GetType().Name,
                              object2, object2.GetType().Name,
                              object1.Equals(object2));
         }
      }
      // The example displays the following output:
      //        12 (Byte) = 12 (Int32): False
      
    • Wartości pola publiczne i prywatne dwa obiekty są równe. Poniższy przykład badań równości wartości. Definiuje Person struktury, która jest typem wartości, i wywołania Person konstruktora klasy można utworzyć dwa nowe Person obiektów, person1 i person2, które mają taką samą wartość. Jak dane wyjściowe w przykładzie pokazano, mimo że zmienne dwóch obiektów odwoływać się do różnych obiektów, person1 i person2 są takie same, ponieważ mają one taką samą wartość dla prywatnego personName pola.

      using System;
      
      // Define a value type that does not override Equals.
      public struct Person
      {
         private string personName;
      
         public Person(string name)
         {
            this.personName = name;
         }
      
         public override string ToString()
         {
            return this.personName;
         }
      }
      
      public struct Example
      {
         public static void Main()
         {
            Person person1 = new Person("John");
            Person person2 = new Person("John");
      
            Console.WriteLine("Calling Equals:"); 
            Console.WriteLine(person1.Equals(person2)); 
      
            Console.WriteLine("\nCasting to an Object and calling Equals:");
            Console.WriteLine(((object) person1).Equals((object) person2));  
         }
      }
      // The example displays the following output:
      //       Calling Equals:
      //       True
      //       
      //       Casting to an Object and calling Equals:
      //       True
      

Ponieważ Object klasa jest klasą bazową dla wszystkich typów w programie .NET Framework Object.Equals(Object) metoda zapewnia domyślne porównania równości dla wszystkich innych typów. Jednak typy często przesłaniać Equals metody do zaimplementowania równości wartości. Aby uzyskać więcej informacji zobacz uwagi dla wywołań i uwagi dotyczące dziedziczenia sekcji.

Podczas wywoływania Equals(Object) przeciążenie metody w klasie w Środowisko wykonawcze systemu Windows, zapewnia domyślne zachowanie dla klas, które nie zastępują Equals(Object). To jest częścią programu .NET Framework zapewnia obsługę Środowisko wykonawcze systemu Windows (zobacz Obsługa .NET Framework dla aplikacji sklepu Windows Store i środowiska wykonawczego systemu Windows). Klasy w Środowisko wykonawcze systemu Windows nie dziedziczy Object, a obecnie nie implementują Equals(Object)metody. Jednak pojawią się one mieć ToString, Equals(Object), i GetHashCode metody, gdy ich używać w kodzie C# lub Visual Basic i .NET Framework zapewnia domyślne zachowanie dla tych metod.

System_CAPS_noteUwaga

Środowisko wykonawcze systemu Windowsklasy, które są napisane w języku C# lub Visual Basic można zastąpić Equals(Object) przeciążenie metody.

Klasy pochodne często zastąpienia Object.Equals(Object) metody do zaimplementowania równości wartości. Ponadto typy również często udostępniają dodatkowe przeładowania jednoznacznie Equals metody zwykle zaimplementowanie IEquatable<T> interfejsu. Podczas wywoływania Equals metody do testowania pod kątem równości, należy sprawdzić, czy bieżące wystąpienie zastępuje Object.Equals i zrozumieć, w jaki sposób wywołania określonej Equals metody został rozwiązany. W przeciwnym razie należy pod kątem równości, który różni się od zgodny z zamierzonym wykonywania testu, a metoda może zwracać nieoczekiwaną wartość.

Poniższy przykład stanowi ilustrację. Tworzy wystąpienie, trzy StringBuilder obiekty o identycznych ciągów, a następnie tworzy cztery wywołania Equals metody. Pierwsza metoda wywołania zwraca truei pozostałe trzy zwrot false.

using System;
using System.Text;

public class Example
{
   public static void Main()
   {
      StringBuilder sb1 = new StringBuilder("building a string...");
      StringBuilder sb2 = new StringBuilder("building a string...");

      Console.WriteLine("sb1.Equals(sb2): {0}", sb1.Equals(sb2));
      Console.WriteLine("((Object) sb1).Equals(sb2): {0}", 
                        ((Object) sb1).Equals(sb2));
      Console.WriteLine("Object.Equals(sb1, sb2): {0}",
                        Object.Equals(sb1, sb2));      

      Object sb3 = new StringBuilder("building a string...");
      Console.WriteLine("\nsb3.Equals(sb2): {0}", sb3.Equals(sb2));                              
   }
}
// The example displays the following output:
//       sb1.Equals(sb2): True
//       ((Object) sb1).Equals(sb2): False
//       Object.Equals(sb1, sb2): False
//
//       sb3.Equals(sb2): False

W pierwszym przypadku silnie typizowaną StringBuilder.Equals(StringBuilder) przeciążenie metody, które testy w celu porównania wartości, jest wywoływana. Ponieważ ciągi są przypisywane dwa StringBuilder obiekty są takie same, metoda zwraca true. Jednak StringBuilder nie przesłania Object.Equals(Object). Ze względu na to gdy StringBuilder obiektu jest rzutowane na Object, gdy StringBuilder wystąpienia jest przypisany do zmiennej typu Objecti kiedy Object.Equals(Object, Object) metody jest przekazywany dwa StringBuilder obiektów, domyślne Object.Equals(Object) metoda jest wywoływana. Ponieważ StringBuilder jest typem referencyjnym, co jest równoważne przekazywanie dwa StringBuilder obiekty do ReferenceEquals metody. Mimo że wszystkie trzy StringBuilder obiekty zawierają identycznych ciągów, odnoszą się do trzech oddzielnych obiektów. W związku z tym te trzy metoda wywołuje zwracany false.

Możesz porównać bieżący obiekt do innego obiektu równości odwołań, wywołując ReferenceEquals metody. W języku Visual Basic, można również użyć is — słowo kluczowe (na przykład If Me Is otherObject Then ...).

Podczas definiowania własnych typu tego typu dziedziczy funkcje zdefiniowane przez Equals metoda jego typ podstawowy. W poniższej tabeli wymieniono Domyślna implementacja Equals metodę główne kategorie typów w programie .NET Framework.

Typ kategorii

Zdefiniowane przez równości

Komentarze

Klasa pochodzi bezpośrednio zObject

Object.Equals(Object)

Równości odwołań; odpowiednikiem wywołania Object.ReferenceEquals.

Struktura

ValueType.Equals

Równość wartości; bezpośrednie porównanie po bicie lub porównanie przez pole przy użyciu odbicia.

Wyliczenie

Enum.Equals

Wartości muszą mieć ten sam typ wyliczeniowy i tej samej wartości podstawowej.

Delegate

MulticastDelegate.Equals

Obiekty delegowane musi mieć ten sam typ z listami identyczne wywołania.

Interface

Object.Equals(Object)

Równość odwołania.

Dla typu wartości powinny zawsze zastępować Equals, ponieważ testy pod kątem równości, które działają na podstawie odbicia oferuje pogorszenie wydajności. Można również zmienić domyślną implementację elementu Equals dla typów odwołań do testowania pod kątem równości wartości zamiast równości odwołań i definiowanie równości wartości znaczenie. Takie implementacje Equals zwracać true Jeśli dwa obiekty mają taką samą wartość, nawet jeśli nie są tego samego wystąpienia. Typ implementujący decyduje o tym, co stanowi wartość obiektu, ale jest zwykle niektórych lub wszystkich danych przechowywanych w zmiennych wystąpienia obiektu. Na przykład wartość String obiektu jest oparta na znaków ciągu; String.Equals(Object) zamienników metod Object.Equals(Object) metodę, aby powrócić true dla dowolnego ciągu dwa wystąpienia, które zawierają te same znaki w tej samej kolejności.

Poniższy przykład przedstawia sposób przesłonięcia Object.Equals(Object) metody do testowania pod kątem równości wartości. Zastępuje on Equals metodę Person klasy. Jeśli Person zaakceptowane implementację jej klasy podstawowej równości, dwa Person obiekty są takie same, tylko wtedy, gdy ich odwołuje się do pojedynczego obiektu. Jednak w takim przypadku dwa Person obiekty są takie same, jeśli mają taką samą wartość Person.Id właściwości.

public class Person
{
   private string idNumber;
   private string personName;

   public Person(string name, string id)
   {
      this.personName = name;
      this.idNumber = id;
   }

   public override bool Equals(Object obj)
   {
      Person personObj = obj as Person; 
      if (personObj == null)
         return false;
      else
         return idNumber.Equals(personObj.idNumber);
   }

   public override int GetHashCode()
   {
      return this.idNumber.GetHashCode(); 
   }
}

public class Example
{
   public static void Main()
   {
      Person p1 = new Person("John", "63412895");
      Person p2 = new Person("Jack", "63412895");
      Console.WriteLine(p1.Equals(p2));
      Console.WriteLine(Object.Equals(p1, p2));
   }
}
// The example displays the following output:
//       True
//       True

Oprócz zastępowania Equals, można zaimplementować IEquatable<T> interfejsu zapewnienie jednoznacznie testu równości.

Poniższe instrukcje musi mieć wartość true dla wszystkich wdrożeń Equals(Object) metody. Na liście x, y, i z reprezentowania odwołań do obiektów, które nie są null.

  • x.Equals(x)Zwraca true, z wyjątkiem przypadków obejmujących typów zmiennoprzecinkowych. Zobacz IEEE-ISO/IEC 60559:2011, technologii informatycznych — mikroprocesora systemów — zmiennoprzecinkowe arytmetyczne.

  • x.Equals(y)zwraca taką samą wartość jak y.Equals(x).

  • x.Equals(y)Zwraca true Jeśli obie x i yNaN.

  • Jeśli (x.Equals(y) && y.Equals(z)) zwraca true, następnie x.Equals(z) zwraca true.

  • Kolejne wywołania x.Equals(y) zwraca tę samą wartość jak odwołują się obiekty x i y nie są modyfikowane.

  • x.Equals(null)Zwraca false.

Implementacje Equals nie może zostać zwrócone wyjątków; należy zawsze zwracają wartość. Na przykład jeśli obj jest null, Equals metoda powinna zwrócić false zamiast zgłaszanie ArgumentNullException.

Skorzystaj z następujących wskazówek podczas zastępowania Equals(Object):

  • Typy, które implementują IComparable przesłonięcie Equals(Object).

  • Typy zastąpienie tego Equals(Object) musi także zastępować metodę GetHashCode; w przeciwnym razie wartość skrótu tabele mogą nie działać poprawnie.

  • Należy rozważyć wdrożenie IEquatable<T> interfejs do obsługi silnie wpisane testy pod kątem równości. Twoje IEquatable<T>.Equals implementacji powinien zwrócić wyników, które są zgodne z Equals.

  • Jeśli język programowania obsługuje przeładowania operatora i przeciążenia operatora równości dla danego typu, musi także zastępować Equals(Object) metodę, aby zwrócić takiego samego wyniku jako operator równości. Pomaga to zapewnić, że kod biblioteki klasy, który używa Equals (takich jak ArrayList i Hashtable) działa w sposób zgodny z sposób operator równości jest używany przez kod aplikacji.

Poniższe wskazówki dotyczą zastępowanie Equals(Object) dla typu odwołania:

  • Należy wziąć pod uwagę zastępowanie Equals przypadku opiera się na fakt, że niektóre wartości reprezentuje typ semantykę typu.

  • Większość typów referencyjnych nie muszą przeciążać operatora równości, nawet jeśli zastępują one Equals. Jednak w przypadku wdrażania typu odwołania, która powinna mieć semantyki wartości, takie jak typ liczby złożonej, konieczne jest przesłonięcie operatora równości.

  • Nie należy zastąpić Equals na modyfikowalnego typu referencyjnego. Jest to spowodowane zastępowanie Equals wymaga się, że możesz też przesłonić GetHashCode metody, zgodnie z opisem w poprzedniej sekcji. Oznacza to, że wartość skrótu wystąpienia modyfikowalnego typu referencyjnego może zmieniać się przez jego okres istnienia, co może powodować obiektu utracone w tablicy skrótów.

Poniższe wskazówki dotyczą zastępowanie Equals(Object) dla typu wartości:

  • Jeśli definiujesz typu wartości, która zawiera co najmniej jedno pole których wartości są typy odwołań, powinny zastępować Equals(Object). Equals(Object) Implementacji podał ValueType przeprowadza porównanie po bicie dla typów wartości, których pola są wszystkie typy wartości, ale używa odbicia do wykonania porównania pola przez typy wartości, których pola obejmują typy referencyjne.

  • Jeśli można zastąpić Equals i przeciążania operatorów obsługuje język programowania, muszą przeciążać operatora równości.

  • Należy zaimplementować IEquatable<T> interfejsu. Wywoływanie silnie typizowaną IEquatable<T>.Equals metoda pozwala uniknąć pakującej obj argumentu.

W poniższym przykładzie przedstawiono Point klasy, która zastępuje Equals metodę w celu zapewnienia równości wartości i Point3D klasy, która jest pochodną Point. Ponieważ Point zastępuje Object.Equals(Object) do testowania równości wartości Object.Equals(Object) nie jest wywoływana metoda. Jednak Point3D.Equals wywołania Point.Equals ponieważ Point implementuje Object.Equals(Object) w taki sposób, który udostępnia wartość porównania.

using System;

class Point
{
   protected int x, y;

   public Point() : this(0, 0) 
   { }

   public Point(int x, int y) 
   {
      this.x = x;
      this.y = y;
   }

   public override bool Equals(Object obj) 
   {
      //Check for null and compare run-time types.
      if ((obj == null) || ! this.GetType().Equals(obj.GetType())) {
         return false;
      }
      else { 
         Point p = (Point) obj; 
         return (x == p.x) && (y == p.y);
      }   
   }

   public override int GetHashCode() 
   {
      return (x << 2) ^ y;
   }

    public override string ToString()
    {
        return String.Format("Point({0}, {1})", x, y);
    }
}

sealed class Point3D: Point 
{
   int z;

   public Point3D(int x, int y, int z) : base(x, y) 
   {
      this.z = z; 
   }

   public override bool Equals(Object obj) 
   {
      Point3D pt3 = obj as Point3D;
      if (pt3 == null)
         return false;
      else
         return base.Equals((Point)obj) && z == pt3.z;
   }

   public override int GetHashCode() 
   {
      return (base.GetHashCode() << 2) ^ z;
   }

   public override String ToString() 
   {
        return String.Format("Point({0}, {1}, {2})", x, y, z);
    }
}

class Example 
{
  public static void Main() 
  {
     Point point2D = new Point(5, 5);
     Point3D point3Da = new Point3D(5, 5, 2);
     Point3D point3Db = new Point3D(5, 5, 2);
     Point3D point3Dc = new Point3D(5, 5, -1);

     Console.WriteLine("{0} = {1}: {2}", 
                       point2D, point3Da, point2D.Equals(point3Da));
     Console.WriteLine("{0} = {1}: {2}", 
                       point2D, point3Db, point2D.Equals(point3Db));        
     Console.WriteLine("{0} = {1}: {2}", 
                       point3Da, point3Db, point3Da.Equals(point3Db));
     Console.WriteLine("{0} = {1}: {2}", 
                       point3Da, point3Dc, point3Da.Equals(point3Dc));
  } 
}
// The example displays the following output:
//       Point(5, 5) = Point(5, 5, 2): False
//       Point(5, 5) = Point(5, 5, 2): False
//       Point(5, 5, 2) = Point(5, 5, 2): True
//       Point(5, 5, 2) = Point(5, 5, -1): False

The Point.Equals method checks to make sure that the obj argument is not null and that it references an instance of the same type as this object. If either check fails, the method returns false.

The Point.Equals method calls the M:System.Object.GetType method to determine whether the run-time types of the two objects are identical. If the method used a check of the form obj is Point in C# or TryCast(obj, Point) in Visual Basic, the check would return true in cases where obj is an instance of a derived class of Point, even though obj and the current instance are not of the same run-time type. Having verified that both objects are of the same type, the method casts obj to type Point and returns the result of comparing the instance fields of the two objects.

In Point3D.Equals, the inherited Point.Equals method, which overrides M:System.Object.Equals(System.Object), is invoked before anything else is done. Because Point3D is a sealed class (NotInheritable in Visual Basic), a check in the form obj is Point in C# or TryCast(obj, Point) in Visual Basic is adequate to ensure that obj is a Point3D object. If it is a Point3D object, it is cast to a Point object and passed to the base class implementation of M:System.Object.Equals(System.Object). Only when the inherited Point.Equals method returns true does the method compare the z instance fields introduced in the derived class.

W poniższym przykładzie zdefiniowano Rectangle klasy, która implementuje wewnętrznie prostokąt jako dwa Point obiektów. Rectangle Klasy również zastąpienia Object.Equals(Object) do zapewnienia równości wartości.

using System;

class Rectangle 
{
   private Point a, b;

   public Rectangle(int upLeftX, int upLeftY, int downRightX, int downRightY) {
      this.a = new Point(upLeftX, upLeftY);
      this.b = new Point(downRightX, downRightY);
   }

   public override bool Equals(Object obj) {
      // Perform an equality check on two rectangles (Point object pairs).
      if (obj == null || GetType() != obj.GetType()) 
          return false;
      Rectangle r = (Rectangle)obj;
      return a.Equals(r.a) && b.Equals(r.b);
   }

   public override int GetHashCode() {
      return Tuple.Create(a, b).GetHashCode();
   }

    public override String ToString() 
    {
       return String.Format("Rectangle({0}, {1}, {2}, {3})",
                            a.x, a.y, b.x, b.y); 
    }
}

class Point 
{
  internal int x;
  internal int y;

  public Point(int X, int Y) {
     this.x = X;
     this.y = Y;
  }

  public override bool Equals (Object obj) {
     // Performs an equality check on two points (integer pairs).
     if (obj == null || GetType() != obj.GetType()) return false;
     Point p = (Point)obj;
     return (x == p.x) && (y == p.y);
  }

  public override int GetHashCode() {
     return Tuple.Create(x, y).GetHashCode();
  }
}

class Example 
{
   public static void Main() 
   {
      Rectangle r1 = new Rectangle(0, 0, 100, 200);
      Rectangle r2 = new Rectangle(0, 0, 100, 200);
      Rectangle r3 = new Rectangle(0, 0, 150, 200);

      Console.WriteLine("{0} = {1}: {2}", r1, r2, r1.Equals(r2));
      Console.WriteLine("{0} = {1}: {2}", r1, r3, r1.Equals(r3));
      Console.WriteLine("{0} = {1}: {2}", r2, r3, r2.Equals(r3));
   }
}
// The example displays the following output:
//    Rectangle(0, 0, 100, 200) = Rectangle(0, 0, 100, 200): True
//    Rectangle(0, 0, 100, 200) = Rectangle(0, 0, 150, 200): False
//    Rectangle(0, 0, 100, 200) = Rectangle(0, 0, 150, 200): False

Niektóre języki, takich jak C# i Visual Basic obsługują przeładowania operatora. Gdy typem overloads operator równości, musi także zastępować Equals(Object) metodę, aby dostarczyć te same funkcje. Zazwyczaj jest to realizowane za pomocą Equals(Object) metody pod względem operator równości przeciążone, jak w poniższym przykładzie.

using System;

public struct Complex {
   public double re, im;

   public override bool Equals(Object obj) {
      return obj is Complex && this == (Complex)obj;
   }

   public override int GetHashCode() {
      return Tuple.Create(re, im).GetHashCode();
   }

   public static bool operator ==(Complex x, Complex y) {
      return x.re == y.re && x.im == y.im;
   }

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

    public override String ToString()
    {
       return String.Format("({0}, {1})", re, im);
    } 
}

class MyClass 
{
  public static void Main() 
  {
    Complex cmplx1, cmplx2;

    cmplx1.re = 4.0;
    cmplx1.im = 1.0;

    cmplx2.re = 2.0;
    cmplx2.im = 1.0;

    Console.WriteLine("{0} <> {1}: {2}", cmplx1, cmplx2, cmplx1 != cmplx2);        
    Console.WriteLine("{0} = {1}: {2}", cmplx1, cmplx2, cmplx1.Equals(cmplx2));        

    cmplx2.re = 4.0;

    Console.WriteLine("{0} = {1}: {2}", cmplx1, cmplx2, cmplx1 == cmplx2);        
    Console.WriteLine("{0} = {1}: {2}", cmplx1, cmplx2, cmplx1.Equals(cmplx2));          
  }
}
// The example displays the following output:
//       (4, 1) <> (2, 1): True
//       (4, 1) = (2, 1): False
//       (4, 1) = (4, 1): True
//       (4, 1) = (4, 1): True

Because Complex is a value type, it cannot be derived from. Therefore, the override to M:System.Object.Equals(System.Object) method need not call M:System.Object.GetType to determine the precise run-time type of each object, but can instead use the is operator in C# or the TypeOf operator in Visual Basic to check the type of the obj parameter.

Platforma uniwersalna systemu Windows
Dostępne od 8
.NET Framework
Dostępne od 1.1
Biblioteka klas przenośnych
Obsługiwane w: przenośne platformy .NET
Silverlight
Dostępne od 2.0
Windows Phone Silverlight
Dostępne od 7.0
Windows Phone
Dostępne od 8.1
Powrót do początku
Pokaż: