Ic和Ib有什么ib课程和ap课程的区别?

NPN和PNP有什么区别。_百度知道您所在位置: &
&nbsp&&nbsp&nbsp&&nbsp
模拟技术基础的答案(完整版).doc129页
本文档一共被下载:
次 ,您可全文免费在线阅读后下载本文档。
文档加载中...广告还剩秒
需要金币:150 &&
你可能关注的文档:
··········
··········
模拟电子技术基础答案
第三部分 习题与解答
客观检测题
一、填空题
1、在杂质半导体中,多数载流子的浓度主要取决于掺入的 杂质浓度 ,而少数载流子的浓度则与
有很大关系。
2、当PN结外加正向电压时,扩散电流
漂移电流,耗尽层
变窄 。当外加反向电压时,扩散电流
漂移电流,耗尽层
3、在N型半导体中,电子为多数载流子, 空穴
为少数载流子。
二.判断题
1、由于P型半导体中含有大量空穴载流子,N型半导体中含有大量电子载流子,所以P型半导体带正电,N型半导体带负电。( × )
2、在N型半导体中,掺入高浓度三价元素杂质,可以改为P型半导体。( √ )
3、扩散电流是由半导体的杂质浓度引起的,即杂质浓度大,扩散电流大;杂质浓度小,扩散电流小。(× )
4、本征激发过程中,当激发与复合处于动态平衡时,两种作用相互抵消,激发与复合停止。( × )
5、PN结在无光照无外加电压时,结电流为零。( √ )
6、温度升高时,PN结的反向饱和电流将减小。( × )
7、PN结加正向电压时,空间电荷区将变宽。(×
三.简答题
1、PN结的伏安特性有何特点?
答:根据统计物理理论分析,PN结的伏安特性可用式表示。
式中,ID为流过PN结的电流;Is为PN结的反向饱和电流,是一个与环境温度和材料等有关的参数,单位与I的单位一致;V为外加电压; VT kT/q,为温度的电压当量(其单位与V的单位一致),其中玻尔兹曼常数,电子电量,则,在常温(T 300K)下,VT 25.875mV 26mV。当外加正向电压,即V为正值,且V比VT大几倍时,,于是,这时正向电流将随着正向电压的增加按指数规律增大,PN结为正向导通状态.外加反向电压,即V为负值,且
正在加载中,请稍后...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# 语言范畴之内),如果有不准确、不全面的,欢迎各位朋友指正!
&1.静态变量和非静态变量的区别?
静态变量:
静态变量使用 static 修饰符进行声明
在所属类被装载时创建
通过类进行访问
所属类的所有实例的同一静态变量都是同一个值
非静态变量:
不带有 static 修饰符声明的变量称做非静态变量
在类被实例化时创建
通过对象进行访问
同一个类的不同实例的同一非静态变量可以是不同的值
&1using&S&2using&System.Collections.G&3using&System.T&4&&5namespace&Example01&6{&7&&&&class&Program&8&&&&{&9&&&&&&&&class&Class110&&&&&&&&{11&&&&&&&&&&&&public&static&String&staticStr&=&"Class";12&&&&&&&&&&&&public&String&notstaticStr&=&"Obj";13&&&&&&&&}14&&&&&&&&static&void&Main(string[]&args)15&&&&&&&&{16&&&&&&&&&&&&//静态变量通过类进行访问,该类所有实例的同一静态变量都是同一个值17&&&&&&&&&&&&Console.WriteLine("Class1's&staticStr:&{0}",&Class1.staticStr);18&19&&&&&&&&&&&&Class1&tmpObj1&=&new&Class1();20&&&&&&&&&&&&tmpObj1.notstaticStr&=&"tmpObj1";21&&&&&&&&&&&&Class1&tmpObj2&=&new&Class1();22&&&&&&&&&&&&tmpObj2.notstaticStr&=&"tmpObj2";23&24&&&&&&&&&&&&//非静态变量通过对象进行访问,不同对象的同一非静态变量可以有不同的值25&&&&&&&&&&&&Console.WriteLine("tmpObj1's&notstaticStr:&{0}",&tmpObj1.notstaticStr);26&&&&&&&&&&&&Console.WriteLine("tmpObj2's&notstaticStr:&{0}",&tmpObj2.notstaticStr);27&28&&&&&&&&&&&&Console.ReadLine();29&&&&&&&&}30&&&&}31}3233结果:34Class1's&staticStr:&Class35tmpObj1's&notstaticStr:&tmpObj136tmpObj2's&notstaticStr:&tmpObj237
2.const 和 static readonly 区别?
用 const 修饰符声明的成员叫常量,是在编译期初始化并嵌入到客户端程序
static readonly
用 static readonly 修饰符声明的成员依然是变量,只不过具有和常量类似的使用方法:通过类进行访问、初始化后不可以修改。但与常量不同的是这种变量是在运行期初始化
&1using&S&2using&System.Collections.G&3using&System.T&4&&5namespace&Example02Lib&6{&7&&&&public&class&Class1&8&&&&{&9&&&&&&&&public&const&String&strConst&=&"Const";10&&&&&&&&public&static&readonly&String&strStaticReadonly&=&"StaticReadonly";11&&&&&&&&//public&const&String&strConst&=&"Const&Changed";12&&&&&&&&//public&static&readonly&String&strStaticReadonly&=&"StaticReadonly&Changed";13&&&&}14}
客户端代码:
&1using&S&2using&System.Collections.G&3using&System.T&4using&Example02L&5&&6namespace&Example02&7{&8&&&&class&Program&9&&&&{10&&&&&&&&static&void&Main(string[]&args)11&&&&&&&&{12&&&&&&&&&&&&//修改Example02中Class1的strConst初始值后,只编译 Example02Lib项目13&&&&&&&&&&&&//然后到资源管理器里把新编译的Example02Lib.dll拷贝 Example02.exe所在的目录,执行Example02.exe14&&&&&&&&&&&&//切不可在IDE里直接调试运行因为这会重新编译整个解决方案!!15&16&&&&&&&&&&&&//可以看到strConst的输出没有改变,而strStaticReadonly的输 出已经改变17&&&&&&&&&&&&//表明Const变量是在编译期初始化并嵌入到客户端程序,而 StaticReadonly是在运行时初始化的18&&&&&&&&&&&&Console.WriteLine("strConst&:&{0}",&Class1.strConst);19&&&&&&&&&&&&Console.WriteLine("strStaticReadonly&:&{0}",&Class1.strStaticReadonly);20&21&&&&&&&&&&&&Console.ReadLine();22&&&&&&&&}23&&&&}24}25结果:26strConst&:&Const27strStaticReadonly&:&StaticReadonly&28
修改后的示例:
&1using&S&2using&System.Collections.G&3using&System.T&4&&5namespace&Example02Lib&6{&7&&&&public&class&Class1&8&&&&{&9&&&&&&&&//public&const&String&strConst&=&"Const";10&&&&&&&&//public&static&readonly&String&strStaticReadonly&=&"StaticReadonly";11&&&&&&&&public&const&String&strConst&=&"Const&Changed";12&&&&&&&&public&static&readonly&String&strStaticReadonly&=&"StaticReadonly&Changed";13&&&&}14}15结果1617strConst&:&Const18strStaticReadonly&:&StaticReadonly&Changed1920
3.extern 是什么意思?
extern 修饰符用于声明由程序集外部实现的成员函数
经常用于系统API函数的调用(通过 DllImport )。注意,和DllImport一起使用时要加上 static 修饰符
也可以用于对于同一程序集不同版本组件的调用(用 extern 声明别名)
不能与 abstract 修饰符同时使用
&1using&S&2using&System.Collections.G&3using&System.T&4using&System.Runtime.InteropS&5&&6namespace&Example03&7{&8&&&&class&Program&9&&&&{10&&&&&&&&//注意DllImport是一个Attribute&Property,在 System.Runtime.InteropServices命名空间中定义11&&&&&&&&//extern与DllImport一起使用时必须再加上一个static修饰符12&&&&&&&&[DllImport("User32.dll")]13&&&&&&&&public&static&extern&int&MessageBox(int&Handle,&string&Message,&string&Caption,&int&Type);14&15&&&&&&&&static&int&Main()16&&&&&&&&{17&&&&&&&&&&&&string&myS18&&&&&&&&&&&&Console.Write("Enter&your&message:&");19&&&&&&&&&&&&myString&=&Console.ReadLine();20&&&&&&&&&&&&return&MessageBox(0,&myString,&"My&Message&Box",&0);21&&&&&&&&}22&&&&}23}24结果:25&2627
4.abstract 是什么意思?
abstract 修饰符可以用于类、方法、属性、事件和索引指示器(indexer),表示其为抽象成员
abstract 不可以和 static 、virtual 、override 一起使用
声明为 abstract 成员可以不包括实现代码,但只有类中还有未实现的抽象成员,该类就不可以被实例化,通常用于强制继承类必须实现某一成员
&&1&&2using&S&&3using&System.Collections.G&&4using&System.T&&5&&&6namespace&Example04&&7{&&8&&&&基类,抽象类&基类,抽象类&&9&&&&public&abstract&class&BaseClass&10&&&&{&11&&&&&&&&//抽象属性,同时具有get和set访问器表示继承类必须将该属性实现为可读写&12&&&&&&&&public&abstract&String&Attribute&13&&&&&&&&{&14&&&&&&&&&&&&get;&15&&&&&&&&&&&&set;&16&&&&&&&&}&17&&18&&&&&&&&//抽象方法,传入一个字符串参数无返回值&19&&&&&&&&public&abstract&void&Function(String&value);&20&&21&&&&&&&&//抽象事件,类型为系统预定义的代理(delegate):EventHandler&22&&&&&&&&public&abstract&event&EventHandler&E&23&&24&&&&&&&&//抽象索引指示器,只具有get访问器表示继承类必须将该索引指示器实现为只读&25&&&&&&&&public&abstract&Char&this[int&Index]&26&&&&&&&&{&27&&&&&&&&&&&&get;&28&&&&&&&&}&29&&&&}&30&&&&#endregion&31&&32&&&&继承类&继承类&33&&&&public&class&DeriveClass&:&BaseClass&34&&&&{&35&&&&&&&&private&String&&36&&37&&&&&&&&public&override&String&Attribute&38&&&&&&&&{&39&&&&&&&&&&&&get&40&&&&&&&&&&&&{&41&&&&&&&&&&&&&&&&return&&42&&&&&&&&&&&&}&43&&&&&&&&&&&&set&44&&&&&&&&&&&&{&45&&&&&&&&&&&&&&&&attribute&=&&46&&&&&&&&&&&&}&47&&&&&&&&}&48&&&&&&&&public&override&void&Function(String&value)&49&&&&&&&&{&50&&&&&&&&&&&&attribute&=&&51&&&&&&&&&&&&if&(Event&!=&null)&52&&&&&&&&&&&&{&53&&&&&&&&&&&&&&&&Event(this,&new&EventArgs());&54&&&&&&&&&&&&}&55&&&&&&&&}&56&&&&&&&&public&override&event&EventHandler&E&57&&&&&&&&public&override&Char&this[int&Index]&58&&&&&&&&{&59&&&&&&&&&&&&get&60&&&&&&&&&&&&{&61&&&&&&&&&&&&&&&&return&attribute[Index];&62&&&&&&&&&&&&}&63&&&&&&&&}&64&&&&}&65&&&&#endregion&66&&67&&&&class&Program&68&&&&{&69&&&&&&&&static&void&OnFunction(object&sender,&EventArgs&e)&70&&&&&&&&{&71&&&&&&&&&&&&for&(int&i&=&0;&i&&&((DeriveClass)sender).Attribute.L&i++)&72&&&&&&&&&&&&{&73&&&&&&&&&&&&&&&&Console.WriteLine(((DeriveClass)sender)[i]);&74&&&&&&&&&&&&}&75&&&&&&&&}&76&&&&&&&&static&void&Main(string[]&args)&77&&&&&&&&{&78&&&&&&&&&&&&DeriveClass&tmpObj&=&new&DeriveClass();&79&&80&&&&&&&&&&&&tmpObj.Attribute&=&"1234567";&81&&&&&&&&&&&&Console.WriteLine(tmpObj.Attribute);&82&&83&&&&&&&&&&&&//将静态函数OnFunction与tmpObj对象的Event事件进行关联&84&&&&&&&&&&&&tmpObj.Event&+=&new&EventHandler(OnFunction);&85&&86&&&&&&&&&&&&tmpObj.Function("7654321");&87&&88&&&&&&&&&&&&Console.ReadLine();&89&&&&&&&&}&90&&&&}&91}&92结果:&931234567&947&956&965&974&983&9921001&101102
5.internal 修饰符起什么作用?
internal 修饰符可以用于类型或成员,使用该修饰符声明的类型或成员只能在同一程集内访问
接口的成员不能使用 internal 修饰符
&1&2Example05Lib&项目的&Class1&3&4using&S&5using&System.Collections.G&6using&System.T&7&&8namespace&Example05Lib&9{10&&&&public&class&Class111&&&&{12&&&&&&&&internal&String&strInternal&=&null;13&&&&&&&&public&String&strP14&&&&}15}16结果17Example05Lib&项目的&Class2&类可以访问到&Class1&的&strInternal&成员1819&2021Example05&项目的&Program&类无法访问到&Class1&的&strInternal&成员2223&2425
6.sealed 修饰符是干什么的?
sealed 修饰符表示密封
用于类时,表示该类不能再被继承,不能和 abstract 同时使用,因为这两个修饰符在含义上互相排斥
用于方法和属性时,表示该方法或属性不能再被继承,必须和 override 关键字一起使用,因为使用 sealed 修饰符的方法或属性肯定是基类中相应的虚成员
通常用于实现第三方类库时不想被客户端继承,或用于没有必要再继承的类以防止滥用继承造成层次结构体系混乱
恰当的利用 sealed 修饰符也可以提高一定的运行效率,因为不用考虑继承类会重写该成员
&1&2using&S&3using&System.Collections.G&4using&System.T&5&&6namespace&Example06&7{&8&&&&class&Program&9&&&&{10&&&&&&&&class&A11&&&&&&&&{12&&&&&&&&&&&&public&virtual&void&F()13&&&&&&&&&&&&{14&&&&&&&&&&&&&&&&Console.WriteLine("A.F");15&&&&&&&&&&&&}16&&&&&&&&&&&&public&virtual&void&G()17&&&&&&&&&&&&{18&&&&&&&&&&&&&&&&Console.WriteLine("A.G");19&&&&&&&&&&&&}20&&&&&&&&}21&&&&&&&&class&B&:&A22&&&&&&&&{23&&&&&&&&&&&&public&sealed&override&void&F()24&&&&&&&&&&&&{25&&&&&&&&&&&&&&&&Console.WriteLine("B.F");26&&&&&&&&&&&&}27&&&&&&&&&&&&public&override&void&G()28&&&&&&&&&&&&{29&&&&&&&&&&&&&&&&Console.WriteLine("B.G");30&&&&&&&&&&&&}31&&&&&&&&}32&&&&&&&&class&C&:&B33&&&&&&&&{34&&&&&&&&&&&&public&override&void&G()35&&&&&&&&&&&&{36&&&&&&&&&&&&&&&&Console.WriteLine("C.G");37&&&&&&&&&&&&}38&&&&&&&&}39&&&&&&&&static&void&Main(string[]&args)40&&&&&&&&{41&&&&&&&&&&&&new&A().F();42&&&&&&&&&&&&new&A().G();43&&&&&&&&&&&&new&B().F();44&&&&&&&&&&&&new&B().G();45&&&&&&&&&&&&new&C().F();46&&&&&&&&&&&&new&C().G();47&48&&&&&&&&&&&&Console.ReadLine();49&&&&&&&&}50&&&&}51}52结果:53类&B&在继承类&A&时可以重写两个虚函数,如图所示:5455&5657由于类&B&中对&F&方法进行了密封,&类&C&在继承类&B&时只能重写一个函数,如图所示:5859&6061控制台输出结果,类&C&的方法&F&只能是输出&类B&中对该方法的实现:6263A.F64A.G65B.F66B.G67B.F68C.G&69
7.override 和 overload 的区别?
override 表示重写,用于继承类对基类中虚成员的实现
overload 表示重载,用于同一个类中同名方法不同参数(包括类型不同或个数不同)的实现
&1&2using&S&3using&System.Collections.G&4using&System.T&5&&6namespace&Example07&7{&8&&&&class&Program&9&&&&{10&&&&&&&&class&BaseClass11&&&&&&&&{12&&&&&&&&&&&&public&virtual&void&F()13&&&&&&&&&&&&{14&&&&&&&&&&&&&&&&Console.WriteLine("BaseClass.F");15&&&&&&&&&&&&}16&&&&&&&&}17&&&&&&&&class&DeriveClass&:&BaseClass18&&&&&&&&{19&&&&&&&&&&&&public&override&void&F()20&&&&&&&&&&&&{21&&&&&&&&&&&&&&&&base.F();22&&&&&&&&&&&&&&&&Console.WriteLine("DeriveClass.F");23&&&&&&&&&&&&}24&&&&&&&&&&&&public&void&Add(int&Left,&int&Right)25&&&&&&&&&&&&{26&&&&&&&&&&&&&&&&Console.WriteLine("Add&for&Int:&{0}",&Left&+&Right);27&&&&&&&&&&&&}28&&&&&&&&&&&&public&void&Add(double&Left,&double&Right)29&&&&&&&&&&&&{30&&&&&&&&&&&&&&&&Console.WriteLine("Add&for&int:&{0}",&Left&+&Right);31&&&&&&&&&&&&}32&&&&&&&&}33&&&&&&&&static&void&Main(string[]&args)34&&&&&&&&{35&&&&&&&&&&&&DeriveClass&tmpObj&=&new&DeriveClass();36&&&&&&&&&&&&tmpObj.F();37&&&&&&&&&&&&tmpObj.Add(1,&2);38&&&&&&&&&&&&tmpObj.Add(1.1,&2.2);39&40&&&&&&&&&&&&Console.ReadLine();41&&&&&&&&}42&&&&}43}44结果:45BaseClass.F46DeriveClass.F47Add&for&Int:&348Add&for&int:&3.3&
8.什么是索引指示器?
实现索引指示器(indexer)的类可以象数组那样使用其实例后的对象,但与数组不同的是索引指示器的参数类型不仅限于int
简单来说,其本质就是一个含参数属性
&&1using&S&&2using&System.Collections.G&&3using&System.T&&4&&&5namespace&Example08&&6{&&7&&&&public&class&Point&&8&&&&{&&9&&&&&&&&private&double&x,&y;&10&&&&&&&&public&Point(double&X,&double&Y)&11&&&&&&&&{&12&&&&&&&&&&&&x&=&X;&13&&&&&&&&&&&&y&=&Y;&14&&&&&&&&}&15&&&&&&&&//重写ToString方法方便输出&16&&&&&&&&public&override&string&ToString()&17&&&&&&&&{&18&&&&&&&&&&&&return&String.Format("X:&{0}&,&Y:&{1}",&x,&y);&19&&&&&&&&}&20&&&&}&21&&&&public&class&Points&22&&&&{&23&&&&&&&&Point[]&&24&&&&&&&&public&Points(Point[]&Points)&25&&&&&&&&{&26&&&&&&&&&&&&points&=&P&27&&&&&&&&}&28&&&&&&&&public&int&PointNumber&29&&&&&&&&{&30&&&&&&&&&&&&get&&31&&&&&&&&&&&&{&&32&&&&&&&&&&&&&&&&return&points.L&&33&&&&&&&&&&&&}&34&&&&&&&&}&&&&&35&&&&&&&&//实现索引访问器&36&&&&&&&&public&Point&this[int&Index]&37&&&&&&&&{&38&&&&&&&&&&&&get&39&&&&&&&&&&&&{&40&&&&&&&&&&&&&&&&return&points[Index];&41&&&&&&&&&&&&}&42&&&&&&&&}&43&&&&}&44&&45&&&&//感谢watson&hua(/)的指点&46&&&&//索引指示器的实质是含参属性,参数并不只限于int&47&&&&class&WeatherOfWeek&48&&&&{&49&&&&&&&&public&string&this[int&Index]&50&&&&&&&&{&51&&&&&&&&&&&&get&52&&&&&&&&&&&&{&53&&&&&&&&&&&&&&&&//注意case段使用return直接返回所以不需要break&54&&&&&&&&&&&&&&&&switch&(Index)&55&&&&&&&&&&&&&&&&{&56&&&&&&&&&&&&&&&&&&&&case&0:&57&&&&&&&&&&&&&&&&&&&&&&&&{&58&&&&&&&&&&&&&&&&&&&&&&&&&&&&return&"Today&is&cloudy!";&59&&&&&&&&&&&&&&&&&&&&&&&&}&60&&&&&&&&&&&&&&&&&&&&case&5:&61&&&&&&&&&&&&&&&&&&&&&&&&{&62&&&&&&&&&&&&&&&&&&&&&&&&&&&&return&"Today&is&thundershower!";&63&&&&&&&&&&&&&&&&&&&&&&&&}&64&&&&&&&&&&&&&&&&&&&&default:&65&&&&&&&&&&&&&&&&&&&&&&&&{&66&&&&&&&&&&&&&&&&&&&&&&&&&&&&return&"Today&is&fine!";&67&&&&&&&&&&&&&&&&&&&&&&&&}&68&&&&&&&&&&&&&&&&}&69&&&&&&&&&&&&}&70&&&&&&&&}&71&&&&&&&&public&string&this[string&Day]&72&&&&&&&&{&73&&&&&&&&&&&&get&74&&&&&&&&&&&&{&75&&&&&&&&&&&&&&&&string&TodayWeather&=&null;&76&&&&&&&&&&&&&&&&//switch的标准写法&77&&&&&&&&&&&&&&&&switch&(Day)&78&&&&&&&&&&&&&&&&{&79&&&&&&&&&&&&&&&&&&&&case&"Sunday":&80&&&&&&&&&&&&&&&&&&&&&&&&{&81&&&&&&&&&&&&&&&&&&&&&&&&&&&&TodayWeather&=&"Today&is&cloudy!";&82&&&&&&&&&&&&&&&&&&&&&&&&&&&&break;&83&&&&&&&&&&&&&&&&&&&&&&&&}&84&&&&&&&&&&&&&&&&&&&&case&"Friday":&85&&&&&&&&&&&&&&&&&&&&&&&&{&86&&&&&&&&&&&&&&&&&&&&&&&&&&&&TodayWeather&=&"Today&is&thundershower!";&87&&&&&&&&&&&&&&&&&&&&&&&&&&&&break;&88&&&&&&&&&&&&&&&&&&&&&&&&}&89&&&&&&&&&&&&&&&&&&&&default:&90&&&&&&&&&&&&&&&&&&&&&&&&{&91&&&&&&&&&&&&&&&&&&&&&&&&&&&&TodayWeather&=&"Today&is&fine!";&92&&&&&&&&&&&&&&&&&&&&&&&&&&&&break;&93&&&&&&&&&&&&&&&&&&&&&&&&}&94&&&&&&&&&&&&&&&&}&95&&&&&&&&&&&&&&&&return&TodayW&96&&&&&&&&&&&&}&97&&&&&&&&}&98&&&&}&99&&&&class&Program100&&&&{101&&&&&&&&static&void&Main(string[]&args)102&&&&&&&&{103&&&&&&&&&&&&Point[]&tmpPoints&=&new&Point[10];104&&&&&&&&&&&&for&(int&i&=&0;&i&&&tmpPoints.L&i++)105&&&&&&&&&&&&{106&&&&&&&&&&&&&&&&tmpPoints[i]&=&new&Point(i,&Math.Sin(i));107&&&&&&&&&&&&}108&109&&&&&&&&&&&&Points&tmpObj&=&new&Points(tmpPoints);110&&&&&&&&&&&&for&(int&i&=&0;&i&&&tmpObj.PointN&i++)111&&&&&&&&&&&&{112&&&&&&&&&&&&&&&&Console.WriteLine(tmpObj[i]);113&&&&&&&&&&&&}114&115&116&&&&&&&&&&&&string[]&Week&=&new&string[]&{&"Sunday",&"Monday",&"Tuesday",&"Wednesday",&"Thursday",&"Friday",&"Staurday"};117&&&&&&&&&&&&WeatherOfWeek&tmpWeatherOfWeek&=&new&WeatherOfWeek();118&&&&&&&&&&&&for&(int&i&=&0;&i&&&6;&i++)119&&&&&&&&&&&&{120&&&&&&&&&&&&&&&&Console.WriteLine(tmpWeatherOfWeek[i]);121&&&&&&&&&&&&}122&&&&&&&&&&&&foreach&(string&tmpDay&in&Week)123&&&&&&&&&&&&{124&&&&&&&&&&&&&&&&Console.WriteLine(tmpWeatherOfWeek[tmpDay]);125&&&&&&&&&&&&}126&127&&&&&&&&&&&&Console.ReadLine();128&&&&&&&&}129&&&&}130}131结果:132X:&0&,&Y:&0133X:&1&,&Y:&0.897134X:&2&,&Y:&0.682135X:&3&,&Y:&0.867136X:&4&,&Y:&-0.928137X:&5&,&Y:&-0.138138X:&6&,&Y:&-0.926139X:&7&,&Y:&0.789140X:&8&,&Y:&0.382141X:&9&,&Y:&0.757142Today&is&cloudy!143Today&is&fine!144Today&is&fine!145Today&is&fine!146Today&is&fine!147Today&is&thundershower!148Today&is&cloudy!149Today&is&fine!150Today&is&fine!151Today&is&fine!152Today&is&fine!153Today&is&thundershower!154Today&is&fine!155156&157158
9.new 修饰符是起什么作用?
new 修饰符与 new 操作符是两个概念
new 修饰符用于声明类或类的成员,表示隐藏了基类中同名的成员。而new 操作符用于实例化一个类型
new 修饰符只能用于继承类,一般用于弥补基类设计的不足
new 修饰符和 override 修饰符不可同时用在一个成员上,因为这两个修饰符在含义上互相排斥
&1using&S&2using&System.Collections.G&3using&System.T&4&&5namespace&Example09&6{&7&&&&class&BaseClass&8&&&&{&9&&&&&&&&//基类设计者声明了一个PI的公共变量,方便进行运算10&&&&&&&&public&static&double&PI&=&3.1415;11&&&&}12&&&&class&DervieClass&:&BaseClass13&&&&{14&&&&&&&&//继承类发现该变量的值不能满足运算精度,于是可以通过new修饰符显示隐藏基类中的声 明15&&&&&&&&public&new&static&double&PI&=&3.1415926;16&&&&}17&&&&class&Program18&&&&{19&&&&&&&&static&void&Main(string[]&args)20&&&&&&&&{21&&&&&&&&&&&&Console.WriteLine(BaseClass.PI);22&&&&&&&&&&&&Console.WriteLine(DervieClass.PI);23&24&&&&&&&&&&&&Console.ReadLine();25&&&&&&&&}26&&&&}27}28结果:293.1415303.1415926&3132
10.this 关键字的含义?
this 是一个保留字,仅限于构造函数和方法成员中使用
在类的构造函数中出现表示对正在构造的对象本身的引用,在类的方法中出现表示对调用该方法的对象的引用,在结构的构造上函数中出现表示对正在构造的 结构的引用,在结构的方法中出现表示对调用该方法的结果的引用
this 保留字不能用于静态成员的实现里,因为这时对象或结构并未实例化
在 C# 系统中,this 实际上是一个常量,所以不能使用 this++ 这样的运算
this 保留字一般用于限定同名的隐藏成员、将对象本身做为参数、声明索引访问器、判断传入参数的对象是否为本身
&1using&S&2using&System.Collections.G&3using&System.T&4&&5namespace&Example10&6{&7&&&&class&Class1&8&&&&{&9&&&&&&&&private&double&c;10&&&&&&&&private&string&11&12&&&&&&&&public&double&C13&&&&&&&&{14&&&&&&&&&&&&get15&&&&&&&&&&&&{16&&&&&&&&&&&&&&&&return&c;17&&&&&&&&&&&&}18&&&&&&&&}19&&&&&&&&public&Class1(double&c)20&&&&&&&&{21&&&&&&&&&&&&//限定同名的隐藏成员22&&&&&&&&&&&&this.c&=&c;23&&&&&&&&}24&&&&&&&&public&Class1(Class1&value)25&&&&&&&&{26&&&&&&&&&&&&//用对象本身实例化自己没有意义27&&&&&&&&&&&&if&(this&!=&value)28&&&&&&&&&&&&{29&&&&&&&&&&&&&&&&c&=&value.C;30&&&&&&&&&&&&}31&&&&&&&&}32&&&&&&&&public&override&string&ToString()33&&&&&&&&{34&&&&&&&&&&&&//将对象本身做为参数35&&&&&&&&&&&&return&string.Format("{0}&Celsius&=&{1}&Fahrenheit",&c,&UnitTransClass.C2F(this));36&&&&&&&&}37&38&&&&&&&&//由于好奇,在这做了一个效率测试,想看看到底哪种方式访问成员变量更快,结论:区别不 大。。。39&&&&&&&&public&string&Test1()40&&&&&&&&{41&&&&&&&&&&&&long&vTickCount&=&Environment.TickC42&&&&&&&&&&&&for&(int&i&=&0;&i&&&;&i++)43&&&&&&&&&&&&&&&&this.value&=&i.ToString();44&&&&&&&&&&&&return&string.Format("Have&this.:&{0}&MSEL",&Environment.TickCount&-&vTickCount);45&&&&&&&&}46&&&&&&&&public&string&Test2()47&&&&&&&&{48&&&&&&&&&&&&long&vTickCount&=&Environment.TickC49&&&&&&&&&&&&for&(int&i&=&0;&i&&&;&i++)50&&&&&&&&&&&&&&&&value&=&i.ToString();51&&&&&&&&&&&&return&string.Format("Don't&have&this.:&{0}&MSEL",&Environment.TickCount&-&vTickCount);52&&&&&&&&}53&&&&}54&&&&class&UnitTransClass55&&&&{56&&&&&&&&public&static&double&C2F(Class1&value)57&&&&&&&&{58&&&&&&&&&&&&//摄氏到华氏的转换公式59&&&&&&&&&&&&return&1.8&*&value.C&+&32;60&&&&&&&&}61&&&&}62&&&&class&Program63&&&&{64&&&&&&&&static&void&Main(string[]&args)65&&&&&&&&{66&&&&&&&&&&&&Class1&tmpObj&=&new&Class1(37.5);67&68&&&&&&&&&&&&Console.WriteLine(tmpObj);69&70&&&&&&&&&&&&Console.WriteLine(tmpObj.Test1());71&&&&&&&&&&&&Console.WriteLine(tmpObj.Test2());72&73&&&&&&&&&&&&Console.ReadLine();74&&&&&&&&}75&&&&}76}77结果:7837.5&Celsius&=&99.5&Fahrenheit79Have&this.:&4375&MSEL80Don't&have&this.:&4406&MSEL&8182
11.可以使用抽象函数重写基类中的虚函数吗?
可以,但需使用 new 修饰符显式声明,表示隐藏了基类中该函数的实现
&1&&&class&BaseClass&2&&&&{&3&&&&&&&&public&virtual&void&F()&4&&&&&&&&{&5&&&&&&&&&&&&Console.WriteLine("BaseClass.F");&6&&&&&&&&}&7&&&&}&8&&&&abstract&class&&DeriveClass&:&BaseClass&9&&&&{10&&&&&&&&public&new&abstract&void&F();11&&&&}12
12.密封类可以有虚函数吗?
可以,基类中的虚函数将隐式的转化为非虚函数,但密封类本身不能再增加新的虚函数
&1&&&&class&BaseClass&2&&&&{&3&&&&&&&&public&virtual&void&F()&4&&&&&&&&{&5&&&&&&&&&&&&Console.WriteLine("BaseClass.F");&6&&&&&&&&}&7&&&&}&8&&&&sealed&class&DeriveClass&:&BaseClass&9&&&&{10&&&&&&&&//基类中的虚函数F被隐式的转化为非虚函数11&12&&&&&&&&//密封类中不能再声明新的虚函数G13&&&&&&&&//public&virtual&void&G()14&&&&&&&&//{15&&&&&&&&//&&&&Console.WriteLine("DeriveClass.G");16&&&&&&&&//}17&&&&}
13.如果基类中的虚属性只有一个属性访问器,那么继承类重写该属性后可以有几个属性访问器?如果基类中有 get 和 set 两个呢?
如果基类中的虚属性只有一个属性访问器,那么继承类重写该属性后也应只有一个。如果基类中有 get 和 set 两个属性访问器,那么继承类中可以只有一个也可以同时有两个属性访问器
14.abstract 可以和 virtual 一起使用吗?可以和 override 一起使用吗?
abstract 修饰符不可以和 static、virtual 和 override 修饰符一起使用
15.接口可以包含哪些成员?
接口可以包含属性、方法、索引指示器和事件,但不能包含常量、域、操作符、构造函数和析构函数,而且也不能包含任何静态成员
16.类和结构的区别?
类是引用类型在堆上分配,类的实例进行赋值只是复制了引用,都指向同一段实际对象分配的内存
类有构造和析构函数
类可以继承和被继承
结构是值类型在栈上分配(虽然栈的访问速度比较堆要快,但栈的资源有限放),结构的赋值将分配产生一个新的对象。
结构没有构造函数,但可以添加。结构没有析构函数
结构不可以继承自另一个结构或被继承,但和类一样可以继承自接口
根据以上比较,我们可以得出一些轻量级的对象最好使用结构,但数据量大或有复杂处理逻辑对象最好使用类。
如:Geoemtry(GIS 里的一个概论,在 OGC 标准里有定义) 最好使用类,而 Geometry 中点的成员最好使用结构
&&1using&S&&2using&System.Collections.G&&3using&System.T&&4&&&5namespace&Example16&&6{&&7&&&&interface&IPoint&&8&&&&{&&9&&&&&&&&double&X&10&&&&&&&&{&11&&&&&&&&&&&&get;&12&&&&&&&&&&&&set;&13&&&&&&&&}&14&&&&&&&&double&Y&15&&&&&&&&{&16&&&&&&&&&&&&get;&17&&&&&&&&&&&&set;&18&&&&&&&&}&19&&&&&&&&double&Z&20&&&&&&&&{&21&&&&&&&&&&&&get;&22&&&&&&&&&&&&set;&23&&&&&&&&}&24&&&&}&25&&&&//结构也可以从接口继承&26&&&&struct&Point:&IPoint&27&&&&{&28&&&&&&&&private&double&x,&y,&z;&29&&&&&&&&//结构也可以增加构造函数&30&&&&&&&&public&Point(double&X,&double&Y,&double&Z)&31&&&&&&&&{&32&&&&&&&&&&&&this.x&=&X;&33&&&&&&&&&&&&this.y&=&Y;&34&&&&&&&&&&&&this.z&=&Z;&35&&&&&&&&}&36&&&&&&&&public&double&X&37&&&&&&&&{&38&&&&&&&&&&&&get&{&return&x;&}&39&&&&&&&&&&&&set&{&x&=&&}&40&&&&&&&&}&41&&&&&&&&public&double&Y&42&&&&&&&&{&43&&&&&&&&&&&&get&{&return&x;&}&44&&&&&&&&&&&&set&{&x&=&&}&45&&&&&&&&}&46&&&&&&&&public&double&Z&47&&&&&&&&{&48&&&&&&&&&&&&get&{&return&x;&}&49&&&&&&&&&&&&set&{&x&=&&}&50&&&&&&&&}&51&&&&}&52&&&&//在此简化了点状Geometry的设计,实际产品中还包含Project(坐标变换) 等复杂操作&53&&&&class&PointGeometry&54&&&&{&55&&&&&&&&private&Point&&56&&&&&&&&&57&&&&&&&&public&PointGeometry(double&X,&double&Y,&double&Z)&58&&&&&&&&{&59&&&&&&&&&&&&value&=&new&Point(X,&Y,&Z);&60&&&&&&&&}&61&&&&&&&&public&PointGeometry(Point&value)&62&&&&&&&&{&63&&&&&&&&&&&&//结构的赋值将分配新的内存&64&&&&&&&&&&&&this.value&=&&65&&&&&&&&}&66&&&&&&&&public&double&X&67&&&&&&&&{&68&&&&&&&&&&&&get&{&return&value.X;&}&69&&&&&&&&&&&&set&{&this.value.X&=&&}&70&&&&&&&&}&71&&&&&&&&public&double&Y&72&&&&&&&&{&73&&&&&&&&&&&&get&{&return&value.Y;&}&74&&&&&&&&&&&&set&{&this.value.Y&=&&}&75&&&&&&&&}&76&&&&&&&&public&double&Z&77&&&&&&&{&78&&&&&&&&&&&&get&{&return&value.Z;&}&79&&&&&&&&&&&&set&{&this.value.Z&=&&}&80&&&&&&&&}&81&&&&&&&&public&static&PointGeometry&operator&+(PointGeometry&Left,&PointGeometry&Rigth)&82&&&&&&&&{&83&&&&&&&&&&&&return&new&PointGeometry(Left.X&+&Rigth.X,&Left.Y&+&Rigth.Y,&Left.Z&+&Rigth.Z);&84&&&&&&&&}&85&&&&&&&&public&override&string&ToString()&86&&&&&&&&{&87&&&&&&&&&&&&return&string.Format("X:&{0},&Y:&{1},&Z:&{2}",&value.X,&value.Y,&value.Z);&88&&&&&&&&}&89&&&&}&90&&&&class&Program&91&&&&{&92&&&&&&&&static&void&Main(string[]&args)&93&&&&&&&&{&94&&&&&&&&&&&&Point&tmpPoint&=&new&Point(1,&2,&3);&95&&96&&&&&&&&&&&&PointGeometry&tmpPG1&=&new&PointGeometry(tmpPoint);&97&&&&&&&&&&&&PointGeometry&tmpPG2&=&new&PointGeometry(tmpPoint);&98&&&&&&&&&&&&tmpPG2.X&=&4;&99&&&&&&&&&&&&tmpPG2.Y&=&5;100&&&&&&&&&&&&tmpPG2.Z&=&6;101&102&&&&&&&&&&&&//由于结构是值类型,tmpPG1&和&tmpPG2&的坐标并不一样103&&&&&&&&&&&&Console.WriteLine(tmpPG1);104&&&&&&&&&&&&Console.WriteLine(tmpPG2);105&106&&&&&&&&&&&&//由于类是引用类型,对tmpPG1坐标修改后影响到了tmpPG3107&&&&&&&&&&&&PointGeometry&tmpPG3&=&tmpPG1;108&&&&&&&&&&&&tmpPG1.X&=&7;109&&&&&&&&&&&&tmpPG1.Y&=&8;110&&&&&&&&&&&&tmpPG1.Z&=&9;111&&&&&&&&&&&&Console.WriteLine(tmpPG1);112&&&&&&&&&&&&Console.WriteLine(tmpPG3);113&114&&&&&&&&&&&&Console.ReadLine();115&&&&&&&&}116&&&&}117}118结果:119X:&1,&Y:&2,&Z:&3120X:&4,&Y:&5,&Z:&6121X:&7,&Y:&8,&Z:&9122X:&7,&Y:&8,&Z:&9&123124
17.接口的多继承会带来哪些问题?
C# 中的接口与类不同,可以使用多继承,即一个子接口可以有多个父接口。但如果两个父成员具有同名的成员,就产生了二义性(这也正是 C# 中类取消了多继承的原因之一),这时在实现时最好使用显式的声明
&1using&S&2using&System.Collections.G&3using&System.T&4&&5namespace&Example17&6{&7&&&&class&Program&8&&&&{&9&&&&&&&&//一个完整的接口声明示例10&&&&&&&&interface&IExample11&&&&&&&&{12&&&&&&&&&&&&//属性13&&&&&&&&&&&&string&P14&&&&&&&&&&&&{15&&&&&&&&&&&&&&&&get;16&&&&&&&&&&&&&&&&set;17&&&&&&&&&&&&}18&&&&&&&&&&&&//方法19&&&&&&&&&&&&string&F(int&Value);20&&&&&&&&&&&&//事件21&&&&&&&&&&&&event&EventHandler&E;22&&&&&&&&&&&&//索引指示器23&&&&&&&&&&&&string&this[int&Index]24&&&&&&&&&&&&{25&&&&&&&&&&&&&&&&get;26&&&&&&&&&&&&&&&&set;27&&&&&&&&&&&&}28&&&&&&&&}29&&&&&&&&interface&IA30&&&&&&&&{31&&&&&&&&&&&&int&Count&{&get;&set;}32&&&&&&&&}33&&&&&&&&interface&IB34&&&&&&&&{35&&&&&&&&&&&&int&Count();36&&&&&&&&}37&&&&&&&&//IC接口从IA和IB多重继承38&&&&&&&&interface&IC&:&IA,&IB39&&&&&&&&{40&&&&&&&&}41&&&&&&&&class&C&:&IC42&&&&&&&&{43&&&&&&&&&&&&private&int&count&=&100;44&&&&&&&&&&&&//显式声明实现IA接口中的Count属性45&&&&&&&&&&&&int&IA.Count46&&&&&&&&&&&&{47&&&&&&&&&&&&&&&&get&{&return&100;&}48&&&&&&&&&&&&&&&&set&{&count&=&&}49&&&&&&&&&&&&}50&&&&&&&&&&&&//显式声明实现IB接口中的Count方法51&&&&&&&&&&&&int&IB.Count()52&&&&&&&&&&&&{53&&&&&&&&&&&&&&&&return&count&*&54&&&&&&&&&&&&}55&&&&&&&&}56&&&&&&&&static&void&Main(string[]&args)57&&&&&&&&{58&&&&&&&&&&&&C&tmpObj&=&new&C();59&60&&&&&&&&&&&&//调用时也要显式转换61&&&&&&&&&&&&Console.WriteLine("Count&property:&{0}",&((IA)tmpObj).Count);62&&&&&&&&&&&&Console.WriteLine("Count&function:&{0}",&((IB)tmpObj).Count());63&64&&&&&&&&&&&&Console.ReadLine();65&&&&&&&&}66&&&&}67}68结果:69Count&property:&10070Count&function:&10000&71727374
18.抽象类和接口的区别?
抽象类(abstract class)可以包含功能定义和实现,接口(interface)只能包含功能定义
抽象类是从一系列相关对象中抽象出来的概念, 因此反映的是事物的内部共性;接口是为了满足外部调用而定义的一个功能约定, 因此反映的是事物的外部特性
分析对象,提炼内部共性形成抽象类,用以表示对象本质,即&是什么&
为外部提供调用或功能需要扩充时优先使用接口
19.别名指示符是什么?
通过别名指示符我们可以为某个类型起一个别名
主要用于解决两个命名空间内有同名类型的冲突或避免使用冗余的命名空间
别名指示符只在一个单元文件内起作用
&1Class1.cs:&2&3using&S&4using&System.Collections.G&5using&System.T&6&&7namespace&com.nblogs.reonlyrun.CSharp26QExample.Example19.Lib01&8{&9&&&&class&Class110&&&&{11&&&&&&&&public&override&string&ToString()12&&&&&&&&{13&&&&&&&&&&&&return&"com.nblogs.reonlyrun.CSharp26QExample.Example19.Lib01's&Class1";14&&&&&&&&}15&&&&}16}17Class2.cs1819using&S20using&System.Collections.G21using&System.T22&23namespace&com.nblogs.reonlyrun.CSharp26QExample.Example19.Lib0224{25&&&&class&Class126&&&&{27&&&&&&&&public&override&string&ToString()28&&&&&&&&{29&&&&&&&&&&&&return&"com.nblogs.reonlyrun.CSharp26QExample.Example19.Lib02's&Class1";30&&&&&&&&}31&&&&}32}33主单元(Program.cs):3435using&S36using&System.Collections.G37using&System.T38&39//使用别名指示符解决同名类型的冲突40using&Lib01Class1&=&com.nblogs.reonlyrun.CSharp26QExample.Example19.Lib01.Class1;41using&Lib02Class2&=&com.nblogs.reonlyrun.CSharp26QExample.Example19.Lib02.Class1;42&43namespace&Example1944{45&&&&class&Program46&&&&{47&&&&&&&&static&void&Main(string[]&args)48&&&&&&&&{49&&&&&&&&&&&&Lib01Class1&tmpObj1&=&new&Lib01Class1();50&&&&&&&&&&&&Lib02Class2&tmpObj2&=&new&Lib02Class2();51&52&&&&&&&&&&&&Console.WriteLine(tmpObj1);53&&&&&&&&&&&&Console.WriteLine(tmpObj2);54&55&&&&&&&&&&&&Console.ReadLine();56&&&&&&&&}57&&&&}58}59结果:60com.nblogs.reonlyrun.CSharp26QExample.Example19.Lib01's&Class161com.nblogs.reonlyrun.CSharp26QExample.Example19.Lib02's&Class1&6263&6465
20.如何释放非托管资源?
&.NET 平台在内存管理方面提供了GC(Garbage Collection),负责自动释放托管资源和内存回收的工作,但它无法对非托管资源进行释放,这时我们必须自己提供方法来释放对象内分配的非托管资 源,比如你在对象的实现代码中使用了一个COM对象
最简单的办法,可以通过实现protected void Finalize()(析构函数会在编译时变成这个东东)来释放非托管资源,因为GC在释放对象时会检查该对象是否实现了 Finalize() 方法,如果是则调用它。但,据说这样会降低效率。。。
有一种更好的,那就是通过实现一个接口显式的提供给客户调用端手工释放对象的方法,而不是傻傻的等着GC来释放我们的对象(何况效率又那么低)
System 命名空间内有一个 IDisposable 接口,拿来做这事非常合适,就省得我们自己再声明一个接口了
另外补充一句,这种实现并不一定要使用了非托管资源后才用,如果你设计的类会在运行时有大些的实例(象 GIS 中的Geometry),为了优化程序性能,你也可以通过实现该接口让客户调用端在确认不需要这些对象时手工释放它们
&1using&S&2using&System.Collections.G&3using&System.T&4&&5namespace&Example20&6{&7&&&&class&Program&8&&&&{&9&&&&&&&&class&Class1&:&IDisposable10&&&&&&&&{11&&&&&&&&&&&&//析构函数,编译后变成&protected&void&Finalize(),GC会 在回收对象前会调用调用该方法12&&&&&&&&&&&&~Class1()13&&&&&&&&&&&&{14&&&&&&&&&&&&&&&&Dispose(false);15&&&&&&&&&&&&}16&17&&&&&&&&&&&&//通过实现该接口,客户可以显式地释放对象,而不需要等待GC来释放资源,据说那样会降 低效率18&&&&&&&&&&&&void&IDisposable.Dispose()19&&&&&&&&&&&&{20&&&&&&&&&&&&&&&&Dispose(true);21&&&&&&&&&&&&}22&23&&&&&&&&&&&&//将释放非托管资源设计成一个虚函数,提供在继承类中释放基类的资源的能力24&&&&&&&&&&&&protected&virtual&void&ReleaseUnmanageResources()25&&&&&&&&&&&&{26&&&&&&&&&&&&&&&&//Do&something27&&&&&&&&&&&&}28&29&&&&&&&&&&&&//私有函数用以释放非托管资源30&&&&&&&&&&&&private&void&Dispose(bool&disposing)31&&&&&&&&&&&&{32&&&&&&&&&&&&&&&&ReleaseUnmanageResources();33&34&&&&&&&&&&&&&&&&//为true时表示是客户显式调用了释放函数,需通知GC不要再调用对象的 Finalize方法35&&&&&&&&&&&&&&&&//为false时肯定是GC调用了对象的Finalize方法,所以没有必要再告诉GC 你不要调用我的Finalize方法啦36&&&&&&&&&&&&&&&&if&(disposing)37&&&&&&&&&&&&&&&&{38&&&&&&&&&&&&&&&&&&&&GC.SuppressFinalize(this);39&&&&&&&&&&&&&&&&}40&&&&&&&&&&&&}&41&&&&&&&&}42&&&&&&&&static&void&Main(string[]&args)43&&&&&&&&{44&&&&&&&&&&&&//tmpObj1没有手工释放资源,就等着GC来慢慢的释放它吧45&&&&&&&&&&&&Class1&tmpObj1&=&new&Class1();46&47&&&&&&&&&&&&//tmpObj2调用了Dispose方法,传说比等着GC来释放它效率要调一些48&&&&&&&&&&&&//个人认为是因为要逐个对象的查看其元数据,以确认是否实现了Dispose方法吧49&&&&&&&&&&&&//当然最重要的是我们可以自己确定释放的时间以节省内存,优化程序运行效率50&&&&&&&&&&&&Class1&tmpObj2&=&new&Class1();51&&&&&&&&&&&&((IDisposable)tmpObj2).Dispose();52&&&&&&&&}53&&&&}54}5556
21.P/Invoke是什么?
在受控代码与非受控代码进行交互时会产生一个事务(transition) ,这通常发生在使用平台调用服务(Platform Invocation Services),即P/Invoke
如调用系统的 API 或与 COM 对象打交道,通过 System.Runtime.InteropServices 命名空间
虽然使用 Interop 非常方便,但据估计每次调用事务都要执行 10 到 40 条指令,算起来开销也不少,所以我们要尽量少调用事务
如果非用不可,建议本着一次调用执行多个动作,而不是多次调用每次只执行少量动作的原则
22.StringBuilder 和 String 的区别?
String 虽然是一个引用类型,但在赋值操作时会产生一个新的对象,而 StringBuilder 则不会
所以在大量字符串拼接或频繁对某一字符串进行操作时最好使用 StringBuilder,不要使用 String
&1using&S&2using&System.Collections.G&3using&System.T&4&&5namespace&Example22&6{&7&&&&class&Program&8&&&&{&9&&&&&&&&static&void&Main(string[]&args)10&&&&&&&&{11&&&&&&&&&&&&const&int&cycle&=&100000;12&13&&&&&&&&&&&&long&vTickCount&=&Environment.TickC14&&&&&&&&&&&&String&str&=&null;15&&&&&&&&&&&&for&(int&i&=&0;&i&&&&i++)16&&&&&&&&&&&&&&&&str&+=&i.ToString();17&&&&&&&&&&&&Console.WriteLine("String:&{0}&MSEL",&Environment.TickCount&-&vTickCount);18&19&&&&&&&&&&&&vTickCount&=&Environment.TickC20&&&&&&&&&&&&//看到这个变量名我就生气,奇怪为什么大家都使它呢?&:)21&&&&&&&&&&&&StringBuilder&sb&=&new&StringBuilder();22&&&&&&&&&&&&for&(int&i&=&0;&i&&&&i++)23&&&&&&&&&&&&&&&&sb.Append(i);24&&&&&&&&&&&&Console.WriteLine("StringBuilder:&{0}&MSEL",&Environment.TickCount&-&vTickCount);25&26&&&&&&&&&&&&Console.ReadLine();27&&&&&&&&}28&&&&}29}30结果:31String:&102047&MSEL32StringBuilder:&46&MSEL3334
23.explicit 和 implicit 的含义?
explicit 和 implicit 属于转换运算符,如用这两者可以让我们自定义的类型支持相互交换
explicti 表示显式转换,如从 A -& B 必须进行强制类型转换(B = (B)A)
implicit 表示隐式转换,如从 B -& A 只需直接赋值(A = B)
隐式转换可以让我们的代码看上去更漂亮、更简洁易懂,所以最好多使用 implicit 运算符。不过!如果对象本身在转换时会损失一些信息(如精度),那么我们只能使用 explicit 运算符,以便在编译期就能警告客户调用端
&1using&S&2using&System.Collections.G&3using&System.T&4&&5namespace&Example23&6{&7&&&&class&Program&8&&&&{&9&&&&&&&&//本例灵感来源于大话西游经典台词&神仙?妖怪?&--主要是我实在想不出什么好例子了10&&&&&&&&class&Immortal11&&&&&&&&{12&&&&&&&&&&&&public&string&13&&&&&&&&&&&&public&Immortal(string&Name)14&&&&&&&&&&&&{15&&&&&&&&&&&&&&&&name&=&N16&&&&&&&&&&&&}17&&&&&&&&&&&&public&static&implicit&operator&Monster(Immortal&value)18&&&&&&&&&&&&{19&&&&&&&&&&&&&&&&return&new&Monster(value.name&+&":神仙变妖怪?偷偷下凡即可。。。");20&&&&&&&&&&&&}21&&&&&&&&}22&&&&&&&&class&Monster23&&&&&&&&{24&&&&&&&&&&&&public&string&25&&&&&&&&&&&&public&Monster(string&Name)26&&&&&&&&&&&&{27&&&&&&&&&&&&&&&&name&=&N28&&&&&&&&&&&&}29&&&&&&&&&&&&public&static&explicit&operator&Immortal(Monster&value)30&&&&&&&&&&&&{31&&&&&&&&&&&&&&&&return&new&Immortal(value.name&+&":妖怪想当神仙?再去修炼五百年!");32&&&&&&&&&&&&}33&&&&&&&&}34&&&&&&&&static&void&Main(string[]&args)35&&&&&&&&{36&&&&&&&&&&&&Immortal&tmpImmortal&=&new&Immortal("紫霞仙子");37&&&&&&&&&&&&//隐式转换38&&&&&&&&&&&&Monster&tmpObj1&=&tmpI39&&&&&&&&&&&&Console.WriteLine(tmpObj1.name);40&41&&&&&&&&&&&&Monster&tmpMonster&=&new&Monster("孙悟空");42&&&&&&&&&&&&//显式转换43&&&&&&&&&&&&Immortal&tmpObj2&=&(Immortal)tmpM44&&&&&&&&&&&&Console.WriteLine(tmpObj2.name);45&46&&&&&&&&&&&&Console.ReadLine();47&&&&&&&&}48&&&&}49}50结果:51紫霞仙子:神仙变妖怪?偷偷下凡即可。。。52孙悟空:妖怪想当神仙?再去修炼五百年!&5354
&24.params 有什么用?
params 关键字在方法成员的参数列表中使用,为该方法提供了参数个数可变的能力
它在只能出现一次并且不能在其后再有参数定义,之前可以
&1using&S&2using&System.Collections.G&3using&System.T&4&&5namespace&ConsoleApplication1&6{&7&&&&class&App&8&&&&{&9&&&&&&&&//第一个参数必须是整型,但后面的参数个数是可变的。10&&&&&&&&//而且由于定的是object数组,所有的数据类型都可以做为参数传入11&&&&&&&&public&static&void&UseParams(int&id,&params&object[]&list)12&&&&&&&&{13&&&&&&&&&&&&Console.WriteLine(id);14&&&&&&&&&&&&for&(int&i&=&0;&i&&&list.L&i++)15&&&&&&&&&&&&{16&&&&&&&&&&&&&&&&Console.WriteLine(list[i]);17&&&&&&&&&&&&}18&&&&&&&&}19&20&&&&&&&&static&void&Main()21&&&&&&&&{22&&&&&&&&&&&&//可变参数部分传入了三个参数,都是字符串类型23&&&&&&&&&&&&UseParams(1,&"a",&"b",&"c");24&&&&&&&&&&&&//可变参数部分传入了四个参数,分别为字符串、整数、浮点数和双精度浮点数数组25&&&&&&&&&&&&UseParams(2,&"d",&100,&33.33,&new&double[]&{&1.1,&2.2&});26&27&&&&&&&&&&&&Console.ReadLine();28&&&&&&&&}29&&&&}30}31结果:32133a34b35c36237d381003933.3340System.Double[]&4142
25.什么是反射?
反射,Reflection,通过它我们可以在运行时获得各种信息,如程序集、模块、类型、字段、属性、方法和事件
通过对类型动态实例化后,还可以对其执行操作
一般用于插件式框架程序和设计模式的实现,当然反射是一种手段可以充分发挥其能量来完成你想做的任何事情(前面好象见过一位高人用反射调用一个官方 类库中未说明的函数。。。)
&1using&S&2using&System.Collections.G&3using&System.T&4&&5namespace&Example25Lib&6{&7&&&&public&class&Class1&8&&&&{&9&&&&&&&&private&string&10&&&&&&&&private&int&11&12&&&&&&&&//如果显式的声明了无参数构造函数,客户端只需要用程序集的 CreateInstance即可实例化该类13&&&&&&&&//在此特意不实现,以便在客户调用端体现构造函数的反射实现14&&&&&&&&//public&Class1()15&&&&&&&&//{16&&&&&&&&//}17&&&&&&&&public&Class1(string&Name,&int&Age)18&&&&&&&&{19&&&&&&&&&&&&name&=&N20&&&&&&&&&&&&age&=&A21&&&&&&&&}22&&&&&&&&public&void&ChangeName(string&NewName)23&&&&&&&&{24&&&&&&&&&&&&name&=&NewN25&&&&&&&&}26&&&&&&&&public&void&ChangeAge(int&NewAge)27&&&&&&&&{28&&&&&&&&&&&&age&=&NewA29&&&&&&&&}30&&&&&&&&public&override&string&ToString()31&&&&&&&&{32&&&&&&&&&&&&return&string.Format("Name:&{0},&Age:&{1}",&name,&age);33&&&&&&&&}34&&&&}35}36
反射实例化对象并调用其方法,属性和事件的反射调用略去
&1using&S&2using&System.Collections.G&3using&System.T&4&&5//注意添加该反射的命名空间&6using&System.R&7&&8namespace&Example25&9{10&&&&class&Program11&&&&{12&&&&&&&&static&void&Main(string[]&args)13&&&&&&&&{14&&&&&&&&&&&&//加载程序集15&&&&&&&&&&&&Assembly&tmpAss&=&Assembly.LoadFile(AppDomain.CurrentDomain.BaseDirectory&+&"Example25Lib.dll");16&17&&&&&&&&&&&&//遍历程序集内所有的类型,并实例化18&&&&&&&&&&&&Type[]&tmpTypes&=&tmpAss.GetTypes();19&&&&&&&&&&&&foreach&(Type&tmpType&in&tmpTypes)20&&&&&&&&&&&&{21&&&&&&&&&&&&&&&&//获取第一个类型的构造函数信息22&&&&&&&&&&&&&&&&ConstructorInfo[]&tmpConsInfos&=&tmpType.GetConstructors();23&&&&&&&&&&&&&&&&foreach&(ConstructorInfo&tmpConsInfo&in&tmpConsInfos)24&&&&&&&&&&&&&&&&{25&&&&&&&&&&&&&&&&&&&&//为构造函数生成调用的参数集合26&&&&&&&&&&&&&&&&&&&&ParameterInfo[]&tmpParamInfos&=&tmpConsInfo.GetParameters();&27&&&&&&&&&&&&&&&&&&&&object[]&tmpParams&=&new&object[tmpParamInfos.Length];28&&&&&&&&&&&&&&&&&&&&for&(int&i&=&0;&i&&&tmpParamInfos.L&i++)29&&&&&&&&&&&&&&&&&&&&{30&&&&&&&&&&&&&&&&&&&&&&&&tmpParams[i]&=&tmpAss.CreateInstance(tmpParamInfos[i].ParameterType.FullName);31&&&&&&&&&&&&&&&&&&&&&&&&if&(tmpParamInfos[i].ParameterType.FullName&==&"System.String")32&&&&&&&&&&&&&&&&&&&&&&&&{33&&&&&&&&&&&&&&&&&&&&&&&&&&&&tmpParams[i]&=&"Clark";34&&&&&&&&&&&&&&&&&&&&&&&&}35&&&&&&&&&&&&&&&&&&&&}36&37&&&&&&&&&&&&&&&&&&&&//实例化对象38&&&&&&&&&&&&&&&&&&&&object&tmpObj&=&tmpConsInfo.Invoke(tmpParams);39&&&&&&&&&&&&&&&&&&&&Console.WriteLine(tmpObj);40&41&&&&&&&&&&&&&&&&&&&&//获取所有方法并执行42&&&&&&&&&&&&&&&&&&&&foreach&(MethodInfo&tmpMethod&in&tmpType.GetMethods())43&&&&&&&&&&&&&&&&&&&&{44&&&&&&&&&&&&&&&&&&&&&&&&//为方法的调用创建参数集合45&&&&&&&&&&&&&&&&&&&&&&&&tmpParamInfos&=&tmpMethod.GetParameters();46&&&&&&&&&&&&&&&&&&&&&&&&tmpParams&=&new&object[tmpParamInfos.Length];47&&&&&&&&&&&&&&&&&&&&&&&&for&(int&i&=&0;&i&&&tmpParamInfos.L&i++)48&&&&&&&&&&&&&&&&&&&&&&&&{49&&&&&&&&&&&&&&&&&&&&&&&&&&&&tmpParams[i]&=&tmpAss.CreateInstance(tmpParamInfos[i].ParameterType.FullName);50&&&&&&&&&&&&&&&&&&&&&&&&&&&&if&(tmpParamInfos[i].ParameterType.FullName&==&"System.String")51&&&&&&&&&&&&&&&&&&&&&&&&&&&&{52&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&tmpParams[i]&=&"Clark&Zheng";53&&&&&&&&&&&&&&&&&&&&&&&&&&&&}54&&&&&&&&&&&&&&&&&&&&&&&&&&&&if&(tmpParamInfos[i].ParameterType.FullName&==&"System.Int32")55&&&&&&&&&&&&&&&&&&&&&&&&&&&&{56&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&tmpParams[i]&=&27;57&&&&&&&&&&&&&&&&&&&&&&&&&&&&}58&&&&&&&&&&&&&&&&&&&&&&&&}59&&&&&&&&&&&&&&&&&&&&&&&&tmpMethod.Invoke(tmpObj,&tmpParams);60&&&&&&&&&&&&&&&&&&&&}61&62&&&&&&&&&&&&&&&&&&&&//调用完方法后再次打印对象,比较结果63&&&&&&&&&&&&&&&&&&&&Console.WriteLine(tmpObj);64&&&&&&&&&&&&&&&&}65&&&&&&&&&&&&}66&67&&&&&&&&&&&&Console.ReadLine();68&&&&&&&&}69&&&&}70}71结果:72Name:&Clark,&Age:&073Name:&Clark&Zheng,&Age:&27
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:1701次
排名:千里之外

我要回帖

更多关于 ac33ib和ac33b的区别 的文章

 

随机推荐