c\#중 의뢰 에 대한 이해

이해 의뢰 는 간단 한 예 부터 시작한다.
금성 무 가 연기 한 오래된 영 화 는 라 는 영화 가 있 는데 그 안에 줄거리 가 있 는데 대략 이렇다.김 군 은 고객 의 돈 을 받 고 고객 을 대표 하여 다른 사람 에 게 간다.Say I love you.
처음에 그의 고객 은 모두 중국인 이 었 다.중국 어 를 말 하기 만 하면 다음 과 같은 코드 예 시 는 매우 간단 하고 모든 중국 고객 을 지원 했다.

public class LoveManager
{
    public void Love(string name)
    {
        Console.WriteLine(" , {0}", name);
    }
}

class Program
{
    static void Main(string[] args)
    {
        LoveManager loveManager = new LoveManager();
        loveManager.Love(" ");
    }
}
실행 결과:

,
나 는 나중에 영화 에 외국 고객 이 나 타 났 다 는 것 을 알 게 되 었 다.나 는 코드 가 이렇게 되 어야 한다 고 생각한다.

// ,
public enum Language
{
    English,
    Chinese
}

public class LoveManager
{
    public void Love(string name, Language lang)
    {
        switch (lang)
        {
            case Language.Chinese:
                loveChinese(name);
                break;
            case Language.English:
                loveEnglish(name);
                break;
        }
    }

    //
    public void LoveChinese(string name)
    {
        Console.WriteLine(" , {0}", name);
    }

    //
    public void LoveEnglish(string name)
    {
        Console.WriteLine("I love you, {0}", name);
    }
}


class Program
{
    static void Main(string[] args)
    {
        LoveManager loveManager = new LoveManager();
        loveManager.Love(" ", Language.Chinese);
        loveManager.Love("Sophie Marceau", Language.English);
    }
}
실행 결과:

,
I love you, Sophie Marceau
OK,이제 장만 옥 은'사랑 해'를 알 아들 을 수 있 고,소 피 마 르 코 는'I love you'를 알 아들 을 수 있다.영 한 이중 언어 고백 을 지 지 했 지만 앞으로 프랑스 고객,포르투갈 고객,아랍 고객 은 어떻게 할 것 인가?하나의 언어 를 확장 할 때마다'사랑 해'라 는 언어 를 추가 하 는 방법 외 에 도 매 거 진 을 확장 해 야 합 니 다.LoveManager.Love()를 확장 하 는 것 은 정말 번 거 롭 습 니 다.
 
C 언어 시대:지침
이때 C 언어 에서 명성 이 자자 한 지침 을 언급 하지 않 을 수 없 었 다.포인 터 는 한 함수 의 주 소 를 매개 변수 로 다른 함수 에 전달 할 수 있 습 니 다.이 기능 은 이후 의 각종 고급 언어 에서 확장 되 고 강화 되 었 습 니 다.먼저 다음 C 코드 를 보십시오.

#include <stdio.h>

