7.泛型约束

7.泛型-泛型约束


7.1 知识点

知识回顾

泛型类

// 泛型类
class GenericClass<T, U>
{
    // 泛型变量
    public T t;
    public U u;

    // 泛型类中的成员方法
    public U GenericClassFunction(T t)
    {
        return default(U);
    }

    // 泛型类中的泛型方法
    public V GenericClassFunction<K, V>(K k)
    {
        return default(V);
    }
}

主函数内

// 泛型类,实际使用时再具体传入类型
GenericClass<string, int> genericClass = new GenericClass<string, int>();

// 泛型变量
genericClass.t = "123123";
genericClass.u = 10;

// 泛型类中的成员方法
genericClass.GenericClassFunction("123");

// 泛型类中的泛型方法
genericClass.GenericClassFunction<float, double>(1.4f);

什么是泛型约束

  • 泛型约束:让泛型的类型有一定限制。
  • 关键字:where
  • 语法:where 泛型字母: (约束的类型)

泛型约束分类

  1. 值类型:where 泛型字母: struct
  2. 引用类型:where 泛型字母: class
  3. 存在无参公共构造函数:where 泛型字母: new()
  4. 某个类本身或者其派生类:where 泛型字母: 类名
  5. 某个接口的派生类型:where 泛型字母: 接口名
  6. 另一个泛型类型本身或者派生类型:where 泛型字母: 另一个泛型字母

各泛型约束讲解

值类型约束

// 值类型泛型约束类,代表 T 一定是一个结构体
class Test1<T> where T : struct
{
    // 泛型变量
    public T value;

    // 值类型泛型约束方法,代表 K 一定是一个结构体
    public void TestFun<K>(K v) where K : struct
    {

    }
}
// int 实际上也是一个结构体,可以传入值类型泛型约束类的实例中
Test1<int> t1 = new Test1<int>();

// float 实际上也是一个结构体,可以传入值类型泛型约束方法中
t1.TestFun<float>(1.3f);

引用类型约束

// 引用类型泛型约束类,代表 T 一定是一个类
class Test2<T> where T : class
{
    // 泛型变量
    public T value;

    // 引用类型泛型约束方法,代表 K 一定是一个类
    public void TestFun<K>(K k) where K : class
    {

    }
}
// Random 实际上是一个类,可以传入引用类型泛型约束类的实例中
Test2<Random> t2 = new Test2<Random>();

// 这样 value 的类型也是 Random
t2.value = new Random();

// object 实际上也是一个类,可以传入引用类型泛型约束方法中
t2.TestFun<object>(new object());

公共无参构造约束

// 公共无参构造泛型约束类,代表 T 一定要有公共无参构造函数
class Test3<T> where T : new()
{
    // 泛型变量
    public T value;

    // 公共无参构造泛型约束方法,代表 K 一定要有公共无参构造函数
    public void TestFun<K>(K k) where K : new()
    {

    }
}
// Test31 有公共无参构造,正常 new 出来
Test3<Test31> t31 = new Test3<Test31>();

// Test32 没有公共无参构造,报错
// Test3<Test32> t32 = new Test3<Test32>();

// Test33 只有私有无参构造,报错
// Test3<Test33> t33 = new Test3<Test33>();

// Test34 有公共无参构造,但是 Test34 是抽象类,无法直接用无参构造 new 出来,报错
// Test3<Test34> t34 = new Test3<Test34>();

// 可以传入结构体,因为结构体默认有公共无参构造,而且就算写了有参构造,公共无参构造也不会被顶掉
Test3<int> t3Struct = new Test3<int>();

类约束

// 类约束泛型约束类,代表 T 一定是 Test31 或 Test31 的派生类
class Test4<T> where T : Test31
{
    // 泛型变量
    public T value;

    // 类约束泛型约束方法,代表 K 一定是 Test31 或 Test31 的派生类
    public void TestFun<K>(K k) where K : Test31
    {

    }
}
// 直接传入 Test31,正常 new
Test4<Test31> t4 = new Test4<Test31>();

// Test41 继承 Test31,正常 new
Test4<Test41> t41 = new Test4<Test41>();

// Test42 没有继承 Test31,报错
// Test4<Test42> t42 = new Test4<Test42>();

// object 是 Test31 的父类,不是 Test31 的派生类,报错
// Test4<object> t4Object = new Test4<object>();

接口约束

