您的位置:首页 > 移动开发

Microsoft .NET Framework 2.0 Application Development Foundation 翻译系列8(第一章:第四课 类型转换)

2007-01-06 12:01 585 查看

Lesson4:ConvertingBetweenTypes类型转换

Often,youneedtoconvertbetweentwodifferenttypes.Forexample,youmightneedtodeterminewhetheranIntegerisgreaterorlessthanaDouble.YoumightneedtopassaDoubletoamethodthatrequiresanIntegerasaparameter.Oryoumightneedtodisplayanumberastext.

你经常需要在两个不同类型之间进行转换。例如,你也许需要确定一个Integer是大于还是小于一个Double。你可能要传递一个Double给一个方法,但却将Integer作为参数。或者你可能需要以文本的方式显示数字。

ThislessondescribeshowtoconvertbetweentypesinbothVisualBasicandC#.TypeconversionisoneofthefewareaswhereVisualBasicandC#differconsiderably.

本课讨论,在VB和C#中,如何在类型之间进行转换。类型转换只是VB和C#那少的可怜的区别之一。

Afterthislesson,youwillbeableto:课后你将可以

·Convertbetweentypes.进行类型间的转换

·Explainboxingandwhyitshouldbeavoided.解释装箱和为什么要避免它。

·Implementconversionoperators.实现转换操作符

Estimatedlessontime:20minutes本课时20分钟

ConversioninVisualBasicandC#VB和C#中的转换

Bydefault,VisualBasicallowsimplicitconversionsbetweentypes,whileC#prohibitsimplicitconversionsthatloseprecision.ToturnoffimplicitconversionsinVisualBasic,addOptionStrictOntothetopofeachcodefile,or(inVisualStudio)selectProject,chooseProperties,selectCompile,andselectOptionStrictOnfortheentireproject.

BothVisualBasicandC#allowimplicitconversionifthedestinationtypecanaccommodateallpossiblevaluesfromthesourcetype.Thatiscalledawideningconversion,anditisillustratedbythefollowingexample:

默认情况下,VB允许类型之间进行隐式转换(implicitconversions),这与C#不允许隐式转换相比丧失了精度。可以通过在每个Vb代码文件顶部添加“OptionStrictOn”(参考下面注解)来关闭隐式转换。或者(在VS中)选择项目(project)-》属性(properties)-》编译(complie)-》OptionStrictOn来为全部的项目取消隐式转换。在目的类型可以提供源类型包含的所有可能的值的情况下,Vb和C#都允许隐式转换。这叫做一个“放大转换”。(这句话的意思是,源类型的值的范围小于等于目的类型的值的范围。或者说将小范围的类型转换为大范围的类型。例如:int16toint32)通过下面实例来说明:

注解:OptionExplicit:用于在文件级强制对该文件中的所有变量进行显式声明。=on,用变量之前必须先申明,否则编缉出错!反之不必申就可以用。OptionStrict是用来约束数据类型是否隐式转换还是不转换。

'VB

DimiAsInteger=1

DimdAsDouble=1.0001

d=i'Conversionallowed


//C#

inti=1;

doubled=1.0001;

d=i;//Conversionallowed.

Iftherangeorprecisionofthesourcetypeexceedsthatofthedestinationtype,theoperationiscalledanarrowingconversion,whichusuallyrequiresexplicitconversion.Table1-7liststhewaystoperformexplicitconversions.

假设源类型的范围和精度都超过了目的类型,这个操作被成为:“缩小转换”,(这句话的意思是,大范围的类型转换为小范围的类型。例如:int32toint16)通常这种情况要求“显示转换”(explicitconversion)。表1-7列出了执行显示转换的方法。

Table1-7:MethodsforExplicitConversion显式转换的方法

SystemType

VisualBasic

C#

Converts

System.Convert

BetweentypesthatimplementtheSystem.IConvertibleinterface.

在实现了System.IConvertible接口的类型之间转换。

CType

(type)castoperator

Betweentypesthatdefineconversionoperators.

在定义了转换操作符的类型之间转换

type.ToString,type.Parse

Betweenstringandbasetypes;throwsexceptioniftheconversionisnotpossible.

在string和基本类型间转换,如果不能转换抛出异常。

type.TryParse,type.TryParseExact

Fromstringtoabasetype;returnsfalseiftheconversionisnotpossible.

将string转换为一个基本类型,如果不能转换则返回fasle

CBool,CInt,CStr,etc.

BetweenbaseVisualBasictypes;compiledinlineforbetterperformance.(VisualBasiconly.)

在VB基本类型间转换;内嵌编译器提供更好的性能(只在VB使用)

DirectCast,TryCast

Betweentypes.DirectCastthrowsanexceptionifthetypesarenotrelatedthroughinheritanceoriftheydonotshareacommoninterface;TryCastreturnsNothinginthosesituations.(VisualBasiconly.)

