入门泛型(C#)

一、泛型定义

允许编写一个可以与任何数据类型一起工作的类或方法

二、泛型类型

  • 类:class 类名<占位字符>
  • 函数:返回值类型 函数名<占位字符>(参数类型 参数1,...)

三、实例演示(类与函数)

1、创建一个数组类

class MyArray<T>//数组类
    {
        private T[] myarray;//数组定义
        public int MyarrayLength//属性获取数组长度
        {
            get
            {
                return myarray.Length;
            }
        }

        public MyArray(int size)//构造函数初始化数组长度
        {
            myarray = new T[size];
        }

        //通过下标获取数组数据
        public T GetMyarrayByIndex(int index)
        {
            return myarray[index];
        }

        //数组赋值
        public void SetMyarrayByindex(int index,T value)
        {
            myarray[index] = value;
        }
    }

2、在主函数中调用与使用,int类型

            MyArray<int> intMyarray = new MyArray<int>(5);//实例化并调用构造函数初始化数组长度为5

            for (int i = 0; i < intMyarray.MyarrayLength; i++)
            {
                intMyarray.SetMyarrayByindex(i, i * 2);//赋值
            }

            for (int i = 0; i < intMyarray.MyarrayLength; i++)
            {
                Console.WriteLine(intMyarray.GetMyarrayByIndex(i));//输出数组
            }

3、string类型

            MyArray<string> stringMyarray = new MyArray<string>(5);//实例化并调用构造函数初始化数组长度为5

            for (int i = 0; i < stringMyarray.MyarrayLength; i++)
            {
                stringMyarray.SetMyarrayByindex(i, (i * 2).ToString());//赋值
            }

            for (int i = 0; i < stringMyarray.MyarrayLength; i++)
            {
                Console.WriteLine(stringMyarray.GetMyarrayByIndex(i));//输出数组
            }

4、完整代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

/*
    泛型:允许编写一个可以与任何数据类型一起工作的类或方法

    类:class 类名<占位字符>
    函数:返回值类型 函数名<占位字符>(参数类型 参数1,...)
 */

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            MyArray<int> intMyarray = new MyArray<int>(5);//实例化并调用构造函数初始化数组长度为5

            for (int i = 0; i < intMyarray.MyarrayLength; i++)
            {
                intMyarray.SetMyarrayByindex(i, i * 2);//赋值
            }

            for (int i = 0; i < intMyarray.MyarrayLength; i++)
            {
                Console.WriteLine(intMyarray.GetMyarrayByIndex(i));//输出数组
            }

            MyArray<string> stringMyarray = new MyArray<string>(5);//实例化并调用构造函数初始化数组长度为5

            for (int i = 0; i < stringMyarray.MyarrayLength; i++)
            {
                stringMyarray.SetMyarrayByindex(i, (i * 2).ToString());//赋值
            }

            for (int i = 0; i < stringMyarray.MyarrayLength; i++)
            {
                Console.WriteLine(stringMyarray.GetMyarrayByIndex(i));//输出数组
            }
        }
    }
    class MyArray<T>//数组类
    {
        private T[] myarray;//数组定义
        public int MyarrayLength//属性获取数组长度
        {
            get
            {
                return myarray.Length;
            }
        }

        public MyArray(int size)//构造函数初始化数组长度
        {
            myarray = new T[size];
        }

        //通过下标获取数组数据
        public T GetMyarrayByIndex(int index)
        {
            return myarray[index];
        }

        //数组赋值
        public void SetMyarrayByindex(int index,T value)
        {
            myarray[index] = value;
        }
    }
}

四、泛型是一种增强程序功能的技术

  1. 最大限度的复用代码
  2. 泛型类、泛型函数、泛型接口、泛型委托、泛型事件
  3. 可以对泛型进行约束,从而访问特定的数据类型
  4. 泛型数据类型的类型信息可以利用反射在程序运行时获取

五、泛型委托

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    public delegate T numberChanger<T>(T num);//泛型委托声明
    class Program
    {
        static void Main(string[] args)
        {
            Number number = new Number();
            numberChanger<int> nc1 = new numberChanger<int>(number.AddNum);//int
            Console.WriteLine(nc1(5));
            numberChanger<double> nc2 = new numberChanger<double>(number.MulNum);//double
            Console.WriteLine(nc2(5));
        }
    }
    class Number
    {
        public int AddNum(int num)
        {
            return num += num;
        }
        public double MulNum(double num)
        {
            return num *= num;
        }
    }
}

六、约束

