版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、个人学习文档 C#学习-提高篇目 录 TOC o 1-3 h z HYPERLINK l _Toc300930253 (1)学习概述-新的在上面 PAGEREF _Toc300930253 h 2 HYPERLINK l _Toc300930254 (2)问题- IIS7经典模式和集成模式的区别分析-12 PAGEREF _Toc300930254 h 3 HYPERLINK l _Toc300930255 (3)问题- DataTable.Select使用得小心,出现查询不到数据-12 PAGEREF _Toc300930255 h 4 HYPERLINK l _Toc300930256 (
2、4)提高- .NET下的内存分配机制-02 PAGEREF _Toc300930256 h 5 HYPERLINK l _Toc300930257 (5)提高- .NET中类型的转换-02 PAGEREF _Toc300930257 h 8 HYPERLINK l _Toc300930258 (6)问题:WebService-服务器未能识别 HTTP 头 SOAPAction 的值-20 PAGEREF _Toc300930258 h 11 HYPERLINK l _Toc300930259 (7)cs0016:未能写入输出文件 c:WINDOWSMicrosoft.NET PAGEREF _
3、Toc300930259 h 12 HYPERLINK l _Toc300930260 (8)问题:虚拟目录继承根Web.Config的问题解决-28 PAGEREF _Toc300930260 h 13 HYPERLINK l _Toc300930261 (9)C#获得客户端的IP,主机名 获取当前时间的方法 PAGEREF _Toc300930261 h 14 HYPERLINK l _Toc300930262 (10)关于Session事件的理解 PAGEREF _Toc300930262 h 17 HYPERLINK l _Toc300930263 (11)null object模式-
4、详见设计模式学习-提高篇 PAGEREF _Toc300930263 h 18 HYPERLINK l _Toc300930264 (12)C# Lock()语句-13 PAGEREF _Toc300930264 h 20 HYPERLINK l _Toc300930265 (13)认识全面的null-13 PAGEREF _Toc300930265 h 22 HYPERLINK l _Toc300930266 (14)IEnumerator 和 IEnumberator 理解-12 PAGEREF _Toc300930266 h 25 HYPERLINK l _Toc300930267 (1
5、5)IList 接口 PAGEREF _Toc300930267 h 27 HYPERLINK l _Toc300930268 (16)视图状态:控件生命周期中的装载和保存视图阶段 PAGEREF _Toc300930268 h 28 HYPERLINK l _Toc300930269 (17)提高:.net类的初始化机制,顺序,内存分配概述-17 PAGEREF _Toc300930269 h 32学习概述-新的在上面值描述20110513注意,新学习的放在上面!复制本节点加在下面即可,注意标注日期学习站点 HYPERLINK 问题- IIS7经典模式和集成模式的区别分析-12值描述很多的项
6、目转移到win7系统上都会出现莫名其妙的问题,这其中有意部分可以通过应用程序池的模式修改解决,这也算是一个解决方案!下面详细描述 经典模式 与 集成模式 的区别!简单描述经典模式是为了与之前的版本兼容,使用ISAPI扩展来调用ASP.NET运行库,原先运行于IIS6.0下的Web应用程序迁移到IIS7.0中只要将应用程序配置成经典模式,代码基本不用修改就可以正常运行。集成模式是一种统一的哀求处理管道,它将ASP.NET请求管道与IIS核心管道组合在一起,这种模式能够提供更好的性能,能够实现配置和治理的模块化,而且增加了使用托管代码模块扩展IIS时的灵活性。假如老的Web应用程序运行于IIS7.
7、0的集成模式下,可能需要对应用程序的web.config文件进行修改,尤其是使用了实现IHttpHandler接口的自定义模块的情况。IIS7.0在同一个服务器上能够同时支持两种模式的应用程序。 IIS6.0中ASP.NET MMC管理单元用于配置ASP.NET,7.0中ASP.NET应用程序的管理域IIS管理更加紧密的集成在一起,不存在单独的管理单元,所有的IIS和ASP.NET配置都是使用IIS管理器完成的。IIS7.0配置信息基于.NET framework配置系统,所以IIS7.0中运行的应用程序的web.config文件同时包含web服务器和ASP.NET配置设置,例如可以再web.
8、config文件中设置扩展名和文件的映射(IIS6.0中必须在IIS中进行配置)。web.config一些设置仅适用于集成模式,而不适用于经典模式,如经典模式下运行的应用程序则忽略web.config的system.WebServer节中指定的所有托管代码模块和处理程序,这种模式下web应用程序应该在syste.web节的httpModules和httpHandlers中定义模块和处理程序。在将应用程序从经典模式迁移到集成模式时,可以保留经典模式下的自定义模块和处理程序注册,也可以将这些注册移除。如果不移除经典模式下使用的 httpModules 和 httpHandlers 注册,则必须将
9、validation 元素的 validateIntegratedModeConfiguration 属性设置为 false 以避免错误。validation 元素是 system.webServer 元素的子元素。有关更多信息,请参见 ASP.NET Integration with IIS 7.0(将 ASP.NET 与 IIS 7.0 集成)中的“Disabling the migration message”(禁用迁移消息)部分。总结当改变程序池模式时,可能需要修改配置文件,详细见上面描述!学习站点 HYPERLINK /keke/archive/2011/07/12/2104174.
10、html /keke/archive/2011/07/12/2104174.html 问题- DataTable.Select使用得小心,出现查询不到数据-12值描述20110812问题描述有时候用这个方法查询能得正确的结果,但当传输的参数10时,通过myds.Tables0.Select(cate=10)就查询不到,而实际上DataTable中是存在数据的?问题解决一开始百思不得其解, 因为我认为cate在myds中是被作为int类型处理的。后来,我想到是不是当cate变成两位数时, DataSet把cate作为字符串处理?我将代码改成: querystr=cate=+Request.Que
11、ryStringcate+;问题就解决了。相关代码当前学习部分1-应用篇-示例13Demonet201107-EXT.NetVs2008Model_CatchInfoMyApplicationUIAccordionBasic.aspx.cs private DataRow GetSubNode(string noteID) DataRow drs = InitDataTable().Select(ParentID= + noteID+); return drs; 学习站点 HYPERLINK /dudu/archive/2004/07/12/23537.html /dudu/archive/2
12、004/07/12/23537.html 提高- .NET下的内存分配机制-02值描述内存分配原则在.NET Framework中,内存中的资源(即所有二进制信息的集合)分为托管资源和非托管资源.托管资源必须接受.NET Framework的CLR(通用语言运行时)的管理(诸如内存类型安全性检查),而非托管资源则不必接受.NET Framework的CLR管理. (了解更多区别请参阅.NET Framework或C#的高级编程资料) 托管资源在.NET Framework中又分别存放在两种地方: 堆栈和托管堆(以下简称堆)。这里只讨论托管资源的内存分配。内存分配机制线程栈|GC堆|LOH对于值
13、类型的实例,CLR在运行时有两种分配方式:(1) 如果该值类型的实例作为类型中的方法(Method)中的局部变量,则该实例被创建在线程栈上;(2) 如果该值类型的实例作为类型的成员,则该实例作为引用类型(引用类型在GC堆或者LOH上创建)的实例的一部分,被创建在GC堆上。对于引用类型的实例,CLR在运行时也有两种分配方式:(1) 如果该引用类型的实例的Size=85000byte,则该实例被创建在LOH(Large Object Heap)上(LOH不会被压缩)。要注意的是,对于引用对象,他包括了引用和对象实例两部分,实例需要通过对其存储位置的引用来访问,对于private Object o
14、= new Object(),其实可以分解为两句话: private Object o;o = new Object(); 其中private Object o是定义了对象的引用,也就是记录对象实例的指针,而不是对象本身。这个引用存储于堆栈中,占用4个字节;当没有使用o = new Object()时,引用本身的值为null,也就是不指向任何有效位置; 当o = new Object()后,才真正根据对象的大小,在托管堆中分配空间给对象实例,然后将实例的指针位置赋值给前面的引用。这才完成一个对象的实例化。嵌套结构值类型如果嵌套在引用类型时,也就是值类型在内联的结构中时,其内存分配是什么样子呢?
15、 其实很简单,例如类的私有字段如果为值类型,那它作为引用类型实例的一部分,也分配在托管堆上。引用类型嵌套在值类型时,内存的分配情况为:该引用类型将作为值类型的成员变量,堆栈上将保存该成员的引用,而成员的实际数据还是保存在托管堆中。一个简单的讨论AType myType = new AType10;/见下面示例【试问】如果AType是值类型,则分配了多少内存;而如果AType是引用类型时,又分配了多少内存?【分析】根据CRL的内存机制,我们知道如果ATpye为Int32类型,则表示其元素是值类型,而数组本身为引用类型,myType将保存指向托管堆中的一块大小为410byte的内存地址,并且将所有
16、的元素赋值为0;而如果AType为自定义的引用类型,则会只做一次内存分配,在线程的堆栈创建了一个指向托管堆的引用,而所有的元素被设置为null值,表示为空。分配的内存大小计算sizeof(type)sizeof 运算符仅适用于值类型,而不适用于引用类型。并仅可用于 unsafe 模式。分配具体过程(1)计算所需空间大小(2)写屏障:这一步只针对托管堆,因为托管堆涉及到后面的垃圾回收,这一步是必须的。(3)开始实际分配:堆栈的内存地址是由高位到低位向下填充。示例描述现在有MyStruct和MyClass分别代表一个结构体和一个类,如下:在上述的过程中,我们分别定义了值类型变量myStruct和引
17、用类型变量myClass,并使用new操作符完成内存分配和初始化操作。而我们在此强调的是myStruct和myClass两个变量在内存分配方面的区别,还是以一个简明的图来展示一下:我们知道,每个变量或者程序都有其堆栈,不同的变量不能共有同一个堆栈地址,因此myStruct和myStruct2在堆栈中一定占用了不同的堆栈地址,尽管经过了变量的传递,实际的内存还是分配在不同的地址上,如果我们再对myStruct2变量改变时,显然不会影响到myStruct的数据。从图中我们还可以显而易见的看出,myStruct在堆栈中包含其实例数据,而myClass在堆栈中只是保存了其实例数据的引用地址,实际的数据
18、保存在托管堆中。因此,就有可能不同的变量保存了同一地址的数据引用,当数据从一个引用类型变量传递到另一个相同类型的引用类型变量时,传递的是其引用地址而不是实际的数据,因此一个变量的改变会影响另一个变量的值。从上面的分析就可以明白的知道这样一个简单的道理:值类型和引用类型在内存中的分配区别是决定其应用不同的根本原因,由此我们就可以很容易的解释为什么参数传递时,按值传递不会改变形参值,而按址传递会改变行参的值,道理正在于此。 更详细的分析,强烈推荐 HYPERLINK /happyhippy/archive/2007/04/12/710929.html 类型实例的创建位置、托管对象在托管堆上的结构。
19、学习站点 HYPERLINK /lerit/article/details/4441239 /lerit/article/details/4441239 提高- .NET中类型的转换-02值描述类型转换分为隐式转换和显式转换,他们的转换方式都对应了变换、投射、和装箱/拆箱三种类型。当直接将一种类型赋值给另外一个类型,就是隐式转换。系统会在编译时候进行判断,能否进行隐式转换,如果提示出错,就说明无法隐式转换,如果没有提示,这个隐式转换是成立的,并且不会出现错误;接下来就是利用上面三种方式进行转换了。当采取显式转换时,利用诸如(int)a,convert和parse方法吧。这时候有四种情况,一种是
20、编译就出错,因为根本无法强制转换,另一种是可以编译通过,但是运行时候出错,还一种,就是运行也成功了,但是由于截断等原因,结果是不正确的了,最后一种当然就是转换成功喽。其中对于(int)a,编译时候会确保是存在显示转换关系的,如果不存在,就会提示无法转换。如果可以转换,那不会出错,但是结果不一定对,因为可能截断了部分内容;对于Int32.Parse()表示将数字的字符串转换为32 位有符号整数,属于内容转换。只要是字符串,都可以转换过去,至于是否正确,运行过程中会提示是否出错,包括空字符串错,格式不对,或者是溢出。基础.NET中,所有类型都继承自System.Object类型,因此可以很容易的获
21、得对象的准确类型,方法是:GetType()方法。转换机制C#中的类型转换机制有两种分类方法: 一种是根据转换方式的不同进行划分,可以分为显式 (Explicit) 转换和隐式 (Implicit) 转换两种; 另外一种是根据源类型和目标类型之间的关系进行划分,可以分为变换 (Conversion)、投射 (Cast)和装箱/拆箱 (Boxing/Unboxing)。隐式转换就是系统默认的、不需要加以特别声明也不用特殊的方法就可以进行的转换。在隐式转换过程中,编译器无需对转换进行详细检查就能够安全地执行转换。 -隐式数值转换实际上就是从低精度的数值类型到高精度的数值类型的转换。-隐式枚举转换允
22、许把十进制整数0转换成任何枚举类型,对应其它的整数则不存在这种隐式转换。还是让我们用例子来说明。-隐式引用转换是指一类引用类型之间的转换,这种转换总是可以成功,因此不需要在运行时进行任何检查。-装箱转换允许将“值类型”隐式转换为“引用类型”。显式转换又叫强制类型转换。与隐式转换正好相反,显式转换需要用户明确地指定转换的类型。-它并不是总能成功,而且常常可能引起信息丢失。IS和AS操作符为了避免在进行强制类型转换时由于目标类型无效,而导致运行时抛出InvalidCastException异常,C#提供了IS与AS操作符进行类型判断与“安全”的强制类型转换。is 运算符用于检查对象的类型是否与给定
23、类型兼容(对象是该类型,或是派生于该类型)。is的规则如下: 检查对象类型的兼容性,并返回结果,true或者false; 不会抛出异常; 如果对象为null,则返回值永远为false。代码如下:if (studentObj is Student)as 运算符用于执行引用类型的显式类型转换。 如果要转换的类型与指定类型兼容,转换就会成功;如果类型不兼容,则返回null。 表达式as 类型as 运算符类似于类型转换,所不同的是,当转换失败时,as 运算符将返回null,而不是引发异常。as的规则如下: 检查对象类型的兼容性,并返回结果,如果不兼容就返回null; 不会抛出异常; 如果结果判断为空,
24、则强制执行类型转换将抛出NullReferenceException异常。代码如下:Student s1 = studentObj as Student; /如果CLR检测studentProgram引用对象类型不兼容目标类型,即不能进行强制类型转换,则返回一个null,永远不会抛出异常【is与as比较】由代码可以看出,CLR实际会检查两次对象的类型,IS操作符首先检测变量的引用是否兼容于指定的类型,如果返回TRUE,则CLR在进行强制类型转换行进行第二次类型的检测,即studentObj对象是否引用一个Student类型。由于强制类型转换CLR必须首先判断变更引用对象的实际类型,然后CLR必
25、须去遍历继承层次结构,用变量引用类型的每个基类型去核对目标类型。这肯定会对性能造成一定的影响。好在C#提供了AS操作符来弥补这一缺陷。常用的三种显示转换方法(typename)valuename,是通用方法;Convert类提供了灵活的类型转换封装;Parse方法,适用于向数字类型的转换。【三种方法有什么区别】例如,(int),Int32.Parse() 和 Convert.toInt32() 。那么三种方法有什么区别呢?(int)表示使用显式强制转换,是一种类型转换。当我们从 int 类型到 long、float、double 或decimal 类型,可以使用隐式转换,但是当我们从 long
26、 类型到 int 类型转换就需要使用显式强制转换,否则会产生编译错误。也就是说,这个转换方式,编译时会确保是存在显示转换关系的,如果不存在,就会提示无法转换。在对long 类型或是浮点型到int 类型的显式强制转换中使用,但是如果被转换的数值大于 Int32.MaxValue 或小于 Int32.MinValue,那么则会得到一个错误的结果。Int32.Parse()表示将数字的字符串转换为32 位有符号整数,属于内容转换。只要是字符串,都可以转换过去,至于是否正确,运行过程中会提示是否出错。在符合数字格式的 string 到 int 类型转换过程中使用,并可以对错误的 string 数字格式
27、的抛出相应的异常。Convert.ToInt32() 则可以将多种类型的值转换为 int 类型,也可以对错误的数值抛出相应的异常,运行过程中会提示是否出错。投射当源类型和目标类型具有直接或间接的继承关系时,发生的类型转换属于投射。如果将子类型的一个对象转换成祖先类型,则称向上投射 (Upcast-多态)。反之,将祖先类型的对象转换为子孙类型,则称向下投射 (Downcast)。 向上投射可以使用隐式转换,但向下投射必须使用显示转换。这是因为当发生继承关系时,子类将具有父类所有的成员(尽管父类中的private成员在子类中无法访问,但子类确实拥有这些成员),因此子类对象向父类转换时可以确保不会丢
28、失成员,而如果父类对象向子类转换,不一定保证对象具备子类特有的成员。需要注意的是,如果两个类型位于同一继承树中,但没有直接或间接继承关系(通常称这样的类型为“兄弟类型”或“邻居类型”,如上图中的CB和CD、CC和CD),是不允许发生任何转换的,除非重载了类型转换运算符。学习站点 HYPERLINK /lerit/article/details/4441971 /lerit/article/details/4441971 问题:WebService-服务器未能识别 HTTP 头 SOAPAction 的值-20值描述问题描述Web Service + ASP.NET 应用程序部署到服务器默认目录
29、中,在IE中用http:/发生“服务器未能识别 HTTP 标头 SOAPAction 的值”错误。解决方法给WebService类添加属性SoapDocumentService(RoutingStyle=SoapServiceRoutingStyle.RequestElement)学习站点 HYPERLINK http:/52347./blog/505550 http:/52347./blog/505550 cs0016:未能写入输出文件 c:WINDOWSMicrosoft.NET值描述20110630问题描述编译错误 说明: 在编译向该请求提供服务所需资源的过程中出现错误。请检查下列特定错
30、误详细信息并适当地修改源代码。 编译器错误消息: CS0016: 未能写入输出文件“c:WindowsMicrosoft.NETFrameworkv2.0.50727Temporary ASP.NET Filescms_allerr_testf756608224a9b898App_global.asax.vqizlnw_.dll”-“拒绝访问。 ”源错误:没有相关的源行原因分析应用程序运行时产生的临时文件需要存放到c:windowstemp 文件夹下 而运行基于microsoft .net framework 框架下的应用程序 需要对temp 具有读写的权限 ,所以程序运行产生的临时文件不能存
31、储或读取,或者路径不存在的情况下都会产生编译错误。解决方法1、设置c:windowstemp 目录访问权限 temp- 属性-安全- 添加network service -并赋予其权限为 读 和 写- 确定(注意:操作系统为windows server2003 framework 版本在 1.1及以上)2、设置发布网站的程序目录中bin文件夹的权限 同样添加 network service 并设置权限为读取、 运行 3、执行以上两步操作设置后问题解决。学习站点问题:虚拟目录继承根Web.Config的问题解决-28值描述很多人有时都会为虚拟目录中的web.config继承了主目录中的web.c
32、onfig而苦恼,大部分主要是由于根目录中的web.config添加了httphandler、 httpmodule 引起的。其实这个问题解决起来很简单,只将 httphandler httpmodule的声明添加到location中即可。代码 学习站点 HYPERLINK /dongqi/archive/2010/11/01/1866001.html /dongqi/archive/2010/11/01/1866001.html C#获得客户端的IP,主机名 获取当前时间的方法值描述20110531常用方法客户端ip:Request.ServerVariables.Get(Remote_Ad
33、dr).ToString();客户端主机名:Request.ServerVariables.Get(Remote_Host).ToString();客户端浏览器IE:Request.Browser.Browser;客户端浏览器 版本号:Request.Browser.MajorVersion;客户端操作系统:Request.Browser.Platform;服务器ip:Request.ServerVariables.Get(Local_Addr).ToString();服务器名:Request.ServerVariables.Get(Server_Name).ToString();如果你想进一
34、步了解ServerVariables,可以用foreach(String o in Request.ServerVariables) Response.Write(o+=+Request.ServerVariableso+);代理服务器对于了解代理服务器情况的人,我们会知道,如果用户使用了代理服务器,上述代码获得的是代理服务器的IP地址;如果用户使用了多个代理服务器,则是到达服务器的最后一个代理服务器的IP地址。REMOTE_ADDR访问客户端的 IP 地址。 此项信息用户不可以修改。如果真的给改了的话,你也和服务器连接不了了,服务器就是按照这个来与客户端建立连接并进行通讯的。实际我测试修改这
35、个 ServerVariables , 一点效果都没有。仍然获得是实际的值。另: Request.UserHostAddress 和 Request.ServerVariablesREMOTE_ADDR 实际是同一个值。相关问题如何绕过代理服务器获得用户真实的IP地址呢?对于这三个值:REMOTE_ADDR、HTTP_VIA、HTTP_X_FORWARDED_FOR 来说,可以分以下五种情况:一、没有使用代理服务器的情况: REMOTE_ADDR = 您的 IP HTTP_VIA = 没数值或不显示 HTTP_X_FORWARDED_FOR = 没数值或不显示二、使用透明代理服务器的情况:Tr
36、ansparent Proxies REMOTE_ADDR = 最后一个代理服务器 IP HTTP_VIA = 代理服务器 IP HTTP_X_FORWARDED_FOR = 您的真实 IP ,经过多个代理服务器时,这个值类似如下:63, 63, 15。 这类代理服务器还是将您的信息转发给您的访问对象,无法达到隐藏真实身份的目的。三、使用普通匿名代理服务器的情况:Anonymous Proxies REMOTE_ADDR = 最后一个代理服务器 IP HTTP_VIA = 代理服务器 IP HTTP_X_FORWARDED_FOR = 代理服务器 IP ,经过多个代理服务器时,这个值类似如下:
37、63, 63, 15。 隐藏了您的真实IP,但是向访问对象透露了您是使用代理服务器访问他们的。四、使用欺骗性代理服务器的情况:Distorting Proxies REMOTE_ADDR = 代理服务器 IP HTTP_VIA = 代理服务器 IP HTTP_X_FORWARDED_FOR = 随机的 IP ,经过多个代理服务器时,这个值类似如下:63, 63, 15。告诉了访问对象您使用了代理服务器,但编造了一个虚假的随机IP代替您的真实IP欺骗它。五、使用高匿名代理服务器的情况:High Anonymity Proxies (Elite proxies) REMOTE_ADDR = 代理服
38、务器 IP HTTP_VIA = 没数值或不显示 HTTP_X_FORWARDED_FOR = 没数值或不显示 ,经过多个代理服务器时,这个值类似如下:63, 63, 15。小结1、REMOTE_ADDR 不可被修改,但是可能会获得代理服务器的IP,而不是实际客户端的IP。2、通过 HTTP_VIA、HTTP_X_FORWARDED_FOR 我们可以获得代理服务器所代理的信息,但是这依靠代理服务器的支持。另外,这两个值可以被修改。我们通过它获得的信息可能是不真实的。另,HTTP_X_FORWARDED_FOR 的信息可能是一个集合,不含 REMOTE_ADDR 中的代理服务器IP。没有一个完美
39、的解决获得客户端IP地址的方法,我们只能在上面2个信息中取舍。学习站点 HYPERLINK /blog/static/30328911201042343718154/ /blog/static/30328911201042343718154/ 关于Session事件的理解值描述20110531SessionidSessionID是会不停变换的,也就是说一个clientPage并非Sessionid都是保持一致的,除非:1)至少有一个request成功完整地执行 2)至少存储一些data在session state中。可以通过session变量或者加上 session_onstart来实现。se
40、ssion_onend在InProc模式中支持,也就是说,只在session data在 worker process中时支持。Session End事件仅在进程内会话模式情况下,请求结束时,Session.Abandon()被调用时会被激发,或者会话过期时被激发。浏览器关闭并不会激发Session END事件。相关问题关了浏览器再开,怎么session还在?关了浏览器session当然仍然存在,因为session是储存在服务器端的,而服务器是不可能知道你有没有关掉浏览器。 服务器只是简单的保持session接受用户请求,只有当session一段时间没有被请求(比如30分钟以后),服务器才会把
41、session作废。客户端与服务器交互session的时候,客户端会生成一个cookie,这个cookie包含了当前session的ID号。你再次打开浏览器的时候,浏览器会发送这个ID号,如果此时session还没失效的话,服务器就能通过ID号识别出你,从而继续交互session。一般来讲如果服务器关闭,那么所有的session都会消失。 还有,session的setAttribute根本不是用来设置session的过期时间的。设置过期时间是在web.xml里面,或者session的setMaxInactiveInterval方法。学习站点/lovelydinasour126/blog/sta
42、tic/131730730200910353457186/null object模式-详见设计模式学习-提高篇值描述20110513这个模式的出现还是了为了解决代码重复的坏味道。场景在项目中很经常见到类似下面这样的代码:显然,代码重复是坏味道,怎么消除这个坏味道呢?答案就是使用NullObject替代之,Null Object继承原对象。如下: 那么,原来的代码可以改写为:去掉了坏味道,但还不完善:注意技巧,我们可以在NullObject覆写getCost,提供缺省值:这样上面的判断语句也可以去掉了!plan.setCost(prj.getCost();在需要返回NullObject的地方,你
43、应该创建一个null object以替代一般的对象,我们可以建立一个工厂方法:优点Null Object模式带来的好处:减少了检查对象是否为null的代码重复,提高了代码的可读性,通常这些Null Object也可以为单元测试带来简便。学习站点/killme2008/archive/2007/07/31/133628.htmlC# Lock()语句-13值描述20110513MSDNlock 关键字将语句块标记为临界区,方法是获取给定对象的互斥锁,执行语句,然后释放该锁。lock 确保当一个线程位于代码的临界区时,另一个线程不进入临界区。如果其他线程试图进入锁定的代码,则它将一直等待(即被阻止
44、),直到该对象被释放。通常,应避免锁定 public 类型,否则实例将超出代码的控制范围。最佳做法是定义 private 对象来锁定, 或 private static 对象变量来保护所有实例所共有的数据。单例模式相关问题【问题】问lock那里的object实例可以直接用instance替代吗?new一个object是否多余?【解答】程序运行到lock的时候,抛出ArgumentNullException异常,“值不能为null”。【分析】见msdn中的定义“lock 确保当一个线程位于代码的临界区时,另一个线程不进入临界区。如果其他线程试图进入锁定的代码,则它将一直等待(即被阻止),直到该对
45、象被释放”,注意标红部分,可以确定是不可以的,因为当对象未实例化时是null,而null只是一个空引用。学习站点/jeffwongishandsome/archive/2010/09/17/1829599.html认识全面的null-13值描述20110513 从什么是null开始?用于标识变量引用的一种状态,这种状态表示没有引用任何对象实例,也就是表示“什么都没有”,既不是Object实例,也不是User实例,而是一个空引用而已。在.NET中,null表示一个对象引用是无效的。作为引用类型变量的默认值,null是针对指针(引用)而言的,它是引用类型变量的专属概念,表示一个引用类型变量声明但未
46、初始化的状态。在.NET中,对null有如下的基本规则和应用:null为引用类型变量的默认值,为引用类型的概念范畴。null不等同于0,string.Empty。引用is或as模式对类型进行判断或转换时,需要做进一步的null判断。 判断一个变量是否为null,可以应用=或!=操作符来完成。对任何值为nul的l变量操作,都会抛出NullReferenceException异常。Nullable(可空类型)以下代码在本质上是完全等效的:int? i = null;Nullable i = null;可空类型的意义在于,通过Nullable类型,.NET为值类型添加“可空性”,例如Nullable
47、的值就包括了true、false和null,而Nullable则表示值即可以为整形也可以为null。同时,可空类型实现了统一的方式来处理值类型和引用类型的“空”值问题,例如值类型也可以享有在运行时以NullReferenceException异常来处理。在本质上Nullable可以看着是预定义的struct类型。对于可空类型,同样需要必要的小结:可空类型表示值为null的值类型。不允许使用嵌套的可空类型,例如NullableNullable 。Nullable和T?是等效的。对可空类型执行GetType方法,将返回类型T,而不是Nullable。c#允许在可空类型上执行转换和转型,例如: in
48、t? a = 100;Int32 b = (Int32)a;a = null;同时为了更好的将可空类型于原有的类型系统进行兼容,CLR提供了对可空类型装箱和拆箱的支持。?运算符?运算符,又称为null-coalescing operator,如果左侧操作数为null,则返回右侧操作数的值, 如果不为null则返回左侧操作数的值。它既可以应用于可空类型,有可以应用于引用类型。Nulll Object模式解决什么问题? 简单来说,null object模式就是为对象提供一个指定的类型,来代替对象为空的情况。说白了就是解决对象为空的情况,提供对象“什么也不做”的行为,这种方式看似无聊,但却是很聪明的
49、解决之道。举例来说,一个User类型对象user需要在系统中进行操作,那么典型的操作方式是:if (user != null)manager.SendMessage(user);这种类似的操作,会遍布于你的系统代码,无数的if判断让优雅远离了你的代码,如果大意忘记null判断,那么只有无情的异常伺候了。于是,Null object模式就应运而生了,对User类实现相同功能的NullUser类型,就可以有效的避免繁琐的if和不必要的失误:二者的差别体现在哪儿呢?其实主要的思路就是将null value转换为null object,把对user = null这样的判断,转换为user.IsNull
50、虽然只有一字之差,但是本质上是完全两回事儿。通过null object模式,可以确保返回有效的对象,而不是没有任何意义的null值。同时,“在执行方法时返回null object而不是null值,可以避免NullReferenceExecption异常的发生。”。null object模式的小结有效解决对象为空的情况,为值为null提供可靠保证。保证能够返回有效的默认值,例如在一个IList userList中,能够保证任何情况下都有有效值返回,可以保证对userList操作的有效性。 提供统一判定的IsNull属性。可以通过实现INullable接口,也可以通过Extension Metho
51、d实现IsNull判定方法。null object要保持原object的所有成员的不变性,所以我们常常将其实现为Sigleton模式。Scott Doman说“在执行方法时返回null object而不是null值,可以避免NullReferenceExecption异常的发生”,这完全是对的。区别object obj和object obj = null有实际的区别吗?答案是:有。主要体现在编译器的检查上。默认情况下,创建一个引用类型变量时,CLR即将其初始化为null,表示不指向任何有效实例,所以本质上二者表示了相同的意义,但是有有所区别:学习站点/anytao/archive/2008/0
52、7/31/must_net_21.htmlIEnumerator 和 IEnumberator 理解-12值描述IEnumerable 只是表明某个对象能够被枚举,真正的工作是由IEnumerator的Current、 MoveNext、Reset完成的,为什么要有2个不同的接口来作枚举呢?主要是考虑到被枚举的对象会有多个独立的客户端调用。IEnumerable在现实应用中,对于集合以及枚举这些集合的需求非常普遍, 因此在.NET中集合所依赖的接口被设计为公共的。想要实现对象的枚举就必须继承IEnumerable接口。public interface IEnumerable public IE
53、numerator GetEnumerator();它只有一个成员:GetEnumerator方法。该方法返回一个世纪的枚举器(enumerator)对象。IEnumrator要定义一个枚举器就要必须实现IEnumrator接口:public interface IEnumerator public Boolean MoveNext(); public Object Current get; public void Reset();也就是说如果我们希望一个类型支持枚举特性,那么我们就必须还要额外定义一个辅助类型来实现IEnumerator的所有方法。这个辅助类型通常被定义为一个Nested c
54、lass声明在主类内部。这样在实现的时候我们发现,在app调用GetEnumerator()方法时,我们需要构造一个辅助类型的实例作为返回值。学习总结1、一个Collection要支持foreach方式的遍历,必须实现IEnumerable接口(亦即,必须以某种方式返回IEnumerator object)。 2、IEnumerator object具体实现了iterator(通过MoveNext(),Reset(),Current)。3、从这两个接口的用词选择上,也可以看出其不同:IEnumerable是一个声明式的接口,声明实现该接口的class是“可枚举(enumerable)”的,但并
55、没有说明如何实现枚举器(iterator);IEnumerator是一个实现式的接口,IEnumerator object就是一个iterator。4、IEnumerable和IEnumerator通过IEnumerable的GetEnumerator()方法建立了连接,client可以通过IEnumerable的GetEnumerator()得到IEnumerator object,在这个意义上,将GetEnumerator()看作IEnumerator object的factory method也未尝不可。相关问题【问题1】有些地方常常把System.Collections.IEnumer
56、ator解释为 类,而把System.Collections.IEnumerable解释为接口?IEnumerator通常是被你看不到的类实现的: System.Collectons.IEnumerator myEnumerator=myList.GetEnumerator(); 然后你可以通过myEnumerator.GetType()获取这个对象的类型,是一个你看不到的类。 对于ArrayList,这个类一般是: ArrayList.ArrayListEnumeratorSimple【问题2】为什么不写做ArrayList.ArrayListEnumeratorSimple myEnume
57、rator=myList.GetEnumerator();? 这是接口的用途之一,避免出现很多无用的类。ArrayListEnumeratorSimple除了实现IEnumerator接口就没有任何别的用处了,让它冒出来只会让人迷惑。对于我们的程序而言,只关心IEnumerator被实现,而并不关心他到底是被什么类实现的。 其他的用处还有很明显的一点:ArrayList.GetEnumerator可以根据实际情况抛出不同实现的类出来。不一定要是ArrayList.ArrayListEnumeratorSimple。相关图片学习站点/a/1065498/IList 接口值描述表示可按照索引单独访
58、问的对象的非泛型集合。语法ComVisibleAttribute(true)public interface IList : ICollection, IEnumerableCopyTo方法从特定的 Array 索引处开始,将 ICollection 的元素复制到一个 Array 中。 (继承自 ICollection。)GetEnumerator方法返回一个循环访问集合的枚举器。 (继承自 IEnumerable。)备注IList 泛型接口是 Icollection 接口的子代,并且是所有非泛型列表的基接口。 Ilist 实现有三种类别:只读、固定大小、可变大小。 无法修改只读 Ilist。
59、 固定大小的 Ilist 不允许添加或移除元素,但允许修改现有元素。 可变大小的 Ilist 允许添加、移除和修改元素。与list区别IList 是个接口,定义了一些操作方法这些方法要你自己去实现,当你只想使用接口的方法时,这种方式比较好.他不获取实现这个接口的类的其他方法和字段,有效的节省空间List 是个类型 已经实现了IList 定义的那些方法。List List11 =new List ();是想创建一个List,而且需要使用到List的功能,进行相关操作。而IList IList11 =new List ();只是想创建一个基于接口IList的对象的实例,只是这个接口是由List实现
60、的。所以它只是希望使用到IList接口规定的功能而已。接口使用接口而非具体类型,是OOP中比较普遍的原则,其核心价值在于解除对特定类的依赖,通过接口将对象的行为与具体实现隔离开来.接口实现松耦合,有利于系统的维护与重构.视图状态:控件生命周期中的装载和保存视图阶段值描述20110503视图状态是一项非常重要的技术,他能使得页面和页面中的控件在从服务器到客户端,再从客户端返回的往返过程中保持状态信息。这样就能在Web这种无状态的环境之上创建一个有状态并持续执行的页面效果。从下图可以看到LoadViewState和SaveViewState分别在控件生命周期的开始(初始化Init后)和最后(呈现R
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 有关数学家的演讲稿
- 基于物联网的智慧温室大棚光热系统设计
- 谷物糊粉层分离富集技术与应用研究进展
- 全国数字孪生水利建设典型案例
- 药店GSP自查报告范文
- 单位公务车辆管理工作总结
- 临床决策支持系统方案
- 智能建筑施工管理方案
- 苗木资源共享与合作实施方案
- 电商平台大数据优化方案
- 0-高压蒸汽管线焊缝返修施工方案
- 一年级上册道德与法治课件-10吃饭有讲究-人教(新版) (2)(共24张PPT)
- GB/T 16571-1996文物系统博物馆安全防范工程设计规范
- GB/T 11618.1-2008铜管接头第1部分:钎焊式管件
- 骨盆-教学讲解课件
- 做好新形势下群众工作培训课件
- 赛课一等奖《林黛玉进贾府》课件3
- 《世间最美的坟墓》PPT
- 中国古代儒家思想的发展演变教学设计
- 慢性阻塞性肺疾病(-COPD)的药物治疗及合理用药课件
- 广电全媒体运营知识考试题库(含答案)
评论
0/150
提交评论