类型之间转换。如果类型没有继承关系或它们不继承于同一个接口,那么DirectCast将抛出一个异常;TryCast在这些情况下返回Nothing。(只能在VB中使用)

.NET2.0

TryParse,TryParseExact,andTryCastarenewin.NET2.0.Previously,youhadtoattemptaparsingorconversionandthencatchtheexceptionifitfailed.

TryParse,TryParseExact,和TryCast是在net2.0中新提供的。以前,你必须尝试一次解析(parsing)或转换,如果失败,那么捕获这个异常。

Narrowingconversionsfailifthesourcevalueexceedsthedestinationtype'srangeorifaconversionbetweenthetypesisnotdefined,soyoushouldencloseanarrowingconversioninTryblocksoruseTryCastorTryParseandcheckthereturnvalue.

如果源类型的值超出了目的类型的范围或者转换中的类型没有被定义,会产生缩小转换(Narrowingconversions)失败。因此,你要将缩小转换放在Try块中,或用TryCast,再或者用TryParse并检查返回值。

WhatIsBoxingandUnboxing?什么是装箱和拆箱?

Boxingconvertsavaluetypetoareferencetype,andunboxingconvertsareferencetypetoavaluetype.ThefollowingexampledemonstratesboxingbyconvertinganInteger(avaluetype)toanObject(areferencetype):

装箱是将一个值类型转换为一个引用类型,而拆箱是将一个引用类型转换为一个值类型。下面例子通过转换一个Integer(值类型)到一个Object(引用类型)来演示装箱:

'VB

DimiAsInteger=123

DimoAsObject=CType(i,Object)


//C#

inti=123;

objecto=(object)i;

Unboxingoccursifyouassignareferenceobjecttoavaluetype.Thefollowingexampledemonstratesunboxing:

如果你将一个引用类型赋给一个值类型将会导致拆箱。下面代码示范拆箱:

'VB

DimoAsObject=123

DimiAsInteger=CType(o,Integer)


//C#

objecto=123;

inti=(int)o;


BestPractices—Boxingandunboxing

Boxingandunboxingincuroverhead,soyoushouldavoidthemwhenprogrammingintenselyrepetitivetasks.BoxingalsooccurswhenyoucallvirtualmethodsthatastructureinheritsfromSystem.Object,suchasToString.Followthesetipstoavoidunnecessaryboxing:

装箱和拆箱将产生损耗,因此当程序总是重复这类任务时,你应该避免它们。当你调用派生于System.Object类的结构的虚函数时也将会导致装箱。例如,ToString。

下面这些提示用于避免不必要的装箱:

·Implementtype-specificversions(overloads)forproceduresthatacceptvariousvaluetypes.ItisbetterpracticetocreateseveraloverloadedproceduresthanonethatacceptsanObjectargument.

·为程序实现明确说明的类型(重载),使它可以接收各式各样的值类型。而接收Object类型参数对于建立重载过程是一个好的习惯。

·UsegenericswheneverpossibleinsteadofacceptingObjectarguments.

·尽可能的使用泛型代替Object类型。

·OverridetheToString,Equals,andGetHashvirtualmemberswhendefiningstructures.

·当定义结构时,覆盖ToString,Equals,和GetHash这些虚方法。

HowtoImplementConversioninCustomTypes如何实现自定义类型的转换

Youcandefineconversionsforyourowntypesinseveralways.Whichtechniqueyouchoosedependsonthetypeofconversionyouwanttoperform:

你可以通过几种方法来对自定义类型进行转换。那么,你想要完成这种类型转换需要哪几项技术呢?

·Defineconversionoperatorstosimplifynarrowingandwideningconversionsbetweennumerictypes.

·定义转换操作符来简化数字类型之间的缩小和放大转换。

·OverrideToStringtoprovideconversiontostrings,andoverrideParsetoprovideconversionfromstrings.

·覆盖ToString来提供转换到字符串功能,并且,覆盖Parse来提供将字符串转换为本类型的功能。

·ImplementSystem.IConvertibletoenableconversionthroughSystem.Convert.Usethistechniquetoenableculture-specificconversions.

·实现System.IConvertible接口来允许通过System.Convert转换。使用这个技巧来实现特定类型的转换。

·ImplementaTypeConverterclasstoenabledesign-timeconversionforuseintheVisualStudioPropertieswindow.Design-timeconversionisoutsidethescopeoftheexamandtheTypeConverterclassisnotcoveredinthisbook.

·实现一个TypeConverter类,这样允许在VS属性窗体中设计时进行转换。设计时转换是考试范围外的内容,但TypeConverter类在这本书中仍会被介绍。

MoreInfo—Design-timeconversion

Formoreinformationaboutdesign-timeconversion,read"ExtendingDesign-TimeSupport"athttp://msdn2.microsoft.com/en-us/library/37899azc(en-US,VS.80).aspx.

