C#学习(三)之类的浅析

这一周章老师讲了C#有关类的方面的知识,由于与C++,JAVA等语言类似之处不少,所以学起来不是特别吃力。但C#中类也有着不少新颖而有趣的用法与规则,本次学习记录就主要以探究这些内容为主。

 

1.从C#4.0开始支持optional arguments

optional arguments,即可选参数。(翻译如有错误,请指正!)

用下列代码可快速简简洁说明什么是optional arguments:

 1 class myClass
 2 {
 3       public void TestParam(int aaa, float bbb = 5.5f)
 4       {
 5  6       }
 7 }
 8  9 myClass myCs= new myClass();
10 myCs. TestParam(aaa);
11 myCs. TestParam(aaa, 6.8);

这是可以编译通过的。也就是说,传入函数的参数是可变的,有一些预先定义好的参数可定义不用传进去,函数将自动采用它们的默认值。

下面通过一个简单的实例看一下效果:

 1 namespace Class3Test
 2 {
 3     class Program
 4     {
 5         static void Main(string[] args)
 6         {
 7             Email email = new Email();
 8        //试验可变函数
 9             email.SendMail("bob@foo.com", "Hello World");
10             email.SendMail("bob@foo.com", "Hello World", isBodyHtml: true);//告诉编译器跳到了哪一个参数
11             email.SendMail("bob@foo.com", "Hello World", true, true);
12 
13             Console.ReadKey();
14         }
15 
16         class Email
17         {
18             public void SendMail(string toAddress, string bodyText, 
19                         bool ccAdministrator = true, bool  isBodyHtml = false)
20             {
21                 Console.WriteLine("{0}, {1}, {2}, {3}", toAddress, bodyText, ccAdministrator, isBodyHtml);
22             }
23         }
24         
25     }
26 }

运行结果如下:

代码浅显易懂,这里就不在解释。不过需要牢记于心的是中间跳过可选参数的时候要使用 参数名:值 这样的形式告诉编译器该语句跳到了哪一个参数,毕竟编译器没有这么智能。

 

2.ref/out参数

ref参数就类似于C++里的&,可使“方法”返回多个返回值,在函数中对传入的参数值的操作是被保存的。如下列代码:

 1 public void TryRef( ref int h, ref int m, ref int s )
 2         {
 3             h = 12;
 4             m = 34;
 5             s = 56;
 6         }
 7 ...
 8 int h1 = 0, m1 = 0, s1 = 0;
 9 ...TryRef(ref h1, ref m1, ref s1);
10  Console.WriteLine("{0}, {1}, {2}", h1, m1, s1);
11 ...

运行结果如图:

但需要注意的一点是定义处“形参”和调用处“实参”都要用 ref 来修饰,缺少一处都无法通过编译。

out参数的用法与ref相似,将上面程序中的ref换成out运行结果是一样的。不过有一点不同的是使用out时,传入的参数是可以只声明而不初始化赋值的。如下列代码所示:

 1 public void TryOut(  int h, ref int m, out int s )
 2         {
 3             h = 12;
 4             m = 34;
 5             s = 56;
 6         }
 7 int h1 = 0, m1 = 0, s1;//s1未赋初值
 8  ...TryOut(  h1, ref m1, out s1);
 9 Console.WriteLine("{0}, {1}, {2}", h1, m1, s1);
10 ...     

运行结果如下:

需要注意的是类似于ref定义处“形参”和调用处“实参”都要用 out来修饰。

 

3.Sealed修饰符

当对一个类应用 sealed 修饰符时,此修饰符会阻止其他类从该类继承。 如在下面的代码:

1 class A {}    
2 sealed class B : A {}

B 从类 A 继承,但是任何类都不能从类 B 继承。

 

另外还可以在重写基类中的虚方法或虚属性的方法或属性上使用 sealed 修饰符。 这能够允许类从该基类继承,并防止它们重写特定的虚方法或虚属性。如下列代码:

 1  class X
 2     {
 3         protected virtual void F() { Console.WriteLine("X.F"); }
 4         protected virtual void F2() { Console.WriteLine("X.F2"); }
 5     }
 6     class Y : X
 7     {
 8         sealed protected override void F() { Console.WriteLine("Y.F"); }
 9         protected override void F2() { Console.WriteLine("Y.F2"); }
10     }
11     class Z : Y
12     {
13         // 错误!尝试编译会遇到错误CS0239.
14         protected override void F() { Console.WriteLine("C.F"); }
15 
16         // 重写F2是允许的
17         protected override void F2() { Console.WriteLine("Z.F2"); }
18     }

在上面的示例中,Z 从 Y 继承,但 Z 无法重写在 X 中声明并在 Y 中密封的虚函数 F。

 

 

4.override 修饰符

要扩展或修改继承的方法、属性、索引器或事件的抽象实现或虚实现,必须使用 override 修饰符。如下列代码:

 1 abstract class ShapesClass
 2 {
 3     abstract public int Area();
 4 }
 5 class Square : ShapesClass
 6 {
 7     int side = 0;
 8 
 9     public Square(int n)
10     {
11         side = n;
12     }
13     // 此处必须重写Area函数,否则通不过编译
14     public override int Area()
15     {
16         return side * side;
17     }
18 
19     static void Main() 
20     {
21         Square sq = new Square(12);
22         Console.WriteLine("Area of the square = {0}", sq.Area());
23     }
24 
25 }

在此示例中,Square 类必须提供 Area 的重写实现,因为 Area 继承自抽象的 ShapesClass。

 

override 方法提供从基类继承的成员的新实现。 override 声明重写的方法称为重写基方法重写的基方法必须与 override 方法具有相同的签名

 

本次学习记录到此为止。有机会以后也会补充一些内容。

 

望各位老师前辈大牛不吝赐教!

http://f.hiphotos.baidu.com/zhidao/pic/item/42a98226cffc1e17078acd7a4a90f603738de940.jpg

posted @ 2015-03-27 16:56  马列神教  阅读(344)  评论(0编辑  收藏  举报