More Effective C# Item10 :在实现泛型接口的同时也实现传统接口

    虽然.NET2.0中引入了泛型,但是对于程序员来说,世界远远没有想象的那么美好,我们还要必须要保证新的系统和旧的系统兼容,即我们在使用了泛型带来的好处的同时,还要兼顾非泛型。因此,如果我们在框架中可以支持泛型接口的同时,也对传统的非泛型接口提供支持,那么会非常有用的。

    我们来看以下的代码。

代码
1 public class Name : IComparable<Name>, IEquatable<Name>
2 {
3  private string m_strFirstName;
4  public string FirstName
5 {
6 get { return m_strFirstName; }
7 set { m_strFirstName = value; }
8 }
9
10  private string m_strLastName;
11  public string LastName
12 {
13 get { return m_strLastName; }
14 set { m_strLastName = value; }
15 }
16
17 public int CompareTo(Name other)
18 {
19 if (other == null)
20 {
21 return 1;
22 }
23 int nResult = Comparer<string>.Default.Compare(this.FirstName, other.FirstName);
24 if (nResult != 0)
25 {
26 return nResult;
27 }
28 return Comparer<string>.Default.Compare(this.LastName, other.LastName);
29 }
30
31 public bool Equals(Name other)
32 {
33 if (object.ReferenceEquals(this, null))
34 {
35 return false;
36 }
37 return this.FirstName == other.FirstName && this.LastName == other.LastName;
38 }
39 }

    上述代码只给出了泛型接口,如果你在开发的系统是一个全新的系统,那么这样做是没有关系的,但是,很多情况下,我们都不得不和其他系统进行关联,而其他系统中定义的类型,无法保证类型能够匹配上。

    我们对代码进行了改进,如下。

代码
1 public class Name : IComparable<Name>, IEquatable<Name>, IComparable
2 {
3 private string m_strFirstName;
4 public string FirstName
5 {
6 get { return m_strFirstName; }
7 set { m_strFirstName = value; }
8 }
9
10 private string m_strLastName;
11 public string LastName
12 {
13 get { return m_strLastName; }
14 set { m_strLastName = value; }
15 }
16
17 public int CompareTo(Name other)
18 {
19 if (other == null)
20 {
21 return 1;
22 }
23 int nResult = Comparer<string>.Default.Compare(this.FirstName, other.FirstName);
24 if (nResult != 0)
25 {
26 return nResult;
27 }
28 return Comparer<string>.Default.Compare(this.LastName, other.LastName);
29 }
30
31 public bool Equals(Name other)
32 {
33 if (object.ReferenceEquals(this, null))
34 {
35 return false;
36 }
37 return this.FirstName == other.FirstName && this.LastName == other.LastName;
38 }
39
40 public int CompareTo(object obj)
41 {
42 if (obj.GetType != typeof(Name))
43 {
44 throw new ArgumentException("The type of obj is InValid !");
45 }
46 return CompareTo(obj as Name);
47 }
48
49 public override bool Equals(object obj)
50 {
51 if (obj.GetType() == typeof(Name))
52 {
53 return this.Equals(obj as Name);
54 }
55 else
56 {
57 return false;
58 }
59 }
60
61 public override int GetHashCode()
62 {
63 int hashCode = 0;
64 if (FirstName != null)
65 {
66 hashCode ^= FirstName.GetHashCode();
67 }
68 if (LastName != null)
69 {
70 hashCode ^= LastName.GetHashCode();
71 }
72 return hashCode;
73 }
74
75 public static bool operator ==(Name left, Name right)
76 {
77 if (left == null)
78 {
79 return right == null;
80 }
81 return left.Equals(right);
82 }
83
84 public static bool operator !=(Name left, Name right)
85 {
86 if (left == null)
87 {
88 return right != null;
89 }
90 return !left.Equals(right);
91 }
92
93 public static bool operator <(Name left, Name right)
94 {
95 if (left == null)
96 {
97 return right != null;
98 }
99 return left.CompareTo(right) < 0;
100 }
101
102 public static bool operator >(Name left, Name right)
103 {
104 if (left == null)
105 {
106 return right != null;
107 }
108 return left.CompareTo(right) < 0;
109 }
110 }

    我们在改进的过程中,实现了IComparable接口,重写了Equals方法,同时声明了几个操作符方法,这样我们就能同时以泛型和非泛型两种方式调用。

    大多数情况下,添加对传荣接口的支持只不过是为类添加带有合适签名的方法而已,这样编译器就可以选择合适的重载形式了。

    .NET2.0提供了很多新的接口和类型,这些接口和类型在很大程度上提高了应用程序和类库中的类型安全性。不过在你使用它们的同时,也不要忘记并不是世界上的所有人也都在使用它们,虽然可以通过显示接口实现来避免可能出现的误用,但也应该尽力支持那些有着同样功能的传统接口。

posted @ 2010-06-15 12:34  李潘  阅读(554)  评论(0编辑  收藏  举报