IL을 통해 C#의 대리자, 이벤트, Func, Action 및 Predicate 간의 차이점과 연결을 분석합니다.
저는 항상 이벤트와 위임에 대해 헷갈리고 잘 활용하지 못합니다. 잠시 시간을 내어 요약해 본 후에는 훨씬 더 명확해진 느낌이 들었습니다.
먼저 개인적인 이해에 대해 이야기하겠습니다.
Delegate는 C#의 유형입니다. 실제로 메소드에 대한 참조를 보유할 수 있는 클래스입니다.
델리게이트가 선언한 변수와 델리게이트가 선언한 이벤트는 본질적인 차이가 없습니다. 이벤트는 델리게이트가 선언한 변수를 기준으로 패키징됩니다. 변수와 속성 사이(대리자가 선언한 각 이벤트가 개인 대리자가 선언한 변수에 해당함을 IL 코드에서 볼 수 있음)는 보안을 향상시킵니다.
Action 및 Func: 이 두 가지는 실제로 시스템에서 정의한 Delegate입니다. 다양한 애플리케이션 호출을 용이하게 하기 위해 많은 오버로드된 메서드가 있습니다. 이는 시스템의 System 네임스페이스 아래에 있으므로 전역적으로 표시됩니다.
먼저 ILDasm의 아이콘 의미를 이해해 보겠습니다.
이 사진 출처: http://www.php.cn/
위임 생성 단계:
1. 대리자 사용 키워드는 반환 값 및 매개 변수 유형 선언을 포함하여 대리자를 생성합니다
2. 사용된 대리자를 수신합니다
3. 이 대리자의 인스턴스를 만들고 반환 값이 일치하는 메서드를 지정합니다. 매개변수 유형을 입력하고 거기에 전달하세요
1.
구체적인 코드는 다음과 같습니다.
<span style="font-size:14px;"><span style="font-size:14px;">namespace EventDelegateTest
{
public class TestClass
{
public delegate int delegateAction();
public event delegateAction OnActionEvent;
public delegateAction daNew;
}
}</span></span>
1. Delegation Public Delegate int DelegateAction();
은 클래스(delegateAction) 형태로 존재합니다. IL
.NET에서는 대리자를 기본 클래스 System.MulticastDelegate에서 파생된 봉인된 클래스로 정의하고 기본 클래스
<🎜의 세 가지 메서드를 상속합니다. >
2. 공개 이벤트 DelegateAction OnActionEvent;
IL에서는 이벤트에만 해당하는 것이 아닙니다. OnActionEvent는 OnActionEvent 필드에도 해당합니다.
OnActionEvent 필드와 public DelegateAction daNew에 의해 생성된 daNew 필드는 동일합니다
都是以字段(field )的形式存在的。
双击event OnActionEvent可以看到如下信息:
在IL中事件被封装成了包含一个add_前缀和一个remove_前缀的的代码段。
其中,add_前缀的方法其实是通过调用Delegate.Combine()方法来实现的,组成了一个多播委托;remove_就是调用Delegate.Remove()方法,用于移除多播委托中的某个委托。
也就是说:事件其实就是一个特殊的多播委托
那么对于事件进行这一次封装有什么好处呢?
1、因为delegate可以支持的操作非常多,比如我们可以写onXXXChanged += aaaFunc,把某个函数指针挂载到这个委托上面,但是我们也可以简单粗暴地直接写onXXXChanged = aaaFunc,让这个委托只包含这一个函数指针。不过这样一来会产生一个安全问题:如果我们用onXXXChanged = aaaFunc这样的写法,那么会把这个委托已拥有的其他函数指针给覆盖掉,这大概不是定义onXXXChanged的程序员想要看到的结果。
小注:
虽然事件不能直接=某个函数,也不可以直接=null
2、还有一个问题就是onXXXChanged这个委托应该什么时候触发(即调用它所包含的函数指针)。从面向对象的角度来说,XXX改变了这个事实(即onXXXChaned的字面含义)应该由包含它的那个对象来决定。但实际上我们可以从这个对象的外部环境调用onXXXChanged,这既产生了安全问题也不符合面向对象的初衷。
说到这里对于事件与委托的管理算是说明白了,那么平时常用的Action与Func,与委托又有什么关系呢?
二、Action 与Func
Action 委托:封装一个方法,该方法具有参数(0到16个参数)并且不返回值。
具体形式如下:http://www.php.cn/(v=vs.110).aspx
Func
具体形式如下:http://www.php.cn/(v=vs.110).aspx
那么这Action与Func是怎么实现的呢?
1、Action(以Action
从微软公布的源码中,可以看到,如下实现:
public Action<bool,bool> ac;
上面这个声明就是:该方法具有两个参数并且不返回值的委托。
其余使用方式与委托变量一样。
2、Func(以Func
从微软公布的源码中,可以看到,如下实现:
此处,可以看出Func与Action是类似的,唯一的区别就是,Func必须指定返回值的类型,使用方式与委托咱们自己使用委托变量是一样的,直接使用相应参数的Func或者Action声明变量,=或者+=挂载函数(方法即可)
这两个其实说白了就是系统定义好的Delegate,他有很多重载的方法,便于各种应用情况下的调用。他在系统的System命名空间下,因此全局可见。
三、Predicate
是返回bool型的泛型委托,Predicate有且只有一个参数,返回值固定为bool。表示定义一组条件并确定指定对象是否符合这些条件的方法。此方法常在集合(Array 和 List
官方文档:点击打开链接
具体用法demo如下:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace IconTest { public partial class Form2 : Form { Predicate<int> myPredicate; int[] myNum = new int[8] { 12, 33, 89, 21, 15, 29, 40, 52 }; public int[] myResult; public Form2() { InitializeComponent(); myPredicate = delegate(int curNum) { if (curNum % 2 == 0) { return true; } else { return false; } }; } private void Form2_Load(object sender, EventArgs e) { myResult = Array.FindAll(myNum, myPredicate); } } }
上例中说明了Predicate的使用,FindAll方法中,参数2即是一个Predicate,在具体的执行中,每一个数组的元素都会执行指定的方法,如果满足要求返回true,并会被存放在结果集中,不符合的则被剔除,最终返回的集合,即是结果判断后想要的集合。
Array.FindAll 泛型方法:点击打开链接
以上代码执行结果为:
那么Predicate
从微软源码中可以看出Predicate
以上就是通过IL分析C#中的委托、事件、Func、Action、Predicate之间的区别与联系的内容,更多相关内容请关注PHP中文网(www.php.cn)!

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











이 기사는 C의 Null 포인터 단축의 도전에 대해 탐구합니다. 그것은 문제가 그 자체가 아니라 오용한다고 주장합니다. 이 기사는 사전 수준 점검, 포인터 이니셜을 포함한 수반을 방지하기위한 모범 사례에 대해 자세히 설명합니다.

이 기사에서는 printf 내에서 \ n 탈출 시퀀스를 사용하여 C에서 Newline 문자를 만드는 방법을 설명하고 함수를 넣습니다. 기능을 자세히 설명하고 출력에서 라인 브레이크 사용을 보여주는 코드 예제를 제공합니다.

이 기사는 초보자가 C 컴파일러를 선택하도록 안내합니다. GCC는 사용 편의성, 광범위한 가용성 및 광범위한 리소스로 인해 초보자에게 가장 적합하다고 주장합니다. 그러나 GCC, Clang, MSVC 및 TCC도 비교하여 차이를 강조합니다.

이 기사는 현대 C 프로그래밍에서 NULL의 지속적인 중요성을 강조합니다. 발전에도 불구하고 NULL은 명시적인 포인터 관리에 중요하며, 유효한 메모리 주소가 없음을 표시하여 세분화 결함을 방지합니다. 최고의 PRAC

이 기사에서는 초보자를위한 온라인 C 컴파일러를 검토하여 사용 편의성 및 디버깅 기능에 중점을 둡니다. OnlineGDB 및 Repl.it는 사용자 친화적 인 인터페이스 및 유용한 디버깅 도구를 위해 강조 표시됩니다. 프로그램 및 컴파일과 같은 다른 옵션

이 기사는 온라인 C 프로그래밍 플랫폼을 비교하여 디버깅 도구, IDE 기능, 표준 컴플라이언스 및 메모리/실행 제한과 같은 기능의 차이점을 강조합니다. "최고의"플랫폼은 사용자의 요구에 달려 있다고 주장합니다.

이 기사에서는 C IDE의 효율적인 코드 복사에 대해 설명합니다. 복사는 컴파일러 기능이 아닌 IDE 기능이며 IDE 선택 도구 사용, 코드 폴딩, 검색/교체, Templa를 포함하여 효율성 향상을위한 세부 사항 전략을 강조합니다.

이 기사는 C 프로그램 컴파일에서 누락 된 출력 창을 문제 해결합니다. 실행 가능, 프로그램 오류, 잘못된 컴파일러 설정, 백그라운드 프로세스 및 빠른 프로그램 종료와 같은 원인을 검사합니다. 솔루션은 ch
