百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

C#自学——委托、LINQ(c#中委托)

myzbx 2025-07-21 16:29 26 浏览

委托的概念

委托是一种可以指向方法数据类型(委托类型),可以声明委托类型的变量

数据类型指的是类似类的,前面提到过一切皆对象,委托就是将方法当作对象使用

声明委托

delegate 返回值类型 委托类型名称(参数);

创建委托

委托类型 变量 = new 委托类型(方法);

注:方法的参数必须与委托类型的参数一致,方法后面不需要括号,方法后面加括号是调用

简化创建委托

创建委托可以不使用new关键词

委托类型 变量 = 方法;

注:方法后面不可以加括号

注:委托是引用类型,可以为null,如果调用会抛出 NullReferenceException(空引用异常)

使用无返回值的委托

直接代码展示

class MainClass
{
  public static void Main(string[] args)
  {
    MyDelegate del = new MyDelegate(UseDelegate); // 创建委托
    del(); // 使用委托
  }

  public static void UseDelegate()
  {
    Console.WriteLine("使用无参委托");
  }
}
delegate void MyDelegate();

下面同上面是一样的效果

class MainClass
{
  public static void Main(string[] args)
  {
    MyDelegate del = UseDelegate; // 简写创建委托
    del();
  }

  public static void UseDelegate()
  {
    Console.WriteLine("使用无参委托");
  }
}

delegate void MyDelegate();

输出:

使用无参委托

委托相互赋值

class MainClass
{
	public static void Main(string[] args)
  {
    // 委托赋值给委托 需要是同一个委托类型
    MyDelegate del = UseDelegate;
    MyDelegate my = null;
    my = del;
    my();
  }

  public static void UseDelegate()
  {
    Console.WriteLine("使用无参委托");
  }
}

delegate void MyDelegate();

输出:

使用无参委托

有参委托

class MainClass
{
  public static void Main(string[] args)
  {
    MyDelegate myDelegate = UseDelegate; // 创建委托,方法的参数必须与委托的参数一致
    myDelegate("Tom-Cat"); // 调用委托
  }

  public static void UseDelegate(string name)
  {
    // #34;" 里面可以直接写参数,但是需要使用 {参数名}
    Console.WriteLine(#34;My Name Is {name}");
  }
}
delegate void MyDelegate(string name);

使用有返回值的委托

class MainClass
{
  public static void Main(string[] args)
  {
    MyDelegate myDelegate = UseDelegate;
    int a = myDelegate("Tom-Cat");
    Console.WriteLine("返回值: {0}",a);
  }

  public static int UseDelegate(string name)
  {
    Console.WriteLine(#34;My Name Is {name}");
    return 1;
  }
}
delegate int MyDelegate(string name);

输出:

My Name Is Tom-Cat
返回值: 1

泛型

泛型是用来替代不确定的数据类型,看下面代码

class MainClass
    {
        public static void Main(string[] args)
        {
            // 声明类的时候定义数据类型
            Persion<string, int, double> p = new Persion<string, int, double>();
            p.name = "Tom";
            p.age = 10;
            p.height = 170.50;
            Console.WriteLine("p.name 的数据类型:{0},内容是:{1}",p.name.GetType(),p.name);
            Console.WriteLine("p.age 的数据类型:{0},内容是:{1}", p.age.GetType(), p.age);
            Console.WriteLine("p.height 的数据类型:{0},内容是:{1}", p.height.GetType(), p.height);
        }
    }

    class Persion<T,T1,T2>
    {
        public T name;
        public T1 age;
        public T2 height;
    }

输出:

p.name 的数据类型:System.String,内容是:Tom
p.age 的数据类型:System.Int32,内容是:10
p.height 的数据类型:System.Double,内容是:170.5

系统内置泛型委托

