Hello World
Spiga

标签:struct

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

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

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

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

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

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

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

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

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

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