关于设计时转换的更多信息可以访问http://msdn2.microsoft.com/en-us/library/37899azc(en-US,VS.80).aspx.页面中的“扩展设计时支持”

.NET2.0

Conversionoperatorsarenewin.NET2.0.

转换操作符是net2.0中新提供的功能。

Definingconversionoperatorsallowsyoutodirectlyassignfromavaluetypetoyourcustomtype.UsetheWidening/implicitkeywordforconversionsthatdon'tloseprecision;usetheNarrowing/explicitkeywordforconversionsthatcouldloseprecision.Forexample,thefollowingstructuredefinesoperatorsthatallowassignmenttoandfromintegervalues:

定义转换操作符可以允许你直接将一个值类型赋给你的自定义类型。转换时使用Widening/implicit关键字可以保证转换的精度;转换时使用Narrowing/Explicit关键字无法保证精度。例如,下面的结构定义了操作符,它允许分配并获取整型数值。

'VB

StructureTypeA

PublicValueAsInteger


'Allowsimplicitconversionfromaninteger.

PublicSharedWideningOperatorCType(ByValargAsInteger)AsTypeA

DimresAsNewTypeA

res.Value=arg

Returnres

EndOperator


'Allowsexplicitconversiontoaninteger

PublicSharedNarrowingOperatorCType(ByValargAsTypeA)AsInteger

Returnarg.Value

EndOperator


'Providesstringconversion(avoidsboxing).

PublicOverridesFunctionToString()AsString

ReturnMe.Value.ToString

EndFunction


EndStructure


//C#

structTypeA


{

publicintValue;


//Allowsimplicitconversionfromaninteger.允许将一个integer隐式转换为TypeA


publicstaticimplicitoperatorTypeA(intarg)

{

TypeAres=newTypeA();

res.Value=arg;

returnres;

}


//Allowsexplicitconversiontoaninteger.允许将TypeA显式转换为int

publicstaticexplicitoperatorint(TypeAarg)

{

returnarg.Value;

}


//Providesstringconversion(avoidsboxing).提供字符串转换

publicoverridestringToString()

{

returnthis.Value.ToString();

}

}

TheprecedingtypealsooverridesToStringtoperformthestringconversionwithoutboxing.Nowyoucanassignintegerstothetypedirectly,asshownhere:

上述类型也覆盖了ToString方法,但字符串转换的执行并不会产生装箱。现在,你可以将integer直接赋给这个类型,象下面显示的:

'VB

DimaAsTypeA,iAsInteger

'WideningconversionisOKimplicit.

a=42'Ratherthana.Value=42

'Narrowingconversionmustbeexplicit.

i=CInt(a)'Ratherthani=a.Value

'ThissyntaxisOK,too.

i=CType(a,Integer)

Console.WriteLine("a={0},i={0}",a.ToString,i.ToString)


//C#

TypeAa;inti;

//WideningconversionisOKimplicit.放大转换可以是隐式的

a=42;//Ratherthana.Value=42

//Narrowingconversionmustbeexplicit.缩小转换必须是显式的。

i=(int)a;//Ratherthani=a.Value

Console.WriteLine("a={0},i={0}",a.ToString(),i.ToString());

ToimplementtheSystem.IConvertibleinterface,addtheIConvertibleinterfacetothetypedefinition.ThenuseVisualStudiotoautomaticallyimplementtheinterface.VisualStudioinsertsmemberdeclarationsfor17methods,includingGetTypeCode,ChangeType,andToTypemethodsforeachbasetype.Youdon'thavetoimplementeverymethod,andsome-suchasToDateTime-willprobablybeinvalid.Forinvalidmethods,simplythrowanexception-VisualStudioautomaticallyaddscodetothrowanexceptionforanyconversionmethodsyoudon'timplement.

为了实现System.IConvertible接口,需要添加IConvertible接口到类型定义。然后,使用VS来自动实现这个接口。VS自动建立了17个成员声明,包括每个基本类型都具有的GetTypeCode,ChangeType,和ToType方法。你不必实现每一个方法,例如象ToDateTime这种可能不会被调用的方法。对于这种方法,只需简单的抛出一个异常,不过你不需要自己来实现,VS会自动给每个转换方法添加一个异常抛出代码。

AfteryouimplementIConvertible,thecustomtypecanbeconvertedusingthestandardSystem.Convertclassasshownhere:

在你实现了IConvertible后,这个自定义类型就可以使用标准的System.Convert类来进行转换了。

'VB

DimaAsTypeA,bAsBoolean

a=42

'ConvertusingToBoolean.

b=Convert.ToBoolean(a)

Console.WriteLine("a={0},b={1}",a.ToString,b.ToString)


//C#

TypeAa;boolb;

a=42;

//ConvertusingToBoolean.

b=Convert.ToBoolean(a);

Console.WriteLine("a={0},b={1}",a.ToString(),b.ToString());

