List和Dictionary想必是我们平常用到最多的C#容器了,他们使用起来都很简单,所以很多人就可能就没去深究,其实在使用过程中有很多的小技巧能让我们写的代码变得更高效也更安全。

1·合理的指定初始容量。

List和Dictionary的构造函数都有一个入参为int的构造函数:public Dictionary(int capacity);和public List(int capacity);。capacity用来指定List和Dictionary的初始容量。这步操作有什么用呢?是这样的,List和Dictionary的内部实现方式都是使用数组,因为数组的容量是固定的,所以初始化的时候就会对其申请内存,List的默认大小为4,Dictionary的默认大小为3。也就是说如果不指定初始化容量的,系统会给你默认创建。当你往容器里Add数据时,如果当前数组已满,则新创建一块两倍于当前数组长度的内存,把原有数据copy到新内存中,再继续往里添加。例如你创建一个没指定初始容量的List后,依次往里面添加了10个元素,内存是这样分配的:首先默认分配了一块长度为4个List元素的内存给List数组,当添加到第五个时,发现长度已然不足,所以分配4*2=8的内存,把原有的4个数据拷贝到新内存块中并把第五个元素添加到末尾,当添加到第九个时,同第五个的操作一样,所以最终List数组的长度为16,里面存放了10个元素,共分配了三次内存,进行了两次的内存拷贝。讲到这,大家应该就很明了了,合理的指定初始容量,可以减少内存的分配和拷贝次数,甚至还能节省内存空间。

2·给Dictionary添加元素时,建议直接用中括号的方式,而不是使用Add方法。

虽然不管是用[]还是Add方法,调用的都是Dictionary的Insert函数,但是区别在于用Add函数的话,如果已经存在同样的键对值,会直接抛出ArgumentException,这意味着后续的代码都不执行了,这可很要命,明明是一个小问题,可看上去可能是一个大Bug。而用中括号属性的方法,如果不存在会添加,如果存在则进行改写,只要key值不为null,是不会抛出异常的。

3·学会使用List的AsReadOnly函数。

如果你有写C++的经历的话,写C#会觉得蛋疼,因为它不允许入参和返回值设置为const。这意味着别人可以随意修改你的入参和返回值,这好难受啊。List有个返回只读的接口:ReadOnlyCollection<T> AsReadOnly()。首先这个类型名称就叫ReadOnly,起到了强烈的提示作用,其次这个类只有Contains、CopyTo、GetEnumerator、IndexOf几个接口,至少防止了使用者在接口层对List进行修改。

4·利用TryGetValue(TKey key, out TValue value)接口获取Dictionary中的数据。

      string GetDictionaryVal(string strkey)
{
if (!dicTest.ContainsKey(strkey))
{
return string.Empty;
} return dicTest[strkey];
}

上面这段代码其实非常正确,但是从效率的角度上看却对dictionary进行两遍的查找:ContainsKey和下标操作各一次。所以我们可以这么写:

      string GetDictionaryVal(string strkey)
{
string strVal = string.Empty;
dicTest.TryGetValue(strkey, out strVal);
return strVal;
}

TryGetValue函数的返回值为bool值,表示是否存在于Dictionary中。

5·编写返回Dictionary或者List的函数时,别返回null,如果没数据可以返回个空的Dictionary或者List,因为如果返回null,上层的代码很容易会对其做foreach时抛出异常。例如:

//纯测试

  List<uint> lstInfo = new List<uint>() { , ,  };
public List<uint> GetLstInfo(bool bSuc)
{
if (!bSuc)
{
return null;
} return lstInfo;
}

有些人会写类似于上面这样的接口,然后上层程序员经常会这样使用它:

foreach (var item in GetLstInfo(true))
    {
 
        }

如果入参为false,那么将返回null,然后foreach时程序就抛出异常了,后续代码无法执行,所以我们可以这样写:

public List<uint> GetLstInfo(bool bSuc)
{
if (!bSuc)
{
return new List<uint>();
} return lstInfo;
}

————————————————
版权声明:本文为CSDN博主「钢与铁」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_14914623/java/article/details/104422202

