注册 登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

农村人

 
 
 

日志

 
 

引用 你必须知道的C#的25个基础概念(二)  

2010-09-13 22:27:25|  分类: 电脑生活 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

 

引用

━洣阳光你必须知道的C#的25个基础概念(二)

 

对于c#的学习,可能很多人也许都会说我很懂,但是你知道C#里面的一些需要掌握的基本概念有那些吗? 

你们先自己复习一下,看看下面的C#问题都能回答上来么?

1.静态变量和非静态变量的区别?

2.const 和 static readonly 区别?

3.extern 是什么意思?

4.abstract 是什么意思?

5.internal 修饰符起什么作用?

6.sealed 修饰符是干什么的?

7.override 和 overload 的区别?

8.什么是索引指示器?

9.new 修饰符是起什么作用?

10.this 关键字的含义?

11.可以使用抽象函数重写基类中的虚函数吗?

12.密封类可以有虚函数吗?

13.如果基类中的虚属性只有一个属性访问器,那么继承类重写该属性后可以有几个属性访问器?如果基类中有 get 和 set 两个呢?

14.abstract 可以和 virtual 一起使用吗?可以和 override 一起使用吗?

15.接口可以包含哪些成员?

16.类和结构的区别?

17.接口的多继承会带来哪些问题?

18.抽象类和接口的区别?

19.别名指示符是什么?

20.如何释放非托管资源?

21.P/Invoke是什么?

22.StringBuilder 和 String 的区别?

23.explicit 和 implicit 的含义?

24.params 有什么用?

25.什么是反射?