// 接口约束泛型约束类,代表 T 一定是 IFly 或 IFly 的派生类
class Test5<T> where T : IFly
{
    // 泛型变量
   

 public T value;

    // 接口约束泛型约束方法,代表 T 一定是 IFly 或 IFly 的派生类
    public void TestFun<K>(K k) where K : IFly
    {

    }
}

// 飞行接口
interface IFly
{

}

// 走路接口
interface IWalk
{

}

// 移动接口继承飞行接口和走路接口
interface IMove : IFly, IWalk
{

}

// 我的飞行类,继承飞行接口
class MyFly : IFly
{

}
// 直接传入 IFly,正常 new
Test5<IFly> t51 = new Test5<IFly>();
t51.value = new MyFly(); // MyFly 继承 IFly,可以 new 出接口的实现子类

// IWalk 没有继承 IFly,报错
// Test5<IWalk> t52 = new Test5<IWalk>();

// IMove 继承 IFly,正常 new
Test5<IMove> t53 = new Test5<IMove>();

// MyFly 继承 IFly,正常 new
Test5<MyFly> t54 = new Test5<MyFly>();

另一个泛型约束

// 另一个泛型约束泛型约束类,代表 T 一定是 U 或 U 的派生类
class Test6<T, U> where T : U
{
    // 泛型变量
    public T value;

    // 另一个泛型约束泛型约束类,代表 K 一定是 V 或 V 的派生类
    public void TestFun<K, V>(K k) where K : V
    {

    }
}
// MyFly 是 IFly 的子类,正常 new
Test6<MyFly, IFly> t61 = new Test6<MyFly, IFly>();

// MyFly 不是 IWalk 的子类,报错
// Test6<MyFly, IWalk> t62 = new Test6<MyFly, IWalk>();

约束的组合使用

// 语法:class 类<T> where T: 约束1,约束2

// 意味着 T 必须是个类,而且有公共的无参构造函数
// 有些约束只能现在另一个约束前面,比如 class 要写在 new() 前面,否则报错
class Test71<T> where T : class, new()
{

}

// 有些组合不能一起使用,会报错
// 比如 struct 本身就有公共的无参构造函数,不能组合
// class Test72<T> where T : struct, new()
// {
//
// }

多个泛型有约束

// 语法:class 类<T,K> where T: 约束1,约束2 where K:约束3
class Test8<T, K> where T : class, new() where K : struct
{

}

总结

  • 泛型约束:让泛型的类型有一定限制。
  • 泛型约束分类:
    • class
    • struct
    • new()
    • 类名
    • 接口名
    • 另一个泛型字母
  • 注意:
    1. 可以组合使用。
    2. 多个泛型约束用 where 连接即可。

7.2 知识点代码

using System;

namespace Lesson6_泛型约束
{
    //class语句块外 namespace语句块内

    #region 知识回顾

    //泛型类
    class GenericClass<T, U>
    {
        //泛型变量
        public T t;
        public U u;

        //泛型类中的成员方法
        public U GenericClassFunction(T t)
        {
            return default(U);
        }

        //泛型类中的泛型方法
        public V GenericClassFunction<K, V>(K k)
        {
            return default(V);
        }
    }

    #endregion

    #region 知识点一 什么是泛型约束

    //泛型约束:让泛型的类型有一定的限制
    //关键字:where
    //语法:where 泛型字母:(约束的类型)

    //泛型约束一共有6种
    //1.值类型                              where 泛型字母:struct
    //2.引用类型                            where 泛型字母:class
    //3.存在无参公共构造函数                 where 泛型字母:new()
    //4.某个类本身或者其派生类               where 泛型字母:类名
    //5.某个接口的派生类型                  where 泛型字母:接口名
    //6.另一个泛型类型本身或者派生类型       where 泛型字母:另一个泛型字母


    #endregion

    #region 知识点二 各泛型约束讲解

    #region 值类型约束

    //值类型泛型约束类 代表T一定是一个结构体
    class Test1<T> where T : struct
    {
        //泛型变量
        public T value;

        //值类型泛型约束方法 代表K一定是一个结构体
        public void TestFun<K>(K v) where K : struct
        {

        }
    }

    #endregion

    #region 引用类型约束

    //引用类型泛型约束类 代表T一定是一个类
    class Test2<T> where T : class
    {
        //泛型变量
        public T value;