Lab:SafelyPerformingConversions练习:安全的执行转换

Thefollowingexercisesshowhowtoavoidproblemswithimplicitconversionssothatyourprogramsfunctionpredictably.Ifyouencounteraproblemcompletinganexercise,thecompletedprojectsareavailableonthecompanionCDintheCodefolder.

下面练习将示范如何避免隐式转换时产生的问题。

Exercise1:ExamineImplicitConversion练习1:考察隐式转换

Inthisexercise,youwillexamineconversiontodeterminewhichnumbertypesallowimplicitconversion.

在这个练习中,你将考察并确定哪几个number类型允许隐式转换。

1.CreateanewconsoleapplicationinVisualStudio.

1.在VS中建立一个新的客户端应用程序

2.Declareinstancesofthreevaluetypes:Int16,Int32,anddouble.Thefollowingcodesampledemonstratesthis:

2.声明三个值类型实例:int16,int32,double。

3.'VB

4.Dimi16AsInt16=1

5.Dimi32AsInt32=1

6.DimdbAsDecimal=1

7.

8.//C#

9.Int16i16=1;

10.Int32i32=1;

11.doubledb=1;

12.Attempttoassigneachvariabletoalltheothers,asthefollowingcodesampledemonstrates.

12.尝试去将它们互相赋值

13.'VB

14.i16=i32

15.i16=db

16.

17.i32=i16

18.i32=db

19.

20.db=i16

21.db=i32

22.

23.//C#

24.i16=i32;

25.i16=db;

26.

27.i32=i16;

28.i32=db;

29.

30.db=i16;

31.db=i32;

32.Attempttobuildyourproject.Whichimplicitconversionsdidthecompilerallow,andwhy?

32.尝试编译你的项目。哪几个隐式转换是可以编译的,为什么?

Exercise2:EnableOptionStrict(VisualBasicOnly)练习2:使用精确选项(只能在VB中使用)

Inthisexercise,whichisonlyfordevelopersusingVisualBasic,youwillmodifythecompiler'soptionsandthenrebuildtheprojectyoucreatedinExercise1.

这个练习只是针对哪些使用VB进行开发的人员,你将修改编译器的选项,然后重新编译你在练习1中建立的项目。

1.InVisualStudio,opentheprojectyoucreatedinExercise1.

1.在VS中,打开你在练习1中建立的项目。

2.ClicktheProjectmenu,andthenclickProjectNameProperties.

2.点击项目菜单,然后点击项目属性。

3.ClicktheCompiletab.ForImplicitConversion,changetheNotificationtypetoError.

3.点击“编译”(compile)卡片项。对于隐式转换,改变Notification(通告)选项类型为Error。(sorry,我这没有VS2005,具体显示名称无法确定。)

4.Attempttobuildyourproject.Whichimplicitconversionsdidthecompilerallow,andwhy?

4.尝试编译你的项目。查看哪几个隐式转换是可以编译的,为什么?

LessonSummary本课摘要

·The.NETFrameworkcanautomaticallyconvertbetweenbuilt-intypes.WideningconversionsoccurimplicitlyinbothVisualBasicandC#.NarrowingconversionsrequireexplicitconversioninC#,whileVisualBasicallowsnarrowingconversionsbydefault.

·.net框架能够自动在默认类型之间进行转换。

·Boxingallowsanytypetobetreatedasareferencetype.

·装箱允许任意类型被加工为引用类型。

·Youmustspecificallyimplementconversionoperatorstoenableconversionincustomtypes.

·你必须实现指定的转换操作符,才可以进行自定义类型的转换。

LessonReview本课回顾

YoucanusethefollowingquestionstotestyourknowledgeoftheinformationinLesson4,"ConvertingBetweenTypes."ThequestionsarealsoavailableonthecompanionCDifyouprefertoreviewtheminelectronicform.

你可以使用下列问题来测试你在本课学习到的知识。

Answers

Answerstothesequestionsandexplanationsofwhyeachanswerchoiceisrightorwrongarelocatedinthe"Answers"sectionattheendofthebook.

回答下列问题并解释每个答案正确或错误的原因。

1.

Whyshouldboxingbeavoided?(Chooseone.)

为什么要避免装箱?(单选)

A.Itaddsoverhead.它增加了损耗(成本)

B.Usersmusthaveadministrativeprivilegestoruntheapplication.用户必须具有管理权限来允许这个应用程序。

C.Itmakescodelessreadable.它降低了代码可读性。



2.

StructuresinheritToStringfromSystem.Object.Whywouldsomeoneoverridethatmethodwithinastructure?(Chooseasmanycorrectanswersasapply.)

结构从System.Object继承了ToString方法。为什么在一个结构中要重写这个方法?(多选)

A.Toavoidboxing.避免装箱

B.Toreturnsomethingotherthanthetypename.返回除了这个类型名称之外的其他信息。

