对于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. Win7与Ubuntu双系统时卸载Ubuntu的方法

    Win7与Ubuntu双系统时卸载Ubuntu的方法 [日期:2010-03-26] 来源:Ubuntu社区  作者:Ubuntu编辑 [字体:大 中 小]       1. 下载MBRFix工具,放 ...

  2. WiresShark 一站式学习

    按照国际惯例,从最基本的说起. 抓取报文: 下载和安装好Wireshark之后,启动Wireshark并且在接口列表中选择接口名,然后开始在此接口上抓包.例如,如果想要在无线网络上抓取流量,点击无线接 ...

  3. PopupWindow组件的使用问题

    //如果默认屏幕的话,父view就写自己 popupWindow.showAtLocation(inflate, Gravity.BOTTOM, 0, 0); PopupWindow 顾名思义为弹出式 ...

  4. javascript的事件冒泡,阻止事件冒泡和事件委托, 事件委托是事件冒泡的一个应用。

    首先,弄明白js 当中,什么是事件,事件模型在js中是如何设计的.什么是事件冒泡? 什么是“事件冒泡”呢?假设这里有一杯水,水被用某种神奇的方式分成不同颜色的几层.这时,从最底层冒出了一个气泡,气泡会 ...

  5. 使用virsh命令创建KVM虚拟机快照

    查看虚拟机所在主机和虚拟机名称:[root@node-1 ~]# nova show a88dcf5d-c8b2-46a5-af27-a176d8235c9d|grep hyper| OS-EXT-S ...

  6. CSS中关于margin的理解误区

    思考一 在以前,我对于margin的理解是这样的,此处用margin-top举例:指的是离相邻元素之间的距离. 但是实际是:相对于自身原来的位置偏移. 举个例子: <!DOCTYPE HTML ...

  7. String类的两种赋值

    java.lang包是java的默认引入包,所以我们不需显式地导包. String s1 = new String("字符串");//创建2个字符串对象,堆中一个,字符串常量池中一 ...

  8. PHP 删除非法UTF-8字符

    //reject overly long 2 byte sequences, as well as characters above U+10000 and replace with ? $some_ ...

  9. 多年心愿,终于完成,热泪盈眶啊。。。Adrew NG 的 机器学习

    谢谢Andrew老师!谢谢Coursera!谢谢自己!希望这是一个好的开始!希望自己也能使用机器学习来make a better world...  

  10. 配置 Gitblit 进行 Git 代码管理

    配置 Gitblit 进行 Git 代码管理 环境 CentOS 7 x64 IP: 10.6.0.2 首先需要安装jdk  安装步骤 就略过了 下载最新版本  gitblit wget http:/ ...