原生 System.Tuple<T1...Tn> 為密封類別、無共同基類、無預設建構函式、無型別檢查方法。自訂 Tuple 基類可解決:
1. 統一基類 TupleBase 便於多型處理
2. HasType<T>() 判斷元組是否包含特定型別
3. 預設建構函式支援泛型程式設計 (如 new Tuple<T1,T2>())
4. 型別比較使用 typeof(T).Equals(obj.GetType()) 正確處理繼承關係
public abstract class TupleBase
{
protected TupleBase() { } // 允許衍生類別呼叫
// 判斷兩個型別是否完全相同 (非繼承關係)
protected bool ExactTypeMatch(T t, V v)
=> typeof(T).Equals(v?.GetType());
// 判斷元組是否包含指定型別的元素
public virtual bool HasType(V v) => false;
}
public class Tuple : TupleBase
{
public T1 Item1 { get; }
public Tuple(T1 item1) => Item1 = item1;
public Tuple() : this(default!) { } // 預設建構函式
public override bool HasType(V v)
=> base.HasType(v) || ExactTypeMatch(Item1, v);
}
public class Tuple : Tuple
{
public T2 Item2 { get; }
public Tuple(T1 item1, T2 item2) : base(item1) => Item2 = item2;
public Tuple() : this(default!, default!) { }
public override bool HasType(V v)
=> base.HasType(v) || ExactTypeMatch(Item2, v);
}
依此類推繼承鏈:Tuple<T1,T2,T3> : Tuple<T1,T2> ... 至 Tuple<T1..T8>,各加一個 ItemN、建構函式、HasType 覆寫。
class Base { }
class Derived : Base { }
Tuple t = new Tuple(new Derived());
Base b = new Derived();
t.HasType(b);
// 若用 typeof(T) == typeof(V) → typeof(Derived) == typeof(Base) → false
// 實際 v.GetType() 為 Derived → typeof(Derived).Equals(typeof(Derived)) → true ✅
這確保**執行時實際型別**匹配,而非編譯時靜態型別,符合「元組包含此具體型別元素」的語意。
var t1 = new Tuple(42, "hello");
var t2 = new Tuple(); // 預設建構函式
t1.HasType(42); // true
t1.HasType("world"); // true
t1.HasType(3.14); // false
// 多型處理
List tuples = new() { t1, t2 };
foreach (var t in tuples)
if (t.HasType(0)) Console.WriteLine("Contains int");
(int, string) 語法糖、結構體、高效能、支解構 var (id, name) = t;、**推薦首選**。record Person(int Id, string Name); 不可變、值相等、with 運算式。自訂 Tuple 基類展示了泛型繼承鏈、型別精確匹配、預設建構函式等進階技巧,但在現代專案中 **ValueTuple/Record 為優先選擇**。