[c#] C #에서 대리자 사용

C # 언어 및 .NET 프레임 워크에서 대리자를 이해하는 데 도움을 줄 수 있습니까? 일부 코드를 확인하려고했는데 내가받은 결과가 예상치 못한 결과라는 것을 알았습니다. 여기있어:

class Program
{
    public static int I = 0;

    static Func<string> del = new Func<string>(I.ToString);

    static void Main(string[] args)
    {
        I = 10;
        Console.WriteLine("{0}", del());
    }
}

대답은 0 이었지만 10이 아니 었습니다. 이유가 무엇입니까?



답변

그 이유는 다음과 같습니다.

대리자를 선언하는 ToString방식은 정적 int 인스턴스 의 메서드를 직접 가리 킵니다 . 생성 당시 캡처됩니다.

flindeberg가 아래 주석에서 지적했듯이 각 대리자는 대상에서 실행할 대상과 메서드를 가지고 있습니다.

이 경우 실행될 ToString메서드 는 분명히 메서드입니다. 흥미로운 부분은 메서드가 실행되는 인스턴스입니다 I. 생성 당시의 인스턴스입니다 . 즉, 대리자가 I사용할 인스턴스를 가져 오는 데 사용하지 않지만 인스턴스 자체에 대한 참조를 저장합니다.

나중에 I다른 값으로 변경 하여 기본적으로 새 인스턴스를 할당합니다. 이것은 델리게이트에서 캡처 된 인스턴스를 마술처럼 변경하지 않습니다. 왜 그래야합니까?

예상 한 결과를 얻으려면 대리자를 다음과 같이 변경해야합니다.

static Func<string> del = new Func<string>(() => I.ToString());

이와 같이 대리자는 대리자를 실행할 ToString때 현재 I에서 실행되는 익명 메서드를 가리 킵니다 .

이 경우 실행할 메서드는 델리게이트가 선언 된 클래스에서 생성 된 익명 메서드입니다. 인스턴스는 정적 메서드이므로 null입니다.

컴파일러가 대리자의 두 번째 버전에 대해 생성하는 코드를 살펴보십시오.

private static Func<string> del = new Func<string>(UserQuery.<.cctor>b__0);
private static string cctor>b__0()
{
    return UserQuery.I.ToString();
}

보시다시피, 이것은 무언가를 하는 일반적인 방법입니다 . 우리의 경우에는 ToString의 현재 인스턴스를 호출 한 결과를 반환합니다 I.


답변

함수가 생성 될 때가 아니라 적절한 시간에 실행될 수 I있도록 함수 에 전달해야합니다 I.ToString().

class Program
{
    public static int I = 0;

    static Func<int, string> del = num => num.ToString();

    static void Main(string[] args)
    {
        I = 10;
        Console.WriteLine("{0}", del(I));
    }
}


답변

이 작업을 수행하는 방법은 다음과 같습니다.

using System;

namespace ConsoleApplication1
{

    class Program
    {
        public static int I = 0;

        static Func<string> del = new Func<string>(() => {
            return I.ToString();
        });

        static void Main(string[] args)
        {
            I = 10;
            Console.WriteLine("{0}", del());
        }
    }
}


답변

C # 대리자는 개체와 인스턴스 및 메서드를 모두 캡슐화 할 수 있습니다. 대리자 선언은 System.Delegate 클래스에서 파생 된 클래스를 정의합니다. 델리게이트 인스턴스는 호출 목록을 캡슐화합니다.이 목록은 하나 이상의 메서드 목록이며 각 메서드는 호출 가능한 엔터티라고합니다.

더 많은 양식을 배우십시오

http://asp-net-by-parijat.blogspot.in/2015/08/what-is-delegates-in-c-how-to-declare.html


답변

내 생각에 int는 참조가 아닌 값에 의해 전달되기 때문에 대리자를 만들 때 현재 값 “I”(0)의 ToString 메서드에 대한 대리자입니다.


답변