C# 기본 지식 편집 기본 지식(16) IList 인터페이스 - 일반이 아님

黄舟
풀어 주다: 2017-02-11 13:44:42
원래의
1331명이 탐색했습니다.

ICollection 인터페이스, 반복 및 일반 컬렉션을 이해한 후 IList 인터페이스에 대해 자세히 알아보겠습니다.
MSDN에서 두 가지 유형의 IList 인터페이스가 있음을 확인할 수 있습니다.

요소가 개체 유형인 IList 인터페이스는 다양한 유형의 개체 참조를 보유할 수 있습니다.
IList 인터페이스, 지정된 유형의 객체 참조만 저장할 수 있습니다.
실제로 IList 및 IList는 컬렉션의 길이를 동적으로 변경할 수 있다는 특징이 있습니다. 컬렉션의 초기 길이는 자동으로 변경됩니다. 저장된 데이터의 양.
IList와 IList 사이의 상속 관계를 볼 수 있습니다.

[ComVisibleAttribute(true)]
public interface IList : ICollection, IEnumerable

public interface IList<T> : ICollection<T>, 
 IEnumerable<T>, IEnumerable
로그인 후 복사

이제 다시 돌아가서 IList와 IList의 차이점을 확인하세요. ArrayList가 IList를 상속하는 코드를 살펴보세요. List Inherit IList:

   public class IListClass
    {
        void test()
        {
            TestClass1 c1 = null;

            ArrayList arryList = new ArrayList();

            arryList.Add(c1);

            List<TestClass1> list = new List<TestClass1>();

            list.Add(c1);

            //取值
            TestClass1 getC1Array = arryList[0] as TestClass1;//必须要一次强制转换

            TestClass1 getC1List = list[0];//不需要转换,所谓泛型
        }
    }

    public class TestClass1
    {
    }
로그인 후 복사

이제 더 명확해졌습니다.
1. IList 인터페이스 개요
ILis 인터페이스는 ICollection 인터페이스에서 상속되며 다음과 같은 특징을 갖습니다.
Count 속성 - 컬렉션 요소 수를 가져옵니다.
GetEnumerator 메서드 - 반복 가능.
CopyTo 메서드 ——지정된 요소를 다른 배열로 복사합니다.
Clear 메서드 ——전체 컬렉션을 지웁니다.
IList의 새로운 기능,
인덱서 속성 - 인덱스를 기반으로 컬렉션의 모든 요소에 액세스합니다.
추가 메서드 - 컬렉션의 끝에 요소를 추가합니다.
삽입 메서드 - 지정된 요소에 요소를 삽입합니다.
제거 메서드 - 지정된 요소 제거(RemoveAt 포함)
포함 메서드 - 개체가 컬렉션에 있는지 확인
IndexOf 메서드 - 지정된 개체의 인덱스 위치를 찾습니다. 컬렉션.
또한 IList 인터페이스 컬렉션은 요소를 순서대로 저장하며 요소 저장 순서를 변경하지 않습니다.
2. 알고리즘
벡터 컬렉션은 배열과 마찬가지로 랜덤 액세스의 특징을 가지고 있습니다. 즉, 벡터 세트의 어떤 단위에 액세스하든 관계없이 필요한 액세스 시간은 정확히 동일합니다. 벡터 클래스에서 일반 배열은 실제로 컬렉션 데이터를 기록하는 데 사용됩니다. 벡터 클래스는 일부 알고리즘 기술을 사용하여 전체 클래스가 외부적으로 일반 배열과 다르게 동작하도록 만듭니다. 즉, 배열 길이를 동적으로 변경할 수 있습니다. 구체적인 알고리즘은 다음과 같습니다.
내부 배열이 충분히 길면 추가 및 삽입 작업이 직접 수행됩니다. 내부 배열 길이가 부족할 경우 내부 배열의 길이를 새 배열 길이의 2배로 늘립니다. 그런 다음 데이터를 이동합니다. 즉, 이전 배열 배열을 새 배열로 이동합니다. 벡터가 요소 저장 공간을 할당할 때 메모리 할당 수를 최소화하기 위해 더 많은 중복 공간을 할당합니다. 데이터가 삭제되면 내부 배열의 길이는 변경되지 않고 삭제된 데이터 이후의 데이터만 삭제된 데이터를 덮어쓰는 데 사용됩니다.
그러나 벡터가 공간을 할당할 때마다 더 많은 중복 공간을 할당하므로 메모리 부족이 발생하므로 프로그램에서 집중적이고 많은 메모리 할당을 피하도록 노력해야 합니다.
3. 구현 클래스
IList 및 IList의 구현 클래스는 각각 ArrayList 클래스와 List 클래스입니다.
ArrayList 클래스는 System.Collection 네임스페이스 아래에 있습니다.
List 클래스는 System.Collection.Specialized 네임스페이스 아래에 있습니다.
4. 구현 코드(비일반)