//
void func1(void(*p)(void)){
    printf("this is func1\r
");
    //
    p();
}

void func2(){
    printf("this is func2\r
");
}

int main() {
    // func2
    func1(func2);
    return 0;
}

실행 결과:

this is func1
this is func2
.Net 에서 C 언어 처럼 함 수 를 매개 변수 로 전달 하고 호출 할 수 있 습 니까?

// , .Net Love(" ", LoveChinese);
Love("Sophie Marceau", LoveEnglish);
.Net 에서 더 완벽 한 해결 방안:의뢰
.Net 에서 C 언어 처럼 함 수 를 매개 변수 로 전달 할 수 있 을 뿐만 아니 라.Net 은 유형 보안 체제 와 더욱 강력 한 기능 을 제공 합 니 다.다음 과 같이 의뢰 를 사용 하 는 전체 코드 예 시 를 제공 합 니 다.

using System;

namespace DelegateDemo
{
    //
    public delegate void LoveDelegate(string name);

    public class LoveManager
    {
        public void Love(string name, LoveDelegate loveDelegate)
        {
            loveDelegate(name);
        }

        //
        public void LoveChinese(string name)
        {
            Console.WriteLine(" , {0}", name);
        }

        //
        public void LoveEnglish(string name)
        {
            Console.WriteLine("I love you, {0}", name);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            LoveManager loveManager = new LoveManager();
            loveManager.Love(" ", loveManager.LoveChinese);
            loveManager.Love("Sophie Marceau", loveManager.LoveEnglish);
        }
    }
}

실행 결과:

,
I love you, Sophie Marceau
정의 의뢰

public delegate void LoveDelegate(string name);
우 리 는 현재 의뢰 에 대해 정 리 를 하고 있다.의뢰 는 하나의 유형 으로 방법의 유형 을 정의 하여 방법 을 다른 방법의 매개 변수 로 전달 할 수 있다.이런 방법 을 매개 변수 에 동적 으로 부여 하 는 방법 은 프로그램 에서 If-Else(Switch)문 구 를 대량으로 사용 하 는 것 을 피 할 수 있 고 프로그램 이 더욱 확장 성 을 가지 게 할 수 있다.C\#에서 특유 의 키워드 delegate 를 사용 하여 정 의 를 의뢰 합 니 다.delegate 다음 에 함수 서명 을 따라 갑 니 다.형식 안전 을 확보 하기 위해.Net 의 의뢰 요구 함 수 는 같은 서명 을 가지 고 있 습 니 다.예 를 들 어 func(int p)와 func(string p)는 같은 의뢰 를 사용 할 수 없습니다.매개 변수 유형 이 다 르 기 때 문 입 니 다.

ILDasm.exe 를 통 해 의뢰 를 정의 하 는 줄 코드 는 실제 컴 파일 할 때 자동 으로 클래스 를 생 성 합 니 다.이 클래스 를 복원 하려 면 코드 는 다음 과 같 습 니 다.

public class LoveDelegate : System.MulticastDelegate
{
      //
      public LoveDelegate(Object obj, IntPtr method);

      //
      public virtual void Invoke(string name);

      //
      public virtual IAsyncResult BeginInvoke(Int32 value, AsyncCallback callback, Object obj);
      public virtual void EndInvoke(IAsyncResult result);
}

따라서 의뢰 는 실제 적 으로 하나의 클래스 로 System.MulticastDelegate 에 계승 되 어 클래스 를 정의 할 수 있 는 곳 이 라면 의뢰 를 정의 할 수 있 습 니 다.
위탁 구조 함수

LoveManager loveManager = new LoveManager();
// ,
//LoveDelegate loveDelegate = new LoveDelegate();
LoveDelegate loveDelegate = new LoveDelegate(loveManager.LoveChinese);
loveDelegate(" ");
클래스 와 달리 의뢰 는 매개 변 수 를 가 진 구조 함 수 를 사용 해 야 합 니 다.
추정 문법

LoveManager loveManager = new LoveManager();
// :LoveDelegate loveDelegate = new LoveDelegate(loveManager.LoveChinese);
LoveDelegate loveDelegate = loveManager.LoveChinese;
loveDelegate(" ");
의뢰 및 방법 귀속
위의 예 로 돌아 가면 어느 날 1 부 2 세 는 김 군 을 찾 아 돈 이 문제 가 아니 라 고 말 했다.너 는 장만 옥 아래층 에 가서 중국어 로 한 번 외치 고 영어 로 한 번 외 쳤 다.

static void Main(string[] args)
{
        LoveManager loveManager = new LoveManager();
        //
        LoveDelegate delegate1;
        // ( )
        delegate1 = loveManager.LoveChinese;
        // ( )
        delegate1 += loveManager.LoveEnglish;
        delegate1(" ");
}
실행 결과:

,
I love you,
우 리 는+=여러 가지 방법 을 하나의 의뢰 에 귀속 시 킬 수도 있 고,사용 할 수도 있다  -= 제거 방법 과 의뢰 의 귀속.
익명 방법
고객 의 수 요 는 항상 변화무쌍 하 다.한 고객 이 김 군 에 게 나 는 만 옥 에 게 고백 할 것 이다.중국 과 영 어 를 사용 하 는 것 외 에 뒤에 한 마디 더 해 줄 수 있 느 냐 고 말 했다.만 옥 은 이 말 을 듣 자마자 반드시 나 에 게 대답 할 것 이다.

LoveManager loveManager = new LoveManager();
LoveDelegate loveDelegate = loveManager.LoveEnglish;
loveDelegate += loveManager.LoveChinese;
loveDelegate += delegate(string name)
{
    Console.WriteLine("{0}, ?", name);
};
loveDelegate(" ");
실행 결과:

I love you,

, ?
이 특수 고객 에 대해 익명 의 방법 을 사용 했다.모든 사람 이 사랑 을 표시 할 때 대명 호숫가 의 하 우 하,즉 이 특수 고객 이 한 번 사용 하기 때문에 독립 적 인 방법 을 정의 할 필요 가 없다.익명 의 방법 을 사용 하면 인 코딩 량 을 줄 이 고 코드 의 복잡 도 를 낮 출 수 있다.
Lambda(λ)표현 식
C\#3.0 은 익명 의 방법 으로 Lambda 표현 식 을 제공 합 니 다.다음 코드 의 실행 결 과 는 위의 예제 와 완전히 일치 합 니 다.

LoveManager loveManager = new LoveManager();
LoveDelegate loveDelegate = loveManager.LoveEnglish;
loveDelegate += loveManager.LoveChinese;
// Lambda loveDelegate += name =>
{
    Console.WriteLine("{0}, ?", name);
};
loveDelegate(" ");
=>Lambda 연산 자 입 니 다.연산 자 왼쪽 에 익명 방법 에 필요 한 인 자 를 표시 합 니 다.이렇게 사용 할 수 있 습 니 다.
(string param1, int param2)
가능 하 다
(param1, param2)
예 를 들 어 예제 코드 는 하나의 매개 변수 만 있 고 괄호 도 제거 할 수 있 습 니 다.
param1
Lambda 표현 식 오른쪽 은 익명 방법 으로 코드 를 실현 합 니 다.코드 가 한 줄 만 있 으 면 괄호 와 return 문 구 를 삭제 할 수 있 습 니 다.컴 파일 러 가 자동 으로 추가 되 기 때 문 입 니 다.
함께 공부 하고 함께 진보 하 자!

좋은 웹페이지 즐겨찾기