对于List这种顺序表,我们解决的时候还是可以使用for代替foreach即可。但是对于非顺序表,比如Dictionary或者Set之类,我们可以扩展方法Foreach,ForeachKey和ForeachValue来代替原有的foreach。 
关于扩展方法,可参考:https://msdn.microsoft.com/zh-cn/library/bb383977.aspx

static class DictionaryEx
{
/// <summary>
/// 提供一个方法遍历所有项
/// </summary>
public static void Foreach<TKey, TValue>(this Dictionary<TKey, TValue> dic, Action<TKey, TValue> action, int maxCount = 1000)
{
if (action == null) return;
var enumerator = dic.GetEnumerator();
int i = 0;
while (enumerator.MoveNext() && i++ < maxCount)
{
action(enumerator.Current.Key, enumerator.Current.Value);
}
} /// <summary>
/// 提供一个方法遍历所有key值
/// </summary>
public static void ForeachKey<TKey, TValue>(this Dictionary<TKey, TValue> dic, Action<TKey> action, int maxCount = 1000)
{
if (action == null) return;
var enumerator = dic.GetEnumerator();
int i = 0;
while (enumerator.MoveNext() && i++ < maxCount)
{
action(enumerator.Current.Key);
}
} /// <summary>
/// 提供一个方法遍历所有value值
/// </summary>
public static void ForeachValue<TKey, TValue>(this Dictionary<TKey, TValue> dic, Action<TValue> action, int maxCount = 1000)
{
if (action == null) return;
var enumerator = dic.GetEnumerator();
int i = 0;
while (enumerator.MoveNext() && i++ < maxCount)
{
action(enumerator.Current.Value);
}
}
}

在调用时,我们可以使用Lambda表达式简化代码,如:

protected Dictionary<int, ReleaseOnceSkillBunchListShell> m_SkillBunchList = new Dictionary<int, ReleaseOnceSkillBunchListShell>(); // 一个技能列表
/////////////
public void Update(float deltaTime)
{
// 更新技能列表
m_SkillBunchList.ForeachValue(
(value) =>
{
value.Update(deltaTime);
});
}

本以为这样就解决问题了,结果打开profiler一看,妈蛋,竟然还有GC,仔细对比后发现,原来是lambda表达式的问题。没办法,之后把lambda表达式拆开了,拆完如下。

    protected float m_deltaTime;
public void Update(float deltaTime)
{
m_deltaTime = deltaTime;
m_SkillBunchList.ForeachValue(OnUpdateSkillBunch);
}
public void OnUpdateSkillBunch(ReleaseOnceSkillBunchListShell shell)
{
shell.Update(m_deltaTime);
}

拆完不爽的地方就是,原来作用域里面的deltaTime,需要放到更高层的作用域里,否则不好访问。 
所以,小心了,lambda表达式也会产生GC!

