1.ArrayList

        ArrayList概念:

                ArrayList 是 C# 中的一个动态数组,它可以根据需要自动调整大小,并允许在列表中进行动态内存分配、增加、搜索和排序各项。ArrayList是一个C#为我们封装好的类,它的本质是一个object类型的数组。(也就是说一个ArrayList中可以存储不同类型的数据)

           ArrayList的声明

                ArrayList的声明需要引用命名空间using System.Collections;命名空间

ArrayList array = new ArrayList();

        ArrayList的使用

                1.增加的操作

ArrayList array = new ArrayList();
// 单个元素增加,在数组尾部添加
array.Add(1);
array.Add("123");
array.Add("Unity");
foreach(var t in array)
{
    Console.WriteLine(t); // 输出:1,123,Unity
}

ArrayList array2 = new ArrayList();
array2.Add("Game");

// 增加范围(批量增加,把另外一个ArrayList里的内容添加到后面)
// AddRange方法通常用于将一个集合(如数组、列表等)中的所有元素添加到另一个集合中,
// 不直接接受多个单独的参数。
array2.AddRange(array2);

array.AddRange(new string[] {"Orange", "Grape"}); // 添加多个元素


// 在指定位置增加(插入)
array.Insert(1, "Banana"); // 在指定位置插入

                  2.删操作

// 移除指定元素(如果数组中有两个相同的元素删除前面那个)
array.Remove(1);

// 移除指定位置的元素
array.RemoveAt(3);

// 移除移除一定范围的元素
array.RemoveRange(1,4); // 不是左开右闭区间​​,而是从指定位置开始移除指定数量的元素​​

// 清空
array.Clear();

                3.查操作

// 通过索引访问
object fruit = array[3];

// 查看元素是否存在
array.Contains("123") // 返回值为bool值

// 查看元素数量
int count = array.Count;

// 获取索引
// 正向查找
// 找到则返回元素位置,没有则返回-1
// 若有相同元素查找的是第一个元素
int index = array.IndexOf("Unity");

// 逆向查找
// 返回的从头开始的索引数
int index = array.LastIndexOf("123");

遍历

              1.获取长度

// 获取元素个数
array.Count;

// 获取容量
// 避免产生更多的垃圾
array.Capacity;

                2.遍历

1.for循环遍历
for(int i; i<array.Count;i++)
{

}

2.foreach 迭代器遍历
foreach(var item in array)
{

}

2.Stack(栈)

        概念:

                Stack是C#为我们封装好的类,它的本质也是一个object类型的数组,只是封装了特殊的存储规则。Stack(栈),先进后出的规则

        Stack声明:

Stack stack = new Stack();

        Stack使用:

                1.增加(压栈)操作

// 增
stack.Push(1);
stack.Push("Stack");
stack.Push(true);

                2.取(弹栈)操作

