2020/10/29
前言
本文主要对泛型做一个概述,对委托和事件的一个概述
提示:以下是本篇文章正文内容,下面案例可供参考
一、泛型
1.泛型的定义:声明类和方法时一般都需要定义是什么类,class Brid ,Class Food… 声明泛型类和方法时只需要传入类型的地方用 ,有点类似于占位符的作用,用的时候传入具体的类型。当针对不同类型具有相同行为的时候,也就是泛型发挥作用的时候。
自己对泛型的理解为:假设我开一个小卖部,要买苹果就得拿苹果篮子来装(声明苹果类),卖书的话就得拿书来装(声明书类),这样势必会造成类和成员的膨胀,为了解决这样的问题那么引入了泛型。
2.泛型的优点:
a.使用泛型类、方法,我们可以极大提高代码的重用性,不需要对类型不同代码相同(仅类型参数不同)的代码写多次。
b .创建泛型类,可在编译时创建类型安全的集合
c.避免装箱和拆箱操作降低性能,在大型集合中装箱和拆箱的影响非常大,
下面的代码主要是针对泛型使用的好处,泛型类,泛型接口,泛型委托,泛型方法的了解:
代码如下(示例):
namespace fanxing
{
class Program
{
static void Main(string[] args)
{
#region 泛型委托,加一句Lambda表达式
--->Action泛型委托,他是给没有返回值用的。
Action<string> a1 = Say;
a1.Invoke("Timothy");
Action<int> a2 = Mul;
a2(2);
Func<int, int, int> func1 = Add;
Console.WriteLine(func1(100, 200));
Func<double, double, double> func2 = Add;
Console.WriteLine(func2(100.1,200.2));
Func<int, int, int> func3 = (int a, int b) => { return a + b; };
Console.WriteLine(func3.Invoke(200, 200));
#endregion
#region 写一点泛型集合常见的列子
IDictionary<int, string> dict = new Dictionary<int, string>();
dict[1] = "Timothy";
dict[2] = "Michael";
Console.WriteLine($"Student #1 is {dict[1]}");
Console.WriteLine($"Student #2 is {dict[2]}");
IList<int> list = new List<int>();
for (int i = 0; i < 100; i++)
{
list.Add(i);
}
foreach (var item in list)
{
Console.WriteLine(item);
}
#endregion
--->一个类实现的是泛型接口,那么这个类也是泛型类。
Apple apple = new Apple() { Color = "Red" };
Book book = new Book() { Name = "New Book" };
Student<int> student = new Student<int>();
student.ID = 101;
student.Name = "Timothy";
Student student1 = new Student();
student1.ID = 100;
Console.WriteLine(student.ID);
--->好处是这样既不会产生类型膨胀,也不会产生成员膨胀
Box<Apple> box1 = new Box<Apple>() { Cargo = apple };
Box<Book> box2 = new Box<Book>() { Cargo = book };
Console.WriteLine(box1.Cargo.Color);
Console.WriteLine(box2.Cargo.Name);
--->下面这种方式,针对每一个物品都需要一个盒子来装,所以这样会导致类型膨胀,而采用object类型来做的话,就调用不到里面的属性了,所以要采用泛型来做
--->如果是采用泛型来做,这样避免了成员膨胀和类膨胀,而且泛型具有类型推断功能(这就是泛型的具体作用)
BookBox bookBox = new BookBox() { BookCargo = book };
Console.WriteLine(bookBox.BookCargo.Name);
AppleBox appleBox = new AppleBox() { Cargo = apple };
Console.WriteLine(appleBox.Cargo.Color);
Console.ReadKey();
}
#region 为泛型委托提供的方法
static void Say(string str)
{
Console.WriteLine($"Hello,{str}!");
}
static void Mul(int x)
{
Console.WriteLine(x * 100);
}
static int Add(int a, int b)
{
return a + b;
}
static double Add(double a, double b)
{
return a + b;
}
#endregion
}
#region 泛型接口接口中的两种泛型 1.一种是类继承与接口但是但是不特化出具体的数据类型(实例化泛型类的时候才给一定的类型)
--->2.二种是直接特化接口,就直接特化出具体的数据类型
interface IUnique<TId>
{
TId ID { get; set; }
}
--->特化接口,就是继承就给实际类型---->IUnique<ulong>
class Student : IUnique<ulong>
{
public ulong ID { get; set; }
}
interface IUnique1<TId>
{
TId ID { get; set; }
}
--->要继承与一个泛型接口那么这个类也要变为泛型类才行,泛型类中可以包含非泛型成员,因为实现这个接口的时候,没有指定这个接口的中id的类型
---> 就是等着类实例化才去给定这个属性类型
class Student<TId> : IUnique<TId>
{
public TId ID { get; set; }
public string Name { get; set; }
}
#endregion
#region 对泛型的了解提供的代码
class Apple
{
private string color;
public string Color
{
get { return color; }
set { color = value; }
}
}
class Book
{
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
}
--->采用泛型来做。
class Box<T>
{
public T Cargo { get; set; }
}
--->这个类拿来装苹果
class AppleBox
{
private Apple cargo;
public Apple Cargo
{
get { return cargo; }
set { cargo = value; }
}
}
--->这个类拿来装书
class BookBox
{
private Book bookCargo;
public Book BookCargo
{
get { return bookCargo; }
set { bookCargo = value; }
}
}
#endregion
}
二、委托
1.委托概念及其语法
1.委托定义:委托就是一个函数指针,他可以指向一个传进来的函数地址,就是将一个函数作为参数传递给另一个函数
2.关于委托的特性以及规则,匿名函数与Lambda初次了解:
a.传递的函数一定跟委托具有相同的签名,及其返回值
b.函数可以直接赋值给委托
c.匿名函数:如果函数只用一次,不需要再别的地方被重复的调用么可以写成匿名函数
d.Lambda表达式,匿名函数的简化版
e.c#只有Action和Func委托,其中Action是没有返回值的,Func有返回值
代码如下(示例):
class Program
{
static void Main(string[] args)
{
//委托:就是将一个函数作为参数传递给另一个函数
string[] names = {"abcDDEd","dasdaQWEQ", "dasdaQWEQ", "dasdaQWEQ" };
//三个需求:
//第一个需求:把数组中每个元素都变成小写
//第二个需求:把数组中每个元素都变成大写
//第三个需求:把数组中每个元素两遍再加上一对双引号
ProcessStr(names,SToUpper);//这里其实就是把函数传进去了,但是传进去的函数必须要是委托一样的签名和返回值
//传递的函数一定跟委托具有相同的签名
//结论:函数可以直接赋值给委托
//但是其实他在运行时,就是在调用传进去的函数,其实就是委托指向了传进去的那个函数,真的在做事的就是那个函数
//DelSayHi del = SayHiChinese; //new DelSayHi(SayHiChinese);
//del("张三");
//匿名函数:如果函数只用一次,不需要再别的地方被重复的调用么可以写成匿名函数
//SayHi("张三",SayHiEnglish);
SayHi("张三",
delegate(string name)
{
Console.WriteLine("你好{0}~!!!!!!!",name);
}
);
//Lambda表达式,匿名函数的简化版
SayHi("李四", name => { Console.WriteLine("吃了吗?"+name); });
Console.ReadKey();
}
public static void ProcessStr(string[] names, DelProStr del)
{
for (int i = 0; i < names.Length; i++)
{
names[i] = del(names[i]);
}
}
static void SayHi(string name, DelSayHi del)
{
del(name);
}
#region
public static string SToUpper(string name)
{
return name.ToUpper();
}
public static string SToLower(string name)
{
return name.ToLower();
}
public static string SSYH(string name)
{
return "\""+name+"\"";
}
#endregion
static void SayHiChinese(string name)
{
Console.WriteLine("吃了么?" + name);
}
static void SayHiEnglish(string name)
{
Console.WriteLine("nice to meet you " + name);
}
static void SayHiKorea(string name)
{
Console.WriteLine("o ba 思密达" + name);
}
static void SayHiJapanese(string name)
{
Console.WriteLine("o ha yo" + name);
}
}
}
2.委托中的模板方法
定义:相当于是一个工厂,但是这个传进工厂做工的方式,是委托,委托中有包含有方法,自我感觉功能很强大。
代码如下(示例):
namespace 委托模板方法
{
class Program
{
static void Main(string[] args)
{
ProductFactory productFactory = new ProductFactory();
WrapFactory wrapFactory = new WrapFactory();
Func<Product> func1 = new Func<Product>(productFactory.MakePizze);//这里只是传方法
Func<Product> func2 = new Func<Product>(productFactory.MakeToyCar);
Box box1 = wrapFactory.WrapProduct(func1);
Box box2 = wrapFactory.WrapProduct(func2);
Console.WriteLine(box1.Product.Name);
Console.WriteLine(box2.Product.Name);
Console.ReadKey();
}
}
class Product
{
public string Name { get; set; }
}
class Box
{
public Product Product { get; set; }
}
/// <summary>
/// 包装产品
/// </summary>
class WrapFactory
{
public Box WrapProduct(Func<Product> getProduct)//但是这里传进去的参数是委托
{
Box box = new Box();
Product product = getProduct.Invoke();//这里相当于是执行传进来的方法
box.Product = product;
return box;
}
}
/// <summary>
/// 这个类是生产产品,
/// </summary>
class ProductFactory
{
public Product MakePizze()
{
Product product = new Product();
product.Name = "Pizza";
return product;
}
public Product MakeToyCar()
{
Product product = new Product();
product.Name = "Toy Car";
return product;
}
}
}
2.模板方法
1.模板方法相当于是一个工厂,把大家几乎相同的一个工作,交给一个类似于工厂的方法中。
2.利用委托传入
代码如下(示例):
namespace 委托模板方法
{
class Program
{
static void Main(string[] args)
{
ProductFactory productFactory = new ProductFactory();
WrapFactory wrapFactory = new WrapFactory();
Func<Product> func1 = new Func<Product>(productFactory.MakePizze);//这里只是传方法
Func<Product> func2 = new Func<Product>(productFactory.MakeToyCar);
Box box1 = wrapFactory.WrapProduct(func1);
Box box2 = wrapFactory.WrapProduct(func2);
Console.WriteLine(box1.Product.Name);
Console.WriteLine(box2.Product.Name);
Console.ReadKey();
}
}
class Product
{
public string Name { get; set; }
public double Price { get; set; }
}
class Box
{
public Product Product { get; set; }
}
/// <summary>
/// 包装产品
/// </summary>
class WrapFactory
{
public Box WrapProduct(Func<Product> getProduct)//但是这里传进去的参数是委托
{
Box box = new Box();
Product product = getProduct.Invoke();//这里相当于是执行传进来的方法
box.Product = product;
return box;
}
}
/// <summary>
/// 这个类是生产产品,
/// </summary>
class ProductFactory
{
public Product MakePizze()
{
Product product = new Product();
product.Name = "Pizza";
product.Price = 10;
return product;
}
public Product MakeToyCar()
{
Product product = new Product();
product.Name = "Toy Car";
product.Price = 100;
return product;
}
}
}
总结
多看看,多写写,多思考,收获总会多一点