/// <summary>
    /// 实现IList,非泛型
    /// </summary>
    public class ArrayList : IList
    {
        /// <summary>
        /// 迭代
        /// </summary>
        public struct Enumertor : IEnumerator
        {
            /// <summary>
            /// 迭代索引
            /// </summary>
            private int index;

            /// <summary>
            /// 迭代器所属的向量类对象的引用
            /// </summary>
            private ArrayList arrayList;

            /// <summary>
            /// 构造函数
            /// </summary>
            /// <param name="arrayList">迭代器所属的集合类</param>
            public Enumertor(ArrayList arrayList)
            {
                this.arrayList = arrayList;

                this.index = -1;
            }

            /// <summary>
            /// 获取当前对象,根据index的值返回向量对应的对象引用
            /// </summary>
            public object Current
            {
                get 
                { 
                    return arrayList[index]; 
                }
            }

            /// <summary>
            /// 将迭代器指向下一个数据位置,通过改变index的值,加1或减1
            /// </summary>
            /// <returns></returns>
            public bool MoveNext()
            {
                if (this.index < arrayList.Count)
                {
                    ++this.index;
                }

                return this.index < arrayList.Count;
            }

            /// <summary>
            /// 迭代器回到起始位置,将index置为-1
            /// </summary>
            public void Reset()
            {
                this.index = -1;
            }
        }

        /// <summary>
        /// 保存集合的数组
        /// </summary>
        private object[] array = new object[1];

        /// <summary>
        /// 当前集合的长度
        /// </summary>
        private int count;

        /// <summary>
        /// 默认构造函数
        /// </summary>
        public ArrayList()
        {

        }

        /// <summary>
        /// 参数构造函数,通过参数指定内部数组长度,减少重新分配空间
        /// </summary>
        /// <param name="capacity"></param>
        public ArrayList(int capacity)
        {
            if (capacity < 0)
            {
                throw new Exception();
            }

            if (capacity == 0)
            {
                capacity = 1;
            }

            this.array = new object[capacity];

            this.count = 0;
        }

        public int Count
        {
            get
            {
                return this.count;//该属性只读
            }
        }

        /// <summary>
        /// 集合实际使用长度
        /// </summary>
        public int Capacity
        {
            get
            {
                return this.array.Length;
            }
        }

        /// <summary>
        /// 是否固定大小
        /// </summary>
        public bool IsFixedSize
        {
            get
            {
                return false;
            }
        }

        /// <summary>
        /// 是否只读集合
        /// </summary>
        public bool IsReadOnly
        {
            get
            {
                return false;
            }
        }
        /// <summary>
        /// 是否同步,即是否支持多线程访问
        /// </summary>
        public bool IsSynchronized
        {
            get
            {
                return false;
            }
        }
        /// <summary>
        /// 同步对象
        /// </summary>
        public object SyncRoot
        {
            get
            {
                return null;
            }
        }

        /// <summary>
        /// 当array长度不足时,重新分配新的长度足够的数组
        /// </summary>
        /// <returns></returns>
        private object[] GetNewArray()
        {
            return new object[(this.array.Length + 1) * 2];
        }

        public int Add(object value)
        {
            int newCount = this.count + 1;

            if (this.array.Length < newCount)//长度不足
            {
                object[] newArray = GetNewArray();

                Array.Copy(this.array, newArray, this.count);

                this.array = newArray;//重新引用,指向新数组
            }

            //增加新元素
            this.array[this.count] = value;

            this.count = newCount;

            //返回新元素的索引位置
            return this.count - 1;
        }

        /// <summary>
        /// 索引器属性,按索引返回向量中的某一项
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public object this[int index]
        {
            get
            {
                if (index < 0 || index >= this.count)
                {
                    throw new Exception();
                }

                return this.array[index];
            }

            set
            {
                if (index < 0 || index >= this.count)
                {
                    throw new Exception();
                }

                this.array[index] = value;
            }
        }

        /// <summary>
        /// 删除集合中的元素
        /// </summary>
        /// <param name="index"></param>
        /// <param name="count"></param>
        public void RemoveRange(int index, int count)
        {
            if (index < 0)
            {
                throw new Exception();
            }

            int removeIndex = index + count;//计算集合中最后一个被删元素的索引

            if (count < 0 || removeIndex > this.count)
            {
                throw new Exception();
            }

            //删除其实是将要删除元素之后的所有元素拷贝到要删除元素的位置覆盖掉
            Array.Copy(this.array, index + 1, this.array, index + count - 1, this.count - removeIndex);

            //重新设置集合长度
            this.count -= count;
        }

        /// <summary>
        /// 查找对应的数组项,实际是遍历查找
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public int IndexOf(object value)
        {
            int index = 0;

            if (value == null)
            {
                while (index < this.count)
                {
                    if (this.array[index] == null)
                    {
                        return index;
                    }

                    ++index;
                }
            }
            else
            {
                while (index < this.count)
                {
                    if (this.array[index].Equals(value))
                    {
                        return index;
                    }

                    ++index;
                }
            }

            return -1;
        }

        /// <summary>
        /// 从集合中删除指定元素
        /// </summary>
        /// <param name="value"></param>
        public void Remove(object value)
        {
            int index = this.IndexOf(value);

            if (index >= 0)
            {
                this.RemoveRange(index, 1);
            }
        }

        /// <summary>
        /// 从集合中删除指定位置的元素
        /// </summary>
        /// <param name="index"></param>
        public void RemoveAt(int index)
        {
            RemoveRange(index, 1);
        }

        /// <summary>
        /// 获取最后一个元素的引用后删除最后一个元素
        /// </summary>
        /// <returns></returns>
        public object PopBack()
        {
            object obj = this.array[this.count - 1];

            RemoveAt(this.count - 1);

            return obj;
        }

        /// <summary>
        /// 获取第一个元素引用并删除第一个元素
        /// </summary>
        /// <returns></returns>
        public object PropFront()
        {
            object obj = this.array[0];

            RemoveAt(0);

            return obj;
        }

        /// <summary>
        /// 插入元素
        /// </summary>
        /// <param name="index"></param>
        /// <param name="value"></param>
        public void Insert(int index, object value)
        {
            if (index >= this.count)
            {
                throw new Exception();
            }
            //插入元素当空间不足时也是声明新的2倍长度数组,并拷贝旧数据。
            //插入数据原理是,将指定位置后的数据全部后移,再将新数据放在指定位置。

            int newCount = this.count + 1;

            if (this.array.Length < newCount)
            {
                object[] newArray = GetNewArray();

                Array.Copy(this.array, newArray, index);

                this.array = newArray;
            }

            Array.Copy(this.array, index, this.array, index + 1, this.count - index);

            this.array[index] = value;

            this.count = newCount;
        }

        /// <summary>
        /// 查看当前集合是否包含指定对象
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool Contains(object value)
        {
            return this.IndexOf(value) >= 0;
        }

        /// <summary>
        /// 将集合的长度改变为实际长度
        /// </summary>
        public void TrimToSize()
        {
            //为了消除Add和Insert时增加的冗余,原理是新生成一个和实际长度相同的数组,然后将值全部移过来。
            if (this.array.Length > this.count)
            {
                object[] newArray = null;

                if (this.count > 0)
                {
                    newArray = new object[this.count];

                    Array.Copy(this.array, newArray, this.count);
                }
                else
                {
                    newArray = new object[1];
                }

                this.array = newArray;
            }
        }

        /// <summary>
        /// 清空集合
        /// </summary>
        public void Clear()
        {
            this.count = 0;
        }
        /// <summary>
        /// 获取集合的迭代器
        /// </summary>
        /// <returns></returns>
        public IEnumerator GetEnumerator()
        {
            Enumertor enumerator = new Enumertor(this);

            return enumerator;
        }

        /// <summary>
        /// 转移集合元素
        /// </summary>
        /// <param name="targetArray"></param>
        /// <param name="index"></param>
        public void CopyTo(Array targetArray, int index)
        {
            Array.Copy(this.array, 0, targetArray, index, this.count);
        }
    }
