Programing

C # Lambda 표현식 : 왜 사용해야합니까?

lottogame 2020. 3. 15. 09:32
반응형

C # Lambda 표현식 : 왜 사용해야합니까?


Microsoft Lambda Expression 설명서를 빨리 읽었습니다 .

그러나 이런 종류의 예는 다음과 같이 더 잘 이해하는 데 도움이되었습니다.

delegate int del(int i);
del myDelegate = x => x * x;
int j = myDelegate(5); //j = 25

그래도 왜 그런 혁신인지 이해할 수 없습니다. "메소드 변수"가 끝나면 죽는 방법 일뿐입니다. 실제 방법 대신 이것을 사용해야하는 이유는 무엇입니까?


람다 식은 익명 대리자의 간단한 구문이며 익명 대리자가 사용될 수있는 모든 곳에서 사용할 수 있습니다. 그러나 그 반대는 사실이 아닙니다. 람다 식은 LINQ to SQL과 같은 많은 마법을 허용하는 식 트리로 변환 될 수 있습니다.

다음은 익명 대리자를 사용하고 람다 식을 사용하여 LINQ to Objects 표현식 의 예입니다 .

// anonymous delegate
var evens = Enumerable
                .Range(1, 100)
                .Where(delegate(int x) { return (x % 2) == 0; })
                .ToList();

// lambda expression
var evens = Enumerable
                .Range(1, 100)
                .Where(x => (x % 2) == 0)
                .ToList();

Lambda 표현식과 익명 델리게이트는 별도의 함수를 작성하는 것보다 이점 이 있습니다. 클로저구현 하면 함수에 매개 변수추가 하거나 일회용 객체를 만들지 않고도 함수에 로컬 상태를 전달할 수 있습니다.

식 트리는 C # 3.0의 매우 강력한 새로운 기능으로, API가 실행할 수있는 메서드에 대한 참조를 얻는 대신 식의 구조를 볼 수 있도록합니다. API는 대리자 매개 변수를 매개 변수로 만들면 Expression<T>컴파일러가 익명 ​​대리자 대신 람다에서 식 트리를 생성합니다.

void Example(Predicate<int> aDelegate);

처럼 호출 :

Example(x => x > 5);

된다 :

void Example(Expression<Predicate<int>> expressionTree);

후자는 표현식을 설명하는 추상 구문 트리 의 표현을 전달 받게됩니다 x > 5. LINQ to SQL은 C # 표현식을 서버 측에서 필터링 / 순서 등으로 원하는 SQL 표현식으로 변환 할 수 있도록이 동작에 의존합니다.


익명 함수 및 표현식은 전체 메소드를 작성하는 데 필요한 추가 작업의 이점이없는 일회성 메소드에 유용합니다.

이 예제를 고려하십시오.

 string person = people.Find(person => person.Contains("Joe"));

 public string FindPerson(string nameContains, List<string> persons)
 {
     foreach (string person in persons)
         if (person.Contains(nameContains))
             return person;
     return null;
 }

이들은 기능적으로 동일합니다.


다른 컨트롤을 사용하여 일부 컨트롤의 이벤트에 대한 핸들러를 선언하려는 상황에서 유용하다는 것을 알았습니다. 일반적으로 컨트롤의 참조를 클래스의 필드에 저장하여 생성 된 것과 다른 방법으로 사용할 수 있도록해야합니다.

private ComboBox combo;
private Label label;

public CreateControls()
{
    combo = new ComboBox();
    label = new Label();
    //some initializing code
    combo.SelectedIndexChanged += new EventHandler(combo_SelectedIndexChanged);
}

void combo_SelectedIndexChanged(object sender, EventArgs e)
{
    label.Text = combo.SelectedValue;
}

람다 식 덕분에 다음과 같이 사용할 수 있습니다.

public CreateControls()
{
    ComboBox combo = new ComboBox();
    Label label = new Label();
    //some initializing code
    combo.SelectedIndexChanged += (s, e) => {label.Text = combo.SelectedValue;};
}

훨씬 쉽게.


Lambda는 C # 2.0의 익명 대리자 구문을 정리했습니다.

Strings.Find(s => s == "hello");

C # 2.0에서 다음과 같이 수행되었습니다.

Strings.Find(delegate(String s) { return s == "hello"; });

기능적으로 그들은 똑같은 일을합니다. 단지 훨씬 간결한 구문입니다.


