신입 개발자 공부 과정

Delegate 대리자 2 + Lamda 람다 본문

C#/수업 내용

Delegate 대리자 2 + Lamda 람다

Lewisjkim 2022. 1. 5. 20:59

대리자2

// Declare a delegate.
delegate void Del(int x);

// Define a named method.
void DoWork(int k) { /* ... */ }

// Instantiate the delegate using the method as a parameter.
Del d = obj.DoWork;

대리자는 호출 시 둘 이상의 메서드를 호출할 수 있습니다. 이러한 호출을 멀티캐스트라고 합니다. 대리자의 메서드 목록(호출 목록)에 메서드를 더 추가하려는 경우 더하기 또는 더하기 대입 연산자('+' 또는 '+=')를 사용하여 대리자만 두 개 더 추가하면 됩니다. 예를 들어:

var obj = new MethodClass();
Del d1 = obj.Method1;
Del d2 = obj.Method2;
Del d3 = DelegateMethod;

//Both types of assignment are valid.
Del allMethodsDelegate = d1 + d2;
allMethodsDelegate += d3;

-----

멀티

private delegate void Del(string message);
        public App()
        {
            var obj = new Method();
            Del d1 = obj.Method1;
            Del d2 = obj.Method2;
            Del d3 = this.DelegateMethod;

            Del allMethodsDelegate = d1 + d2;
            allMethodsDelegate += d3;

            allMethodsDelegate("hi");
        }
        private void DelegateMethod(string message)
        {
            Console.WriteLine(message);
        }
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LearnDelegate2
{
    class Method
    {
        public void Method1(string message) { Console.WriteLine("Method1:{0}",message); }
        public void Method2(string message) { Console.WriteLine("Method2:{0}", message); }


    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LearnDelegate2
{
    class Program
    {
        static void Main(string[] args)
        {
            
            new App();
        }
    }
}

-----

빼기

allMethodsDelegate -=d1;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LearnDelegate2
{
    class App
    {
        private delegate void Del(string message);
        public App()
        {
            var obj = new Method();
            Del d1 = obj.Method1;
            Del d2 = obj.Method2;
            Del d3 = this.DelegateMethod;

            Del allMethodsDelegate = d1 + d2;
            allMethodsDelegate += d3;
            //remove
            allMethodsDelegate -=d1;

            allMethodsDelegate("hi");
        }
        private void DelegateMethod(string message)
        {
            Console.WriteLine(message);
        }
    }
          
}

----------------

대리자는 명명된 메서드에 연결할 수 있습니다. 명명된 메서드를 사용하여 대리자를 인스턴스화하면 메서드가 매개 변수로 전달됩니다. 예를 들면 다음과 같습니다.

이 코드는 명명된 메서드를 사용하여 호출됩니다. 명명된 메서드를 사용하여 생성된 대리자는 정적 메서드 또는 인스턴스 메서드를 캡슐화할 수 있습니다. 명명된 메서드는 이전 버전의 C#에서 대리자를 인스턴스화할 수 있는 유일한 방법입니다. 그러나 새 메서드 생성이 불필요한 오버헤드인 경우 C#에서 대리자를 인스턴스화하고 호출 시 대리자에서 처리할 코드 블록을 즉시 지정할 수 있습니다. 블록에는 람다 식 또는 무명 메서드가 포함될 수 있습니다.

대리자 매개 변수로 전달하는 메서드에는 대리자 선언과 동일한 시그니처가 있어야 합니다. 대리자 인스턴스는 정적 또는 인스턴스 메서드를 캡슐화할 수 있습니다.

// Declare a delegate.
delegate void Del(int x);

// Define a named method.
void DoWork(int k) { /* ... */ }

// Instantiate the delegate using the method as a parameter.
Del d = obj.DoWork;

-------------

 

반환값 있으면 Function<T,TResult>을 사용한다

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LearnDelegate2
{
    class App
    {
        //1. .net에서 action 대리자 정의 미리 해둠
        private Action action;//3
        private Func<string> func; //string은 반환값

        public App()
        {
            action = this.SayHello;//4

            action(); //5

            this.func = this.Hello; //func 호출
            string message = this.func();
            Console.WriteLine(message);
        }

        //2
        private string Hello()
        {
            return "Hello World(func)";
        }
        private void SayHello()
        {
            Console.WriteLine("hello world!");
        }
    }
          
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

람다식

화살표 함수

c# 교과서

식 람다 기본형=

(input-parameters) => expression

문 람다 기본형=

(input-parameters) => { <sequence-of-statements> }

문의 개수에는 제한이 없지만 일반적으로 2-3개 정도만 지정

Action<string> greet = name =>
{
    string greeting = $"Hello {name}!";
    Console.WriteLine(greeting);
};
greet("World");
// Output:
// Hello World!

 

람다 식은 대리자 형식으로 변환할 수 있습니다.

//Func<int, int> square = x => x * x;   //현대 코드 

        //Func<int, int> square = (x) => x * x;
        
        //Func<int, int> square = (x) =>
        //{
        //    return x * x;
        //};

        //신생대 신제3기 코드 
        Func<int, int> square;
        
        public App() 
        {
            this.square = this.Square;
        }

        private int Square(int x) {
            return x * x;
        }

 

람다 식을 변환할 수 있는 대리자 형식해당 매개 변수 및 반환 값의 형식에 따라 정의됩니다

- 람다 식에서 값을 반환하지 않는 경우 Action 대리자 형식 중 하나로 변환할 수 있습니다

Action<string> greet = name => 
{
var message = "Hello {0}", name;
Console.WriteLine(message);
};

/////

greet("you")
////

//output
//Hello you

값을 반환하는 경우 Func 대리자 형식으로 변환할 수 있습니다

Func<int, int> square = x => x * x;
Console.WriteLine(square(5));
// Output:
// 25

------------------

람다식의 입력 매개 변수는 괄호로 묶는다

 

-매개 변수 0개 

빈괄호 

Action line = () => Console.WriteLine();
//Action line = (매개변수 0개) => Console.WriteLine();

 

-입력 매개 변수가 하나만 있는 경우 괄호는 선택 사항입니다.

ex) x

Func<double, double> cube = x => x * x * x;

 

-두 개 이상의 입력 매개 변수는 쉼표로 구분합니다.

ex) (x, y)

Func<int, int, bool> testForEquality = (x, y) => x == y;

 

컴파일러가 입력 매개 변수의 형식을 유추할 수 없는 경우도 있습니다. 다음 예제와 같이 형식을 명시적으로 지정할 수 있습니다.

ex) (int x, string s)

Func<int, string, bool> isTooLong = (int x, string s) => s.Length > x;

 

 

 

 

'C# > 수업 내용' 카테고리의 다른 글

01/06 과제  (0) 2022.01.07
Dictionary  (0) 2022.01.06
Delegate 대리자1  (0) 2022.01.04
1월3일 인벤3  (0) 2022.01.03
12/30 수업 스타크래프트 부대지정  (0) 2021.12.30