        //引用类型泛型约束方法 代表K一定是一个结构体
        public void TestFun<K>(K k) where K : class
        {

        }
    }

    #endregion

    #region 公共无参构造约束

    //公共无参构造泛型约束类 代表T一定要有公共无参构造函数
    class Test3<T> where T : new()
    {
        //泛型变量
        public T value;

        //公共无参构造泛型约束方法 代表K一定要有公共无参构造函数
        public void TestFun<K>(K k) where K : new()
        {

        }
    }

    //测试类 有公共无参构造
    class Test31
    {
        public Test31()
        {

        }
    }

    //测试类 没有公共无参构造
    class Test32
    {
        public Test32(int a)
        {

        }
    }

    //测试类 有私有无参构造
    class Test33
    {
        private Test33(int a)
        {

        }
    }

    //抽象测试类 有公共无参构造 
    abstract class Test34
    {
        public Test34(int a)
        {

        }
    }

    #endregion

    #region 类约束

    //类约束泛型约束类 代表T一定是Test31或Test31的派生类
    class Test4<T> where T : Test31
    {
        //泛型变量
        public T value;

        //类约束泛型约束方法 代表K一定是Test31或Test31的派生类
        public void TestFun<K>(K k) where K : Test31
        {

        }
    }

    //Test41继承Test31
    class Test41 : Test31
    {

    }

    //Test42没有继承Test31
    class Test42
    {

    }

    #endregion

    #region 接口约束

    //接口约束泛型约束类 代表T一定是IFly或IFly的派生类
    class Test5<T> where T : IFly
    {
        //泛型变量
        public T value;

        //接口约束泛型约束方法 代表T一定是IFly或IFly的派生类
        public void TestFun<K>(K k) where K : IFly
        {

        }
    }

    //飞行接口
    interface IFly
    {

    }

    //走路接口
    interface IWalk
    {

    }

    //移动接口继承飞行接口和走路接口
    interface IMove : IFly, IWalk
    {

    }

    //我的飞行类 继承飞行接口
    class MyFly : IFly
    {

    }

    #endregion

    #region 另一个泛型约束

    //另一个泛型约束泛型约束类 代表T一定是U或U的派生类
    class Test6<T, U> where T : U
    {
        //泛型变量
        public T value;

        //另一个泛型约束泛型约束类 代表K一定是V或V的派生类
        public void TestFun<K, V>(K k) where K : V
        {

        }
    }

    #endregion

    #endregion

    #region 知识点三 约束的组合使用

    //语法:class 类<T> where T: 约束1,约束2

    //意味着T必须是个类 而且有公共的无参构造函数
    //有些约束只能现在另一个约束前面 比如class要写在new()前面 否则报错
    class Test71<T> where T : class, new()
    {

    }

    //有些组合不能一起使用 会报错
    //比如struct本身就有公共的无参构造函数 不能组合
    //class Test72<T> where T : struct, new()
    //{

    //}

    #endregion

    #region 知识点四 多个泛型有约束

    //语法:class 类<T,K> where T: 约束1,约束2 where K:约束3
    class Test8<T, K> where T : class, new() where K : struct
    {

    }

    #endregion

    #region 总结

    //泛型约束:让泛型的类型有一定限制
    //泛型约束分类:
    //class
    //struct
    //new()
    //类名
    //接口名
    //另一个泛型字母

    //注意:
    //1.可以组合使用
    //2.多个泛型约束 用where连接即可

    #endregion

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("泛型约束");

            //主函数内

            #region 知识回顾

            //泛型类 实际使用的时候再具体传入类型
            GenericClass<string, int> genericClass = new GenericClass<string, int>();

            //泛型变量
            genericClass.t = "1`23123";
            genericClass.u = 10;

            //泛型类中的成员方法
            genericClass.GenericClassFunction("123");

            //泛型类中的泛型方法
            genericClass.GenericClassFunction<float, double>(1.4f);

            #endregion

            #region 知识点二 各泛型约束讲解


            #region 值类型约束

            //int实际上也是一个结构体 可以传入值类型泛型约束类的实例中
            Test1<int> t1 = new Test1<int>();

            //float实际上也是一个结构体 可以传入值类型泛型约束方法中
            t1.TestFun<float>(1.3f);

            //Test31<object> t11 = new Test31<object>();//报错  值类型泛型约束类不能传入引用类型

            #endregion

            #region 引用类型约束

