Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >用Stack<T>和数组定制的IEnumerable<T>?

用Stack<T>和数组定制的IEnumerable<T>?
EN

Stack Overflow用户
提问于 2013-05-10 22:16:05
回答 1查看 1.2K关注 0票数 1

我一直在努力解决这个问题。我试图使CustomStack像Stack一样,只实现Push(T)、Pop()、Peek()和Clear()方法。我有这段代码,我认为它是正确的,但输出只显示了一半的数字。我认为这与推送法有关,但我看不出它有什么问题。

代码语言:javascript
运行
AI代码解释
复制
using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;

namespace Enumerator
{
    class Program
    {
        static void Main(string[] args)
        {
            CustomStack<int> collection = new CustomStack<int>();

            for (int i = 0; i < 30; i++)
            {
                collection.Push(i);
                Console.WriteLine(collection.Peek());
            }
            collection.Push(23);
            foreach (int x in collection)
            {
                Console.WriteLine(collection.Pop());
            }

            Console.WriteLine("current", collection.Peek());
            Console.ReadKey();
        }
    }

    public class CustomStack<T> : IEnumerable<T>
    {

        private T[] arr;
        private int count;

        public CustomStack()
        {
            count = 0;
            arr = new T[5];
        }


        public T Pop()
        {
            int popIndex = count;
            if (count > 0)
            {
                count--;
                return arr[popIndex];
            }
            else
            {
                return arr[count];
            }

        }

        public void Push(T item)
        {

            count++;
            if (count == arr.Length)
            {
                Array.Resize(ref arr, arr.Length + 1);
            }

            arr[count] = item;


        }

        public void Clear()
        {
            count = 0;

        }

        public T Peek()
        {
            return arr[count];
        }

        public int Count
        {
            get
            {
                return count;
            }
        }

        public IEnumerator<T> GetEnumerator()
        {
            return new MyEnumerator(this);
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return new MyEnumerator(this);
        }

        public class MyEnumerator : IEnumerator<T>
        {
            private int position;
            private CustomStack<T> stack;

            public MyEnumerator(CustomStack<T> stack)
            {
                this.stack = stack;
                position = -1;
            }
            public void Dispose()
            {

            }
            public void Reset()
            {
                position = -1;
            }

            public bool MoveNext()
            {
                position++;
                return position < stack.Count;
            }

            Object IEnumerator.Current
            {
                get
                {
                    return stack.arr[position];
                }
            }
            public T Current
            {
                get
                {
                    return stack.arr[position];

                }
            }
        }
    }
}
EN

回答 1

Stack Overflow用户

发布于 2013-05-10 22:23:42

您正在做一些要求您永远不要做的事情:在使用枚举数迭代集合时,您正在修改集合。( foreach循环是分配枚举数的语法糖。)

IEnumerable的文档实际上表明,如果您的数据结构在被枚举时被修改,像您这样的实现会抛出异常。(尝试使用List<T>,您将看到;如果在foreach中枚举列表时添加或删除项,则列表将抛出。)

这就是造成问题的原因;您的数据结构的设计不是(1)在滥用时抛出,也不是(2)在被滥用时表现良好,因此当您滥用它时,它表现得很糟糕。

我的建议是:如果你那样做会很伤人,那就别那么做。不要在枚举集合的循环中修改集合。

相反,创建一个IsEmpty属性并编写您的循环:

代码语言:javascript
运行
AI代码解释
复制
while(!collection.IsEmpty)  
  Console.WriteLine(collection.Pop());

这样,在同时处理枚举数时,就不会修改集合。

这里的具体问题是:每次循环时,position总是在增加。count一直在下降。你说只有一半的物品被清点。那就算了吧。如果你有十个项目,位置从零开始,直到它大于计数,然后每次通过循环.

代码语言:javascript
运行
AI代码解释
复制
position    count
 0           10
 1           9
 2           8
 3           7
 4           6
 5           5  

我们完成了,我们只列举了一半的项目。

如果您想让您的集合在迭代时被修改时保持健壮,那么当堆栈被推送或弹出时,position必须更改。每一次都不能盲目地增加,即使计数在变。找出正确的行为是非常棘手的,这就是为什么文档建议您直接抛出。

