(1)方法C#中,一个类中可以定义多个方法,但相同签名的方法只能有一个。方法的签名包括: 方法的名称,形式参数的类型、个数、修饰符。如果方法是泛型方法,其签名还包括类型参数的个数。修饰符是指ref和out。参见:参数
(2)事件
事件相当于一个字段,这个字段是一个委托类型。但在类体的外面,只能在事件上执行+=或-=操作。也可以将事件定义成这样:
1 public class Button
2 {
3 private EventHandler handler;
4 public event EventHandler Click 
5 {
6   add { handler += value; }
7   remove { handler -= value; }
8 }
9 }

add和remove访问器类似属性里面的get和set。
(3)索引器
提供类似数组模式的成员访问。
 1 public class Stack
 2 {
 3 private Node GetNode(int index) {
 4 Node temp = first;
 5 while (true) {
 6 if (temp == null || index < 0)
 7 throw new Exception("Index out of range.");
 8 if (index == 0)
 9 return temp;
10 temp = temp.Next;
11 index--;
12 }
13 }
14 public object this[int index] {
15 get {
16 return GetNode(index).Value;
17 }
18 set {
19 GetNode(index).Value = value;
20 }
21 }
22 
23 }
24 class Test
25 {
26 static void Main() {
27 Stack s = new Stack();
28 s.Push(1);
29 s.Push(2);
30 s.Push(3);
31 s[0= 33// Changes the top item from 3 to 33
32 s[1= 22// Changes the middle item from 2 to 22
33 s[2= 11// Changes the bottom item from 1 to 11
34 }
35 }

(4)类
方法、属性、索引器都可以是virtual的,意味着在子类中可以得到重写。
(5)静态类
像这样:
1 public static class Months
2 {
3 static Months() { … }
4 private static readonly string[] monthName = { … }
5 public static string GetMonthName(int mm) { … }
6 private static readonly int[,] daysInMonth = { … }
7 public static int GetDaysInMonth(bool isLeapYear, int mm) { … }
8 public static bool IsLeapYear(int yy) { … }
9 }

静态类只能这样用,typeof(Months)或者Months.IsLeapYear(200),不能被继承、实例化或者作为泛型类型参数。
(6)结构
结构和类相似,可以实现接口,却不能继承类或被继承。
举例:
 1 class Point
 2 {
 3 public int x, y;
 4 public Point(int x, int y) {
 5 this.x = x;
 6 this.y = y;
 7 }
 8 }
 9 class Test
10 {
11 static void Main() {
12 Point[] points = new Point[100];
13 for (int i = 0; i < 100; i++)
14 points[i] = new Point(i, i*i);
15 }
16 }

问Main方法中共有几个对象?一个points数组,和100个Point,共101个。
 1 struct Point
 2 {
 3 public int x, y;
 4 public Point(int x, int y) {
 5 this.x = x;
 6 this.y = y;
 7 }
 8 }
 9 class Test
10 {
11 static void Main() {
12 Point[] points = new Point[100];
13 for (int i = 0; i < 100; i++)
14 points[i] = new Point(i, i*i);
15 }
16 }

如果是这样呢?只有一个对象,就是points数组。
(7)接口
接口可以包含的成员是:
方法,属性,索引器,事件。接口中的成员默认都是public的,不能有任何访问修饰符。
1 interface IExample
2 {
3 string this[int index] { getset; }
4 event EventHandler E;
5 void F(int value);
6 string P { getset; }
7 }
8 public delegate void EventHandler(object sender, EventArgs e);

实现时,必须实现为public:
 1 interface IControl
 2 {
 3 void Paint();
 4 }
 5 interface IDataBound
 6 {
 7 void Bind(Binder b);
 8 }
 9 public class EditBox: Control, IControl, IDataBound
10 {
11 public void Paint() {…}
12 public void Bind(Binder b) {…}
13 }

如果要实现为private的,那就"显示实现":
1 public class EditBox: IControl, IDataBound
2 {
3 void IControl.Paint() {…}
4 void IDataBound.Bind(Binder b) {…}
5 }

这样用:
1 class Test
2 {
3 static void Main() {
4 EditBox editbox = new EditBox();
5 editbox.Paint(); // error: no such method
6 IControl control = editbox;
7 control.Paint(); // calls EditBox’s Paint implementation
8 }
9 }

实现时默认为private,不能有任何修饰符。
(8)代理
代理相当于C语言中的函数指针。c#中的代理值面向对象的(和class一样是一种类型),同时是类型安全的。
一个代理可以封装一个或多个方法,这些方法被成为“调用实体”。执行这个代理时,这些方法都将被调用。
方法可以是实例方法,也可以是静态方法。包含方法的类可以是任意的(甚至可以是匿名方法,即没有类的存在!),只要方法的定义和代理的定义相一致。
定义和使用:
 1 delegate void SimpleDelegate();
 2 class Test
 3 {
 4 static void F() {
 5 System.Console.WriteLine("Test.F");
 6 }
 7 static void Main() {
 8 SimpleDelegate d = new SimpleDelegate(F);
 9 d();
10 }
11 }

像方法一样使用代理。代理的返回值是,最后一个方法的返回值:
 
 1 delegate string GetAString();
 2   [TestFixture]
 3   public class DelegateTest
 4   {
 5   public string get1()
 6   {
 7   return "get1";
 8   }
 9   public string get2()
10   {
11   return "get2";
12   }
13   [Test]
14   public void TestDelegate()
15   {
16   GetAString dele = new GetAString(get1);
17   dele += get2;
18   Assert.That(dele(), Is.EqualTo(get2()));
19   }
20   }

上述代码使用了NUnit。简单介绍:[TestFixture]是一个c#中的特性(Attribute),这样Nunit就认为DelegateTest类是包含测试方法的类。 同样,[Test]标记了方法TestDelegate,意味着这个方法是一个测试方法。 测试方法返回值是void,没有参数,必须是public的,保证Nunit能调用到。Assert.That(dele(), Is.EqualTo(get2()));断言dele()的结果是get2()。断言失败则测试不通过。 (9)枚举 例子:  1 enum Color  2 {  3 Red,  4 Blue,  5 Green  6 }  7 class Shape  8 {  9 public void Fill(Color color) { 10 switch(color) { 11 case Color.Red: 12 … 13 break; 14 case Color.Blue: 15 … 16 break; 17 case Color.Green: 18 … 19 break; 20 default: 21 break; 22 } 23 } 24 } 枚举相当于符号常量的集合,这些符号常量是整型的,默认实现是int:  1  enum Fruit1  2   {  3   Apple, Orange  4   }  5   enum Fruit2:byte  6   {  7   Apple,Orange  8   }  9     10   [TestFixture] 11   public class EnumTest 12   { 13   [Test] 14   public void TestEnum() 15   { 16   Fruit1 f = Fruit1.Apple; 17   Assert.That(Enum.GetUnderlyingType(typeof(Fruit1)),Is.EqualTo(typeof(int))); 18   Assert.That(Enum.GetUnderlyingType(typeof(Fruit2)), Is.EqualTo(typeof(byte))); 19   Assert.That(Enum.GetValues(typeof(Fruit1)), Is.EqualTo(new Fruit1[] { Fruit1.Apple,Fruit1.Orange }).AsCollection); 20  21   } 22   } 注意Fruit2用byte作为枚举常量的类型。
posted on 2009-03-27 20:35  apple123  阅读(538)  评论(0编辑  收藏  举报