            //Random实际上是一个类 可以传入引用类型泛型约束类的实例中
            Test2<Random> t2 = new Test2<Random>();

            //这样value的类型也是Random
            t2.value = new Random();

            //object实际上也是一个结构体 可以传入引用类型泛型约束方法中
            t2.TestFun<object>(new object());

            //Test32<int> t11 = new Test32<int>();//报错 引用类型泛型约束类不能传入值类型

            #endregion

            #region 公共无参构造约束

            //Test31有公共无参构造 正常new出来
            Test3<Test31> t31 = new Test3<Test31>();

            //Test32没有公共无参构造 报错
            //Test41<Test32> t32 = new Test41<Test32>();

            //Test33只有私有无参构造 报错
            //Test3<Test33> t33 = new Test3<Test33>();

            //Test34有公共无参构造 但是Test34是抽象类 无法直接用无参构造new出来 所以其实他的公共无参构造没用 报错
            //Test3<Test34> t34 = new Test3<Test34>();

            //可以传入结构体 因为结构体默认有公共无参构造 而且就算写了有参构造 公共无参构造也不会被顶掉
            Test3<int> t3Struct = new Test3<int>();

            #endregion

            #region 类约束

            //直接传入Test31 正常new
            Test4<Test31> t4 = new Test4<Test31>();

            //Test41继承Test31 正常new
            Test4<Test41> t41 = new Test4<Test41>();

            //Test42没有继承Test31 报错
            //MyFly<Test42> t42 = new MyFly<Test42>();

            //object是Test31的父类 不是Test31的派生类 报错
            //MyFly<object> t4Object = new MyFly<object>();

            #endregion

            #region 接口约束

            //直接传入IFly 正常new
            Test5<IFly> t51 = new Test5<IFly>();
            //t51.value = new IFly();//报错 接口不能new
            t51.value = new MyFly();//MyFly继承IFly 可以new出接口的实现子类

            //IWalk没有继承IFly 报错
            //Test5<IWalk> t52 = new Test5<IWalk>();

            //IMove继承IFly 正常new
            Test5<IMove> t53 = new Test5<IMove>();

            //MyFly继承IFly 正常new
            Test5<MyFly> t54 = new Test5<MyFly>();

            #endregion

            #region 另一个泛型约束

            //MyFly是IFly的子类 正常new
            Test6<MyFly, IFly> t61 = new Test6<MyFly, IFly>();

            //MyFly不是IWalk的子类 报错
            //Test6<MyFly, IWalk> t62 = new Test6<MyFly, IWalk>();

            #endregion


            #endregion
        }
    }
}

7.3 练习题

用泛型实现一个单例模式基类

class语句块外 namespace语句块内

// 泛型单例基类,泛型约束一下,必须要有公共无参构造
// 缺点:有无参构造暴露给外部使用,不能私有,但其实无伤大雅,有经验的程序员不会new单例类
class SingleBase<T> where T : new()
{
    private static T instance = new T();

    public static T Instance
    {
        get
        {
            return instance;
        }
    }
}

// 游戏管理类,继承泛型单例基类
class GameMgr : SingleBase<GameMgr>
{
    public int value = 10;
}

// 测试类1,继承泛型单例基类
class Test : SingleBase<Test>
{
    public int value = 10;
}

// 测试类2,不继承泛型单例基类,要自己手动写单例实现
class Test2
{
    private static Test2 instance = new Test2();

    public int value = 10;
    private Test2()
    {

    }

    public static Test2 Instance
    {
        get
        {
            return instance;
        }
    }
}

主函数内

GameMgr.Instance.value = 10; // 直接.Instance使用单例
// GameMgr g = new GameMgr(); // 缺点:有无参构造暴露给外部使用,不能私有,但其实无伤大雅,有经验的程序员不会new单例类

Test.Instance.value = 10; // 直接.Instance使用单例
// Test t = new Test(); // 缺点:有无参构造暴露给外部使用,不能私有,但其实无伤大雅,有经验的程序员不会new单例类

Test2.Instance.value = 10; // 直接.Instance使用单例,但是是自己手动实现的,没有继承泛型单例基类

利用泛型知识点,仿造ArrayList实现一个不确定数组类型的类,实现增删查改方法

class语句块外 namespace语句块内