C.ThecompilerrequiresstructurestooverridetheToStringmethod.编译器要求结构重写ToString方法

D.Toavoidrun-timeerrorscausedbyinvalidstringconversions.由于这个有问题的字符串转换将导致运行时错误。



3.

Ifthereisnovalidconversionbetweentwotypes,whatshouldyoudowhenimplementingtheIConvertibleinterface?

假设两个类型间的转换无法避免,当实现IConvertible接口时,你要作什么?

A.DeletetheToTypememberthatperformstheconversion.删除ToType成员

B.ThrowanInvalidCastException.抛出一个InvalidCastException异常

C.Throwanewcustomexceptionreportingtheerror.抛出一个自定义异常来报告这个错误。

D.Leavethememberbodyempty.丢弃空的成员。



4.

Withstrictconversionsenabled,whichofthefollowingwouldallowanimplicitconversion?(Chooseallthatapply.)

在精度转换设置为允许时,下面哪些选项将允许一个隐式转换(多选)

A.Int16toInt32

B.Int32toInt16

C.Int16toDouble

D.DoubletoInt16



Answers

1.

CorrectAnswer:A

A.Correct:Theprimaryreasontoavoidboxingisbecauseitaddsoverhead.避免装箱的主要原因是它导致增加了成本(损耗)

B.Incorrect:Boxingrequiresnospecialprivileges.装箱不需要指定权限

C.Incorrect:Boxingdoesnotmakecodelessreadable.装箱不会降低代码可读性

2.

CorrectAnswers:AandB

A.Correct:ValuetypesareboxedwhenanabstractmethodinheritedfromSystem.Objectiscalled.Overridingthemethodavoidsboxing.当一个从System.Object类继承的抽象方法被调用时,导致值类型被装箱。重写这个方法可以避免装箱。

B.Correct:Bydefault,theToStringmethodsimplyreturnsthetypename,whichistypicallynotusefulforaconsumingapplication.默认情况下,Tostring方法仅返回类型名称,这在实现应用程序时,没有特别的用处。

C.Incorrect:ThecompilerdoesnotrequirestructurestooverridetheToStringmethod.编译器不要求结构重写ToString方法

D.Incorrect:ToStringnevercausesarun-timeerror;itsimplyreturnsthetypenameunlessoverridden.ToString方法从来没有导致一个运行时错误的产生;没有被重写的ToString仅返回类型名称

3.

CorrectAnswer:B

A.Incorrect:Youcan'tomitamemberofaninterfaceandstillconformtothatinterface.你不能忽略任何一个接口的成员,并保持它们和接口中定义的一致性。

B.Correct:InvalidCastExceptionistherecommendedexceptiontothrow.InvalidCastException是被推荐使用的异常。

C.Incorrect:Whileyoucouldthrowacustomexception,usingstandardexceptiontypesmakesiteasierfordeveloperswritingcodetoconsumeyourtypetocatchspecificexceptions.你可以抛出一个自定义异常,引用标准异常类型,开发人员可以更容易的编写代码来实现你的类型并捕获指定的异常。

D.Incorrect:Youmustreturnavalueforeachconversionmember.每个转换成员都必须有返回值。

4.

CorrectAnswers:AandC

A.Correct:YoucanconvertfromInt16toInt32becausethatisconsideredawideningconversion.BecauseInt32canstoreanyvalueofInt16,implicitconversionisallowed.可以,因为它是一个拓展转换。(小范围赋给大范围)

B.Incorrect:YoucannotconvertfromInt32toInt16becausethatisconsideredanarrowingconversion.BecauseInt16cannotstoreanyvalueofInt32,implicitconversionisnotallowed.不可用,因为当前设定了确保精度选项,不可用进行一个截断转换。(大范围赋给小范围)

C.Correct:YoucanconvertfromInt16toDoublebecausethatisconsideredawideningconversion.BecauseDoublecanstoreanyvalueofInt16,implicitconversionisallowed.可以。原因同A

D.Incorrect:YoucannotconvertfromDoubletoInt16becausethatisconsideredanarrowingconversion.BecauseInt16cannotstoreanyvalueofDouble,implicitconversionisnotallowed.不可用,原因同B

ChapterReview本章回顾

Tofurtherpracticeandreinforcetheskillsyoulearnedinthischapter,youcanperformthefollowingtasks:

持续的练习和巩固,将保持你在本章学到的东西。你可以完成下列任务。

·Reviewthechaptersummary.

·回顾本章摘要

·Reviewthelistofkeytermsintroducedinthischapter.

·回顾本章中的关键术语列表

·Completethecasescenarios.Thesescenariossetupreal-worldsituationsinvolvingthetopicsofthischapterandaskyoutocreateasolution.

·完成场景案例。这些场景设置了包括本章的主题在内的真实世界的情况,并要求你建立一个解决方案。

·Completethesuggestedpractices.完成建议的练习