如果要使集合在被枚举时修改时抛出异常,诀窍是使对象具有一个名为“版本号”的int。每次推送或弹出集合时,请更改版本号。然后让迭代器在迭代开始时获取版本号的副本;如果它检测到当前版本号与副本不同,则集合在枚举期间已被修改,您可以抛出一个集合修改的异常。

谢谢这个有趣的问题;我可能会在我的博客中使用它作为一个例子,并可能看我是否可以编写一个静态分析器来检测这种危险的修改。

票数 15
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16494395

复制
相关文章
vmware workstation 克隆后网卡eth0不能正常工作
解决方法如下 修改/etc/udev/rules.d/70-persistent-net.rules 将eth0这行注释掉或者删除, 这里记载的还是克隆系统时的MAC地址,但是新启动的系统MAC已经更改, 将NAME="eth1" 改为 “eth0”,ATTR 标记的MAC地址,这个是虚拟机为这个虚拟网卡分配的MAC,用上面的MAC替换掉 /etc/sysconfig/network-scripts /ifcfg-eth0中的MAC 然后重启即可 还有一个办法,不用eth0,直接用eth1等,把/etc/sysconfig/network-scripts/ifcfg-eth0复制成/etc/sysconfig/network-scripts/ifcfg-eth1
三杯水Plus
2018/11/14
2.5K0
Linux下shell不能正常执行
看上面信息【with CRLF line terminators】,大概能定位到问题
小码匠
2022/06/16
4.3K0
错题本:ConstraintLayout 不能正常显示
这个属性是 app:layout_constraintLeft_toLeftOf="@id/oa_setting_group_tv_add" 写成了自己在自己左边了。
佛系编码
2019/12/11
1.9K0
错题本:ConstraintLayout 不能正常显示
uploadifive参数fileType不能正常解析
鉴于html5已经是主流,flash终究是快湮灭了。所以现在上传也从uploadify更换成了uploadifive了,价值5美刀。在上传的过程中经常需要限制上传文件的类型,就需要用到参数fileType,于是就看下了官方手册上的介绍,文档上的对fileType参数定义的类型是string,且不是必须参数。经过拷贝demo的代码,发现根本无效,任何文件类型还是能够被上传。结果耗时3小时15分钟,翻遍国内外技术网站,最终确认uploadifive的fileType参数是个BUG,官方文档也标错了。经过反复测试,要想实现文件格式限制效果,需要使用json类型数据进行配置,才能实现参数正常解析。
世纪访客
2018/08/02
1.1K0
uploadifive参数fileType不能正常解析
配置SSL证书后,Nginx的HTTPS 不能正常工作的原因有哪些
申请ssl证书,配置nginx支持https与证书,可是访问https的nginx总是出现错误,也导致小程序发https请求失败,这是什么原因呢?
网盾JoySSL小张
2023/08/31
5K0
正常的工作流程
修改文件,将它们更新的内容添加到索引中。 $ git add file1 file2 file3 你现在为commit做好了准备,你可以使用git diff命令再加上–cached参数,看看哪些文件将被提交(commit)。 (如果没有–cached参数,git diff会显示当前你所有已做的但没有加入到索引里的修改。)你也可以使用git status命令来获得当前项目的一个状况。
用户3004328
2018/09/06
7810
记录一下fail2ban不能正常工作的问题 & 闲扯安全
在加载配置这个事情上,许多linux应用程序只需要发一个信号,应用自己就完成配置重载,无需重启中断服务,但是依然有很多程序并不支持。
horsley
2022/08/16
3.7K0
Apache编译后无法正常工作
因为某个场景的需求,要在一个国产系统Rocky4.2(国产凝思4.2操作系统)上安装Apache,虽说此系统是基于Redhat 5.8开发的,但是发现yum安装源包管理,RPM命令倒是能用,但是底层依赖完全没有,这就尴尬了,so,只能源码编译安装了。
后场技术
2020/09/03
2.9K0
关于GPU VNC不能正常使用的说明
https://cloud.tencent.com/document/product/560/36207
Windows技术交流
2022/09/07
3.8K0
Ueditor后端配置项没有正常加载,上传插件不能正常使用!的解决过程。
如图:单图上传为灰色,多图上传提示 后端配置项没有正常加载,上传插件不能正常使用!
德顺
2019/11/13
17.7K0
Ueditor后端配置项没有正常加载,上传插件不能正常使用!的解决过程。
关于IIS gzip不能正常启用,该怎么解决
独立主机/VPS 一键开启IIS的GZIP方法 http://www.jb51.net/article/30151.htm
会长君
2023/04/26
9520
Confluence 6 € 欧元字符集不能正常显示
€ (euro) 标记 是一个 3 字节字符,在 (UTF-8)中这个字符被表示为 0xE2, 0x82, 0xAC。
HoneyMoose
2019/01/30
1K0
tomcat能正常启动,但是不能访问http://localhost:8080
最近遇到一个问题,下载了一个tomcat7.0.23版本的软件(不是官网下载的),环境变量设置正确但是都是不能访问http:localhost:8080.下面是我解决方法:
全栈程序员站长
2022/06/29
2.5K0
关于的MongoDB Compass Community 不能够正常连接
解决办法2:     a.先看服务启动没有,如果没有启动服务先启动服务:net stat MongoDB     b.如果服务已经启动了,那有可能是上次不正常关闭mongo,导致存放数据的文件被占用了,被锁住了。只需将D:\MongoDB\db中的mongod.lock文件删除掉。重新启动服务net stat MongoDB即可
拓荒者
2019/03/14
2.7K0
pyCharm全局搜索不能正常使用的解決方法
提示:pyCharm全局搜索不能使用的主要原因是热键被占用 通过百度搜索到的答案一般都是搜狗输入法热键占用的原因导致pyCharm全局搜索不能使用 但是我的电脑并没有安装搜狗输入法 并且经过排查,所有的外部软件的热键都没有占用ctrl + shift + f
全栈程序员站长
2022/09/04
1.8K0
pyCharm全局搜索不能正常使用的解決方法
建站小技巧|添加了产品为什么不能正常显示?
之前我们有分享过【如何正确的发布文章?】近期许多客户反馈希望能都出几期视频教程,因此本期我们接着分享如何正确发布产品。  为什么添加了产品,预览时无法正常打开? 腾讯云网站建设系统为了更好的满足用户自定义需求,产品详情页排版结构可支持自定义。因此部分企业用户在使用的时候以为我在后台发布了产品,应该就可以正常打开了,实际如需产品正常打开,还需要进行以下步骤操作,下面一起跟着视频了解下吧! ①进入网站编辑页面,添加适合的产品列表模块; ②进入产品管理,添加产品分类,为对应分类添加产品; ③刷新页面,即可自动
腾讯云DNSPod团队
2022/02/08
1.1K0
CentOS7.0下,apache不能正常运行的解决思路
/usr/local/apache/bin/apachectl startapache
一朵灼灼华
2022/08/05
1.6K0
无线鼠标非硬件原因显示驱动异常不能正常使用。
1、点击[确定] 2、点击[小图标] 3、点击[设备管理器] 4、点击[鼠标和其他指针设备] 5、点击[扫描检测硬件改动] 6、点击[鼠标和其他指针设备] 7、点击[ELAN PS/2 Port Input Device] 8、点击[更新驱动程序] 9、点击[自动搜索更新的驱动程序软件] 10、点击[HID-compliant mouse] 11、点击[更新驱动程序] 12、点击[自行搜索更新的驱动程序软件] 13、点击[关闭]
裴来凡
2022/05/28
2.8K0
无线鼠标非硬件原因显示驱动异常不能正常使用。
EasyCVR分屏播放不能正常使用是什么原因?
EasyCVR视频融合云服务支持H.265编码视频Web直播,以及RTSP、RTMP、FLV、HLS视频流输出,可实现远程PC端(Windows、Mac、Linux)、手机端(Android、iOS)、微信端浏览功能。监控人员可在任意时间、任意地点,通过公用网络查看监控区域的实时图像。电脑网页客户端支持单画面、多画面显示,用户可选择任意一路或多路视频观看,视频窗口数量1、4、9、16个可选。
TSINGSEE青犀视频
2022/03/11
6980
点击加载更多

相似问题

>=不能正常工作

21

不能正常工作

11

不能正常工作

21

*()不能正常工作

27

不能正常工作

20
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文