// 我们自己写的泛型ArrayList类
// 和C#自带的ArrayList相比,我们自己写的可以约束类型,不能什么类都往里面加,不用装箱拆箱
class ArrayList<T>
{
    // 泛型数组
    private T[] array;

    // 当前正儿八经存了多少数
    private int count;

    // 构造函数
    public ArrayList()
    {
        // 默认一一开始存的数为0
        count = 0;
        // 一开始的容量就是16
        array = new T[16];
    }

    // 增
    public void Add(T value)
    {
        // 是否需要扩容
        if (count >= Capacity)
        {
            // 每次加倍扩容
            T[] temp = new T[Capacity * 2];

            // 遍历搬家
            for (int i = 0; i < Capacity; i++)
            {
                temp[i] = array[i];
            }

            // 重新指向地址
            array = temp;
        }

        // 不需要扩容,直接加
        array[count] = value;

        // 当前存的数+1
        ++count;
    }

    // 按值删
    public void Remove(T value)
    {
        // 实现略
    }

    // 按位置删
    public void RemoveAt(int index)
    {
        // 实现略
    }

    // 索引器
    public T this[int index]
    {
        get
        {
            // 实现略
        }
        set
        {
            // 实现略
        }
    }

    /// <summary>
    /// 获取容量
    /// </summary>
    public int Capacity
    {
        get
        {
            return array.Length;
        }
    }

    /// <summary>
    /// 得到具体存了几个值
    /// </summary>
    public int Count
    {
        get
        {
            return count;
        }
    }
}

主函数内

// 声明泛型int的ArrayList
ArrayList<int> array = new ArrayList<int>();

Console.WriteLine(array.Count); // 0
Console.WriteLine(array.Capacity); // 16

array.Add(1);
array.Add(2);
array.Add(3);
Console.WriteLine(array.Count); // 3
Console.WriteLine(array.Capacity); // 16
for (int i = 0; i < array.Count; i++)
{
    Console.WriteLine(array[i]); // 1 2 3
}


Console.WriteLine(array[1]); // 2
Console.WriteLine(array[-1]); // 索引不合法 返回默认值0
Console.WriteLine(array[3]); // 索引不合法 返回默认值0

array.RemoveAt(0); // 移除索引为0的元素
Console.WriteLine(array.Count); // 2
for (int i = 0; i < array.Count; i++)
{
    Console.WriteLine(array[i]); // 2 3
}

array.Remove(3); // 移除值为3的元素
Console.WriteLine(array.Count); // 1
for (int i = 0; i < array.Count; i++)
{
    Console.WriteLine(array[i]); // 2
}


Console.WriteLine(array[0]); // 2
array[0] = 99;
Console.WriteLine(array[0]); // 99

// 泛型string的ArrayList同理
ArrayList<string> array2 = new ArrayList<string>();

7.4 练习题代码

using System;

namespace Lesson6_练习题
{
    //class语句块外 namespace语句块内

    #region 练习题一 

    //用泛型实现一个单例模式基类

    //泛型单例基类 泛型约束一下 必须要有公共无参构造
    //缺点:有无参构造暴露给外部使用 不能私有 但其实无伤大雅 有经验的程序员不会new单例类
    class SingleBase<T> where T : new()
    {
        private static T instance = new T();

        public static T Instance
        {
            get
            {
                return instance;
            }
        }
    }

    //游戏管理类 继承泛型单例基类
    class GameMgr : SingleBase<GameMgr>
    {
        public int value = 10;
    }

    //测试类1 继承泛型单例基类
    class Test : SingleBase<Test>
    {
        public int value = 10;
    }

    //测试类2 不继承泛型单例基类 要自己手动写单例实现
    class Test2
    {
        private static Test2 instance = new Test2();

        public int value = 10;
        private Test2()
        {

        }

        public static Test2 Instance
        {
            get
            {
                return instance;
            }
        }
    }

    #endregion

    #region 练习题二
    //利用泛型知识点,仿造ArrayList实现一个不确定数组类型的类,实现增删查改方法

    //我们自己写的泛型ArrayList类
    //和C#自带的ArrayList相比 我们自己写的可以约束类型 不能什么类都往里面加 不用装箱拆箱
    class ArrayList<T>
    {
        //泛型数组
        private T[] array;

        //当前正儿八经存了多少数
        private int count;

        //构造函数
        public ArrayList()
        {
            //默认一一开始存的数为0
            count = 0;
            //一开始的容量就是16
            array = new T[16];
        }

