• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

C#入门级——泛型、泛型类、泛型接口、泛型方法和泛型委托

武飞扬头像
dlwlrma_516
帮助1

目录

一、泛型(generic)

二、为什么需要泛型类

类型膨胀

成员膨胀

使用object类

三、泛型的定义

定义泛型类

使用泛型类

泛型接口

两种泛型接口的实现方法

泛型方法

成员膨胀

使用泛型

泛型委托

Action委托——只能引用没有返回值的方法

Func泛型委托——要有返回值

泛型委托和Lambda表达式的配合使用


一、泛型(generic)

泛型类是以实例化过程中提供的类型或类为基础建立的,可对对象进行强类型化

尖括号语法是把类型参数传送给泛型类型的方式

泛型并不限于类,还可以创建泛型接口、泛型方法(可以在非泛型类上定义),甚至泛型委托

泛化和特化是相对的

System.Collections.Generics名称空间的两个类型

类型:List<T>               说明:T类型对象的集合

类型:Dictionary<K,V> 说明:与K类型的键值相关的V类型的项的集合

前文已提及到:

二、为什么需要泛型类

场景:新百货商店开业,两个类,Chair类,Desk类

不同的货物要用不同的纸箱去装

类型膨胀

现在百货商店新开张,卖Chair和Desk,Chair需要用ChairCarton装,Desk需要用DeskCarton装;但是如果以后百货商店有1000种商品呢?要准备1000种纸箱吗?而且程序不好维护…

创建控制台项目

学新通

学新通

  1.  
    using System;
  2.  
    using System.Collections.Generic;
  3.  
    using System.Linq;
  4.  
    using System.Text;
  5.  
    using System.Threading.Tasks;
  6.  
     
  7.  
    namespace ConsoleApp1
  8.  
    {
  9.  
    internal class Program
  10.  
    {
  11.  
    static void Main(string[] args)
  12.  
    {
  13.  
    Chair chair = new Chair() { Color = "Red" };
  14.  
    ChairCarton chairCarton = new ChairCarton() { Cargo = chair };
  15.  
    Console.WriteLine(chairCarton.Cargo.Color);
  16.  
     
  17.  
    Desk desk = new Desk() { Weight = "20kg" };
  18.  
    DeskCarton deskCarton = new DeskCarton() { Cargo = desk };
  19.  
    Console.WriteLine(deskCarton.Cargo.Weight);
  20.  
    Console.ReadKey();
  21.  
    }
  22.  
    }
  23.  
     
  24.  
    class Chair
  25.  
    {
  26.  
    public string Color { get; set; }
  27.  
    }
  28.  
     
  29.  
    class Desk
  30.  
    {
  31.  
    public string Weight { get; set; }
  32.  
    }
  33.  
     
  34.  
    class ChairCarton
  35.  
    {
  36.  
    public Chair Cargo { get; set; }
  37.  
    }
  38.  
    class DeskCarton
  39.  
    {
  40.  
    public Desk Cargo { get; set; }
  41.  
    }
  42.  
    }
学新通

成员膨胀

只准备一种纸箱,填写不同的属性,carton1实例只用到了Chair属性,没有用到Desk属性,而carton2属性则相反

以后1000种商品呢?Carton类1000个对应属性,只有1个属性能用,每次增加或减少商品,都要修改Carton类

  1.  
    using System;
  2.  
    using System.Collections.Generic;
  3.  
    using System.Linq;
  4.  
    using System.Text;
  5.  
    using System.Threading.Tasks;
  6.  
     
  7.  
    namespace ConsoleApp1
  8.  
    {
  9.  
    internal class Program
  10.  
    {
  11.  
    static void Main(string[] args)
  12.  
    {
  13.  
    Chair chair = new Chair() { Color = "Red" };
  14.  
    Desk desk = new Desk() { Weight = "20kg" };
  15.  
    Carton carton1 = new Carton() { ChairCargo = chair };
  16.  
    Carton carton2 = new Carton() { DeskCargo = desk };
  17.  
    Console.WriteLine(carton1.ChairCargo.Color);
  18.  
    Console.WriteLine(carton2.DeskCargo.Weight);
  19.  
    Console.ReadKey();
  20.  
    }
  21.  
    }
  22.  
     
  23.  
    class Chair
  24.  
    {
  25.  
    public string Color { get; set; }
  26.  
    }
  27.  
     
  28.  
    class Desk
  29.  
    {
  30.  
    public string Weight { get; set; }
  31.  
    }
  32.  
     
  33.  
    class Carton
  34.  
    {
  35.  
    public Chair ChairCargo { get; set; }
  36.  
    public Desk DeskCargo { get; set; }
  37.  
    }
  38.  
    }