·Takeapracticetest.完成练习测试

ChapterSummary本章摘要

·Valuetypesaresmallvariablesthatstoredatadirectlyratherthanstoringapointertoasecondmemorylocationthatcontainsthedata.Assignmentbetweenvaluetypescopiesthedatafromonevariabletotheother,creatingaseparateinstanceofthedata.YoucanmakevaluetypesnullableusingtheNullablegenerictype,andyoucancreatestructuresthatcombinemultiplevaluetypes.

·值类型是一种小的变量,它直接存储数据,这种方式比存储一个指向一小片包含数据的内存地址要更好。值类型之间的数据拷贝是将一个变量分配给另一个,这个过程建立的是一个单独的数据实例。利用Nullable泛型类型,你能够判断值类型是否被赋值,并且你能够建立由多种值类型组成的结构。

·Referencetypescontaintheaddressofdataratherthantheactualdata.The.NETFrameworkincludesthousandsofreferencetypestoperformalmostanytaskyoucouldrequire.ThemostcommonlyusedreferencetypeistheStringclass.BecausetheStringclassisimmutable,itbehavesdifferentlyfromotherreferencetypes:whenyoucopyastring,auniqueinstanceofthedataiscreated.Whenyoucopymostreferenceclasses,onlythepointeriscopied,whichmeanschangesmadetooneinstancearealsoreflectedintheotherinstance.Whenanunexpectedeventoccurs,the.NETFrameworkthrowsanexception.YoucanhandletheseexceptionsbycreatingTry/Catchblocksinyourcode.

·引用类型包含实际数据的数据地址。Net框架包括数以千计的引用类型用来执行你需要的大部分任务。最常用的引用类型使String类。因为String类是不可变的,它与其他引用类型不同的区别是:当你拷贝一个string,将建立一个唯一的数据实例。当你大量复制引用类型的时候,拷贝的只是指针。这个意思就是:对一个实例的改变将反映到其他的实例。当一个未预料到的事件发生时,net框架抛出一个异常。在你的代码中,通过建立Try/Catch块,你能够处理这些异常。

·Classesin.NETFrameworklanguagesarecustomtypesthatcanincludevaluetypes,referencetypes,methods,attributes,andproperties.Toenableconsistencybetweenclasses,youcanuseinheritance(whereyouderiveanewclassfromanexistingclass)oraninterface(whereyouarerequiredtoimplementspecifiedinterfaces).Genericsenableyoutocreateaclassormethodthatworkswithavarietyoftypes.Toenableapplicationstorespondtoplannedevents,youcanraiseandrespondtoevents.

·类在net框架语言中是自定义类型,它能够包括值类型,引用类型,方法,attributes,和properties。你可以使用继承(从一个已存在的类派生一个新类)或接口(要求实现指定接口)来保持类之间的一致性。泛型可以使你建立一个能够使用多种类型的类或方法。允许应用程序响应计划内事件,你能够触发并响应事件。

·Conversionenablesyoutocompareandcopyvaluesbetweendifferenttypes.ImplicitconversionhappensautomaticallyandbehavesdifferentlyinVisualBasicandC#.C#allowsimplicitconversionforonlynarrowingconversions,wherenoinformationcouldbelost.VisualBasicallowsimplicitconversionforbothnarrowingandwideningconversions.Whenvaluesareconvertedfromavaluetypetoareferencetype,itisconsideredboxing.Unboxingoccursifyouassignareferenceobjecttoavaluetype.

·转换允许你在不同类型之间进行值的比较和值的拷贝。隐式转换是自动执行的,并且在VB和C#中有不同的执行情况。C#仅在缩小转换中不会丢失信息时才允许隐式转换。VB在放大转换和缩小转换时都允许隐式转换。当一个值类型转换为一个引用类型时,将会导致装箱。如果你将一个引用类型分配给一个值类型,将导致拆箱的发生。

KeyTerms关键术语

Doyouknowwhatthesekeytermsmean?Youcancheckyouranswersbylookingupthetermsintheglossaryattheendofthebook.

你知道这些关键术语的意思吗?通过查询书后的术语表,你可以检查你的回答。

·Boxing装箱

·Cast造型

·Constraint约束

·Contract约定

·Exception异常

·filteringexceptions异常过滤

·garbagecollection垃圾收集

·generictype泛型类型

·heap堆

·interface接口

·narrowing缩小

·nullabletype未分配类型

·signature签名(出现在代理)

·stack栈

·structure结构

·unboxing拆箱

·widening加宽

CaseScenario

Inthefollowingcasescenario,youwillapplywhatyou'velearnedabouttypes.Youcanfindanswerstothesequestionsinthe"Answers"sectionattheendofthisbook.

在下面案例场景中,你将应用你学到的关于类型的知识。你可以在书后的Answers部分查看问题的答案。

CaseScenario:DesigninganApplication案例场景:设计一个应用程序

