第16天c#基础泛型和数据结构

泛型

泛型类

允许您延迟编写类或方法中的编程元素的数据类型的规范,直到实际在程序中使用它的时候。

泛型相当于类型占位符

定义

 //定义格式:访问修饰符 class 类名<T>    //T为替代的类型参数,可以用任意字母数字组合,
    //          {
    //                public T value;
    //          }
    //定义格式:访问修饰符 class 类名<T>
    //          {
    //                public T value;
    //          }
    public class Test<T>
    {
        public T value;
        public void Call()
        {
            Console.WriteLine(value.GetType());
        }

    }
    public class Test1<T1,T2>    //通常使用T,多个泛型时,使用逗号分隔<T0,T1,T2>
    {
        public T1 value1;
        public T2 value2;
    }

使用

泛型类在使用时,需要指定类型,类中使用代替符号

定义的变量都为该指定类型

        static void Main(string[] args)
        {
            Test<int> t1 = new Test<int>();
            Test<string> t = new Test<string>();
            t.value = "10";
            t.Call();

            Test1<string, int> t2 = new Test1<string, int>();

        }

泛型方法

T类型可以用在形参的类型,也可以用在返回值类型,也可以在方法内使用

定义

        //无参无返回值
        static void Fun1<T>()
        {
            Console.WriteLine("我是无参无返回值");
        }
        //无参有返回值
        static T Fun2<T>()
        {
            
            return default(T);
        }
        //有参无返回值
        static void Fun3<T>(T t1)
        {
            if(t1 is int )
            {
                Console.WriteLine("T1是int");

            }
        }
        //有参有返回值
        static T0 Fun4<T0, T1>(T0 t0, T1 t1)
        {
            return t0;
        }

使用

泛型方法在使用时,需要指定类型,方法中使用代替符号定义的变量或返回值,则都为该指定类型。

可以通过default类获取该类型的默认值

        static void Main(string[] args)
        {
            Fun1<string>();
            int f = Fun2<int>();
            Console.WriteLine("无参有返回值:{0}",f);
            //Fun3<int>(1);                           //如果有参数 <>内可以省略
            Fun3(1);
            //string f4 = Fun4<string, int>("", 2);   //如果有参数 <>内可以省略
            string f4 = Fun4("abc", 2);
            Console.WriteLine("Fun4结果:{0}",f4);
        }

效果:

泛型约束

        //where T:struct                    指定类型,必须是值类型
        //where T:class                     指定类型,必须是引用类型
        //where T:new()                     指定类型,必须有无参数的公共构造函数
        //where T:类名                       指定类型,必须是该类名或该类的派生类
        //where T:接口名                     指定类型,必须是该接口或继承该接口的类型
        //where T:U                         指定类型,该类型必须是U类型或U类型的派生类型
        //where T:class, new()              对同一个泛型进行多个约束,中间用“,”隔开
        //where T0:struct where T1:class    对多个泛型进行分别约束,两个where间用空格隔开
    class Program
    {
        static void Main(string[] args)
        {
            Test<int> t1 = new Test<int>();
            //Test<string> t2 = new Test<string>();
            Test1<string> t2 = new Test1<string>();

            //Test2<Test3> t3 = new Test2<Test3>();
            Test4<Test3> t4 = new Test4<Test3>();
            Test4<Tool> t5 = new Test4<Tool>();

            Test5<IFly> t6 = new Test5<IFly>();
            Test5<Tool> t7 = new Test5<Tool>();

            Test6<Test3> t8 = new Test6<Test3>();
            t8.Function<Tool>();
        }
    }
    public class Test<T> where T:struct
    {

    }
    public class Test1<T> where T : class//引用类型
    {

    }
    public class Test2<T> where T : new()//必须有无参数的公共构造函数
    {

    }
    public class Test3
    {
        //private Test3()
        //{

        //}
    }
    public class Tool:Test3,IFly
    {
        public void Fly()
        {

        }
    }
    public class Test4<T> where T:Test3
    {

    }

    public interface IFly
    {
        void Fly();
    }
    public class Test5<T> where T :IFly
    {

    }

    public class Test6<U>
    {
        public void Function<T>() where T:U
        {

        }
    }

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

    }
    //public class Test8<T> where T:struct,new()
    //{

    //}
    /// <summary>
    /// 对每一个泛型进行单独约束
    /// </summary>
    /// <typeparam name="T0"></typeparam>
    /// <typeparam name="T1"></typeparam>
    public class Test8<T0,T1> where T0:struct where T1:class
    {

    }

