1.泛型
作用:减少成员膨胀或者类型膨胀
1.1认识泛型
假设,一个小卖部只有苹果卖且可以提供给客户打包苹果的服务
namespace ConsoleApp3
{
class Program
{
static void Main(string[] args)
{
Apple objApple = new Apple() { Color = "Red" };
Box box = new Box() { Cargo = objApple };
Console.WriteLine(box.Cargo.Color);
Console.ReadLine();
}
}
class Apple
{
public string Color { get; set; }
}
class Box
{
public Apple Cargo { get; set; }
}
}
- 随着业务逐渐庞大,小卖部开始卖其他产品,书,饮料...,此时,就需要给每个商品类,添加对应的盒子类,使得类型膨胀,解决这种问题,需要使用泛型
- 泛型的定义
class Name<类型参数>
namespace ConsoleApp3
{
class Program
{
static void Main(string[] args)
{
Apple apple1 = new Apple() { Color = "Red" };
Book book1 = new Book() { BookName = "fxx" };
//所以泛型都不直接使用,使用前续特化,转为具体的类
Box<Apple> box1 = new Box<Apple>() { Cargo = apple1 };
Box<Book> box2 = new Box<Book>() { Cargo = book1 };
Console.WriteLine(box1.Cargo.Color);
Console.WriteLine(box2.Cargo.BookName);
}
}
class Apple
{
public string Color { get; set; }
}
class Book
{
public string BookName { get; set; }
}
class Box<TCargo>
{
public TCargo Cargo { get; set; }
}
}
image.png
1.2 泛型方法
- 泛型用作参数
namespace ConsoleApp3
{
class Program
{
static void Main(string[] args)
{
Show<int>(1);
Show<string>("Fxx");
Console.ReadKey();
}
public static void Show<T>(T t)
{
Console.WriteLine(t.GetType().Name + ":" + t);
}
}
}
>>>
Int32:1
String:Fxx
- 可以为多个参数
namespace ConsoleApp3
{
class Program
{
static void Main(string[] args)
{
Show<string>("fxx", "jkk");
Console.ReadKey();
}
public static void Show<T>(T a ,T b)
{
Console.WriteLine(a);
Console.WriteLine(b);
}
}
}
- 用来做返回值
namespace ConsoleApp3
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(Show<int>());
Console.ReadKey();
}
public static T Show<T>()
{
//default:用来返回默认值
return default(T);
}
}
}
>>>
0
- 用于当做局部变量
namespace ConsoleApp3
{
class Program
{
static void Main(string[] args)
{
Console.ReadKey();
}
public static void Show<T>(int a ,int b)
{
T t; //局部变量
}
}
}
1.3 泛型约束
- 有两个主要的约束:class 引用约束和 struct 值类型约束
namespace ConsoleApp3
{
class Program
{
static void Main(string[] args)
{
Show<int>(); //值类型 报错
Show<string>();
Console.ReadKey();
}
public static void Show<T>() where T:class //规定传入的类型只能是引用类型
{
T temp = null;
}
}
}
-
new()
约束:一定要有一个无参数的构造方法
namespace ConsoleApp3
{
class Program
{
static void Main(string[] args)
{
Show<string>(); //字符串无,报错
Show<double>();
Show<double>();
Console.ReadKey();
}
public static void Show<T>() where T:new ()
{
}
}
}
- 自定义约束
namespace ConsoleApp3
{
class Program
{
static void Main(string[] args)
{
Show<Studnet>(); //不是指定的类报错
Show<MyClass>();
Console.ReadKey();
}
public static void Show<T>() where T: MyClass //只能传递指定的类
{
}
}
class Student
{
}
class MyClass
{
}
}
-
接口约束
image.png
1.3泛型接口
namespace ConsoleApp3
{
class Program
{
static void Main(string[] args)
{
Student<int> stu1= new Student<int>();
Student<ulong> stu2 = new Student<ulong>();
stu1.Id = 101;
stu1.Name = "fxx";
stu2.Id = 10000001;
stu2.Name = "hjj";
}
}
//泛型接口:常用
interface IUnique<T>
{
T Id { get; set; }
}
//学生类实现接口,使用泛型接口,那么该类也需要改成泛
class Student<T> : IUnique<T>
{
public T Id { get; set; }
public string Name { get; set; }
}
}
interface IUnique<T>中,T是泛型参数,作为参数的,那么传入Student他表示的就是 Student Id
,传入Book他表示的就是Book Id
- 方法二:直接规定类型
namespace ConsoleApp3
{
class Program
{
static void Main(string[] args)
{
Student stu2 = new Student();
stu2.Id = 10000001;
stu2.Name = "hjj";
}
}
//泛型接口
interface IUnique<T>
{
T Id { get; set; }
}
//直接规定学生接的形式
class Student: IUnique<ulong>
{
public ulong Id { get; set; }
public string Name { get; set; }
}
}
1.2
1.3 泛型委托
- 无返回值的泛型委托
namespace ConsoleApp3
{
class Program
{
static void Main(string[] args)
{
Action<string> a1 = Say;
a1("fxxxx");
Action<int> a2 = Mul;
a2(100);
Console.ReadKey();
}
static void Say(string str)
{
Console.WriteLine(str);
}
static void Mul(int x)
{
Console.WriteLine(x * 1000);
}
}
}