Youhaverecentlyacceptedajobasaninternalapplicationdeveloperintheinformationtechnologydepartmentofanenterprisehealthcarecompany.Yourfirsttaskistodesignaninternalapplicationthatemployeeswillusetomanageinformationaboutcustomers(whomeveryonecalls"subscribers"),theircurrentplans,medications,andchosendoctors.Answeryourmanager'squestionsaboutyourdesignchoices.

你最近找到了一份工作,在一个医疗保健公司的企业技术信息部做一名国内应用程序开发人员。你的第一个任务是设计一款面向国内的软件,人们可以使用它来管理消费者(统称为订户)的信息,他们当前的计划安排,药品信息,和他们的医生的信息。回答你上司关于设计选择的问题。

1.

Weneedtomanageinformationaboutbothsubscribersanddoctors.Howwillyoudothis?Willyouhaveoneclassforboth,twoseparateclasses,orwhat?

我们需要管理订户和医生的信息。你打算如何做?你要为它们俩建立一个类,还是两个单独的类,或者有其他什么想法?



2.

Ouremployeesneedtosearchforgroupsofsubscribersordoctors.Forexample,ifadoctorretires,weneedtocontactallthatdoctor'ssubscribersandassisttheminfindinganewphysician.Similarly,wecontactdoctorsannuallytorenewtheircontracts.Howcanyoustoreagroupofsubscribersordoctorsinyourapplication?

我们的员工需要对订户或医生这两个组进行搜索。例如,假设一名医生退休了,我们需要联系所以与这名医生有关的订户,并帮助他们找到一名新的医生。同样地,我们每年要和医生联系来和他们签新的合同。在你的应用程序中,你打算如何存储订户和医生这两个组。



3.

Oneofthetasksyourapplicationwillperformisgeneratingmailinglabelsforgroupsofsubscribersordoctors.Isthereanywaythatyoucanwriteasinglemethodthatwillhandleaddressesforbothsubscribersanddoctors?Howwillyouimplementthis?

你应用程序的任务之一是为订户或医生组发送邮件。不管怎样,你能够编写一个单独的方法来同时处理订户和医生的地址吗?你打算如何实现它?



4.

Theprivacyofourinformationisextremelyimportanttous.Ourdatabasedeveloperisgoingtorestrictpermissionsonthedatabasetopreventunauthorizedusersfromgainingaccess.Ifauser'sprivilegesarerejected,I'dlikeyoutoinstructtheusertocontacttheirmanagertogainaccess.Howwillyouhandleitifadatabasequeryisrejectedforinsufficientprivileges?

我们的信息是保密的,这点对我们非常重要。我们的数据库开发人员对数据库权限进行来限制,以防止未被授权的用户从开放端口获得访问。假设一个用户权限不足,我希望你可以联系用户,让他去联系他的管理员。假设数据库查询由于权限不足被拒绝,你要如何处理它?



Answers

1.

Bothsubscribersanddoctorswillhavealotofinformationincommon,includingnames,phonenumbers,andaddresses.However,theywilleachhaveuniqueinformation,also.Forexample,youneedtotrackthesubscriptionplanandpaymentinformationforsubscribers.Fordoctors,youneedtotrackcontractdetails,medicalcertifications,andspecialties.Therefore,youshouldcreateseparateclassesforsubscribersanddoctors,butderivethemfromasingleclassthatcontainsallmemberssharedbybothclasses.Todothis,youcouldcreateabaseclassnamedPerson,andderiveboththeSubscriberandDoctorclassesfromPerson.

订户和医生这两者之间有大量相同的信息,包括姓名,电话号码,和地址。但是,他们彼此也有自己独有的信息。例如,你需要跟踪订户计划并发送付款信息给用户。对于医生,你需要跟踪合同信息,医学证明和其他专门的信息。因此,你要为订户和医生分别建立单独的类,但他们都派生于同一个类,这个类包含类订户和医生之间所有公共的成员。至于如何做,你可以建立一个Person基类,并让订户和医生这两个类都派生与Person。

2.

Youcanuseanarraytostoreagroupofsubscribers.

你可以使用数组来存储订户组。

3.

Yes,youcanusegenericstocreateamethodthatcanacceptbothsubscribersanddoctors.Toaccesstheinformationinthebaseclassthatbothclassesshare,youwouldneedtomakethebaseclassaconstraintforthegenericmethod.

可以,你能够建立一个泛型方法,它可以同时接收订户和医生。并访问这两个类都具有的基类的信息,你需要给基类的这个泛型方法添加约束。

4.

Thesecurityerrorwouldgenerateanexception.Therefore,torespondtotheexception,youshouldsurroundthecodeinaTry/Catchblock.WithintheCatchblock,youshouldinformtheuserthatheshouldcontacthismanager.