Unity中使用扩展方法解决foreach导致的GC的更多相关文章

  1. Unity中自定义扩展方法

    问题背景 在使用unity开发过程中,通常会遇到一种情况,比如说给物体重新赋值坐标的问题, Transfrom tran: ,pos_y=,pos_z=; tran.position=new Vect ...

  2. C#编程(六十一)------------LINQ中的扩展方法

    原文链接: http://blog.csdn.net/shanyongxu/article/details/47208401 LINQ中的扩展方法 LINQ中where扩展方法,要想使用,必须导入us ...

  3. C#中的扩展方法(向已有类添加方法,但无需创建新的派生类型)

    C#中的扩展方法 扩展方法使你能够向现有类型"添加"方法,而无需创建新的派生类型.重新编译或以其他方式修改原始类型. 扩展方法是一种特殊的静态方法,但可以像扩展类型上的实例方法一样 ...

  4. jQuery中效果animate方法解决width是百分比出现的问题

    jQuery中效果animate方法解决width是百分比出现的问题 http://www.mafutian.net/131.html 问题描述: 效果如图,初始化,每个层宽20%,采用animate ...

  5. (转)再不用担心DataRow类型转换和空值了(使用扩展方法解决高频问题)

    再不用担心DataRow类型转换和空值了(使用扩展方法解决高频问题) XML文档操作集锦(C#篇) webapi文档描述-swagger

  6. C#3.0中的扩展方法

    在实际应用中,开发者完成代码的编译后,除非重新编译更改后的代码,否则开发者很难在原有代码中添加新的功能. 在C#3.0中,提供了一个扩展方法的新特性,可以使得开发者在编译后的程序集里边添加相关的方法, ...

  7. 记录C#中的扩展方法

    C#中的扩展方法. 系统自带的类型,我们无法去修改: 修改源代码需要较大的精力,而且可能会带来错误: 我们只是需要一个或者较少的几个方法,修改源代码费时费力: 被扩展的类是sealed的,不能被继承: ...

  8. objective-C中的扩展方法与partial class

     在c#中要扩展一个现有类非常easy,比方这样: ? 1 2 3 4 5 6 7 public static class Utils {     public static void PrintTo ...

  9. C#中的扩展方法

    扩展方法使你能够向现有类型“添加”方法,而无需创建新的派生类型.重新编译或以其他方式修改原始类型. 扩展方法是一种特殊的静态方法,但可以像扩展类型上的实例方法一样进行调用. 以上是msdn官网对扩展方 ...

随机推荐

  1. 链接libtorrent库时出现的问题

    在QtCreator中使用libtorrent库的时候, 项目配置中 libs项配置如下: LIBS += -liconv -ltorrent-rasterbar -lboost_system -lb ...

  2. 删除正在登录的SQL账号

    exec sp_who '用户名' kill @spid sp_droplogin 用户名

  3. 【将txt文本转图片】

    [测试类] public static void main(String[] args) { try { File textFile = new File("F:\\java56班\\ecl ...

  4. BootStrap详解之(一)

    一.BootStrap简介 BootStrap是一个用来构建网站前段框架的一个插件.无论你是想构建应用程序.博客还是CMS网站,Bootstrap都特别的使用,只要你想得到,它就能行.Bootstra ...

  5. 参数修饰符ref,out ,params的区别

    参数修饰符ref,out ,params的区别 C#中有三个关键字-ref,out ,params,可是这三个之间的区别你都明白了吗? 那么我们就来认识一下参数修饰符ref,out ,params吧, ...

  6. 货物搬运(move)

    货物搬运(move) 题目描述 天地无情人有情,一方有难八方支援!汶川大地震发生后,灾区最紧缺的是救灾帐篷,全国各地支援的帐篷正紧急向灾区运送.假设围绕纹川县有环行排列的n个救灾帐篷的存储点,每个存储 ...

  7. spider JAVA如何判断网页编码 (转载)

    原文链接 http://www.cnblogs.com/nanxin/archive/2013/03/27/2984320.html 前言 最近做一个搜索项目,需要爬取很多网站获取需要的信息.在爬取网 ...

  8. c# 动态产生控件 注册动态控件事件

    用CheckEdit演示 其他控件类推 CheckEdit AllSele = new CheckEdit(); AllSele.Location = new System.Drawing.Point ...

  9. zepto学习之路--数组去重和原生reduce

    好吧开始读zepto的源代码,最前面给处理trim和reduce的原生实现,感觉写的很紧凑,其中reduce写的有点晦涩,个人感觉还不错.主要zepto的作者是无分号党,看起了有点不习惯. 3 if ...

  10. (H5)FormData+AJAX+SpringMVC跨域异步上传文件

    最近都没时间整理资料了,一入职就要弄懂业务,整天被业务弄得血崩. 总结下今天弄了一个早上的跨域异步上传文件.主要用到技术有HTML5的FormData,AJAX,Spring MVC. 首先看下上传页 ...