        //增
        public void Add(T value)
        {
            //是否需要扩容
            if (count >= Capacity)
            {
                //每次 家扩容2倍
                T[] temp = new T[Capacity * 2];

                //遍历搬家 
                for (int i = 0; i < Capacity; i++)
                {
                    temp[i] = array[i];
                }

                //重新指向地址
                array = temp;
            }

            //不需要扩容 直接加
            array[count] = value;

            //当前存的数+1
            ++count;
        }

        //按值删
        public void Remove(T value)
        {
            //这个地方 不是小于数组的容量
            //是小于 具体存了几个值

            //给index一个默认值-1
            int index = -1;

            //遍历判断
            for (int i = 0; i < Count; i++)
            {
                //不能用==去判断 因为 不是所有的类型都重载了运算符 
                if (array[i].Equals(value))
                {
                    //相等赋值相等的值的索引给index 跳出循环
                    index = i;
                    break;
                }
            }

            //只要不等于-1 就证明找到了 那就去移除
            if (index != -1)
            {
                //删的调用按位置删的重载
                RemoveAt(index);
            }
        }

        //按位置删
        public void RemoveAt(int index)
        {
            //判断索引合法不合法
            if (index < 0 || index >= Count)
            {
                Console.WriteLine("索引不合法");
                return;
            }

            //从传入的index开始 后面的元素逐个往前放
            for (; index < Count - 1; index++)
            {
                array[index] = array[index + 1];
            }

            //把一个数移除了 后面的往前面放 那么最后一个 要移除
            //给最后一个数一个默认值
            array[Count - 1] = default(T);

            //当前存的数-1
            --count;
        }

        //索引器
        public T this[int index]
        {
            get
            {
                if (index < 0 || index >= Count)
                {
                    Console.WriteLine("索引不合法");
                    return default(T);
                }
                return array[index];
            }
            set
            {
                if (index < 0 || index >= Count)
                {
                    Console.WriteLine("索引不合法");
                    return;
                }
                array[index] = value;
            }
        }

        /// <summary>
        /// 获取容量
        /// </summary>
        public int Capacity
        {
            get
            {
                return array.Length;
            }
        }

        /// <summary>
        /// 得到具体存了几个值
        /// </summary>
        public int Count
        {
            get
            {
                return count;
            }
        }

    }

    #endregion

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("泛型约束练习题");

            //主函数内

            #region 练习题一 

            GameMgr.Instance.value = 10;//直接.Instance使用单例
            //GameMgr g = new GameMgr(); //缺点:有无参构造暴露给外部使用 不能私有 但其实无伤大雅 有经验的程序员不会new单例类

            Test.Instance.value = 10;//直接.Instance使用单例
            //Test t = new Test(); //缺点:有无参构造暴露给外部使用 不能私有 但其实无伤大雅 有经验的程序员不会new单例类

            Test2.Instance.value = 10;//直接.Instance使用单例 但是是自己手动实现的 没有继承泛型单例基类

            #endregion

            #region 练习题二

            //声明泛型int的ArrayList
            ArrayList<int> array = new ArrayList<int>();

            Console.WriteLine(array.Count);//0
            Console.WriteLine(array.Capacity);//16

            array.Add(1);
            array.Add(2);
            array.Add(3);
            Console.WriteLine(array.Count);//3
            Console.WriteLine(array.Capacity);//16
            for (int i = 0; i < array.Count; i++)
            {
                Console.WriteLine(array[i]);//1 2 3
            }


            Console.WriteLine(array[1]);//2
            Console.WriteLine(array[-1]);//索引不合法 返回默认值0
            Console.WriteLine(array[3]);//索引不合法 返回默认值0

            array.RemoveAt(0);//移除索引为0的元素
            Console.WriteLine(array.Count);//2
            for (int i = 0; i < array.Count; i++)
            {
                Console.WriteLine(array[i]);//2 3
            }

            array.Remove(3);//移除值为3的元素
            Console.WriteLine(array.Count);//1
            for (int i = 0; i < array.Count; i++)
            {
                Console.WriteLine(array[i]);//2
            }


            Console.WriteLine(array[0]);//2
            array[0] = 99;
            Console.WriteLine(array[0]);//9

            //泛型string的ArrayList同理
            ArrayList<string> array2 = new ArrayList<string>();

            #endregion
        }
    }
}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