这个安全错误将导致一个异常。因此,为了响应这个异常,你需要将代码放到一个Try/Catch块中。而在Catch块里,你要通知用户,让他去联系他的管理员。

SuggestedPractices练习建议

Tohelpyousuccessfullymastertheexamobjectivespresentedinthischapter,completethefollowingtasks.

为了帮助你成功通过考试目标中涉及本章的内容,请完成下列任务。

ManageDataina.NETFrameworkApplicationbyUsing.NETFramework2.0SystemTypes

通过利用net框架2.0的系统类型,在一个net框架应用程序中管理数据。

Forthistask,youshouldcompleteatleastPractices1and2.Ifyouwantabetterunderstandingofhowgenericsperformintherealworld,completePractice3aswell.

这个任务中,你至少要完成练习1和2。如果你想更好的理解在真实世界里泛型是如何执行的,最好完成练习3。

·Practice1Openthelastprojectyoucreated,andaddexceptionhandlingtoyourcode.Unlessperformanceisahigherprioritythanreliability,allcodeoutsideofvaluetypedeclarationsshouldbeinaTryblock.

·练习1.打开你最后建立的项目,并在你的代码中添加异常处理。除非性能比可靠性更重要,否则除了值类型声明外的所有代码都要放到Try块中。

·Practice2Createalinked-listgenericclassthatenablesyoutocreateachainofdifferentobjecttypes.

·练习2建立一个泛型类的连接表,它可以使你建立一个区别于Object类型的系列。

·Practice3Createtwoclasseswithidenticalfunctionality.Usegenericsforthefirstclass,andcastthesecondclasstoObjecttypes.CreateaForloopthatusestheclassoverthousandsofiterations.TimetheperformanceofboththegenericclassandtheObject-basedclasstodeterminewhichperformsbetter.YoucanuseDateTime.Now.Tickstomeasurethetime.

·练习3建立两个具有相同功能的类,一个使用泛型,一个使用Object类型。建立一个For循环,反复千次的使用类。泛型类和基于Object类型的类,比较这两者的执行时间来确定哪个更好。你可以使用DateTime.Now.Ticks来计算时间。

Implement.NETFrameworkInterfacestoCauseComponentstoComplywithStandardContracts

使用标准约束来要求组件实现net框架接口。

Forthistask,youshouldcompleteallthreepracticestogainexperienceimplementingcommoninterfaceswithreal-worldclassesandschema.

这次任务,你要完成所有三个练习,通过使用在真实世界中的类和计划来增加实现公共接口的经验。

·Practice1Createacustomclassthatimplementsthenecessaryinterfacestoallowanarrayoftheclasstobesorted.

·练习1建立一个自定义类,它要实现必要的接口,来允许存储类中的数组。

·Practice2Createacustomclassthatcanbeconvertedtocommonvaluetypes.

·练习2建立一个自定义类,它能够被转换为普通的值类型。

·Practice3CreateacustomclassthatcanbedisposedofusingtheIDisposable.Disposemethod.

·练习3建立一个自定义类,可以利用IDisposable.Dispose方法来释放它。

ControlInteractionsBetween.NETFrameworkApplicationComponentsbyUsingEventsandDelegates

利用事件和代理来控制net框架应用程序组件之间的交互。

Forthistask,youshouldcompletebothPractices1and2.

练习1和2都要完成。

·Practice1OpenthelastWindowsFormsapplicationyoucreated,andexaminethecodeVisualStudioautomaticallygeneratedtorespondtouserinterfaceevents.

·练习1.打开你最后建立的windowforms应用程序,并查看VS自动产生的响应用户接口事件的代码。

·Practice2CreateaclassthatthrowsaneventandderivesacustomclassbasedonEventArgs.Thencreateanassemblythatrespondstotheevent.

·练习2建立一个类,它能够抛出一个事件,并具有一个派生于EventArgs的自定义类。然后,建立一个程序集,用来响应这个事件。

TakeaPracticeTest

做一个练习测试

Thepracticetestsonthisbook'scompanionCDoffermanyoptions.Forexample,youcantestyourselfonjustthecontentcoveredinthischapter,oryoucantestyourselfonallthe70-536certificationexamcontent.Youcansetupthetestsothatitcloselysimulatestheexperienceoftakingacertificationexam,oryoucansetitupinstudymodesothatyoucanlookatthecorrectanswersandexplanationsafteryouanswereachquestion.

在这本书的配套CD中的这个练习测试提供更多的选项,你可以测试自己在70-536认证考试的所有内容。你可以设置它为测试状态,它模拟一个认证考试的环境。或者,将它设为学习模式,在你回答了每个问题后,你可以查看正确答案和原因说明。

Practicetests

Fordetailsaboutallthepracticetestoptionsavailable,seethe"HowtoUsethePracticeTests"sectioninthisbook'sIntroduction.

关于所有练习测试选项的详细信息,可以查看本书介绍中的“如何使用练习测试”部分

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