  • Action 无返回值
class MainClass
{
  delegate void A(int i);
  public static void Main(string[] args)
  {
    Action<int> action = Print; // 等价于 下面这一条语句,相比之下不需要自己写 delegate void A(int)
    A a = Print;

    a(1);
    action(1);
  }
  public static void Print(int i)
  {
    Console.WriteLine("true");
  }
}

输出:

true
true
  • Func 有返回值
class MainClass
{
  delegate int A(int i);
  public static void Main(string[] args)
  {
    // Func<参数类型1,....,参数类型8,返回值类型>
    Func<int,int> action = Print;
    A a = Print;
    int aValue = a(1);
    int bValue = action(9); // 调用的时候写需要进入方法的参数
    Console.WriteLine("a(1)的返回值:{0},action(9)的返回值:{1}",aValue,bValue);
  }
  public static int Print(int i)
  {
    Console.WriteLine("true");
    return i;
  }
}

输出:

true
true
a(1)的返回值:1,action(9)的返回值:9

通过VS编译器中的程序集浏览器可以看到这两个委托

从下面这两幅图可以看到,Func是必须有一个返回值的参数,里面的参数可以最多可以有16个;Action可以没有参数,里面的参数最多也是16

LINQ

LINQ:语言集成查询 (LINQ) 是一系列直接将查询功能集成到 C# 语言的技术统称。

LINQ源数据:从应用程序的角度来看,原始源数据的特定类型和结构并不重要。 应用程序始终将源数据视为 IEnumerable<T>IQueryable<T> 集合。

代码展示:

public static void Main(string[] args)
{
  // List 继承了 IEnumerable接口,所以可以使用 Where
  List<int> list = new List<int>();
  list.Add(4);
  list.Add(9);
  list.Add(100);
  list.Add(50);
  // Where()使用了委托,括号里面可以直接使用 lambda表达式,下面会展示怎么使用lambda
  foreach (var item in list.Where(i => i > 10))
  {
    Console.WriteLine(item);
  }
}

输出:

100
50

使用数组实现同样的效果:

public static void Main(string[] args)
{
  int[] list = { 4, 9, 100, 50 };
  foreach (var item in list.Where(i => i > 10))
  {
    Console.WriteLine(item);
  }
}

使用类似数据库的语句查询:

public static void Main(string[] args)
{
  int[] list = { 4, 9, 100, 50 };
  IEnumerable<int> vs = from item in list where item > 10 select item;
  foreach (var item in vs)
  {
    Console.WriteLine(item);
  }
}

lambda

(参数)=>{ 语句; }

匿名方法

当有一个方法只有委托在使用,且只使用一次,就可以使用匿名方法。使用方法看下面代码

class MainClass
{
  delegate void Del();
  public static void Main(string[] args)
  {
    // 直接在声明的时候写方法,方法直接用delegate命名,参数必须与委托一致,如果有返回值,需要写return
    Del myDelegate = delegate ()
    {
      Console.WriteLine("匿名方法");
    };
  }
}

输出:

匿名方法

使用lambda 替代匿名方法

