Hello World
Spiga

分类:.Net框架

你的字典里有多少元素?

2014-07-12 23:42 by 老赵, 25095 visits
摘要:“字典”或者说“哈希表”大家都会用,这真是一个好东西,只要创建了之后就可以不断的丢东西进去,添加删除都是O(1)操作,那叫一个快字了得。不过这里我要再次引用Alan Perlis的名言:“Lisp programmers know the value of everything but the cost of nothing.”,目的是想提醒做事“不要忘记背后的代价”。那么它的代价是什么呢?这里的代价主要是其内存开销。 阅读全文

逆泛型执行器

2014-05-28 23:25 by 老赵, 9367 visits
摘要:话说微信公众账号上的第一期有奖征答活动发布至今已有两周时间,不过参与人数寥寥,是太难,还是奖品不够吸引人?大家要多参与,我们才能长期互动嘛。现在我就对第一期的题目“逆泛型执行器”进行简单讲解吧,其实这题很简单,以后类似难度的题目可能会放在“快速问答”环节中。话说第一期的快速问答还在进行之中,大家加油。 阅读全文

.NET程序性能的基本要领

2014-05-14 22:18 by 老赵, 20877 visits
摘要:说起Roslyn大家肯定都已经有所耳闻了,这是下一代C#和VB.NET的编译器实现。Roslyn使用纯托管代码开发,但性能超过之前使用C++编写的原生实现。Bill Chiles是Roslyn的PM(程序经理,Program Manager),他最近写了一篇文章叫做《Essential Performance Facts and .NET Framework Tips》,其中总结了几条经验。 阅读全文

防止装箱落实到底,只做一半也是失败

2013-04-10 22:21 by 老赵, 10824 visits
摘要:.NET提供struct类型,正确使用可以减少对象数量,从而降低GC压力,提高性能。不过有时候我会发现,某些同学有这方面的意识,但是有时候一疏忽一偷懒,就没有得到相应的效果了。这里举一个真实的例子:假设我们要将一对int作为字典的键,用于映射到某些数据,那么你会怎么做?当然我们可以直接使用Tuple<int, int>,但这样就可能产生大量的对象。于是我们打算使用自定义的值类型,但简单这么做其实并不一定能满足我们的要求。 阅读全文

如何在不装箱的前提下调用“显式”实现的接口方法?(答案)

2013-04-07 13:51 by 老赵, 4152 visits
摘要:其实已经有不少同学抓住了关键,那就是使用泛型,不过有些同学提出Dispose<T>(T obj) where T : IDisposable这样的做法。我们没有进行类型转化,只是让运行时可以“认识到”类型T实现了IDisposable接口,这自然可以在不装箱的情况下调用其成员。可惜的是,这种做法的“意识”到位了,却是错误的,原因在于忽视了值类型传参的特点:复制所有内容。换句话说,这个辅助方法内部所使用的obj其实是一个副本,而不是原来的参数对象。假如被调用的成员会修改自身状态——尽管这对于值类型来说是一种极差的设计——这便会产生问题,所以正确的方法应该使用ref关键字来修饰参数。 阅读全文

如何在不装箱的前提下调用“显式实现”的接口方法?

2013-03-24 21:45 by 老赵, 3405 visits
摘要:上篇文章谈了针对一个struct对象使用using语句的时候是否会装箱的问题,结论是“不会”。尽管using语句是针对IDisposable接口的,但我们在调用的时候其实已经明确了目标方法,因此根本不需要装箱(或查找虚函数表)了。后来有同学在微博上提出,这点在《CLR via C#》这本书里提到过,于是我去翻了翻,表示这跟前一篇谈的内容其实并没有太多联系。不过这也引出了一个问题,假如一个struct类型显式实现了一个接口,您有什么办法在C#里调用这个接口方法呢?当然,调用时不能在堆上产生任何对象。 阅读全文

针对struct对象使用using关键字是否会引起装箱?

2013-03-22 00:06 by 老赵, 4583 visits
摘要:说起来这是个很简单的问题,我以前肯定可以给出确切地答复,但是前几天想到这点的时候突然楞住了。把这个问题发到微博上去之后,很多人说是“会”,但要么是猜的,或是给出的原因明显不靠谱。最后我只能自己简单研究一下了,最后得到的结果是“不会”装箱。请注意,这个问题是指,对于一个实现了IDisposable接口的值类型对象使用using语句,而不是将它直接复制给一个IDisposable引用——后者显然是会装箱的,会对性能产生一定负面影响。 阅读全文

串与绳(1):.NET与Java里的String类型

