1泛型

泛型

带有<>符合的类型,就叫泛型
T:Type

作用:代码重用,提高效率,类型安全

分类:泛型方法,泛型类

特点:

延迟声明:定义的时候就是一个占位符,

泛型方法:

Public T 方法名(T t)
{

}

基本使用1

 public static T SayHello<T>(T t)
        {
            return t;
        }
 int i = SayHello<int>(1);
string ii = SayHello<string>("a");
double db = SayHello<double>(3.14);
Program pro = SayHello<Program>(new Program());
Children children = SayHello<Children>(new Children());

基本使用2

 public static void Eat<E>(E e)
        {
            Console.WriteLine("吃方法");
        }

在main里调用这个方法用这两种方式都可以,因为这里方法是将泛型作为参数使用而已,泛型本身可以通过传递进来的参数判断类型的,所以这里使用时候也可以不用指定泛型类型
Eat("张三");
或者
Eat<string>("张三");
但是,如果使用时候指定了泛型类型就要给指定的类型的类型值,否则会报错

使用场景:

      //用泛型当作参数使用时,在调用该方法时,可以根据参数推断出类型,也就是可以在使用时不用给类型,直接写参数,如:
        public static void Show<T>(T param)
        {

            Console.WriteLine(param.GetType().Name + " " + param);
        }


        //当返回值使用,调用这个方法时候再具体给返回值类型
        public static T Show<T>()
        {

            //为什么不能直接返回T,因为值类型可以为null,引用类型不可以为null,而且在这个方法里还不确定具体返回是值类型还是引用类型。
            //default关键字,如果返回的是一个为空的引用类型,那就返回null,值类型就返回0,
            return default(T);

        }


        //当局部变量使用,一般都要加约束
        public static T Show<T>(int a) where T : struct
        {

            T t = new T();//值类型都有一个隐式的公共无参数的构造方法

            return t;
        }
	
	
	

泛型类

泛型类在实例化的时候必须指定泛型的类型,就像list集合那样

//泛型类
    public class Person<T>
    {
        public T Name { get; set; }

    }

泛型约束

可以限制泛型传递的类型(设置泛型的类型),给类的多个泛型类型添加泛型约束也是在后面添加where即可,每个泛型类型都是用where分隔
where T:struct :限制T必须是值类型

where T:class :限制T必须是引用类型

where T:new() :限制T必须有一个无参构造函数

where T:具体的类 :类本身和它的子类,约束了泛型的类型为这个类的子类

组合约束:where T:具体的类,new()

比如:要求数泛型必须是某个类的子类,并且这个泛型可以在里面实例化

public static T SayHello<T>(T t) where T : Program, new()
        {
            return t;
        }
 Program pro = SayHello<Program>(new Program());
            Children children = SayHello<Children>(new Children());	

上面用到的Children类是Program的子类


泛型约束配泛型类的基本使用

 class Program
    {
        static void Main(string[] args)
        {
            //因为设置了泛型约束,所以这里只能给Person类型,或者是继承了Person类型的子类类型
            PersonHelper<Person> personHelper = new PersonHelper<Person>(new Person() { Id = 1, UserName = "张三" });

            personHelper.GetPerson();

            Console.ReadKey();
        }
    }

    public class Person
    {
        public int Id { get; set; }

        public string UserName { get; set; }

    }



    //让泛型类型T为Person的子类
    public class PersonHelper<T> where T : Person
    {

        private T _t = null;//有泛型约束才可以将泛型为空,否则如果传入的泛型类型为值类型则会报错。

        public PersonHelper(T t)//构造方法
        {
            _t = t;

        }

        //调用创建泛型实例的方法
        public T GetPerson()
        {

            T t = (T)Activator.CreateInstance(typeof(T));//这里只能使用反射创建泛型T的实例,
                                                         //如果使用default(T);的话下面对泛型T的属性赋值会报异常,因为Default(T);也只是给一个null而已,并没有实例化
            
             // T t = new T();//也可以通过给泛型T添加new()约束,这样就可以避免通过反射进行实例化

            t.UserName = _t.UserName;
            t.Id = _t.Id;
            return t;

        }

    }
posted @ 2021-10-30 16:44  青仙  阅读(87)  评论(0编辑  收藏  举报