이것은 람다 식을 사용하는 한 가지 방법입니다. 대리자를 사용할 수있는 곳이면 람다 식을 사용할 수 있습니다. 이를 통해 다음과 같은 작업을 수행 할 수 있습니다.

List<string> strings = new List<string>();
strings.Add("Good");
strings.Add("Morning")
strings.Add("Starshine");
strings.Add("The");
strings.Add("Earth");
strings.Add("says");
strings.Add("hello");

strings.Find(s => s == "hello");

이 코드는 "hello"단어와 일치하는 항목을 목록에서 검색합니다. 이를 수행하는 다른 방법은 실제로 다음과 같이 대리자를 Find 메서드에 전달하는 것입니다.

List<string> strings = new List<string>();
strings.Add("Good");
strings.Add("Morning")
strings.Add("Starshine");
strings.Add("The");
strings.Add("Earth");
strings.Add("says");
strings.Add("hello");

private static bool FindHello(String s)
{
    return s == "hello";
}

strings.Find(FindHello);

편집 :

C # 2.0에서는 익명 델리게이트 구문을 사용하여이를 수행 할 수 있습니다.

  strings.Find(delegate(String s) { return s == "hello"; });

람다는 구문을 크게 정리했습니다.


Microsoft는 Lambda 식이라는 익명의 대리자를 만드는보다 깨끗하고 편리한 방법을 제공했습니다. 그러나, 이 진술 표현 부분 에는 많은주의를 기울이지 않습니다 . Microsoft는 람다 식을 기반으로 식 트리를 만드는 클래스가 포함 된 전체 네임 스페이스 인 System.Linq.Expressions를 릴리스했습니다 . 식 트리는 논리를 나타내는 개체로 구성됩니다. 예를 들어, x = y + z는 .Net에서 표현식 트리의 일부일 수있는 표현식입니다. 다음 (간단한) 예를 고려하십시오.

using System;
using System.Linq;
using System.Linq.Expressions;


namespace ExpressionTreeThingy
{
    class Program
    {
        static void Main(string[] args)
        {
            Expression<Func<int, int>> expr = (x) => x + 1; //this is not a delegate, but an object
            var del = expr.Compile(); //compiles the object to a CLR delegate, at runtime
            Console.WriteLine(del(5)); //we are just invoking a delegate at this point
            Console.ReadKey();
        }
    }
}

이 예는 사소한 것입니다. 그리고 "당신은 표현식을 생성하고 런타임에 컴파일하는 대신 델리게이트를 직접 생성 할 수 있기 때문에 이것은 쓸모가 없다"고 생각합니다. 그리고 당신은 옳을 것입니다. 그러나 이것은 표현 트리의 기초를 제공합니다. Expressions 네임 스페이스에는 여러 가지식이 있으며 자신 만의 식을 만들 수 있습니다. 디자인이나 컴파일 타임에 알고리즘이 무엇인지 정확히 모르는 경우 이것이 유용 할 수 있다고 생각합니다. 과학 계산기를 작성하기 위해 이것을 사용하는 어딘가의 예를 보았습니다. 베이지안 시스템이나 유전자 프로그래밍 에도 사용할 수 있습니다(일체 포함). 내 경력에서 몇 번이나 Excel과 비슷한 기능을 작성하여 사용 가능한 데이터를 조작 할 수있는 간단한 표현 (추가, 서브 트리 등)을 입력 할 수있었습니다. .Net 3.5 이전에는 C # 외부의 일부 스크립팅 언어에 의존하거나 코드 방출 기능을 사용하여 .Net 코드를 즉석에서 작성해야했습니다. 이제 표현 트리를 사용하겠습니다.


특정 장소에서 한 번만 사용되는 메소드를 사용하는 장소에서 멀리 떨어져 정의하지 않아도됩니다. 정렬과 같은 일반 알고리즘에 대한 비교 자로 사용하면 정렬을 호출하기 위해 다른 곳을 보도록 강요하지 않고 정렬을 호출하는 사용자 정의 정렬 함수를 정의 할 수 있습니다.

그리고 그것은 실제로 혁신이 아닙니다. LISP는 약 30 년 이상 람다 기능을 가지고 있습니다.


또한 메서드에 작용하는 일반 코드를 작성할 때 람다 식을 사용하는 방법을 찾을 수 있습니다.