2013-03-12 23:29 by 老赵, 8908 visits
摘要:话说“字符串”是我们平时最常用的数据类型之一,它表示一个字符序列。在大部分的语言中,字符串还是一个不可变(Immutable)的数据类型。“不可变”意味着要改变则只能生成新的字符串,无论是连接两个字符串,获取或是替换字符串的一部分,这对于内存和CPU都是不可避免的开销。在一般情况下,只要使用合理这些开销都不会构成大问题。不过对于某些类型的应用,例如我前段时间在工作中涉及到的编辑器(IDE那种),就会带来较多麻烦,于是便用到了一个名为Rope的数据结构。Rope其实是一种很简单,很符合直觉的树状数据结构,也常用于表达一个字符序列,不过更适合需要大量修改的场景。不过,我们还是先来回顾一下.NET与Java中的String类型吧。 阅读全文

真是O(1)吗?想清楚了没?

2013-01-18 11:21 by 老赵, 14456 visits
摘要:话说写程序的时候我们会用到各种数据结构,但十有八九不会由我们自己从头写起,都会直接拿来用。于是很多人就会记住,譬如HashMap或Dictionary的存取是O(1)的操作,二分查找什么的则是O(log(N))。不过,我们在实践中直接把这些类拿来用的时候,最好也留个心眼,知道这些类内部到底做了些什么,为什么它们能够达到O(1)之类的时间复杂度。我们在了解“理论”的同时也需要注意实践上的细节,例如,其实在实践中O(log(N))其实也是个不比O(1)大多少的时间复杂度,此时可能也需要考虑下“常数”会对性能造成多大影响。 阅读全文

一个最基本的HashedLinkedList

2013-01-07 23:52 by 老赵, 3590 visits
摘要:Tmc的初衷是补充一些常用的数据结构,例如对null作为字典键的支持,以及带有一个额外Remove方法的HashDictionary。但是,其实我创建Tmc项目的“初衷”却是HashedLinkedList。.NET BCL中已经有一个LinkedList,这是一个双向链表。说起来,我之前在面试中经常会提出一系列数据结构的基础问题,其中便包含LinkedList,我会问各个操作的时间复杂度,以及如何改进它们。例如,如何将它的Remove操作优化成O(1)的时间复杂度?最容易想到的做法便是使用一个字典来记录元素到特定LinkedListNode的映射关系。这种模式实在过于常见,所以便有了个特别的名称,叫做HashedLinkedList。 阅读全文

阅读.NET源代码那些事

2013-01-06 16:32 by 老赵, 17602 visits
摘要:谁都知道.NET(的大部分组件)是不开源的,但是我不止在一个场合不止一次地强调过,“不开源”不代表你没法看代码,不代表你没法知道里面发生了什么。这里我不是在说.NET Reflector或是ILSpy这类反编译工具,当然它们在平时开发中也起到了很大的作用,不过很多时候更直接的方式便是阅读代码本身,尤其是当你像我一样时不时要“抄”点代码的时候。由于最近我在Tmc中“大张旗鼓”地使用.NET中BCL的代码,因此也再次强调一下这部分经验。 阅读全文

NullableKey:解决Dictionary中键不能为null的问题

2012-12-29 02:26 by 老赵, 6210 visits
摘要:众所周知,.NET中Dictionary的键不能为null,否则会抛出NullReferenceException,这在某些时候会显的很麻烦。与此相对的是Java中的HashMap支持以null为键,则方便许多。尽管null的确不是个好东西,但它既然已经存在,既然给我们造成了麻烦,我们就要想办法去解决它。实现一个自己的字典类自然可行,但要精心实现一个高效的字典并不是件容易的事情,例如BCL中的Dictionary.cs就有超过2000行代码。此外另一个容易想到的方法便是实现IDictionary接口,将大部分实现委托给现成的Dictionary类来完成。不过,这相比我在这里要提出的方法还是显得太复杂了。 阅读全文

不同泛型参数区分的独立类型

2012-12-03 23:11 by 老赵, 3981 visits
摘要:相对于的Java的“类型擦除”来说,.NET中的泛型可谓是真正的泛型,这让我们可以有能力区分运行时所使用的不同的具体类型,大大增强了程序设计的性能和表现能力。谁会希望如Java一样,在找出符合条件的一万个int数值的时候,必须额外创建一万个Integer对象,导致堆上增加几百上千K的空间,还有一万个对象带来的GC压力?在运行过程中,.NET运行时会(在第一次使用时)为不同的值类型创建一份不同的代码,而让所有的引用类型共享同一份代码。不过无论执行的代码是否共享,不同具体类型参数的类型都是各自独立的,它们各有各的元数据,各有各的需方法表等等,因此它们的静态成员也是各自独立的。 阅读全文

如何生成一段Typoglycemia文本(解答)