  • 无返回值委托
class MainClass
{
  delegate void Del();
  public static void Main(string[] args)
  {
    Del myDelegate = () =>
    {
      Console.WriteLine("匿名方法");
    };
  }
}

与上面是一样的效果,=> 读作 goes to

class MainClass
{
  public static void Main(string[] args)
  {
    // Action 足够应付大部分无返回值的委托
    Action<int> action = (int i) =>
    {
      Console.WriteLine("匿名方法");
    };
  }
}

再简写一点

class MainClass
{
  public static void Main(string[] args)
  {
    Action<int> action = (i) =>
    {
      Console.WriteLine("匿名方法");
    };
  }
}

如果只有一个参数,多个参数需要写括号

class MainClass
{
  public static void Main(string[] args)
  {
    Action<int> action = i =>
    {
      Console.WriteLine("匿名方法");
    };
  }
}
  • 有返回值委托
class MainClass
{
  public static void Main(string[] args)
  {
    // 如果使用 delegate 的时候有参数,参数必须声明类型,Action、Func都需要遵守这一条
    Func<int, int> func = delegate (int i) {
      return i;
    };
    Console.WriteLine("func({0})的返回值是:{0}",func(9));
  }
}

输出:

func(9)的返回值是:9

使用lambda简写

class MainClass
{
  public static void Main(string[] args)
  {
    Func<int, int> func = (int i) =>{
      return i;
    };
    Console.WriteLine("func({0})的返回值是:{0}",func(9));
  }
}

再简写

class MainClass
{
  public static void Main(string[] args)
  {
    Func<int, int> func = (i) =>{
      return i;
    };
    Console.WriteLine("func({0})的返回值是:{0}",func(9));
  }
}

如果只有一个参数也可以不写括号

class MainClass
{
  public static void Main(string[] args)
  {
    Func<int, int> func = i =>{
      return i;
    };
    Console.WriteLine("func({0})的返回值是:{0}",func(9));
  }
}

如果只有方法体只有一条语句,可以省略大括号和return

class MainClass
{
  public static void Main(string[] args)
  {
    Func<int, int> func = i =>i;
    Console.WriteLine("func({0})的返回值是:{0}",func(9));
  }
}

使用委托实现LINQ的where

class MainClass
{
  public static void Main(string[] args)
  {
    int[] a = { 8, 90, 4, 20 };
    
    // 使用了扩展方法,this关键词修饰的可以不写在括号里面
    IEnumerable<int> data = a.MyWhere(i => i > 10);
    
    foreach (var item in data)
    {
      Console.WriteLine(item);
    }
  }


}

// 扩展方法是写在静态类里面的静态方法,扩展方法必须有一个参数,且参数使用this关键词修饰
static class A
{
  public static IEnumerable<T> MyWhere<T>(this IEnumerable<T> data, Func<T, bool> func)
  {
    List<T> list = new List<T>();
    foreach (var item in data)
    {
      if (func(item))
      {
        list.Add(item);
      }
    }
    return list;
  }
}

输出:

90
20

相关推荐

OPPO Find X9手机曝料:6.6英寸屏幕、天玑9500芯片

IT之家8月27日消息,科技媒体xpertpick今天(8月27日)发布博文,报道称OPPO计划于今年10月推出FindX9系列旗舰手机,其中包括FindX9和...

OPPO Find X9系列搭载影像新硬件,支持Ultra级画质和色彩还原

IT之家8月27日消息,OPPOFindX9系列手机发布时间逐渐临近,目前官方已开启新机的前瞻预热。OPPOFind系列产品负责人周意保今日发文解释了厂商为什么现在都喜欢跨界合作这一...

我回来了!聊聊屏幕对续航的影响_屏幕耗电吗

时隔一周终于回国,让大家久等了本来上周日就能到家,结果在旧金山转机的时候把护照弄丢了…幸好后来被一位黑人大姐找到了,才能顺利回国,感谢勤劳朴实的美利坚人民。出差途中笔记本的续航是很重要的,刚好联想的产...

J人福音、P人救星,Lumix Flow如何重塑专业视频拍摄工作流

“等一下,刚才那个中景拍了没有?”“A机位的素材是哪一场的?”“完了,我忘了记哪一条是最好的了!”“今晚加个班,先把能用的素材挑出来……”作为经常一个人拍视频的内容创作者,这种崩溃称得上习以为常。如果...

realme史上最窄边框和下巴 realme GT Neo3正式发布

中关村在线消息:今天下午14点,realme召开真我GTNeo3发布会。realmeGTNeo3搭载6.7英寸2412×1080OLED直屏,其支持120Hz刷新率,360Hz触控采样率,智能...

用酒精擦屏幕,对屏幕的伤害有多大?

天府新青年你触手可及的朋友圈附录:1.不是所有电脑的屏幕都不能用酒精来擦,通常来说只有镜面屏屏幕才有涂层,这种不能用酒精擦;而雾面屏用的是另外一种抗反射技术,这种一般擦了没事。镜面屏和雾面屏特别好认...

windows11截屏快捷键是哪个?windows11快捷键设置大全

windows11键盘快捷方式就是键盘快捷方式就是按键或按键组合,可提供一种替代方式来执行通常使用鼠标执行的操作。下面就来分享下windows11截屏快捷键是哪个和windows11快捷键设置大全。一...

三星Galaxy S25 Slim配置曝光 6.7英寸屏幕搭配2亿像素主摄

【CNMO科技新闻】三星GalaxyS25系列将于北京时间1月23日正式发布,CNMO注意到有博主爆出了即将亮相GalaxyS25Slim的配置信息。据悉,GalaxyS25Slim将配备一...

两种手机屏幕到底有什么不一样?哪种手机屏幕更好?

一般来说,我们的手机屏幕只分为两种OLED和LCD,LCD是大火的一种手机屏幕,是千元机以及高端机的标配,OLED算是后起之秀,是近几年才渐渐兴起的一种类型的手机屏幕,那么这两种手机屏幕到底有什么不一...

有强芯才好用 这三款高性价比旗舰芯热机最低仅需1799元

在选购手机时,相信大家肯定都会把性能作为考虑的重点之一。而如果希望拥有出色的性能表现,一颗旗舰处理器是必不可少的。今天我就为大家汇总了几款采用旗舰处理器的底价新机,感兴趣的朋友千万不要错过。moto...

一文搞定FastDFS的搭建和使用_fastdfs怎么样

1.FastDFS概述FastDFS是一个开源的轻量级分布式文件系统,它对文件进行管理,功能包括:文件存储、文件同步、文件访问(文件上传、文件下载)等,解决了大容量存储和负载均衡的问题。特别适合以文...

涨姿势!超级计算机用啥文件系统呢?

2015-10-1705:58:00作者:赵为民在计算机中,文件系统(filesystem)是一个非常重要的组件,你可以将他看做是操作系统的子系统,其实质就是一种软件的组件,通过文件系统我们可以...

Window as a VM:Chrome OS 现可窗口化运行其它 Linux 分支

这世上纵然有多种办法可以在Chromebook上安装运行ChromeOS和其它Linux分支多系统,但如果无需重启通过引导切换,确实是个很酷的改进。Google布道师Francois...

Win10新预览版19577开始推送:新图标+多项新功能

今日凌晨,微软正式向Windows10Insider快速通道用户推送了全新版本Windows10——Windows10InsiderPreviewBuild19577。19577版本是...

微软Windows升级密钥(例如家庭版升级为企业版)

下面的密钥,是微软官方提供的,仅能用于Windows10系统版本的升级,比如从家庭版升级为专业版、专业版升级为企业版等。升级密钥不能用于激活系统,激活需要KMS或者数字权利,由于涉及到版权问题,在此不...