1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5
6 namespace ClrVarCSharp.C13Interface
7 {
8 class Program
9 {
10 public static void Main(string[] args)
11 {
12 //Test1();
13 //Test2();
14 //Test3();
15 //Test4();
16 //Test5();
17 //Test6();
18 //A.Test7();
19 //B.Test7();
20 //B.Test8();
21 //Test9();
22 //C.Test10();
23 //D.Test10();
24 //E.Test10();
25 }
26
27 //接口:
28 //对一组方法签名进行了统一命名
29 //定义了在类型之间进行沟通的标准方式
30
31 //13.3 接口定义和实现
32 //定义接口(该定义已包含在FCL中)
33 //public interface IComparable<in T> // in 逆变量,即允许 object -> string
34 //{
35 // int CompareTo(T other);
36 //}
37
38 //实现接口
39 public sealed class Point : IComparable<Point>
40 {
41 private int m_x, m_y;
42 public Point(int x, int y)
43 {
44 m_x = x;
45 m_y = y;
46 }
47 //1). 必须标记为public
48 //2). 编译器总是将其标记为virtual,但派生类不能重写sealed类的接口方法
49 //3). 但派生类可以重写继承同一接口,并为接口方法提供自己的实现
50 //IL代码:.method public final hidebysig newslot virtual
51 public int CompareTo(Point other)
52 {
53 return Math.Sign(Math.Sqrt(m_x * m_x + m_y * m_y) -
54 Math.Sqrt(other.m_x * other.m_x + other.m_y * other.m_y));
55 }
56 }
57
58 //13.5 显示/隐式实现接口
59
60 internal sealed class SimpleType : IDisposable
61 {
62 //隐式实现接口
63 public void Dispose()
64 {
65 Console.WriteLine("Public Dispose");
66 }
67 //显示实现接口,不能定义访问修饰符,总是private
68 //IL代码:.method private final hidebysig newslot virtual
69 void IDisposable.Dispose()
70 {
71 Console.WriteLine("IDisposable Dispose");
72 }
73 }
74 static void Test1()
75 {
76 SimpleType st = new SimpleType();
77 st.Dispose();
78 IDisposable d = st;
79 d.Dispose(); //若为显示实现接口,结果为 Public Dispose
80 }
81
82 //13.6 泛型接口
83
84 //非泛型接口
85 static void Test2()
86 {
87 int x = 1, y = 2;
88 IComparable c = x;
89 c.CompareTo(y); //发生装箱
90 //c.CompareTo("2"); //运行时异常
91 }
92 //泛型接口
93 static void Test3()
94 {
95 int x = 1, y = 2;
96 IComparable<int> c = x;
97 c.CompareTo(y); //不发生装箱
98 //c.CompareTo("2"); //编译错误
99 }
100
101 //实现同一个接口的多个泛型版本
102 public sealed class Number : IComparable<int>, IComparable<string>
103 {
104 private int m_val = 5;
105 public int CompareTo(int other)
106 {
107 return m_val.CompareTo(other);
108 }
109 public int CompareTo(string other)
110 {
111 return m_val.CompareTo(other);
112 }
113 }
114
115 //13.7 约束方法的参数类型为实现指定接口的类型
116 static void Test4()
117 {
118 int x = 5;
119 Guid g = new Guid();
120 M(x); //int 同时实现了 IComparable 和 IConvertible
121 //M(g); //编译错误,guid没有实现IConvertible
122 }
123 static int M<T>(T t) where T : IComparable, IConvertible
124 {
125 return 0;
126 }
127
128 //13.8 一个类实现不同接口的重签名方法
129 //1). 定义接口
130 public interface IWindow
131 {
132 object GetMenu();
133 }
134 public interface IRestaurant
135 {
136 object GetMenu();
137 }
138 //2). 隐式实现接口
139 public sealed class MarioPizzeria : IWindow, IRestaurant
140 {
141 public object GetMenu() //书中“必须使用显式接口方法实现”说法是错误的,可同时实现两个接口!
142 {
143 Console.WriteLine("0");
144 return "0";
145 }
146 }
147 static void Test5()
148 {
149 MarioPizzeria mp = new MarioPizzeria();
150 mp.GetMenu();
151 IWindow window = mp;
152 window.GetMenu();
153 IRestaurant restaurant = mp;
154 restaurant.GetMenu();
155 }
156 //3). 显式实现接口
157 public sealed class MarioPizzeria2 : IWindow, IRestaurant
158 {
159 public object GetMenu()
160 {
161 Console.WriteLine("0");
162 return "0";
163 }
164 object IWindow.GetMenu()
165 {
166 Console.WriteLine("1");
167 return "1";
168 }
169 object IRestaurant.GetMenu()
170 {
171 Console.WriteLine("2");
172 return "2";
173 }
174 }
175 static void Test6()
176 {
177 MarioPizzeria2 mp = new MarioPizzeria2();
178 mp.GetMenu(); //GetMenu()只是该类的一个普通方法,若未实现则出现编译错误
179 IWindow window = mp;
180 window.GetMenu();
181 IRestaurant restaurant = mp;
182 restaurant.GetMenu();
183 }
184
185 //13.9 用显式接口方法实现来增强编译时类型安全
186 //原理是显式实现接口只能“显式”调用
187 //1). 隐式实现接口可能发生装箱和运行时异常
188 class A
189 {
190 public interface IComparable1
191 {
192 int CompareTo(object other);
193 }
194 struct SomeValueType : IComparable1
195 {
196 private int m_x;
197 public SomeValueType(int x) { m_x = x; }
198 public int CompareTo(object other)
199 {
200 return m_x - ((SomeValueType)other).m_x;
201 }
202 }
203 public static void Test7()
204 {
205 SomeValueType v = new SomeValueType(0);
206 object o = new object();
207 int n = v.CompareTo(v); //装箱 SomeValueType -> Object
208 //n = v.CompareTo(o); //运行时异常
209 }
210 }
211 //2). 显式实现接口不发生装箱和编译时类型安全
212 class B
213 {
214 public interface IComparable1
215 {
216 int CompareTo(object other);
217 }
218 struct SomeValueType : IComparable1
219 {
220 private int m_x;
221 public SomeValueType(int x) { m_x = x; }
222 public int CompareTo(SomeValueType other)
223 {
224 return m_x - other.m_x;
225 }
226 int IComparable1.CompareTo(object other)
227 {
228 return CompareTo((SomeValueType)other);
229 }
230 }
231 public static void Test7()
232 {
233 SomeValueType v = new SomeValueType(0);
234 object o = new object();
235 int n = v.CompareTo(v); //不发生装箱
236 //n = v.CompareTo(o); //编译错误,因为显式接口只能显式调用
237 }
238 //3). 重新发生装箱和运行时异常
239 public static void Test8()
240 {
241 SomeValueType v = new SomeValueType(0);
242 IComparable1 c = v; //装箱 struct -> 引用类型
243 object o = new object();
244 int n = c.CompareTo(v); //装箱 引用类型 -> object
245 //n = c.CompareTo(o); //编译异常
246 }
247 }
248
249 //13.10 显式实现接口缺陷
250 public static void Test9()
251 {
252 int x = 5;
253 //1). In32显式实现了IConvertible接口,但此处没有相关帮助
254 //Single s = x.ToSingle(null);
255 //2). Int32值型转换为IConvertible发生装箱
256 Single s = ((IConvertible)x).ToSingle(null);
257 }
258 class C
259 {
260 public static void Test10()
261 {
262 var d1 = new Derived();
263 var d2 = new Derived();
264 d1.CompareTo(d2);
265 }
266 internal class Base : IComparable
267 {
268 int IComparable.CompareTo(object obj)
269 {
270 Console.WriteLine("Base's CompareTo");
271 return 0;
272 }
273 }
274 internal sealed class Derived : Base, IComparable
275 {
276 public int CompareTo(object o)
277 {
278 Console.WriteLine("Derived's CompareTo");
279
280 //没有CompareTo方法
281 //base.CompareTo(o);
282
283 //IComparable c = this; //this实现了IComparable接口
284 //c.CompareTo(o); //所以此处在调用自身导致无穷递归
285
286 return 0;
287 }
288 }
289 }
290 class D
291 {
292 public static void Test10()
293 {
294 var d1 = new Derived();
295 var d2 = new Derived();
296 d1.CompareTo(d2);
297 }
298 internal class Base : IComparable
299 {
300 int IComparable.CompareTo(object obj)
301 {
302 Console.WriteLine("Base's CompareTo");
303 return 0;
304 }
305 }
306 internal sealed class Derived : Base/*, IComparable*/
307 {
308 public int CompareTo(object o)
309 {
310 Console.WriteLine("Derived's CompareTo");
311
312 //没有CompareTo方法
313 //base.CompareTo(o);
314
315 //调用显式接口方法
316 IComparable c = this;
317 c.CompareTo(o);
318
319 return 0;
320 }
321 }
322 }
323 class E
324 {
325 public static void Test10()
326 {
327 var d1 = new Derived();
328 var d2 = new Derived();
329 d1.CompareTo(d2);
330 }
331 internal class Base : IComparable
332 {
333 int IComparable.CompareTo(object obj)
334 {
335 Console.WriteLine("Base's CompareTo");
336 return 0;
337 }
338 public virtual int CompareTo(object o)
339 {
340 Console.WriteLine("Base's virtual CompareTo");
341 return 0;
342 }
343 }
344 internal sealed class Derived : Base, IComparable
345 {
346 public override int CompareTo(object o)
347 {
348 Console.WriteLine("Derived's CompareTo");
349 //此处调用的是虚方法,而非接口的显式实现方法
350 return base.CompareTo(o);
351 }
352 }
353 }
354
355 }
356 }