以下是我做的一份参考答案(C# 语言范畴之内),如果有不准确、不全面的,欢迎各位朋友指正!

6.sealed 修饰符是干什么的?

答:

sealed 修饰符表示密封

用于类时,表示该类不能再被继承,不能和 abstract 同时使用,因为这两个修饰符在含义上互相排斥

用于方法和属性时,表示该方法或属性不能再被继承,必须和 override 关键字一起使用,因为使用 sealed 修饰符的方法或属性肯定是基类中相应的虚成员

通常用于实现第三方类库时不想被客户端继承,或用于没有必要再继承的类以防止滥用继承造成层次结构体系混乱

恰当的利用 sealed 修饰符也可以提高一定的运行效率,因为不用考虑继承类会重写该成员

示例:

CODE:

using System;

using System.Collections.Generic;

using System.Text;

namespace Example06

{

    class Program

    {

        class A

        {

            public virtual void F()

            {

                Console.WriteLine("A.F");

            }

            public virtual void G()

            {

                Console.WriteLine("A.G");

            }

        }

        class B : A

        {

            public sealed override void F()

            {

                Console.WriteLine("B.F");

            }

            public override void G()

            {

                Console.WriteLine("B.G");

            }

        }

        class C : B

        {

            public override void G()

            {

                Console.WriteLine("C.G");

            }

        }

        static void Main(string[] args)

        {

            new A().F();

            new A().G();

            new B().F();

            new B().G();

            new C().F();

            new C().G();

            Console.ReadLine();

        }

    }

}

结果:

类 B 在继承类 A 时可以重写两个虚函数,如图所示:

由于类 B 中对 F 方法进行了密封, 类 C 在继承类 B 时只能重写一个函数,如图所示:

控制台输出结果,类 C 的方法 F 只能是输出 类B 中对该方法的实现:

A.F

A.G

B.F

B.G

B.F

C.G

7.override 和 overload 的区别?

答:

override 表示重写,用于继承类对基类中虚成员的实现

overload 表示重载,用于同一个类中同名方法不同参数(包括类型不同或个数不同)的实现

示例:

CODE:

using System;

using System.Collections.Generic;

using System.Text;

namespace Example07

{

    class Program

    {

        class BaseClass

        {

            public virtual void F()

            {

                Console.WriteLine("BaseClass.F");

            }

        }

        class DeriveClass : BaseClass

        {

            public override void F()

            {

                base.F();

                Console.WriteLine("DeriveClass.F");

            }

            public void Add(int Left, int Right)

            {

                Console.WriteLine("Add for Int: {0}", Left + Right);

            }

            public void Add(double Left, double Right)

            {

                Console.WriteLine("Add for int: {0}", Left + Right);

            }

        }

        static void Main(string[] args)

        {

            DeriveClass tmpObj = new DeriveClass();

            tmpObj.F();

            tmpObj.Add(1, 2);

            tmpObj.Add(1.1, 2.2);

            Console.ReadLine();

        }

    }

}

结果:

BaseClass.F

DeriveClass.F

Add for Int: 3

Add for int: 3.3

8.什么是索引指示器?

答:

实现索引指示器(indexer)的类可以象数组那样使用其实例后的对象,但与数组不同的是索引指示器的参数类型不仅限于int

简单来说,其本质就是一个含参数属性

示例:

CODE:

using System;

using System.Collections.Generic;

using System.Text;

namespace Example08

{

    public class Point

    {

        private double x, y;

        public Point(double X, double Y)

        {

            x = X;

            y = Y;

        }

        //重写ToString方法方便输出

        public override string ToString()

        {

            return String.Format("X: {0} , Y: {1}", x, y);

        }

    }

    public class Points

    {

        Point[] points;

        public Points(Point[] Points)

        {

            points = Points;

        }

        public int PointNumber

        {

            get

            {

                return points.Length;

            }

        }   

        //实现索引访问器

        public Point this[int Index]

        {

            get

            {

                return points[Index];

            }

        }

    }

   

//感谢watson hua(http://huazhihao.cnblogs.com/)的指点

    //索引指示器的实质是含参属性,参数并不只限于int

    class WeatherOfWeek

    {

        public string this[int Index]

        {

            get

            {

                //注意case段使用return直接返回所以不需要break

                switch (Index)

                {

                    case 0:

                        {

                            return "Today is cloudy!";

                        }

                    case 5:

                        {

                            return "Today is thundershower!";

                        }

                    default:

                        {

                            return "Today is fine!";

                        }

                }

            }

        }

        public string this[string Day]

        {

            get

            {

                string TodayWeather = null;

                //switch的标准写法

                switch (Day)

                {

                    case "Sunday":

                        {

                            TodayWeather = "Today is cloudy!";

                            break;

                        }

                    case "Friday":

                        {

                            TodayWeather = "Today is thundershower!";

                            break;

                        }

                    default:

                        {

                            TodayWeather = "Today is fine!";

                            break;

                        }

                }

                return TodayWeather;

            }

        }

    }

    class Program

    {

        static void Main(string[] args)

        {

            Point[] tmpPoints = new Point[10];

            for (int i = 0; i < tmpPoints.Length; i++)

            {

                tmpPoints[i] = new Point(i, Math.Sin(i));

            }

            Points tmpObj = new Points(tmpPoints);

            for (int i = 0; i < tmpObj.PointNumber; i++)

            {

                Console.WriteLine(tmpObj[i]);

            }

            string[] Week = new string[] { &amp;quot;Sunday&amp;quot;, &amp;quot;Monday&amp;quot;, &amp;quot;Tuesday&amp;quot;, &amp;quot;Wednesday&amp;quot;, &amp;quot;Thursday&amp;quot;, &amp;quot;Friday&amp;quot;, &amp;quot;Staurday&amp;quot;};

            WeatherOfWeek tmpWeatherOfWeek = new WeatherOfWeek();

            for (int i = 0; i < 6; i++)

            {

                Console.WriteLine(tmpWeatherOfWeek[i]);

            }

            foreach (string tmpDay in Week)

            {

                Console.WriteLine(tmpWeatherOfWeek[tmpDay]);

            }

            Console.ReadLine();

        }

    }

}

结果:

X: 0 , Y: 0

X: 1 , Y: 0.841470984807897

X: 2 , Y: 0.909297426825682

X: 3 , Y: 0.141120008059867

X: 4 , Y: -0.756802495307928

X: 5 , Y: -0.958924274663138

X: 6 , Y: -0.279415498198926

X: 7 , Y: 0.656986598718789

X: 8 , Y: 0.989358246623382

X: 9 , Y: 0.412118485241757

Today is cloudy!

Today is fine!

Today is fine!

Today is fine!

Today is fine!

Today is thundershower!

Today is cloudy!

Today is fine!

Today is fine!

Today is fine!

Today is fine!

Today is thundershower!

Today is fine!

9.new 修饰符是起什么作用?

答:

new 修饰符与 new 操作符是两个概念

new 修饰符用于声明类或类的成员,表示隐藏了基类中同名的成员。而new 操作符用于实例化一个类型

new 修饰符只能用于继承类,一般用于弥补基类设计的不足

new 修饰符和 override 修饰符不可同时用在一个成员上,因为这两个修饰符在含义上互相排斥

示例:

CODE:

using System;

using System.Collections.Generic;

using System.Text;

namespace Example09

{

    class BaseClass

    {

        //基类设计者声明了一个PI的公共变量,方便进行运算

        public static double PI = 3.1415;

    }

    class DervieClass : BaseClass

    {

        //继承类发现该变量的值不能满足运算精度,于是可以通过new修饰符显示隐藏基类中的声明

        public new static double PI = 3.1415926;

    }

    class Program

    {

        static void Main(string[] args)

        {

            Console.WriteLine(BaseClass.PI);

            Console.WriteLine(DervieClass.PI);

            Console.ReadLine();

        }

    }

}

结果:

3.1415

3.1415926

10.this 关键字的含义?

答:

this 是一个保留字,仅限于构造函数和方法成员中使用

在类的构造函数中出现表示对正在构造的对象本身的引用,在类的方法中出现表示对调用该方法的对象的引用,在结构的构造上函数中出现表示对正在构造的结构的引用,在结构的方法中出现表示对调用该方法的结果的引用

this 保留字不能用于静态成员的实现里,因为这时对象或结构并未实例化

在 C# 系统中,this 实际上是一个常量,所以不能使用 this++ 这样的运算

this 保留字一般用于限定同名的隐藏成员、将对象本身做为参数、声明索引访问器、判断传入参数的对象是否为本身

示例:

CODE:

using System;

using System.Collections.Generic;

using System.Text;

namespace Example10

{

    class Class1

    {

        private double c;

        private string value;

        public double C

        {

            get

            {

                return c;

            }

        }

        public Class1(double c)

        {

            //限定同名的隐藏成员

            this.c = c;

        }

        public Class1(Class1 value)

        {

            //用对象本身实例化自己没有意义

            if (this != value)

            {

                c = value.C;

            }

        }

        public override string ToString()

        {

            //将对象本身做为参数

            return string.Format(&amp;quot;{0} Celsius = {1} Fahrenheit&amp;quot;, c, UnitTransClass.C2F(this));

        }

        //由于好奇,在这做了一个效率测试,想看看到底哪种方式访问成员变量更快,结论:区别不大。。。

        public string Test1()

        {

            long vTickCount = Environment.TickCount;

            for (int i = 0; i < 10000000; i++)

                this.value = i.ToString();

            return string.Format(&amp;quot;Have this.: {0} MSEL&amp;quot;, Environment.TickCount - vTickCount);

        }

        public string Test2()

        {

            long vTickCount = Environment.TickCount;

            for (int i = 0; i < 10000000; i++)

                value = i.ToString();

            return string.Format(&amp;quot;Don't have this.: {0} MSEL&amp;quot;, Environment.TickCount - vTickCount);

        }

    }

    class UnitTransClass

    {

        public static double C2F(Class1 value)

        {

            //摄氏到华氏的转换公式

            return 1.8 * value.C + 32;

        }

    }

    class Program

    {

        static void Main(string[] args)

        {

            Class1 tmpObj = new Class1(37.5);

            Console.WriteLine(tmpObj);

            Console.WriteLine(tmpObj.Test1());

            Console.WriteLine(tmpObj.Test2());

            Console.ReadLine();

        }

    }

}

结果:

37.5 Celsius = 99.5 Fahrenheit

Have this.: 4375 MSEL

Don't have this.: 4406 MSEL

  评论这张
 
阅读(19)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018