Trong C #, sự khác biệt giữa cách toán tử == hoạt động với các kiểu tham chiếu so với nguyên thủy là gì?


Câu trả lời 1:

Giống như trong Java: == tính toán các giá trị cho các nguyên hàm, so sánh các con trỏ cho các tham chiếu. Về cơ bản ==, trừ khi quá tải sẽ so sánh các giá trị được lưu trữ trên ngăn xếp, nếu bạn muốn so sánh các kiểu dữ liệu tham chiếu như String cho đẳng thức, bạn phải sử dụng phương thức .Equals () cái này sẽ so sánh các công cụ được lưu trữ trên heh heap.


Câu trả lời 2:

Tất cả các loại tham chiếu hỗ trợ == so sánh: nếu không bị quá tải, toán tử sẽ thực hiện kiểm tra đẳng thức tham chiếu. Nếu quá tải cho một loại, nó sẽ thực hiện kiểm tra đẳng thức giá trị như được xác định bởi loại đó. Ví dụ: trong C # (không giống như Java) biểu diễn == trên chuỗi thực hiện so sánh giá trị; cụ thể, nó thực hiện một so sánh giá trị thông thường, tức là so sánh theo từng ký tự, không nhạy cảm về văn hóa.

Đối với các loại giá trị nguyên thủy được xây dựng ==, hãy cân bằng giá trị float và double, đặc biệt là NaN). Các loại giá trị do người dùng xác định phải xác định == và! = Hoặc so sánh như vậy sẽ không được hỗ trợ. Nói chung, đối với hầu hết các cấu trúc, nơi có ý nghĩa muốn so sánh cho sự bình đẳng, bạn nên:

  • xác định == và! = ghi đè Bằng (ghi đối tượng) ghi đè GetHashCode () thực hiện IEquitable và thực hiện tất cả các điều đã nói ở trên sao cho mỗi phương thức cung cấp kết quả phù hợp với các phương thức khác

Câu trả lời 3:

Trong C #, so sánh các nguyên thủy sẽ so sánh các giá trị của chúng, so sánh các loại tham chiếu sẽ so sánh các tham chiếu rheir (theo mặc định). Đối với kiểu tham chiếu, điều này có nghĩa là bằng cách so sánh 2 đối tượng, trừ khi chúng là một thể hiện chính xác (cùng tham chiếu), chúng sẽ không bằng nhau:

lớp người
{
  Tên chuỗi công khai {get;}
  
  Người công khai (tên chuỗi)
  {
    Tên = tên;
  }
}

Chúng tôi tạo ra 2 người có cùng tên. Tài liệu tham khảo của họ sẽ khác nhau, cparisom sẽ dẫn đến sai.

var a = Người mới ("Tom");
var b = Người mới ("Tom");

var areEqual = a == b; // sai

Tuy nhiên, bạn có thể ghi đè hành vi mặc định bằng cách ghi đè toán tử ==:

lớp người
{
  Tên chuỗi công khai {get;}
  
  Người công khai (tên chuỗi)
  {
    Tên = tên;
  }

  Toán tử bool tĩnh tĩnh == (Người p1, Người p2)
  {
    if (Object.ReferenceEquals (p1, null)
    {
      if (Object.ReferenceEquals (p2, null)
      {
        trả lại đúng sự thật;
      }
    }

    // Bây giờ chúng ta biết trái không phải là null, chúng ta có thể so sánh các giá trị
    trả lại cái này.Equals (p2);
  }

  Toán tử bool tĩnh công khai! = (Người p1, Người p2) =>! (p1 == p2);

  công khai bool Bằng (đối tượng p)
  {
    // Kiểm tra xem bên phải có giá trị không.
    if (Object.ReferenceEquals (p, null)
    {
      trả lại sai;
    }

    // cho đến thời điểm này, chúng tôi có mặc định == thực hiện.

    // Cả hai tham chiếu đều bằng nhau có nghĩa là cùng một đối tượng có cùng giá trị.
    if (Object.ReferenceEquals (này, p)
    {
      trả lại đúng sự thật;
    }
    
    // Các loại cần khớp chính xác.
    if (this.GetType ()! = p.GetType ())
    {
      trả lại sai;
    }
    
    // Cuối cùng chúng ta có thể so sánh nội dung của từng đối tượng.
    trả lại cái này.Equals (p.Name);
  }
}

Bây giờ nếu chúng ta so sánh hai lần nữa thì kết quả sẽ đúng.

var a = Người mới ("Tom");
var b = Người mới ("Tom");

var areEqual = a == b; // thật