C#【进阶】泛型

1、泛型

在这里插入图片描述

1、泛型是什么

泛型实现了类型参数化,达到代码重用目的
通过类型参数化来实现同一份代码上操作多种类型
    
泛型相当于类型占位符
定义类或方法时使用替代符代表变量类型
当真正使用类或方法时再具体指定类型

2、泛型分类

泛型类和泛型接口
	基本语法
    class 类名<泛型占位字母>
    interface 接口名<泛型占位字母>

泛型函数
    基本语法
    函数名<类型占位字母>(参数列表)
//泛型占位字母可以有多个,用逗号分开

3、泛型类和接口

TestClass<int> t = new TestClass<int>();
t.value = 1;

TestClass<string> t2 = new TestClass<string>();
t2.value = "ok";

TestClass2<int, string, float, bool> t3 = new TestClass2<int, string, float, bool>();
class TestClass<T>
{
    public T value;
}
class TestClass2<T, M, L,Key>
{
    public T Value;
    public M GetM;
    public L GetL;
    public Key GetKey;
}
interface TestInsterface<T>
{
    T vale
    {
        get;
        set;
    }
}
class Test : TestInsterface<int>
{
    public int vale { get; set ;}
}

4、泛型方法

1、普通类中的泛型方法
    Test2 test2 = new Test2();
    test2.Fun<string>("ok");

    class Test2
    {
        public void Fun<T>(T val)
        {
            Console.WriteLine(val);
        }

        public void Fun<T>()
        {
            //用泛型类型,做一些逻辑处理
            T t = default(T);
        }

        public T Fun<T>(string test)
        {
            return default(T);
        }

        public void Fun<T,K,M>(T t, K k, M m){}
    }

2、泛型类中的泛型方法
    Test2<int> test3 = new Test2<int>();
    test3.Fun(1.2f);
    test3.Fun(true);
    test3.Fun(10);

    class Test2<T>
    {
        public T value;
        //这个不是泛型方法,因为T是泛型类声明的时候就指定类型了
        public void Fun(T t)
        {

        }
        public void Fun<T>(T t) { }
    }

5、泛型的作用

1、不同类型对象的相同逻辑处理就可以使用泛型
2、使用泛型可以一定程度避免装箱拆箱
例如:优化ArrayList
class ArrayList<T>
{
    private T[] array;

    public void Add(T value)
    {

    }
    public void Remove(T value)
    {

    }
}
思考 泛型方法判断类型
//定义一个泛型方法,方法内判断该类型为何类型,并返回类型的名称与占有的字节数
//如果是int,则返回整形,4字节
//只考虑int,char,float,string,如果是其他类型,则返回其他类型
//可以通过typeof(类型) == typeof(类型)的方式进行类型判断
Console.WriteLine(Fun<int>());
Console.WriteLine(Fun<char>());
Console.WriteLine(Fun<float>());
Console.WriteLine(Fun<string>());
Console.WriteLine(Fun<bool>());
Console.WriteLine(Fun<uint>());

string Fun<T>()
{
    if (typeof(T) == typeof(int))
    {
        return string.Format("{0},{1}字节","整形",sizeof(int));
    }
    else if (typeof(T) == typeof(char))
    {
        return string.Format("{0},{1}字节", "字符", sizeof(char));
    }
    else if (typeof(T) == typeof(float))
    {
        return string.Format("{0},{1}字节", "单精度浮点数", sizeof(float));
    }
    else if (typeof(T) == typeof(string))
    {
        return  "字符串";
    }
    return "其他类型";
}

2、泛型约束

1、什么是泛型

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

2、各泛型约束

1、值类型	
    Test1<int> test1 = new Test1<int>();
    test1.TestFun(1.2f);
    class Test1<T> where T : struct
    {
        public T value;
        public void TestFun<K>(K k) where K : struct
        {

        }
    }
2、引用类型
    Test2<Random> t2 = new Test2<Random>();
    t2.value = new Random();
    t2.TestFun(new Object());
    class Test2<T> where T : class
    {
        public T value;
        public void TestFun<K>(K k) where K : class { }
    }
