Home Backend Development C#.Net Tutorial Compilation of basic knowledge of C# Basic knowledge (16) IList interface - non-generic

Compilation of basic knowledge of C# Basic knowledge (16) IList interface - non-generic

Feb 11, 2017 pm 01:44 PM

After understanding the ICollection interface, iteration and generic collections, let's learn more about the IList interface in detail.
Through MSDN, you can see that there are two types of IList interfaces:

The IList interface whose elements are of object type can hold different types of object references;
IListgeneric interface, Only object references of specified types can be stored.
In fact, IList and IList are also called vectors. Their characteristic is that they can dynamically change the length of the collection. There is no need to determine the initial length of the collection. The collection will automatically change with the amount of stored data.
You can see the inheritance relationship between IList and IList:

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

public interface IList<T> : ICollection<T>, 
 IEnumerable<T>, IEnumerable
Copy after login

Now go back and see the difference between IList and IList. Look at the following code. ArrayList inherits IList, and 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
    {
    }
Copy after login

This is more clear.
1. Overview of the IList interface
The ILis interface inherits from the ICollection interface and has the following characteristics,
Count property - obtains the number of collection elements;
GetEnumerator method - can be iterated;
CopyTo method ——Copy the specified element to another array;
Clear method——Clear the entire collection.
New features of IList,
Indexer attribute - access any element in the collection according to the index;
Add method - add elements to the end of the collection;
Insert method - insert elements into the specified position of the collection ;
Remove method - remove the specified element; (including RemoveAt)
Contains method - determine whether the object is in the collection;
IndexOf method - find the index position of the specified object in the collection.
In addition, the IList interface collection stores elements in order and does not change the order of element storage.
2. Algorithm
Vector collections, like arrays, have the characteristics of random access. That is, regardless of accessing any unit of the vector set, the access time required is exactly the same. In the vector class, ordinary arrays are actually still used to record collection data. The vector class uses some algorithm techniques to make the entire class externally behave differently from ordinary arrays: it can dynamically change the array length. The specific algorithm is as follows:
When the internal array is long enough, add and insert operations are performed directly. When the internal array length is insufficient, increase the internal array length by 2 times as the length of the new array, and then move the data. (That is, move the old array array to the new array). When a vector allocates element storage space, it will allocate more redundant space to minimize the number of memory allocations. When data is deleted, the length of the internal array is not changed, but the deleted data is overwritten with the data after the deleted data.
However, every time a vector allocates space, it allocates more redundant space, which will cause memory pressure. Therefore, you should try to avoid concentrated and numerous memory allocations in the program.
3. Implementation classes
The implementation classes of IList and IList are ArrayList class and List class respectively.
The ArrayList class is under the System.Collection namespace;
The List class is under the System.Collection.Specialized namespace.
4. Implementation code (non-generic)

/// <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);
        }
    }
Copy after login


Call test:

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();
        }
Copy after login

Result:

The above is the content. For more related content, please pay attention to the PHP Chinese website (www.php.cn)!


Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Roblox: Bubble Gum Simulator Infinity - How To Get And Use Royal Keys
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
Nordhold: Fusion System, Explained
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
Mandragora: Whispers Of The Witch Tree - How To Unlock The Grappling Hook
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Hot Topics

Java Tutorial
1664
14
PHP Tutorial
1269
29
C# Tutorial
1249
24
The Continued Relevance of C# .NET: A Look at Current Usage The Continued Relevance of C# .NET: A Look at Current Usage Apr 16, 2025 am 12:07 AM

C#.NET is still important because it provides powerful tools and libraries that support multiple application development. 1) C# combines .NET framework to make development efficient and convenient. 2) C#'s type safety and garbage collection mechanism enhance its advantages. 3) .NET provides a cross-platform running environment and rich APIs, improving development flexibility.

From Web to Desktop: The Versatility of C# .NET From Web to Desktop: The Versatility of C# .NET Apr 15, 2025 am 12:07 AM

C#.NETisversatileforbothwebanddesktopdevelopment.1)Forweb,useASP.NETfordynamicapplications.2)Fordesktop,employWindowsFormsorWPFforrichinterfaces.3)UseXamarinforcross-platformdevelopment,enablingcodesharingacrossWindows,macOS,Linux,andmobiledevices.

C# as a Versatile .NET Language: Applications and Examples C# as a Versatile .NET Language: Applications and Examples Apr 26, 2025 am 12:26 AM

C# is widely used in enterprise-level applications, game development, mobile applications and web development. 1) In enterprise-level applications, C# is often used for ASP.NETCore to develop WebAPI. 2) In game development, C# is combined with the Unity engine to realize role control and other functions. 3) C# supports polymorphism and asynchronous programming to improve code flexibility and application performance.

Is C# .NET Right for You? Evaluating its Applicability Is C# .NET Right for You? Evaluating its Applicability Apr 13, 2025 am 12:03 AM

C#.NETissuitableforenterprise-levelapplicationswithintheMicrosoftecosystemduetoitsstrongtyping,richlibraries,androbustperformance.However,itmaynotbeidealforcross-platformdevelopmentorwhenrawspeediscritical,wherelanguageslikeRustorGomightbepreferable.

C# .NET and the Future: Adapting to New Technologies C# .NET and the Future: Adapting to New Technologies Apr 14, 2025 am 12:06 AM

C# and .NET adapt to the needs of emerging technologies through continuous updates and optimizations. 1) C# 9.0 and .NET5 introduce record type and performance optimization. 2) .NETCore enhances cloud native and containerized support. 3) ASP.NETCore integrates with modern web technologies. 4) ML.NET supports machine learning and artificial intelligence. 5) Asynchronous programming and best practices improve performance.

Deploying C# .NET Applications to Azure/AWS: A Step-by-Step Guide Deploying C# .NET Applications to Azure/AWS: A Step-by-Step Guide Apr 23, 2025 am 12:06 AM

How to deploy a C# .NET app to Azure or AWS? The answer is to use AzureAppService and AWSElasticBeanstalk. 1. On Azure, automate deployment using AzureAppService and AzurePipelines. 2. On AWS, use Amazon ElasticBeanstalk and AWSLambda to implement deployment and serverless compute.

C# Code within .NET: Exploring the Programming Process C# Code within .NET: Exploring the Programming Process Apr 12, 2025 am 12:02 AM

The programming process of C# in .NET includes the following steps: 1) writing C# code, 2) compiling into an intermediate language (IL), and 3) executing by the .NET runtime (CLR). The advantages of C# in .NET are its modern syntax, powerful type system and tight integration with the .NET framework, suitable for various development scenarios from desktop applications to web services.

C# and the .NET Runtime: How They Work Together C# and the .NET Runtime: How They Work Together Apr 19, 2025 am 12:04 AM

C# and .NET runtime work closely together to empower developers to efficient, powerful and cross-platform development capabilities. 1) C# is a type-safe and object-oriented programming language designed to integrate seamlessly with the .NET framework. 2) The .NET runtime manages the execution of C# code, provides garbage collection, type safety and other services, and ensures efficient and cross-platform operation.

See all articles