C#笔记,ArrayList迭代错误和Struct迭代错误

这是这个星期里我比较头大的两个问题,一个一个说
ArrayList是C#提供的一个动态数组类,用法类似std::list,但是他的核心结构是C#的Array类,所以继承了Array的大部分方法。
如果你用过迭代的方法删除数组中的元素,比如下面:
foreach (int sub in m_listTempArray)
{
    if (sub == 1) m_listTempArray.Remove(sub);
}
那么编译时肯定能过的,因为看上去没什么问题,但是实际执行过程中,可能会抛出一个异常
原因其实很简单,在迭代过程中,你remove了其中的一个元素,导致整个list的结构发生了改变,但是迭代器没有重置,依然按照旧的结构迭代,所以就有可能抛出异常
解决办法1,克隆临时数组
ArrayList m_listCloneArray = (ArrayList )m_listTempArray.Clone();
foreach (int sub in m_listCloneArray )
{
    if (sub == 1) m_listTempArray.Remove(sub);
}
原理很简单,我们克隆了一个数组来进行迭代,这样,remove只会更改原数组的结构,但是迭代却是在克隆数组中进行,所以不会有异常发生,但是这样做的一个致命弱点就是,需要构造一个新ArrayList,如果是在update这类频繁操作的逻辑中使用,肯定会影响效率
解决方法2,不使用迭代器
for (int i=0; i<m_listTempArray.Count; )
{
    if (m_listTempArray[i] == 1)
    {
        m_listTempArray.RemoveAt(i);
    } 
    else
    {
        i++;
    }
}
使用最原始的for循环遍历的话,有一个好处,那就是每次循环结束后,条件都会被重新判定一次,即使Count变化也不要紧,所以这样做也不会抛异常~缺点就是原始了一点,结构不够严谨,不过效率很高,看你怎么取舍了~
解决方法3,不实用ArrayList
这是一个鬼扯的方法,但是我依然在这里建议大家不要频繁使用ArrayList,实际上C#提供了一个更好的容器类,叫做HashTable,也就是哈希表。除了多了一个key值外,用法上和ArrayList没有太多区别。但是由于哈希表的特殊数据结构,使得他在迭代删除时不会有ArrayList的那种问题。而且通过key值访问对象时,哈希表的速度会明显高于ArrayList
然后说说struct,也就是结构体
C#中的结构体不是一般的弱
众所周知,C#所有对象都派生自Object类,而Object类又派生出2个大类,值类型和引用类型。而所有的struct都派生自值类型,所有的class都派生自引用类型
C#的值类型不能有默认无参构造函数,也就是说你无法再结构体的默认构造函数中初始化成员,如果你写了下面这个结构体
struct A{
int a;
ArrayList b;
int[] c;
}
那么你只有在调用的时候自己初始化那些成员了,比如
A a;
a.b = new ArrayList();
a.c = new int[10];
你不这么做的话,a对象的b、c两个成员都是null值,是不可访问的,很不好用
另外,如果你在Array中存放一个struct对象,那么在foreach时可能遇到问题,那就是struct对象的值在迭代时是不可以被修改的!
解决办法?那就只有不用struct了,把struct换成class,一切问题解决,无参构造函数?没问题。初始化成员?也没问题。迭代时修改成员?当然也可以!所以,在C#中,真的除非是简单到傻瓜白痴的数据,否则还是不要轻易使用struct,不然出了问题,debug都非常困难

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值