object v = stack.Pop();

                3.查的操作(只能查看栈顶元素)

                        栈无法查看指定元素,只能查看栈顶元素(即最后入栈的元素

object v = stack.Peek();

// 查看是否存在于栈中
stack.Contains(1);

                4.改的操作

                        栈无法改变其中元素,只能压栈和弹栈。实在要改,只有清空

stack.Clear();

                5.遍历

                栈不能用for循环遍历,只能用foreach遍历

// foreach迭代器遍历
foreach(var item in stack)
{

}


// 将栈转变成object数组
// 遍历出来的顺序也是从栈顶到栈底
object[] array = stack.ToArray();
for(int i = 0; i < array.Length; i++)
{

}

3.Queue(队列)

        队列概念:

                Queue 是一种先进先出(FIFO - First In First Out)的线性数据结构。

        队列的声明:

Queue queue = new Queue();

        队列的使用:

                1.增加操作

queue.Enqueue(1);
queue.Enqueue("Unity");

                2.取操作

                        先进先出

object v = queue.Dnqueue();

                3.查操作

                        查看队首元素(即最早入队的元素)

queue.Peek();


// 查看元素是否存在
queue.Contains("Unity");

                4.改操作

                        队列无法改变其中的元素,只能进出队列。实在要改,只有清空

queue.Clear();

4.Hashtable(散列表、哈希表)

        Hashtable概念

                Hashtable是一个​​非泛型的键值对集合​​,它通过哈希表实现,允许通过键快速查找值。是基于键的哈希代码组织起来的 键/值 对。(注意:Hashtable都是通过键去映射值,不能通过值反过来去查找键的,因为值可以重复,键是唯一的)

        Hashtable声明

Hashtable hashtable = new Hashtable();

        Hashtable的使用:

                增加操作:

hashtable.Add(键key,值value);
// 注意:键和值可以是任意类型(但不能出现相同的键)

hashtable.Add(1,"111");
hashtable.Add(2,"222");

                删除操作:

// 哈希表名.Remove(键); 只能通过键值去删
// 删除不存在的键,没反应

hashtable.Remove(1);

// 清空
hashtable.Clear();

                查找操作:

// 哈希表名[键]; 返回键对应的值,不存在返回null

hashtable[1];

// 查看是否存在
// 哈希表名.ContainsKey(); 返回bool值,存在返回true,不存在返回false

// 通过键去找
// 法一:
hashtable.Contains(键Key);
// 法二:
hashtable.ContainsKey(键Key);


// 通过值去找
hashtable.ContainsValue(值value);

                改操作:

// 只能改键对应的值,不能改键
// 哈希表名[键] = 值;

hashtable[Key] = Value;

                遍历操作:

Console.WriteLine(hashtable.Count); // 得到键值对的数量

// 1. 遍历所有键
foreach (object key in hashtable.Keys)
{
  Console.WriteLine(key);
}

// 2. 遍历所有值
foreach (object value in hashtable.Values)
{
  Console.WriteLine(value);
}

// 3.键值对一起遍历
foreach (DictionaryEntry item in table)
{
  Console.WriteLine(item.Key + " : " + item.Value);
}


// 4.迭代器遍历
IDictionaryEnumerator enumerator = table.GetEnumerator();
bool hasNext = enumerator.MoveNext();
while (hasNext)
{
  Console.WriteLine(enumerator.Key + " : " + enumerator.Value);
}

5.泛型

        泛型概念:

                  泛型实现了类型参数化,达到代码重用目的。通过类型参数化来实现同一份代码上操作多种类型。(使用泛型可以一定程度避免装箱拆箱)

                泛型相当于类型占位符。定义类或者方法时使用替代符代表变量类型,当真正使用类或者方法时再具体指定类型。

       泛型的声明:

1.泛型类
class 类名<泛型占位字母>

2.泛型接口
interface 接口名<泛型占位字母>

3.泛型函数
函数名<泛型占位字母>

注意:占位字母可以有多个,通过逗号隔开

       泛型类:

class TestClass<T>
{
    // 成员变量
    public T value;

}

// 多个泛型
class TestClass2<T1, T2>
{
    public T1 value1;
    public T2 value2;

}


static void Main(string[] args)
{
    TestClass<int> t = new TestClass<T>();
    
    TestClass2<int, string> t = new TestClss2<int ,string>();
}

        泛型接口:

interface TestInterface<T>
{
    T Value
    {
        get;
        set;
    }
}

class Test<T> : TestInterface<T>  // 类的 T 和接口的 T 是同一个类型
{
    public T Value { get; set; }
}

static void Main(string[] args)
{
    // 实例化 Test 类
    Test test = new Test();
    test.Value = 123;          // 设置 Value
    Console.WriteLine(test.Value); // 输出: 123

    // 通过接口引用访问
    // 将一个 Test类的实例 test赋值给一个 TestInterface<int>类型的变量 testInterface

    TestInterface<int> testInterface = test; 
    Console.WriteLine(testInterface.Value); // 输出: 123

    // Test类实现了 TestInterface<int>​​,所以 Test中的 public int Value { get; set; }就是接口 TestInterface<int>要求的 Value属性的具体实现。

}

        泛型方法:

1.普通类中的泛型方法
class Test
{
    // 把泛型占位符作为参数传入
    public void TestFun<T>(T value)
    {
        Cosnsole.WriteLine(value);
    }

    public void TestFun2<T>()
    {
        // default(T) 获取T类型的默认值    
        T t = default(T);
    }

    // 泛型作为返回值
    public T TestFun2<T>()
    {
        return default(T);
    }
}

2.泛型类中泛型方法
class Test<T>
{
    public T value;

    // 这个不叫泛型方法,因为T是泛型类在声明的时候就指定了,在使用这个函数的时候就已经确定了
    public void TestFun(T t)
    {

    }

    // 泛型方法
    public void TestFun<K>(K k)
    {
      Console.WriteLine(k);
    }
}

        总结

                1.声明泛型时,它只是一个类型占位符
                2.泛型真正起作用的时候是在使用它的时候
                3.泛型占位字母可以有n个,用逗号隔开
                4.泛型占位符一般都是大写字母
                5.不确定泛型类型的时获取默认值,可以使用default
                6.看到<>包括的字母那肯定是泛型

6.泛型约束

        泛型约束概念:

                泛型约束角就是让泛型类型有一定限制

                关键字:where

        泛型约束(6类)

                1.值类型                                                        where  泛型字母:struct

                2.引用类型                                                     where  泛型字母:class

                3.存在无参公共构造函数                               where  泛型字母:new()

                4.某个类本身或者其派生类                           where  泛型字母: 类名

                5.某个接口的派生类型                                  where  泛型字母:接口名

                6.另一个泛型类型本身或者派生类型             where  泛型字母:另一个泛型字母

1.值类型约束
class Test<T> where T : struct
{
    public T valuer;

    public void TestFun<K>(K value) where K : struct
    {

    }
}


2.引用类型约束
class Test2<T> where T : class
{

}


3.必须存在无参公共构造函数(抽象类不可以)
class Test3<T> Where T : new()
{



}

class Test4
{

}


4.类约束(T必须是类本身或者它的派生类)
class Test5<T> where T: Test1
{
    public T value;
    
    public void TestFun<K>(K value) Where K : Test1
    {
    
    }
}


class Test6:Test1
{

}


5.接口约束
interface IFly
{

}

class Player:IFly
{

}


class Test7<T> Where T : IFly
{
    public T value;

}


6.另一个泛型本身或者派生类型
// T要么和U是一样的,要么是U的派生类
class Test8<T, U> where T : U
{
    public T valuer;

    public void TestFun1<K,V>(K value) where K : V
    {

    }
}

static void Main(string[] args)
{
    // 值类型约束
    Test<int> test1 = new Test<int>();
    test.TestFun<int>(10);

    // 引用类型约束
    Test2<string> test2 = new Test2<string>();
    
    // 必须存在无参公共构造函数
    Test3<Test4> test3 = new Test3<Test4>();

    // 类约束(T必须是类本身或者它的派生类)
    Test5<Test1> test5 = new Test5<Test1>(); // 类自己本身
    Test5<Test6> test6 = new Test6<Test6>(); // 类的派生类
    
    // 接口约束
    Test7<IFly> test7 = new Test7<IFly>();
    // test7.value = new IFly(); // 错误,接口不能new
    test7.value = new Player();

    // 另一个泛型约束
    Test8<Player, IFly> test8 = new Test8<Player, IFly>();
}

        泛型约束的组合使用

class Test<T> where T : class, new()
{

}

        多个泛型有约束

class Test7<T,K> where T : class, new() where K : struct
{

}

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