2010-08-16 58 views
2

我已經實現了一些元組類的版本,並且真的很想從中學到更多東西。元組實現

請你指點一下我在這裏與我的實現失蹤的點。

class My_tuple<T1, T2> : EqualityComparer<My_tuple<T1, T2>> 
    { 

#region Virables 
     public T1 First { get; private set; } 

     public T2 Second { get; private set; } 
#endregion 

#region Constractors 

     public My_tuple(T1 first, T2 second) 
     { 
      First = first; 
      Second = second; 
     } 

#endregion 

#region Equals && GetHashCode 

     public override bool Equals(My_tuple<T1, T2> L, My_tuple<T1, T2> R) 
     { 
      return EqualityComparer<T1>.Default.Equals(L.First, R.First) && EqualityComparer<T2>.Default.Equals(L.Second , R.Second); 
     } 

     public override bool Equals(object obj) 
     { 
      return obj is My_tuple<T1, T2> && Equals(this, (My_tuple<T1, T2>)obj); 
     } 

     public override int GetHashCode(My_tuple<T1, T2> M) 
     { 
      return M.First.GetHashCode()^M.Second.GetHashCode(); 
     } 

#endregion 

#region operators 

     public static bool operator ==(My_tuple<T1, T2> left, My_tuple<T1, T2> right) 
     { 
      return left.Equals(right); 
     } 

     public static bool operator !=(My_tuple<T1, T2> left, My_tuple<T1, T2> right) 
     { 
      return !(left == right); 
     } 

     public static My_tuple<T1, T2> Create<T1, T2>(T1 first, T2 second) 
     { 
      return new My_tuple<T1, T2>(first, second); 
     } 

#endregion 

    } 

謝謝。

+1

[System.Tuple class](http://msdn.microsoft.com/en-us/library/system.tuple.aspx)。 – 2010-08-16 10:18:15

+1

[構建System.Tuple類的設計決策文章](http://msdn.microsoft.com/en-us/magazine/dd942829.aspx)。 – 2010-08-16 10:19:56

回答

13

有幾件事情:

  • 類型名稱不符合.NET約定
  • 各種參數名稱不符合.NET約定
  • 你不應該從EqualityComparer<T>派生 - 你應該實施IEqualityComparer<T>
  • 您的GetHashCode()的實施是不理想的;這意味着對於任何具有相同類型左右的元組(例如My_tuple<int, int>),在值相等的情況下,您將獲得相同的散列碼0. ie(1,1)具有與(2, 2)等。我更喜歡「加法和乘法」實現 - 在這種情況下,您可以返回(說)17 * hash1 + 31 * hash2。仍然會有碰撞,但希望沒有那麼多。
  • 你的實施Equals(L, R)假定LR非空
  • Create方法是通用的,試圖重新聲明T1和T2類型參數。我很驚訝,即使編譯,雖然這是我以前沒有嘗試過的東西。考慮在非通用類(例如僅僅My_tuple)中創建靜態通用方法以允許類型推斷工作,例如, My_tuple.Create(1, "hello")創建一個My_tuple<int, string>
  • 我會親自使用私人只讀字段和簡單的屬性獲得者,而不是自動屬性。從聲明中可以看出,你永遠不會改變屬性的值 - 你必須閱讀所有的代碼。
2

除了Jon提到的點外,看起來還不錯,記住你總是可以使用Reflector來查看真正的Tuple實現,以獲得更多的洞察。

你實現了所有的運營商和結構上的平等,很好。我注意到,你的工廠方法:

public static My_tuple<T1, T2> Create<T1, T2>(T1 first, T2 second) 
    { 
     return new My_tuple<T1, T2>(first, second); 
    } 

應放在一個單獨的,靜態類(例如數組),讓消費者的元組可以利用C#編譯器類型推斷沒有明確指定泛型類型參數來創建的元組。