C#练习题——泛型实现单例模式和增删改查

一、任务一:使用栈结构方式实现十进制转化为二进制

实现目标:

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


二、任务一核心代码分析

1. 泛型单例基类设计

cs 复制代码
class BaseMgr<T> where T : new()  // 约束T必须有无参构造函数
{
    private static T instance = new T();  // 静态实例,类加载时创建
    public static T Instance
    {
        get { return instance; }  // 提供全局访问点
    }
}

2. 具体单例类实现

cs 复制代码
class Test1 : BaseMgr<Test1>  // 继承泛型基类,自身作为类型参数
{
    public int value = 1;
}

class Test2 : BaseMgr<Test2>
{
    public string name = "开心超人";
}

3. 单例使用方式

cs 复制代码
// 通过基类的静态属性访问单例实例
BaseMgr<Test1>.Instance.value = 100;
BaseMgr<Test2>.Instance.name = "大大怪将军";

三、任务一完整代码以及设计模式解析

(1)完整代码

cs 复制代码
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace 进阶测试
{
    class Program
    {
        class BaseMgr<T>where T : new()
        {
            private static T instance=new T();
            public static T Instance
            {
                get { return instance; }
            }
        }

        class Test1 : BaseMgr<Test1>
        {
            public int value=1;
        }

        class Test2 : BaseMgr<Test2>
        {
            public string name = "开心超人";
        }

        static void Main(string[] args)
        {
            BaseMgr<Test1>.Instance.value=100;
            BaseMgr<Test2>.Instance.name = "大大怪将军";
        }
    }
}

(2)设计模式解析

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

实现目标:

(1)用泛型实现实现一个不确定数组类型的类实现增删查改


五、核心代码实现

1. 类定义与字段

cs 复制代码
class ArrayList<T>
{
    public T[] arrayList = new T[16];
    public int count = 0;    // 数组的实际元素数量
    public int capacity = 16; // 数组的当前容量
}

2. 添加功能 (Add)

cs 复制代码
public void Add(T value)
{
    if (count < capacity)
    {
        arrayList[count] = value; 
        count++;
    }
    else
    {
        // 扩容操作:容量翻倍
        T[] newarray = new T[capacity *= 2];
        for (int i = 0; i < arrayList.Length; i++)
        {
            newarray[i] = arrayList[i];
        }
        newarray[count] = value; // 注意:这里修正了原代码的错误
        count++;
        arrayList = newarray;
    }
}

当数组未满时,直接添加元素

当数组已满时,创建容量翻倍的新数组并拷贝元素

时间复杂度:平均 O(1),最坏情况(需要扩容时)O(n)


3. 删除功能 (Remove)

(1)按索引删除:

cs 复制代码
public void Remove(int index)
{
    if (index >= 0 && index < count)
    {
        for (int i = index; i < count - 1; i++)
        {
            arrayList[i] = arrayList[i + 1];
        }
        // 清空最后一个元素的引用(避免内存泄漏)
        arrayList[count - 1] = default(T);
        count--; // 减少实际元素计数
    }
}

(2)按值删除:

cs 复制代码
public void RemoveAt(T value)
{
    int index = -1;
    for (int i = 0; i < count; i++)
    {
        if (arrayList[i].Equals(value))
        {
            index = i; // 保留相等的下标位置
            break;
        }
    }
    if (index != -1)
    {
        Remove(index);
    }
    else
    {
        Console.WriteLine("数组中没有找到值为{0}", value);
    }
}

4. 修改功能 (Modify)

cs 复制代码
public void Modify(int index, T value)
{
    if (index >= 0 && index < count)
        arrayList[index] = value;
    else
    {
        Console.WriteLine("请输入正确的下标");
        return; 
    }
}

5. 查询功能(索引器)

cs 复制代码
public T this[int index]
{
    get
    {
        if (index < 0 || index >= count)
        {
            Console.WriteLine("请输入合法的索引");
            return default(T);
        }
        return arrayList[index];
    }
    set
    {
        if (index < 0 || index >= count)
        {
            Console.WriteLine("请输入合法的索引");
            return;
        }
        arrayList[index] = value;
    }
}

6. 显示数组信息

cs 复制代码
public void Show()
{
    Console.WriteLine("数组包含{0}个元素", count);
    Console.WriteLine("数组容量大小为{0}", capacity);
    for (int i = 0; i < count; i++)
    {
        Console.WriteLine(arrayList[i]);
    }
}

六、任务二实现原理分析

1. 动态扩容机制

当数组元素数量达到当前容量时,创建一个容量翻倍的新数组,并将原有元素拷贝到新数组中。这种策略保证了添加操作的平均时间复杂度为 O(1)。

2. 内存管理