因为泛型的泛用性,我们一般需要约束其范围,关键字where

约束语法:

  • 值类型:where T:struct    (int、bool、byte、double等)
  • 引用类型:where T:class    (对象、字符串、委托、数组等)
  • 必须存在无参构造函数:where T:new()
  • 类的派生:where T:类名
  • 接口的派生:where T:接口名
  • 泛型派生:where T:U  --另一个泛型

案例演示

1、值类型

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            //泛型类 加上值类型约束
            Test1<int> t1 = new Test1<int>();
            t1.value = 100;
            //使用引用类型对象给值类型约束赋值,报错
            //Test1<string> t2 = new Test1<string>();
            //t2.value = "abc";
        }
    }
    //泛型类 加上值类型约束  where T:struct
    class Test1<T> where T:struct
    {
        public T value;
        //泛型函数,加上值类型约束
        public void TestMethod<K>() where K : struct
        {

        }
    }
}

报错如下:

2、引用类型

与前面相反

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            //使用值类型对象给引用类型约束赋值,报错
            //Test1<int> t1 = new Test1<int>();
            //t1.value = 100;
            //泛型类 加上值类型约束
            Test1<string> t2 = new Test1<string>();
            t2.value = "abc";
        }
    }
    //泛型类 加上引用类型约束  where T:class
    class Test1<T> where T:class
    {
        public T value;
        //泛型函数,加上引用类型约束
        public void TestMethod<K>() where K : class
        {

        }
    }
}

报错如下:

3、必须存在无参构造函数

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            //必须存在无参构造函数约束
            Test1<Test2> t1 = new Test1<Test2>();
            t1.TestMethod<Test2>();
            //当不存在无参构造函数 报错
            //Test1<Test3> t2 = new Test1<Test3>();
            //t2.TestMethod<Test3>();
        }
    }
    //泛型类 必须存在无参构造函数  where T:new()
    class Test1<T> where T : new()
    {
        //泛型函数,加上必须存在无参构造函数约束
        public void TestMethod<K>() where K : new()
        {

        }
    }
    class Test2
    {

    }
    class Test3
    {
        public Test3(int a)//有参构造函数
        {

        }
    }
}

报错如下:

4、类的派生

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            //类名作为约束
            Test1<Test2> t1 = new Test1<Test2>();
            Test1<Test3> t2 = new Test1<Test3>();
            //使用时,只能使用该类本身或者该类的派生类,否则报错
            //Test1<Test4> t3 = new Test1<Test4>();
        }
    }
    //泛型类 加上某个类名作为约束,代表T类型必须是该类本身或者是该类的派生类
    class Test1<T> where T : Test2
    {

    }
    class Test2
    {

    }
    class Test3 : Test2
    {

    }
    class Test4
    {

    }
}

报错如下:

5、接口的派生

和前面类似

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            //接口名作为约束
            Test1<ITest2> t1 = new Test1<ITest2>();
            Test1<ITest3> t2 = new Test1<ITest3>();
            //使用时,只能使用该接口本身或者该接口的派生类,否则报错
            //Test1<ITest4> t3 = new Test1<ITest4>();
        }
    }
    //泛型类 加上某个接口名作为约束,代表T类型必须是该接口本身或者是该接口的派生类
    class Test1<T> where T : ITest2
    {

    }
    interface ITest2
    {

    }
    interface ITest3 : ITest2
    {

    }
    interface ITest4
    {

    }
}

报错如下:

6、泛型派生

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            //泛型作为约束
            Test1<Test3, ITest2> t1 = new Test1<Test3, ITest2>();
            //使用时,只能使用该泛型(U)本身或者该泛型(U)的派生类,否则报错
            //Test1<Test3, Test4> t2 = new Test1<Test3, Test4>();
        }
    }
    //泛型类 加上另一个泛型占位符作为约束,代表T类型必须和U类型是同一类型或者是他的派生类型
    class Test1<T,U> where T : U
    {
        
    }
    interface ITest2
    {

    }
    class Test3 : ITest2
    {

    }
    class Test4
    {

    }

}

报错如下:

7、多个约束组合

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            //多个约束条件使用
            Test1<Test2> t1 = new Test1<Test2>();
            //当有多个约束条件时,那么需要都满足
            //Test1<Test3> t2 = new Test1<Test3>();
        }
    }
    //泛型类 多个约束组合
    class Test1<T> where T : class, new()
    {
        
    }
    class Test2
    {

    }
    class Test3
    {
        public Test3(int a)
        {

        }
    }

}

报错如下:

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

落缨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值