List和Dictionary的使用技巧总结的更多相关文章

  1. C#泛型集合之Dictionary<k, v>使用技巧

    1.要使用Dictionary集合,需要导入C#泛型命名空间 System.Collections.Generic(程序集:mscorlib) 2.描述 1).从一组键(Key)到一组值(Value) ...

  2. C#泛型集合—Dictionary<K,V>使用技巧

    转载:http://blog.csdn.net/a125138/article/details/7742022 1.要使用Dictionary集合,需要导入C#泛型命名空间 System.Collec ...

  3. 转载C#泛型集合—Dictionary<K,V>使用技巧

    1.要使用Dictionary集合,需要导入C#泛型命名空间 System.Collections.Generic(程序集:mscorlib) 2.描述 1).从一组键(Key)到一组值(Value) ...

  4. python 常用技巧 — 字典 (dictionary)

    目录: 1. python 相加字典所有的键值 (python sum all values in dictionary) 2. python 两个列表分别组成字典的键和值 (python two l ...

  5. 探究javascript对象和数组的异同,及函数变量缓存技巧

    javascript中最经典也最受非议的一句话就是:javascript中一切皆是对象.这篇重点要提到的,就是任何jser都不陌生的Object和Array. 有段时间曾经很诧异,到底两种数据类型用来 ...

  6. iOS:小技巧(不断更新)

    记录下一些不常用技巧,以防忘记,复制用. 1.获取当前的View在Window的frame: UIWindow * window=[[[UIApplication sharedApplication] ...

  7. ios开发中的小技巧

    在这里总结一些iOS开发中的小技巧,能大大方便我们的开发,持续更新. UITableView的Group样式下顶部空白处理 //分组列表头部空白处理 UIView *view = [[UIViewal ...

  8. EF查询之性能优化技巧

    上一篇:EF使用CodeFirst方式生成数据库&技巧经验 前言 EF相信大部分同学都已经经常使用了,可是你的查询高效吗? 今天我就以个人使用经验来讲讲在使用EF做查询的时候大家都容易忽略的性 ...

  9. iOS 保持界面流畅的技巧 (转载)

    这篇文章会非常详细的分析 iOS 界面构建中的各种性能问题以及对应的解决思路,同时给出一个开源的微博列表实现,通过实际的代码展示如何构建流畅的交互. Index 演示项目 屏幕显示图像的原理 卡顿产生 ...

随机推荐

  1. Linux学习日志——基本指令②

    文章目录 Linux学习日志--基本指令② 前言 touch cp (copy) mv (move) rm vim 输出重定向(> 或 >>) cat df(disk free) f ...

  2. 怎么写简历,简历才不会被丢到非洲&#127757;

    前言 只有光头才能变强. 文本已收录至我的GitHub精选文章,欢迎Star:https://github.com/ZhongFuCheng3y/3y 最近的三歪朋友圈可以看到很多的字节.腾讯的同学都 ...

  3. java中三大集合框架

    一.List集合 1.List实现的超级父类接口:Collection 存储一组不唯一(允许重复),有序的对象. 2.了解ArrayList类 A):定义的格式:ArrayList<具体类型&g ...

  4. MySQL元数据信息

    一.查看数据库清单 show databases; 二.查看数据库下表清单 方法1) show full tables from ${schema名}; 方法2) use ${数据库名}; show ...

  5. Nmap在实战中的高级用法(详解)

    @ 目录 Nmap在实战中的高级用法(详解) Nmap简单的扫描方式: 一.Nmap高级选项 1.查看本地路由与接口 2.指定网口与IP地址 3.定制探测包 二.Nmap扫描防火墙 1.SYN扫描 2 ...

  6. realm数据库报错:Changing Realm data can only be done from inside a transaction.

    在编写realm数据库相关时: 代码: List<Student> delByStudent(String priNum){ RealmResults<Student> stu ...

  7. sudo 提权漏洞(CVE-2019-14287)复现

    (该文参考网络他人资料,仅为学习,不许用于非法用途) 一.环境 1.sudo版本小于1.8.28的Linux系统 2.sudo 是Linux系统命令,让普通账号以root身份去执行某些命令,比如:安装 ...

  8. linux驱动之内核多线程(二)

    本文摘自http://www.cnblogs.com/zhuyp1015/archive/2012/06/11/2545702.html 内核多线程是在项目中使用到,自己也不熟悉,遇到一个很囧的问题, ...

  9. Jmeter 常用函数(10)- 详解 __threadNum

    如果你想查看更多 Jmeter 常用函数可以在这篇文章找找哦 https://www.cnblogs.com/poloyy/p/13291704.html 作用 返回当前线程组产生的线程的线程编号 语 ...

  10. 要有一颗理财的心 - 读<富爸爸.穷爸爸>

    记得工作没多久后的一次加薪的例行谈话.部门经理和我说,不能靠工资过日子,要多想想怎么投资,我的主要财富就是靠投资赚来的.当时第一反应,老板,你不给我加薪找这借口也太牵强了吧.我的收入只有工资,我的工资 ...