实现IEnumerator时出错

时间:2015-06-05 12:02:06

标签: c# icollection ienumerator

我按照文章https://www.google.com/m8/feeds/contacts/default/full?alt=json&v=3.0&max-results=500&access_token=ya29.jfgsugfsugfjsgfjsgfhkjsgfjksguljcX3JXwPvEwrvcg和其中提供的示例代码进行了操作。

我想要实现的是非常直接的。我对收藏和普查员有一个公平的理解。但是,我不明白的是,尽管我在实现代码的方式与给定文章中的实现方式几乎没有任何区别,但为什么我会收到错误。

实现中唯一不同的是示例代码使用T(通用),而我在实现自定义Addresses集合类时使用名为Address的类。

代码非常直接。我在项目中有以下课程。

  1. 联系班级
  2. 地址类(实现自定义集合并从ICollection继承)
  3. 地址类
  4. AddressEnumerator
  5. 我希望实现的是数据集功能,我们可以使用如下语法: 数据集ds = new Dataset();

    Ds.Tables [0] ....等等等等等。

    我在AddressEnumerator.cs类的以下方法中遇到编译时错误。 错误: 无法将带[]的索引应用于类型的表达式ConsoleApplication2.Addresses(地址类实现ICollection)

    以下语句中发生编译时错误: _current = _collection [index];

    public bool MoveNext()
        {
            if(++index >= _collection.Count)
            {
                return false;
            }
            else
            {
                _current = _collection[index];
            }
            return true;
        }
    

    源代码:

    //以下代码段不会遍历集合

                foreach (Address a in c.Addresses)
                {
                    Console.WriteLine(a.Street);
                }
    

    Program.cs的

    using System;
    using System.Configuration;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace ConsoleApplication2
    {
    class Program
    {
        static void Main(string[] args)
        {
    
            //RenderTimeSheet();
    
            Address ad = new Address();
    
            ad.Street = "Hollywood";
            ad.City = "LA";
            ad.State = "California";
            ad.ZipCode = "93494";
            ad.Country = "USA";
    
    
            using (Contact c = new Contact(ad))
            {
                c.FirstName = "John";
                c.LastName = "Doe";
    
                Console.WriteLine(c.FirstName);
                Console.WriteLine(c.LastName);
    
                foreach (Address a in c.Addresses)
                {
                    Console.WriteLine(a.Street);
                }
            }
    
            Console.ReadKey();
    
        }
    }
    

    Contact.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Data;
    
    namespace ConsoleApplication2
    {
    public class Contact : IDisposable
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
    
        public Addresses Addresses { get; set; }
    
        public Contact(Address a)
        {
            Addresses = new Addresses(a);
        }
    
        public Contact()
        {
    
        }
    
        public void Dispose()
        {
            Console.Write("Disposing off...");
        }
    }
    }
    

    Addresses.cs

    using System;
    using System.Collections.Generic;
    using System.Collections;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace ConsoleApplication2
    {
    public class Addresses : ICollection<Address>
    {
    
        private IList<Address> _lstAddress;
    
        protected bool _IsReadOnly;
    
        public Addresses(Address _a)
        {
            _lstAddress = new List<Address>();
        }
    
        public void Add(Address item)
        {
    
            _lstAddress.Add(item);
    
        }
    
        public void Clear()
        {
    
            _lstAddress.Clear();
    
        }
    
        public bool Contains(Address item)
        {
            foreach(Address a in _lstAddress)
            {
                if(a.Street == item.Street)
                {
                    return true;
                }
            }
            return false;
        }
    
        public void CopyTo(Address[] array, int arrayIndex)
        {
            throw new Exception("Not valid for this implementation.");
        }
    
        public int Count
        {
            get { return _lstAddress.Count; }
        }
    
        public bool IsReadOnly
        {
            get { return _IsReadOnly; }
        }
    
        public bool Remove(Address item)
        {
            bool result = false;
    
            for (int i = 0; i < _lstAddress.Count; i++)
            {
                Address obj = (Address)_lstAddress[i];
    
                if(obj.Street == item.Street)
                {
                    _lstAddress.RemoveAt(i);
                    result = true;
                    break;
                }
            }
            return result;
        }
    
        public IEnumerator<Address> GetEnumerator()
        {
            return new AddressEnumerator(this);
        }
    
        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            //throw new NotImplementedException();
            return this.GetEnumerator();
        }
    }
    }
    

    Address.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace ConsoleApplication2
    {
    public class Address
    {
    
        public string Street { get; set; }
        public string City { get; set; }
        public string State { get; set; }
        public string ZipCode { get; set; }
        public string Country { get; set; }
    }
    }
    

    AddressEnumerator.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace ConsoleApplication2
    {
    public class AddressEnumerator : IEnumerator<Address>
    {
        protected Addresses _collection;
    
        protected int index;
    
        protected Address _current;
    
        public AddressEnumerator()
        {
    
        }
    
        public AddressEnumerator(Addresses collection)
        {
            _collection = collection;
            index = -1;
            _current = default(Address);
        }
    
        public Address Current 
        { 
            get
            {
                return _current;
            } 
        }
    
    
        public void Dispose()
        {
            _collection = null;
            _current = default(Address);
            index = -1;
        }
    
        object System.Collections.IEnumerator.Current
        {
            get 
            {
                return _current;
            }
        }
    
        public bool MoveNext()
        {
            if(++index >= _collection.Count)
            {
                return false;
            }
            else
            {
                _current = _collection[index];
            }
            return true;
        }
    
        public void Reset()
        {
            throw new NotImplementedException();
        }
    }
    }
    

2 个答案:

答案 0 :(得分:2)

这是对您的问题的直接和简短的解决方案, 但它不是一个“完全干净”的解决方案,也应该改变完整实现的编码风格。有更有效的方法来实现可枚举的接口......

更改行

_current = _collection[index];

_current = _collection._lstAddress[index];

但您还需要更改访问修饰符

private IList<Address> _lstAddress

例如

 internal IList<Address> _lstAddress

答案 1 :(得分:0)

示例代码的工作原理和您的原因并不是因为示例代码类BusinessObjectCollection包含以下内容:

public virtual T this[int index]
{
    get
    {
        return (T)_innerArray[index];
    }
    set
    {
        _innerArray[index] = value;
    }
}

提供代码缺少的下标运算符[]

如果您将其添加到Addresses课程(将_innerArray更改为_lstAddress),那么它应该可以正常使用。