在删除元素时,需要将删除位置后的所有元素向前移动一位,并将最后一个元素设置为默认值,避免内存泄漏。

3. 泛型支持

使用泛型类型参数 T,使得该数组可以存储任何类型的元素,同时保持类型安全


七、任务二完整代码

cs 复制代码
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace 进阶测试
{
    class ArrayList<T>
    {
        public T[] arrayList=new T[16];
        public int count = 0;//数组的实际容量
        public int capacity = 16;
        /// <summary>
        /// 增
        /// </summary>
        /// <param name="value">添加的值</param>
        public void Add(T value)
        {
            if(count< capacity)
            {
                arrayList[count]=value; 
                count++;
            }
            else
            {
                T[] newarray = new T[capacity*=2];
                for (int i = 0; i < arrayList.Length; i++)
                {
                    newarray[i] = arrayList[i];
                }
                newarray[capacity - 1] = value;//把待添加的值传给数组
                count++;
                arrayList = newarray;
            }
        }
        
        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="index">需要删除的下标</param>
        public void Remove(int index)//删
        {
            if(index>=0&&index<count)//确保下标在正确的范围内
            {
                for (int i = index; i < count - 1; i++) // ✅ 使用局部变量i
                {
                    arrayList[i] = arrayList[i + 1];
                }
            }
            // 清空最后一个元素的引用(避免内存泄漏)
            arrayList[count - 1] = default(T);
            count--; // 减少实际元素计数
        }

        /// <summary>
        /// 删除(按照值)
        /// </summary>
        /// <param name="value"></param>
        public void RemoveAt(T value)//删
        {
            int index = -1;
            for (int i = 0; i < count; i++)
            {
                if (arrayList[i].Equals(value))
                {
                    index=i; //保留相等的下标位置
                    break;
                }
            }
            if(index!=-1)
            {
                Remove(index);
            }
            else
            {
                Console.WriteLine("数组中没有找到值为{0}",value);
            }
        }

        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="index">需要修改的下标和修改的值</param>
        public void Modify(int index,T value)
        {
            if(index>=0&&index<count)
            arrayList[index]=value;
            else
            {
                Console.WriteLine("请输入正确的下标");
                return; 
            }
        }

        /// <summary>
        /// 查(索引器实现)
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public T this[int index]
        {
            get
            {
                if (index < 0 || index >= count) // ✅ 修正条件判断
                {
                    Console.WriteLine("请输入合法的索引");
                    return default(T);
                }
                return arrayList[index];
            }
            set
            {
                if (index < 0 || index >= count) // ✅ 添加范围检查
                {
                    Console.WriteLine("请输入合法的索引");
                    return;
                }
                arrayList[index] = value;
            }
        }


        /// <summary>
        /// 遍历显示数组信息
        /// </summary>
        public void Show()//遍历显示数组
        {
            Console.WriteLine("数组包含{0}个元素", count);
            Console.WriteLine("数组容量大小为{0}", capacity);
            for (int i = 0; i < count; i++)
            {
                Console.WriteLine(arrayList[i]);
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            ArrayList<int> array = new ArrayList<int>();
            Console.WriteLine("*********增加***********");
            array.Add(1);
            array.Add(2);
            array.Add(4);
            array.Add(5);
            array.Add(26);
            array.Show();
            Console.WriteLine("**********修改**********");
            array.Modify(1, 999);
            array.Show();
            Console.WriteLine("***********删除(下标)*********");
            array.Remove(0);
            array.Show();
            Console.WriteLine("***********删除(值)*********");
            array.RemoveAt(999);
            array.Show();
            Console.WriteLine("***********查看*********");
            Console.WriteLine(array[0]);
            Console.WriteLine(array[1]);
            Console.WriteLine(array[2]);
        }
    }
}
相关推荐
wangyue44 小时前
Doxygen with C#
c#
嵌入式小李.man5 小时前
C++第十篇:const关键字
开发语言·c++
码界筑梦坊5 小时前
194-基于Python的脑肿瘤患者数据分析可视化
开发语言·python·数据分析·sqlite·毕业设计·echarts·fastapi
郝学胜-神的一滴5 小时前
基于Linux,看清C++的动态库和静态库
linux·服务器·开发语言·c++·程序人生
爱吃小胖橘5 小时前
Unity-动画基础
unity·c#·游戏引擎
江上清风山间明月5 小时前
flutter 编译报错java.util.zip.ZipException: zip END header not found
java·开发语言·flutter
蓁蓁啊5 小时前
VMware 性能优化完整指南
开发语言·单片机·嵌入式硬件·物联网·性能优化·鸿蒙系统
hrrrrb6 小时前
【Python】迭代器
开发语言·python
澄澈i6 小时前
设计模式学习[19]---单例模式(饿汉式/懒汉式)
学习·单例模式·设计模式