Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C#

การเปรียบเทียบ Tuple ใน C# (C# 7.3+)

ตั้งแต่ C# 7.3 Tuple รองรับ Structural Equality Comparison — เปรียบเทียบค่าแต่ละ Element แทน Reference

Tuple Syntax (C# 7+)

// Named Tuple Elements
var person1 = (Name: "John", Age: 30, City: "NYC");
var person2 = (Name: "John", Age: 30, City: "NYC");
var person3 = (Name: "Jane", Age: 25, City: "LA");

// Implicit Names (จาก Variable Names)
string name = "John"; int age = 30;
var person4 = (name, age); // (name: "John", age: 30)

Equality Operators (==, !=)

var t1 = (x: 1, y: 2);
var t2 = (x: 1, y: 2);
var t3 = (x: 1, y: 3);

Console.WriteLine(t1 == t2); // True  (Values Equal)
Console.WriteLine(t1 == t3); // False (Values Differ)
Console.WriteLine(t1 != t3); // True

Comparison Rules

  • Element-wise Comparison (Left-to-Right, Short-circuit)
  • Names ไม่สำคัญ — เปรียบเทียบ Position และ Value
  • Types ต้อง Compatible (Implicit Conversion Allowed)
  • Nested Tuples รองรับ

ตัวอย่างครบถ้วน

using System;

class Demo {
    static void Main() {
        // Basic Comparison
        var a = (x: 1, y: 2);
        var b = (p: 1, q: 2); // Different Names, Same Values
        Console.WriteLine($"a == b: {a == b}"); // True
        
        // Different Arity (Compile Error in 7.3+, Allowed in 7.0-7.2 with Warning)
        // var c = (1, 2, 3);
        // Console.WriteLine(a == c); // Error: Tuple Arity Mismatch
        
        // Nested Tuples
        var nested1 = (Id: 1, Coords: (X: 10, Y: 20));
        var nested2 = (Id: 1, Coords: (X: 10, Y: 20));
        Console.WriteLine($"Nested Equal: {nested1 == nested2}"); // True
        
        // With Different Types (Implicit Conversion)
        var t1 = (Value: 10, Ratio: 1.5);
        var t2 = (Value: 10L, Ratio: 1.5); // long vs int, double vs double
        Console.WriteLine($"Mixed Types: {t1 == t2}"); // True (Implicit Conversion)
        
        // Deconstruction for Comparison
        var (x1, y1) = a;
        var (x2, y2) = b;
        Console.WriteLine($"Deconstructed: x1={x1}, y1={y1}");
        
        Console.ReadKey();
    }
}

Comparison vs Equals vs Object.ReferenceEquals

MethodBehavior
t1 == t2Structural Value Equality (Element-wise)
t1.Equals(t2)Same as == (ValueTuple Overrides Equals)
Object.ReferenceEquals(t1, t2)Always False (ValueTuple is Struct, Stack Allocated)

Tuple as Dictionary Key

// Tuples เป็น Key ได้เพราะ Implement IEquatable & GetHashCode
var dict = new Dictionary<(int X, int Y), string> {
    [(0, 0)] = "Origin",
    [(1, 1)] = "Diagonal"
};
Console.WriteLine(dict[(1, 1)]); // "Diagonal"

⚠️ Version Note

  • C# 7.0-7.2: Tuple Comparison ต้องการ Name และ Arity ตรงกัน
  • C# 7.3+: เปรียบเทียบได้ถ้า Arity และ Types ตรงกัน (Names ไม่สำคัญ)
  • C# 7.0: System.ValueTuple NuGet Package Required (.NET Framework)
  • .NET Core 2.0+ / .NET Standard 2.0+: Built-in