로그인 후 복사


호출 테스트:

static void Main(string[] args)
        {
            //调用测试

            ArrayList myArrayList = new ArrayList();

            myArrayList.Add(40);

            myArrayList.Add(80);

            myArrayList.Add("Hello");

            //使用for循环遍历
            for (int i = 0; i < myArrayList.Count; i++)
            {
                Console.WriteLine(myArrayList[i]);
            }

            Console.WriteLine("---------------------");

            //使用迭代循环
            foreach (object obj in myArrayList)
            {
                Console.WriteLine(obj);
            }

            Console.WriteLine("---------------------");

            myArrayList.Insert(1, "Insert");

            foreach (object obj in myArrayList)
            {
                Console.WriteLine(obj);
            }

            Console.WriteLine("---------------------");

            myArrayList.Remove("Insert");

            foreach (object obj in myArrayList)
            {
                Console.WriteLine(obj);
            }

            Console.WriteLine("---------------------");

            myArrayList.RemoveAt(1);

            foreach (object obj in myArrayList)
            {
                Console.WriteLine(obj);
            }

            Console.WriteLine("---------------------");

            myArrayList.Clear();

            foreach (object obj in myArrayList)
            {
                Console.WriteLine(obj);
            }

            Console.WriteLine("---------------------");

            Random rand = new Random();

            for (int i = 0; i < 10; i++)
            {
                myArrayList.Add(rand.Next(10));
            }

            foreach (object obj in myArrayList)
            {
                Console.WriteLine(obj);
            }

            Console.WriteLine("---------------------");

            Console.WriteLine("集合是否包含为1的元素 ? " + (myArrayList.Contains(0) ? "包含" : "不包含"));

            Console.WriteLine("元素1的位置   " + myArrayList.IndexOf(1));

            Console.ReadLine();
        }
로그인 후 복사

결과:

위 내용입니다. 더 많은 관련 내용은 PHP 중국어 홈페이지(www.php.cn)를 주목해주세요!


원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