学新通

使用object类

当把东西往盒子里装时是省事了,但是要把东西从盒子里拿出来时,访问盒子中装的东西就很麻烦

(chair实例赋值给Cargo属性,在Console.WriteLine(carton1.Cargo.时,系统在可选择下拉框中,就已经找不到chair实例下的有关属性Color,需要强制类型转换/as属性操作符)

使用?.的原因:若是个Chair类则打印Color属性,若是Desk类则不会打印Color属性

  1.  
     
  2.  
    using System;
  3.  
    using System.Collections.Generic;
  4.  
    using System.Linq;
  5.  
    using System.Text;
  6.  
    using System.Threading.Tasks;
  7.  
     
  8.  
    namespace ConsoleApp1
  9.  
    {
  10.  
    internal class Program
  11.  
    {
  12.  
    static void Main(string[] args)
  13.  
    {
  14.  
    Chair chair = new Chair() { Color = "Red" };
  15.  
    Desk desk = new Desk() { Weight = "20kg" };
  16.  
    Carton carton1 = new Carton() { Cargo = chair };
  17.  
    Carton carton2 = new Carton() { Cargo = desk };
  18.  
    Console.WriteLine((carton1.Cargo as Chair)?.Color);
  19.  
    Console.WriteLine((carton2.Cargo as Desk)?.Weight);
  20.  
    Console.ReadKey();
  21.  
     
  22.  
    }
  23.  
    }
  24.  
     
  25.  
    class Chair
  26.  
    {
  27.  
    public string Color { get; set; }
  28.  
    }
  29.  
     
  30.  
    class Desk
  31.  
    {
  32.  
    public string Weight { get; set; }
  33.  
    }
  34.  
    class Carton
  35.  
    {
  36.  
    public Object Cargo { get; set; }
  37.  
    }
  38.  
    }
学新通

三、泛型的定义

泛型的定义:泛型类、泛型接口、泛型方法、泛型委托

定义泛型类

<类型参数>     类型参数:标识符,代表泛化的类型

创建泛型类——需在类定义中包含尖括号

  1.  
    class GenericClass<T>
  2.  
    {
  3.  
     
  4.  
    }

class Carton<TCargo>

TCargo类型是商品的类型(写的是类名!!)

声明属性——public TCargo Cargo{get;set;}

定义泛型Carton类

  1.  
    class Carton<TCargo>
  2.  
    {
  3.  
    public TCargo Cargo{get;set;}
  4.  
    }

使用泛型类

使用泛型Carton类

泛型编程实体都不能拿来编程,想要使用泛型实体之前都必须要进行特化

特化

先将泛型Carton类先特化为装Chair的Carton类型:

Carton<Chair>,相当于Chair类型替换了TCargo类型(TCargo-->Chair)

(属性:public TCargo-->public Chair         TCargo类型变成了Chair类型)

在main函数中进行特化:

Carton<Chair> carton1= new Carton<Chair>(){Cargo = Chair};

凡是使用到了类型参数的地方都是强类型的

Cargo属性强类型,属性类型是Chair类型,Chair类型的实例有Color这个属性

Cargo属性强类型,属性类型是Desk类型,Desk类型的实例有Weight这个属性

  1.  
    using System;
  2.  
    using System.Collections.Generic;
  3.  
    using System.Linq;
  4.  
    using System.Text;
  5.  
    using System.Threading.Tasks;
  6.  
     
  7.  
    namespace ConsoleApp1
  8.  
    {
  9.  
    internal class Program
  10.  
    {
  11.  
    static void Main(string[] args)
  12.  
    {
  13.  
    Chair chair = new Chair() { Color = "Red" };
  14.  
    Desk desk = new Desk() { Weight = "20kg" };
  15.  
    Carton<Chair> carton1 = new Carton<Chair>() { Cargo = chair };
  16.  
    Carton<Desk> carton2 = new Carton<Desk>() { Cargo = desk };
  17.  
    Console.WriteLine(carton1.Cargo.Color);
  18.  
    Console.WriteLine(carton2.Cargo.Weight);
  19.  
    Console.ReadKey();
  20.  
    }
  21.  
    }
  22.  
     
  23.  
    class Chair
  24.  
    {
  25.  
    public string Color { get; set; }
  26.  
    }
  27.  
     
  28.  
    class Desk
  29.  
    {
  30.  
    public string Weight { get; set; }
  31.  
    }
  32.  
     
  33.  
    class Carton<TCargo>
  34.  
    {
  35.  
    public TCargo Cargo { get; set; }
  36.  
    }
  37.  
    }
学新通

泛型接口

声明接口,保证对象的唯一——具有ID属性,ID属性的类型不确定,接口改为泛型接口

类型参数:TId——ID属性的类型

接口中不能够加public,因为默认就是public

  1.  
    interface IUnique<TId>
  2.  
    {
  3.  
    TId ID { get; set; }
  4.  
    }

Student类实现IUnique接口,派生自IUnique

类型参数:TId

如果一个类实现了泛型接口,那么它本身也是泛型的

实现接口,就必须把接口的全部成员都实现

泛型的Student类,TId类型参数只会影响到ID这个属性的类型

实现ID属性:

  1.  
    interface IUnique<TId>
  2.  
    {
  3.  
    TId ID { get; set; }
  4.  
    }
  5.  
     
  6.  
    class Student<TId> : IUnique<TId>
  7.  
    {
  8.  
    public TId ID { get; set; }
  9.  
    }

给Student类添加字符串类型的名字Name

  1.  
    using System;
  2.  
    using System.Collections.Generic;
  3.  
    using System.Linq;
  4.  
    using System.Text;
  5.  
    using System.Threading.Tasks;
  6.  
     
  7.  
    namespace ConsoleApp1
  8.  
    {
  9.  
    internal class Program
  10.  
    {
  11.  
    static void Main(string[] args)
  12.  
    {
  13.  
     
  14.  
    }
  15.  
    }
  16.  
     
  17.  
    interface IUnique<TId>
  18.  
    {
  19.  
    TId ID { get; set; }
  20.  
    }
  21.  
     
  22.  
    class Student<TId> : IUnique<TId>
  23.  
    {
  24.  
    public TId ID { get; set; }
  25.  
    public string Name { get; set; }
  26.  
    }
  27.  
    }
学新通

main函数中使用Student类

设置Student类的ID是整数:Student<int>

特化Student类后,使用Student类

  1.  
    using System;
  2.  
    using System.Collections.Generic;
  3.  
    using System.Linq;
  4.  
    using System.Text;
  5.  
    using System.Threading.Tasks;
  6.  
     
  7.  
    namespace ConsoleApp1
  8.  
    {
  9.  
    internal class Program
  10.  
    {
  11.  
    static void Main(string[] args)
  12.  
    {
  13.  
    Student<int> stu = new Student<int>();
  14.  
    stu.ID = 10000;
  15.  
    stu.Name = "Tom";
  16.  
    }
  17.  
    }
  18.  
     
  19.  
    interface IUnique<TId>
  20.  
    {
  21.  
    TId ID { get; set; }
  22.  
    }
  23.  
     
  24.  
    class Student<TId> : IUnique<TId>
  25.  
    {
  26.  
    public TId ID { get; set; }
  27.  
    public string Name { get; set; }
  28.  
    }
  29.  
    }
学新通

随着学校的扩张,ID需要从int改为无符号长整型

ulong作为类型参数传给泛型student类,id的类型就是ulong型

  1.  
    using System;
  2.  
    using System.Collections.Generic;
  3.  
    using System.Linq;
  4.  
    using System.Text;
  5.  
    using System.Threading.Tasks;
  6.  
     
  7.  
    namespace ConsoleApp1
  8.  
    {
  9.  
    internal class Program
  10.  
    {
  11.  
    static void Main(string[] args)
  12.  
    {
  13.  
    Student<ulong> stu = new Student<ulong>();
  14.  
    stu.ID = 10000000000000000;
  15.  
    stu.Name = "Tom";
  16.  
    }
  17.  
    }
  18.  
     
  19.  
    interface IUnique<TId>
  20.  
    {
  21.  
    TId ID { get; set; }
  22.  
    }
  23.  
     
  24.  
    class Student<TId> : IUnique<TId>
  25.  
    {
  26.  
    public TId ID { get; set; }
  27.  
    public string Name { get; set; }
  28.  
    }
  29.  
    }
学新通

两种泛型接口的实现方法

1、声明Student类时,实现IUnique泛型接口,这时Student类成为泛型类

(前面提及到的情况)

2、实行泛型接口时,实现的是特化后的泛型接口,类不再是泛型类

(下面提及到的情况)

实现IUnique接口时,不再用TId,确定ID的类型一定就是ulong,直接特化了接口,Student类不是泛型类了

当声明一个类时,在实现接口时,就已经把接口特化了,类实现的就是特化后的泛型接口

  1.  
    using System;
  2.  
    using System.Collections.Generic;
  3.  
    using System.Linq;
  4.  
    using System.Text;
  5.  
    using System.Threading.Tasks;
  6.  
     
  7.  
    namespace ConsoleApp1
  8.  
    {
  9.  
    internal class Program
  10.  
    {
  11.  
    static void Main(string[] args)
  12.  
    {
  13.  
    Student stu = new Student();
  14.  
    stu.ID = 10000000000000000;
  15.  
    }
  16.  
    }
  17.  
     
  18.  
    interface IUnique<TId>
  19.  
    {
  20.  
    TId ID { get; set; }
  21.  
    }
  22.  
     
  23.  
    class Student : IUnique<ulong>
  24.  
    {
  25.  
    public ulong ID { get; set; }
  26.  
    }
  27.  
    }
学新通

添加Name属性

  1.  
    using System;
  2.  
    using System.Collections.Generic;
  3.  
    using System.Linq;
  4.  
    using System.Text;
  5.  
    using System.Threading.Tasks;
  6.  
     
  7.  
    namespace ConsoleApp1
  8.  
    {
  9.  
    internal class Program
  10.  
    {
  11.  
    static void Main(string[] args)
  12.  
    {
  13.  
    Student stu = new Student();
  14.  
    stu.ID = 10000000000000000;
  15.  
    stu.Name = "Tom";
  16.  
    }
  17.  
    }
  18.  
     
  19.  
    interface IUnique<TId>
  20.  
    {
  21.  
    TId ID { get; set; }
  22.  
    }
  23.  
     
  24.  
    class Student : IUnique<ulong>
  25.  
    {
  26.  
    public ulong ID { get; set; }
  27.  
    public string Name { get; set; }
  28.  
    }
  29.  
    }
学新通

因为IList时泛型接口,而右边的List是泛型类,泛型类实现了泛型接口

带有一个类型参数的IList泛型接口,带有一个类型参数的List泛型类

C#的List就是ArrayList 长度可以改变,动态数组

运行结果:打印出来0-99

泛型接口IList用整型特化下,List泛型类

  1.  
    using System;
  2.  
    using System.Collections.Generic;
  3.  
    using System.Linq;
  4.  
    using System.Text;
  5.  
    using System.Threading.Tasks;
  6.  
     
  7.  
    namespace ConsoleApp1
  8.  
    {
  9.  
    internal class Program
  10.  
    {
  11.  
    static void Main(string[] args)
  12.  
    {
  13.  
    IList<int> list = new List<int>();
  14.  
    for (int i = 0; i < 100; i )
  15.  
    {
  16.  
    list.Add(i);
  17.  
    }
  18.  
     
  19.  
    foreach (int item in list)
  20.  
    {
  21.  
    Console.WriteLine(item);
  22.  
    }
  23.  
    Console.ReadLine();
  24.  
     
  25.  
    }
  26.  
    }
  27.  
    }
学新通

类型参数为T,实现了IList泛型基接口、ICollection泛型基接口、IEnumerable泛型基接口……

List一定是可以被迭代的,因为实现了IEnumerable泛型基接口

ICollection泛型基接口——集合,可以往集合中增加新元素和删除元素

学新通

很多泛型类型带不止一个类型参数,如:IDictionary泛型接口

举例:IDictionary泛型接口

int类型特化TKey类型  string类型特化TValue类型

使用特化后的IDictionary接口类型变量 引用 特化后的Dictionary类型实例

多态:IDictionary接口类型的变量dict可以引用一个Dictionary类型的实例,Dictionary泛型类实现了IDictionary接口,类型参数都是TKey TValue

  1.  
    using System;
  2.  
    using System.Collections.Generic;
  3.  
    using System.Linq;
  4.  
    using System.Text;
  5.  
    using System.Threading.Tasks;
  6.  
     
  7.  
    namespace ConsoleApp1
  8.  
    {
  9.  
    internal class Program
  10.  
    {
  11.  
    static void Main(string[] args)
  12.  
    {
  13.  
    IDictionary<int, string> dict = new Dictionary<int, string>();
  14.  
    dict[1] = "Jack";
  15.  
    dict[2] = "Mary";
  16.  
    Console.WriteLine($"Student #1 is{dict[1]}");
  17.  
    Console.WriteLine($"Student #2 is{dict[2]}");
  18.  
    Console.ReadKey();
  19.  
     
  20.  
    }
  21.  
    }
  22.  
    }
学新通

泛型方法

举例:两个整型数组合并一起

不使用泛型方法时,会出现以下情况:

成员膨胀

(方法也是类的成员)

更加容易出问题,两个方法都是静态的,类的静态成员,两个重载方法,除了类型不同以外,其他的逻辑都是相同的,万一修bug只修了其中一个方法,另一个方法忘记了就出问题了

  1.  
    using System;
  2.  
    using System.Collections.Generic;
  3.  
    using System.Linq;
  4.  
    using System.Text;
  5.  
    using System.Threading.Tasks;
  6.  
     
  7.  
    namespace ConsoleApp1
  8.  
    {
  9.  
    internal class Program
  10.  
    {
  11.  
    static void Main(string[] args)
  12.  
    {
  13.  
    int[] a1 = { 1, 2, 3, 4, 5 };
  14.  
    int[] a2 = { 1, 2, 3, 4, 5, 6 };
  15.  
    double[] a3 = { 1.1, 2.2, 3.3, 4.4, 5.5 };
  16.  
    double[] a4 = { 1.1, 2.2, 3.3, 4.4, 5.5, 6.6 };
  17.  
    var result = Zip(a1, a2);
  18.  
    Console.WriteLine(string.Join(",",result));
  19.  
    Console.ReadKey();
  20.  
    }
  21.  
     
  22.  
    static int[] Zip(int[] a, int[] b)
  23.  
    {
  24.  
    int[] zipped = new int[a.Length b.Length];
  25.  
    int ai = 0, bi = 0, zi = 0;
  26.  
    do
  27.  
    {
  28.  
    if (ai < a.Length) zipped[zi ] = a[ai ];
  29.  
    if (bi < b.Length) zipped[zi ] = b[bi ];
  30.  
    } while (ai < a.Length || bi < b.Length);
  31.  
     
  32.  
    return zipped;
  33.  
    }
  34.  
     
  35.  
    static double[] Zip(double[] a, double[] b)
  36.  
    {
  37.  
    double[] zipped = new double[a.Length b.Length];
  38.  
    int ai = 0, bi = 0, zi = 0;
  39.  
    do
  40.  
    {
  41.  
    if (ai < a.Length) zipped[zi ] = a[ai ];
  42.  
    if (bi < b.Length) zipped[zi ] = b[bi ];
  43.  
    } while (ai < a.Length || bi < b.Length);
  44.  
     
  45.  
    return zipped;
  46.  
    }
  47.  
    }
  48.  
     
  49.  
    }
学新通

使用泛型

方法后面加<T>

  1.  
    using System;
  2.  
    using System.Collections.Generic;
  3.  
    using System.Linq;
  4.  
    using System.Text;
  5.  
    using System.Threading.Tasks;
  6.  
     
  7.  
    namespace ConsoleApp1
  8.  
    {
  9.  
    internal class Program
  10.  
    {
  11.  
    static void Main(string[] args)
  12.  
    {
  13.  
    int[] a1 = { 1, 2, 3, 4, 5 };
  14.  
    int[] a2 = { 1, 2, 3, 4, 5, 6 };
  15.  
    double[] a3 = { 1.1, 2.2, 3.3, 4.4, 5.5 };
  16.  
    double[] a4 = { 1.1, 2.2, 3.3, 4.4, 5.5, 6.6 };
  17.  
    var result = Zip(a1, a2); //可以不写Zip<int>(a1, a2);
  18.  
    Console.WriteLine(string.Join(",",result));
  19.  
    Console.ReadKey();
  20.  
    }
  21.  
     
  22.  
    static T[] Zip<T>(T[] a, T[] b)
  23.  
    {
  24.  
    T[] zipped = new T[a.Length b.Length];
  25.  
    int ai = 0, bi = 0, zi = 0;
  26.  
    do
  27.  
    {
  28.  
    if (ai < a.Length) zipped[zi ] = a[ai ];
  29.  
    if (bi < b.Length) zipped[zi ] = b[bi ];
  30.  
    } while (ai < a.Length || bi < b.Length);
  31.  
     
  32.  
    return zipped;
  33.  
    }
  34.  
    }
  35.  
     
  36.  
    }
学新通

可以无需显式写<T> <int>或<double> 泛型方法在调用时类型参数自动推断

var result = Zip(a1,a2);   var result = Zip<int>(a1,a2);

泛型委托

Action委托——只能引用没有返回值的方法

静态方法Say/Mul,没有返回值

使用泛型委托分别引用参数类型完全不同的方法

类型参数:告诉Action委托未来要引用的方法的参数类型是什么,有多少个参数

Action委托引用Say方法,Say方法只有一个String类型参数

通过委托去调用一个方法叫间接调用

  1.  
    using System;
  2.  
    using System.Collections.Generic;
  3.  
    using System.Linq;
  4.  
    using System.Text;
  5.  
    using System.Threading.Tasks;
  6.  
     
  7.  
    namespace ConsoleApp1
  8.  
    {
  9.  
    internal class Program
  10.  
    {
  11.  
    static void Main(string[] args)
  12.  
    {
  13.  
    Action<string> a1 = Say;
  14.  
    a1.Invoke("Jack");
  15.  
     
  16.  
    Console.ReadKey();
  17.  
    }
  18.  
     
  19.  
    static void Say(string str)
  20.  
    {
  21.  
    Console.WriteLine($"Hello,{str}!");
  22.  
    }
  23.  
    static void Mul(int x)
  24.  
    {
  25.  
    Console.WriteLine(x * 100);
  26.  
    }
  27.  
    }
  28.  
     
  29.  
    }
学新通

直接像一个方法一样调用,委托本身就是一种可调用的类型

  1.  
    using System;
  2.  
    using System.Collections.Generic;
  3.  
    using System.Linq;
  4.  
    using System.Text;
  5.  
    using System.Threading.Tasks;
  6.  
     
  7.  
    namespace ConsoleApp1
  8.  
    {
  9.  
    internal class Program
  10.  
    {
  11.  
    static void Main(string[] args)
  12.  
    {
  13.  
    Action<string> a1 = Say;
  14.  
    a1("Jack");
  15.  
     
  16.  
    Console.ReadKey();
  17.  
    }
  18.  
     
  19.  
    static void Say(string str)
  20.  
    {
  21.  
    Console.WriteLine($"Hello,{str}!");
  22.  
    }
  23.  
    static void Mul(int x)
  24.  
    {
  25.  
    Console.WriteLine(x * 100);
  26.  
    }
  27.  
    }
  28.  
     
  29.  
    }
学新通

创建泛型委托实例,引用Mul函数,有一个int类型参数

调用a2委托,间接调用Mul方法

  1.  
    using System;
  2.  
    using System.Collections.Generic;
  3.  
    using System.Linq;
  4.  
    using System.Text;
  5.  
    using System.Threading.Tasks;
  6.  
     
  7.  
    namespace ConsoleApp1
  8.  
    {
  9.  
    internal class Program
  10.  
    {
  11.  
    static void Main(string[] args)
  12.  
    {
  13.  
    Action<string> a1 = Say;
  14.  
    a1("Jack");
  15.  
    Action<int> a2 = Mul;
  16.  
    a2(1);
  17.  
    Console.ReadKey();
  18.  
    }
  19.  
     
  20.  
    static void Say(string str)
  21.  
    {
  22.  
    Console.WriteLine($"Hello,{str}!");
  23.  
    }
  24.  
    static void Mul(int x)
  25.  
    {
  26.  
    Console.WriteLine(x * 100);
  27.  
    }
  28.  
    }
  29.  
     
  30.  
    }
学新通

Func泛型委托——要有返回值

Func<类型参数:引用的方法有多少个参数及参数类型,最后一个类型参数:函数返回值类型>

特化Func<double,double,double>泛型委托

  1.  
    using System;
  2.  
    using System.Collections.Generic;
  3.  
    using System.Linq;
  4.  
    using System.Text;
  5.  
    using System.Threading.Tasks;
  6.  
     
  7.  
    namespace ConsoleApp1
  8.  
    {
  9.  
    internal class Program
  10.  
    {
  11.  
    static void Main(string[] args)
  12.  
    {
  13.  
    Func<double, double, double> func1 = Add;
  14.  
    var result = func1(100.1, 200.2);
  15.  
    Console.WriteLine(result);
  16.  
    Console.ReadKey();
  17.  
    }
  18.  
     
  19.  
    static double Add(double a,double b)
  20.  
    {
  21.  
    return a b;
  22.  
    }
  23.  
    }
  24.  
    }
学新通

泛型委托和Lambda表达式的配合使用

对于逻辑简单的方法,不去声明,随调用去声明,匿名声明

  1.  
    using System;
  2.  
    using System.Collections.Generic;
  3.  
    using System.Linq;
  4.  
    using System.Text;
  5.  
    using System.Threading.Tasks;
  6.  
     
  7.  
    namespace ConsoleApp1
  8.  
    {
  9.  
    internal class Program
  10.  
    {
  11.  
    static void Main(string[] args)
  12.  
    {
  13.  
    Func<double, double, double> func1 = (double a, double b) => { return a b; };
  14.  
    var result = func1(100.1, 200.2);
  15.  
    Console.WriteLine(result);
  16.  
    Console.ReadKey();
  17.  
    }
  18.  
    }
  19.  
    }
学新通

可以再简化

  1.  
    using System;
  2.  
    using System.Collections.Generic;
  3.  
    using System.Linq;
  4.  
    using System.Text;
  5.  
    using System.Threading.Tasks;
  6.  
     
  7.  
    namespace ConsoleApp1
  8.  
    {
  9.  
    internal class Program
  10.  
    {
  11.  
    static void Main(string[] args)
  12.  
    {
  13.  
    Func<double, double, double> func1 = (a, b) => { return a b; };
  14.  
    var result = func1(100.1, 200.2);
  15.  
    Console.WriteLine(result);
  16.  
    Console.ReadKey();
  17.  
    }
  18.  
    }
  19.  
    }
学新通

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhiabagg
系列文章
更多 icon
同类精品
更多 icon
继续加载