2012-11-11 23:40 by 老赵, 2570 visits
摘要:关于“生成Tygolycemia文本”这个问题,已经有许多同学给了答案。不过,似乎大部分同学都只是以“完成”作为目标,并没有在解法的效率和内存占用上做过多考虑。其实对于这种非常简单的问题,给出一个解法并没有太大意义,而是要从中获取一些经验,否则就算反复解决这类简单的问题,得到的进步依然十分有限。事实上,这样一个高效的实现也可以十分清晰而简单,可以说并没有因为追求效率而引入任何复杂度。 阅读全文

如何生成一段Typoglycemia文本?

2012-11-05 23:39 by 老赵, 3757 visits
摘要:Typoglycemia是个新词,描述的是人们识别一段文本时的一个有趣的现象:只要每个单词的首尾字母正确,中间的字母顺序完全打乱也没有关系,照样可以正常理解。要不您来试下,如何从一段正确的文本生成一段Typoglycemia文本呢?其实这题还有后续,那就是把目标反一反:从一个前后确定中间乱序的单词,找到其原始的,正确的单词。自然,我们会得到一个长长的单词列表,十万个单词吧,并保证没有两个单词仅仅是中间几个字符的顺序不同。那么,您会如何设计一个数据结构,让我们可以快速的从一个乱序后的单词找到其正确形式呢? 阅读全文

如何让您的事件支持逆变

2012-11-04 18:56 by 老赵, 3326 visits
摘要:在.NET里定义一个事件会需要一个委托类型,一般来说我们会使用.NET里自带的EventHandler类型,但它的定义其实有稍许缺陷。例如,如果您在自己的项目中编写了这样的代码,Resharper这样的工具便会提醒您“TEventArgs可以设为逆变”。让一个委托类型支持逆变只需要加上in关键字,但如果我们还是让C#编译器帮我们生成事件,则会由于Delegate.Combine方法并不支持逆变而导致失败。我们可以构造一个MulticastDelegateManager来解决这个问题,要不您也来试试看?不过请不要仅仅给出“思路”,千万要写下代码来,否则您的思路不说也罢。 阅读全文

编写一个“绑定友好”的WPF控件

2012-05-13 23:35 by 老赵, 11910 visits
摘要:最近在搞WPF开发,这对我来说是个陌生的领域。话说回来,可能是缺少耐心的缘故,我现在学习新事物的方式主要是“看一些入门文档”,“看一些示例”,然后“猜测”其实现并摸索着使用。在很多时候这种做法问题不大,但一旦有地方猜错了,但在一段时间里似乎和实践还挺吻合的,则一旦遇到问题就会卡死。上周五我就被一个WPF绑定的问题搞得焦头烂额,虽说基本搞定,但还是想验证下是否会有更好的做法,特此记录一下,欢迎大家指正。 阅读全文

关于C#中async/await中的异常处理(下)

2012-04-12 09:26 by 老赵, 8202 visits
摘要:上一篇文章里我们讨论了某些async/await的用法中出现遗漏异常的情况,并且谈到该如何使用WhenAll辅助方法来避免这种情况。WhenAll辅助方法将会汇总一系列的任务对象,一旦其中某个出错,则会抛出“其中一个”异常。那么究竟是哪个异常?如果我们要处理所有的异常怎么办?我们这次就来详细讨论await操作在异常分派时的相关行为。 阅读全文

关于C#中async/await中的异常处理(上)

2012-04-11 09:15 by 老赵, 17210 visits
摘要:在同步编程中,一旦出现错误就会抛出异常,我们可以使用try…catch来捕捉异常,而未被捕获的异常则会不断向上传递,形成一个简单而统一的错误处理机制。不过对于异步编程来说,异常处理一直是件麻烦的事情,这也是C#中async/await或是Jscex等异步编程模型的优势之一。但是,同步的错误处理机制,并不能完全避免异步形式的错误处理方式,这需要一定实践规范来保证,至少我们需要了解async/await到底是如何捕获和分发异常的。在开发Jscex的过程中,我也在C#内部邮件邮件列表中了解了很多关于TPL和C#异步特性的问题,错误处理也是其中之一。在此记录一下吧。 阅读全文

使用Mono.Cecil辅助ASP.NET MVC使用dynamic类型Model

2011-09-06 00:21 by 老赵, 10654 visits
摘要:这也是之前在珠三角技术沙龙上的示例之一,解决的是在ASP.NET MVC使用dynamic类型Model时遇到的一个真实问题。C# 4编译器支持dynamic类型,因此在编写页面模板的时候自然就可以把它作为视图的Model类型。表现层的需求很容易改变,因此dynamic类型的Model可以减少我们反复修改强类型Model的麻烦,再配合匿名类型的使用,可谓是动静相宜,如鱼得水。不过,如果把一个匿名类型直接作为Model交给视图去使用,在默认情况下会抛出异常。我们可以用Mono.Cecil来改变这一情况。 阅读全文
1 2 3 4 5 6 7 Next >
使用Live Messenger联系我