3、存在无参公共构造函数
    Test3<Test1> t3 = new Test3<Test1>();
    Test3<Test2> t4 = new Test3<Test2>();//必须是具有公共的无参构造函数的非抽象类型
    class Test3<T> where T : new()
    {
        public T value;
        public void TestFun<K>(K k) where K : new() { }
    }
    class Test1 { }
    class Test2 
    {
        public Test2(int i) { }
    }
4、类约束
    Test4<Test1> t4 = new Test4<Test1>();
    Test4<Test2> t5 = new Test4<Test2>();

    class Test4<T> where T : Test1
    {
        public T value;
        public void TestFun<K>(K k) where K : Test1 { }
    }
    class Test1 { }
    class Test2 : Test1
    {
        public Test2(int i) { }
    }
5、接口约束
    Test5<IFoo> t6 = new Test5<IFoo>();
    Test5<Test1> t5 = new Test5<Test1>();
    class Test5<T> where T : IFoo
    {
        public T value;
        public void TestFun<K>(K k) where K : IFoo { }
    }
    interface IFoo { }
    class Test1 : IFoo{ }
6、另一个泛型约束
    Test5<Test1,IFoo> t6 = new Test5<Test1,IFoo>();
    Test5<Test1, Test1> t7 = new Test5<Test1, Test1>();
    class Test5<T,U> where T : U
    {
        public T value;
        public void TestFun<K,V>(K k) where K : V { }
    }
    interface IFoo { }
    class Test1 : IFoo { }

3、约束的组合使用

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

4、多个泛型有约束

class Test8<T,K> where T:class,new() where K:struct{}
思考1 泛型实现单例模式
//用泛型实现一个单例模式基类

Test.Instance.value = 2;
GameMgr.Instance.value = 3;
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;

}
class Test
{
    private static Test instance = new Test();
    public int value = 10;
    private Test() { } 
    public static Test Instance {  get { return instance;} }
}
思考2 ArrayList泛型实现增删查改
//利用泛型知识点,仿造ArrayList实现一个不确定数组类型的类
//实现增删查改方法
ArrayList<int> array = new ArrayList<int>();
Console.WriteLine(array.Count);
Console.WriteLine(array.Capacity);
array.Add(1);
array.Add(2);
array.Add(4);
Console.WriteLine(array.Count);
Console.WriteLine(array.Capacity);

Console.WriteLine(array[1]);
Console.WriteLine(array[3]);

array.Remove(2);
Console.WriteLine(array.Count);
for (int i = 0; i < array.Count; i++)
{
    Console.WriteLine(array[i]);
}

array[0] = 88;
Console.WriteLine(array[0]);
ArrayList<string> array2 = new ArrayList<string>();

class ArrayList<T>
{
    private T[] array;
    //当前存了多少数
    private int count;
    public ArrayList()
    {
        count = 0;
        //开始容量为16
        array = new T[16];
    }
    public void Add(T value)
    {
        //是否要扩容
        if (count >= Capacity)
        {
            //每次扩容两倍
            T[] newArray = new T[Capacity * 2];
            for (int i = 0; i < Capacity; i++)
            {
                newArray[i] = array[i];
            }
            //重写指向地址
            array = newArray;
        }
        //不需要扩容
        array[count++] = value;
    }
    public void Remove(T value)
    {
        int index = -1;
        //遍历存的值,而不是数组的容量
        for (int i = 0; i < Count; i++)
        {
            if (array[i].Equals(value))
            {
                index = i;
                break;
            }
        }
        if (index != -1)
        {
            RemoveAt(index);
        }
    }
    public void RemoveAt(int index)
    {
        if (index < 0 || index >= Count)
        {
            Console.WriteLine("索引不合法");
            return;
        }
        //删除后,将空出来的位置前移
        for (; index < Count - 1; index++)
        {
            array[index] = array[index + 1];
        }
        //把最后剩下的位置设为默认值
        array[Count - 1] = default(T);
        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;
        }
    }
}
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值