补充练习

    public class Person
    {
        public string name;
    }
    public class Player : Person
    {

    }
    interface IFly
    {
        void Fly();
    }

    class Pig:IFly
    {
        public void Fly()
        {
            Console.WriteLine("猪真的飞了");
        }
    }
    class Program
    {
        
        static void Main(string[] args)
        {
            Test<Student> t1 = new Test<Student>();     //struct结构体是数值型,符合约束类型
            //Test<string> t2 = new Test<string>();       //数组、字符串等是引用类型 ,所以无法创建对象

            Test2<int[]> t3 = new Test2<int[]>();       //class约束只能用引用类型
            t3.value = new int[3];                      //实例化一个int类型数组
            t3.value[0] = 1;
            Console.WriteLine(t3.value[0]);

            Test3<Student> t4 = new Test3<Student>();
            t4.value.name = "吕布";
            Console.WriteLine("t4:{0}",t4.value.name);

            //Test4<int> t5 = new Test4<int>();           //因为指定类名Person只能用Person或者其派生类Player类型
            Test4<Player> t6 = new Test4<Player>();
            t6.value = new Player();                        //需要先实例化指定类名的类
            t6.value.name = "指定类名";
            Console.WriteLine(t6.value.name);

            Test5<Pig> t7 = new Test5<Pig>();
            t7.value = new Pig();                           //指定类型为class类名的都要实例化
            t7.value.Fly();

            Test6<Pig> t8 = new Test6<Pig>();
            t8.value = new Pig();
            t8.Can<Pig>();                                  //没搞明白。。。

            Test7<Player> t9 = new Test7<Player>();
            t9.value = new Player();
            t9.value.name = "多种约束";
            Console.WriteLine(t9.value.name);

            Test8<Student, Player> t10 = new Test8<Student, Player>();
            t10.value.name = "泛型1";
            t10.value2 = new Player();
            t10.value2.name = "泛型2";
            Console.WriteLine("value:{0},value2:{1}",t10.value.name,t10.value2.name);

        }
    }

    class Test<T> where T:struct
    {                                       //必须是值类型
        public T value;
    }
    struct Student:IFly
    {
        public string name;
        public int age;
        public void Fly()
        {
            Console.WriteLine("学生也会飞");
        }
    }
    class Test2<T> where T:class
    {                                       //必须是引用类型
        public T value;
    }

    class Test3<T> where T:new()            //指定类型,必须有无参的公开构造函数 结构体和类都可以
    {
        public T value;
    }

    class Test4<T> where T: Person
    {
        public T value;
    }
    class Test5<T> where T:IFly
    {
        public T value;
    }

    class Test6<U>                                                      //U可以换成任意字母 约束该类
    {
        public U value;
        public void Can<T>() where T:U                                  //对方法约束,指定类型和该类指定的类型一样
        {
            Console.WriteLine("跟类指定的类型相同的方法");
        }
    }

    class Test7<T> where T:Person, new()                                    //对一个泛型进行多种约束 “,”分割
    {
        public T value;
    }

    class Test8<T1,T2> where T1:struct where T2:new()                       //对多种泛型分别约束  空格隔开
    {   
        public T1 value;
        public T2 value2;
    }

泛型接口

泛型实例:单例

        static void Main(string[] args)
        {
            Student s = Student.Instance;     
            Student s2 = Student.Instance;
            s.name = "s的名字";
            Console.WriteLine(s2.name);

            Person p1 = Person.Instance;
            Person p2 = Person.Instance;
            p1.name = "饿汉模式";
            Console.WriteLine(p2.name);
        }
    }
    //懒汉模式          用的时候才会new一个实例
    public class Singleton<T> where T : class, new()
    {
        private static T _instance;
        public static T Instance
        {
            get
            {
                if (_instance == null)
                {
                    _instance = new T();
                }
                return _instance;
            }
        }
    }
    //饿汉模式          直接new出一个实例
    public class EagerSingleton<T> where T: class,new()  //new()要放在最后
    {
        private static T _instance = new T();                       //定义变量时直接实例一个对象
        public static T Instance
        {
            get { return _instance; }
        }
        
    }
    class Student : Singleton<Student>              //继承懒汉模式 类型放入自己的类型
    {
        public string name;
    }

    class Person:EagerSingleton<Person>             //继承饿汉模式 类型放入自己的类型
    {
        public string name;
    }

数据结构

概念

数据结构是带有结构特性的数据元素的集合

结构特性

线性表

数组、链表

散列表

哈希表、字典。。。

栈(先入后出)

队列(先入先出)

树:二叉树

动态数组

 

练习1

练习2

原文地址:https://www.cnblogs.com/yifengs/p/14099518.html