|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
竟发现没有太大的帮助。总觉得要用起来,感觉到不了位。因为公司机器的原因,一直没有安装vs.net(也从来没有用过)。以前做asp的时候一直用DW(感觉其代码联想功能不错),可现在到了asp.net却不习惯了。.NET4.5中增加了两个新的汇合接口,IReadOnlyList和IReadOnlyDictionary。只管这些接口外表上看起来是云云稀松寻常,可是他们却揭发了与向后兼容性、互操纵性、和协变的感化等有关的相称庞大的故事。
IReadOnlyList和IReadOnlyDictionary是.NET开辟者自始至终都想失掉的接口。只读接口除供应某种对称性以外,还应打消那些甚么都不做而只抛出NotSupportedException非常的办法。因为某些随工夫流逝已不成知的缘故原由,此接口并未完成。
接上去一次时机是在.NET2.0中引进泛型。这使得微软能够减少弱范例汇合,并利用强范例变体替换它们。基类库[1]团队再次错过了这个供应只读列表(read-onlylist)的时机,正如KitGeorge所写的那样,由于关于你与Joe所议论的成绩,我们盘算供应一种缺省完成,而不是给你一个接口,以是我们供应了ReadOnlyCollectionBase基类。但是,鉴于它不是强范例的,我能了解人们不肯利用它的缘故原由。但跟着泛型的引进,我们如今同时具有了ReadOnlyCollection<T>,以是你不但取得了一律的功效,并且就是强范例的:太棒了!
ReadOnlyCollection<T>不是密封类,因而假如必要能够随便在此之上编写你本人的汇合。自从我们为此创作的这些汇合可合适一样平常需求以来,我们尚没有企图为与此不异的观点引进接口。 KrzysztofCwalina也对此主题举行了批评,不管这听起来使人惊奇与否,可是IList和IList<T>是我们所希冀的只读汇合接口。它们都具有IsReadOnly布尔型属性,当某个只读汇合完成此属性后应前往true。我们不想增加地道的只读接口的缘故原由是,我们以为它会给基类库增加太多不用要的庞大性。请注重,就庞大性而言,我们既指此新接口又指其消耗者。
我们以为API的计划者们要末是其实不体贴在运转时反省IsReadOnly属性、及其大概抛出的非常,在这类情形下利用IList接口就不错,要末他们乐意供应一个真正整齐的自界说API,在这类情形下他们应显现完成IList接口、并发布自界说的简便的只读API。关于从对象模子中公然的汇合而言,后者是种典范体例。 只管开辟曾埋怨此种情形,因为泛型所供应的新时机远宏大于这个关键,因而该成绩在.NET4之前很年夜水平上被无视了。但是,此决意也激发了一些反应,我们将在稍后会商。
跟着在.NET4中一个使人镇静的新功效被增加到运转时。当初期版本的.NET接口呈现在范例中时,那些接口是被过分限定的。比方,即便Customer承继自Person,也没法将范例为IEnumerable<Customer>的对象作为参数范例为IEnumerable<Person>的函数的参数利用。跟着协变撑持的增加,该限定才得以部分化除。
我们之以是说“部分”,是由于在某些情形下,相对IEnumerable接口而言,人们更乐意利用一个具有丰厚API的接口。并且当IList接口不撑持协变的时分,最少该有一个只读列表接口。不幸的是,.NET基类库团队再次决意不办理这个忽略。
接着,WinRT的引进和COM的逝世灰复燃改动了统统。COM互操纵性曾是开辟者在别无选择的情形下才利用的一种手艺,但现已成为.NET编程的基石。并且因为WinRT公然了IVectorView<T>和IMapView<K,V>接口,因而.NET必需与时俱进。
WinRT企图中一个很是风趣的功效是,为每一个开辟平台发布分歧但功效相似的API。正如你大概已晓得的,经由过程JavaScript开辟者的眼睛所看到的是,一切办法名都是驼峰式巨细写(camelCased[2])暗示的,而C++和.NET开辟者所看到办法则是以帕斯卡巨细写(PascalCased[3])暗示的。另外一处加倍激烈的变更是,在C++与.NET的接口之间完成主动映照。因而.NET开辟者无需处置Windows.Foundation.Collections定名空间,而是持续利用System.Collections.Generic定名空间。IVectorView<T>和IMapView<K,V>这两个接口会被运转库转化为IReadOnlyList<T>和IReadOnlyDictionary<TKey,TValue>。
值得注重的是,在C++/WinRT中的这些接口名在某定水平上是更正确的。这些接口是用来暗示针对某汇合的一些视图,可是接口其实不确保该汇合自己是不成变的。即便在那些履历丰厚的.NET开辟者中也很罕见的一种毛病是,假定ReadOnlyCollection范例的对象是某个汇合的不成变正本,实在,现实上此对象仅仅是对某举动汇合的包装(wrapper)(关于只读、解冻、且不成变汇合的具体信息,请参阅AndrewArnott的同名帖子)。
当得知只管IList<T>接口具有与IReadOnlyList<T>接口一切不异的成员、而且一切列表都可暗示为只读列表,而IList<T>却不是承继自IReadOnlyList<T>今后,有人大概会以为很风趣。ImmoLandwerth注释说,这看起来是个公道的假定,它之以是能事情是由于那些只读接口是可读写接口的地道子集。不幸的是,此假定与预期不符,由于在元数据级别上位于每一个接口上的每一个办法都有其本人的槽(这使得显式接话柄现得以事情)。 大概换言之,他们必需将只读接口作为那些可变品种的基类引进的独一时机就是退回到.NET2.0,即它们最后被构想出来的时分。一旦养虎遗患,对其能做的独一改动就是增加协变和/或逆变标志(在VB和C#中暗示为“in”和“out”)。
当被问及为何没有IReadOnlyCollection<T>接口时,Immo回覆说,我们曾思索过这个计划,可是我们以为到场一个供应唯一Count属性的范例关于基类库而言不会增添良多代价。在基类库团队中,我们以为,假如一个API从负1000点入手下手,那末即便能供应一些代价也不敷以证实可被增加。增加新API的来由也包含本钱,比方,开辟者会具有更多可供选择的观点。后来我们以为,增加这个范例将使得代码在某些场景(你只想取得计数,然后对它做一些风趣的工具)下取得更好的功能。比方,批量增加到现有汇合。但是,在这些场景下,我们勉励人们仅接纳一个IEnumerable<T>接口,并且关于具有完成了ICollection<T>接口的实例的特别情形也是云云。自从一切我们的内建汇合范例完成了此接口以后,但是在那些最多见的情形下并未没有取得任何功能收益。特地说一下,针对IEnumerable<T>的扩大办法Count()一样能够完成此功效。 这些新接口可用于.NET4.5和.NETforWindows8。
译注
[1]基类库,BaseClassLibrary,缩写为BCL。有关基类库的更多信息,请介入MSDN。
[2]camelCased,驼峰式定名法,又称小驼峰式定名法(lowercamelcase)。格局为,第一个单字以小写字母入手下手;第二个单字的首字母年夜写,比方:firstName、lastName。
[3]PascalCased,帕斯卡定名法,又称年夜驼峰式定名法(uppercamelcase)。格局为,每个单字的首字母都接纳年夜写字母,比方:FirstName、LastName、CamelCase。
检察英文原文:TheStoryofRead-OnlyCollectionInterfacesin.NET
译者高翌翔基于.NET平台举行Web使用程序计划、开辟,存眷急迅开辟和架构计划,及各类进步代码可保护性的最好理论。
那做企业软件是不是最好用J2EE? |
|