예를 들면 다음과 같습니다. 메소드 호출에 걸리는 시간을 계산하는 일반 함수. (즉 Action여기에)

public static long Measure(Action action)
{
    Stopwatch sw = new Stopwatch();
    sw.Start();
    action();
    sw.Stop();
    return sw.ElapsedMilliseconds;
}

그리고 다음과 같이 람다 식을 사용하여 위의 메소드를 호출 할 수 있습니다.

var timeTaken = Measure(() => yourMethod(param));

Expression을 사용하면 메소드 및 반환 매개 변수에서 반환 값을 얻을 수 있습니다

var timeTaken = Measure(() => returnValue = yourMethod(param, out outParam));

람다 식은 대리자 인스턴스 대신 작성된 익명 메서드와 같습니다.

delegate int MyDelagate (int i);
MyDelagate delSquareFunction = x => x * x;

람다 표현을 고려하십시오 x => x * x;

입력 매개 변수 값은 x (왼쪽 ==)입니다.

함수 논리는 x * x입니다 (오른쪽 =>).

람다 식의 코드는 식 대신 문 블록 일 수 있습니다.

x => {return x * x;};

참고 : Func사전 정의 된 일반 위임입니다.

    Console.WriteLine(MyMethod(x => "Hi " + x));

    public static string MyMethod(Func<string, string> strategy)
    {
        return strategy("Lijo").ToString();
    }

참고 문헌

  1. 델리게이트와 인터페이스를 어떻게 상호 교환하여 사용할 수 있습니까?

많은 경우에 한 곳에서만 기능을 사용하므로 메소드를 작성하면 클래스가 복잡해집니다.


람다 식은 익명의 방법을 나타내는 간결한 방법입니다. 익명 메소드와 Lambda 표현식 모두 메소드 구현을 인라인으로 정의 할 수 있지만 익명 메소드를 사용하려면 메소드의 매개 변수 유형 및 리턴 유형을 명시 적으로 정의해야합니다. Lambda 식은 C # 3.0의 형식 유추 기능을 사용하여 컴파일러가 컨텍스트를 기반으로 변수의 형식을 유추 할 수 있습니다. 그것은 우리에게 많은 타이핑을 저장하기 때문에 매우 편리합니다!


작은 작업을 수행하고 사용 위치에 가까운 변수를 선언하는 것과 달리 사용되는 위치에 매우 가깝게 배치하는 방법입니다. 이것은 코드를 더 읽기 쉽게 만들어야합니다. 표현식을 익명화함으로써, 함수가 다른 곳에서 사용되어 "향상"되도록 클라이언트 코드가 깨지는 경우 누군가가 클라이언트 코드를 깨뜨리기가 훨씬 어려워집니다.

마찬가지로 foreach를 사용해야하는 이유는 무엇입니까? 일반 for 루프를 사용하거나 IEnumerable을 직접 사용하여 foreach의 모든 작업을 수행 할 수 있습니다. 답변 : 당신이하지 않는 필요 로하지만, 그것은 당신의 코드를 읽기 수 있습니다.


혁신은 유형 안전과 투명성에 있습니다. 람다 식 유형을 선언하지는 않지만 유추되어 코드 검색, 정적 분석, 리팩토링 도구 및 런타임 반영에 사용될 수 있습니다.

예를 들어, 해커가 일반적으로 예상했던 문자열을 전달했기 때문에 SQL을 사용하고 SQL 주입 공격을받을 수 있기 전에. 이제 LINQ 람다 식을 사용합니다.

순수한 델리게이트에서 LINQ API를 빌드 할 수 없습니다. 표현식 트리를 평가하기 전에 함께 결합해야하기 때문입니다.

2016 년에 대부분의 인기있는 언어는 람다 식 지원을 제공하며 C #은 주류 명령형 언어 중에서이 진화의 선구자 중 하나였습니다.


이것은 람다 식을 사용하는 이유에 대한 가장 좋은 설명 일 것입니다-> https://youtu.be/j9nj5dTo54Q

요약하면, 코드 가독성을 향상시키고 코드를 복제하는 대신 재사용함으로써 오류 가능성을 줄이고 뒤에서 발생하는 최적화를 활용합니다.

참고 URL : https://stackoverflow.com/questions/167343/c-sharp-lambda-expressions-why-should-i-use-them

반응형