문제

나는 빨리 읽었다 Microsoft Lambda Expression 선적 서류 비치.

이런 종류의 예는 더 잘 이해하는 데 도움이되었습니다.

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

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

도움이 되었습니까?

해결책

람다 표현 익명 대의원을위한 더 간단한 구문이며 익명 대의원을 사용할 수있는 곳마다 사용할 수 있습니다. 그러나 그 반대는 사실이 아닙니다. Lambda 표현은 Expression Tree로 변환 될 수있어 Linq에서 SQL과 같은 많은 마법을 허용합니다.

다음은 a의 예입니다 LINQ에서 개체 익명 대의원을 사용한 표현 및 Lambda 표현을 통해 눈이 얼마나 쉬운지를 보여줍니다.

// 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 Expressions 및 익명 대표는 별도의 기능을 작성하는 것보다 이점이 있습니다. 폐쇄 당신을 허용 할 수 있습니다 매개 변수를 추가하지 않고 로컬 상태를 함수로 전달하십시오 함수 또는 일회성 사용 객체 생성.

표현 나무 C# 3.0의 매우 강력한 새로운 기능으로, API가 실행할 수있는 방법에 대한 참조를 얻는 대신 API가 표현식의 구조를 볼 수 있습니다. API는 단지 대의원 매개 변수를 Expression<T> 매개 변수와 컴파일러는 익명 대의원 대신 람다에서 발현 트리를 생성합니다.

void Example(Predicate<int> aDelegate);

호출 :

Example(x => x > 5);

:

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

후자는 표현을 통과 할 것이다 초록 구문 트리 그것은 표현을 설명합니다 x > 5. LINQ에서 SQL은이 동작에 의존하여 서버 측에서 필터링 / 주문 / 등에 원하는 SQL 표현식으로 C# 표현식을 전환 할 수 있습니다.

다른 팁

익명의 기능과 표현식은 전체 방법을 작성하는 데 필요한 추가 작업의 혜택을받지 않는 일회성 방법에 유용합니다.

이 예를 고려하십시오 :

 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;
 }

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

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

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;
}

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

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"라는 단어와 일치하는 항목 목록을 검색합니다. 이를 수행하는 다른 방법은 실제로 대의원을 찾은 메소드에 다음과 같이 전달하는 것입니다.

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"; });

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

Microsoft는 우리에게 Lambda Expressions라는 익명의 대표를 만드는 더 깨끗하고 편리한 방법을 제공했습니다. 그러나, 표현 이 진술의 일부. Microsoft는 전체 네임 스페이스를 출시했습니다. System.linq.expressions, Lambda 표현을 기반으로 발현 트리를 만드는 클래스가 포함되어 있습니다. 표현 나무는 논리를 나타내는 물체로 구성됩니다. 예를 들어, 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();
        }
    }
}

이 예는 사소합니다. 그리고 나는 당신이 생각하고 있다고 확신합니다. "이것은 표현식을 만들고 런타임에 그것을 컴파일하는 대신 대의원을 직접 만들 수 있었기 때문에 이것은 쓸모가 없습니다." 그리고 당신이 옳을 것입니다. 그러나 이것은 표현 나무의 기초를 제공합니다. 표현식 네임 스페이스에는 여러 가지 표현식이 있으며 직접 구축 할 수 있습니다. 알고리즘이 디자인 또는 컴파일 시간에 무엇을 해야하는지 정확히 알지 못할 때 이것이 유용 할 수 있음을 알 수 있습니다. 나는 이것을 사용하여 과학적 계산기를 작성하기위한 예를 보았다. 당신은 또한 그것을 사용할 수 있습니다 베이지안 시스템 또는 유전자 프로그래밍 (일체 포함). 내 경력에서 몇 번이나 나는 사용자가 간단한 표현식 (첨가, 하중 등)을 입력하여 사용 가능한 데이터에서 작동 할 수 있도록 Excel과 같은 기능을 작성해야했습니다. pre -.net 3.5에서 나는 c#외부의 일부 스크립팅 언어에 의지해야했거나, 코드에 미팅 함수를 반사하여 .net 코드를 즉시 생성해야했습니다. 이제 나는 표현 나무를 사용할 것입니다.

특정 장소에서 한 번만 사용되는 방법이 사용되는 장소에서 멀리 떨어져있는 방법이 있어야합니다. 좋은 용도는 정렬과 같은 일반 알고리즘의 비교기로서, 여기서 다른 곳에서 다른 곳을 보도록 강요하지 않고 정렬을 호출하는 사용자 지정 정렬 기능을 정의 할 수 있습니다.

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

Lambda 표현은 대의원 대신에 작성된 익명 방법과 같습니다.

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

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

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

함수 로직은 x * x입니다 (오른쪽의 =>)

Lambda Expression의 코드는 표현식 대신 진술 블록이 될 수 있습니다.

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 표현식을 찾을 수도 있습니다.

예를 들어 : 메소드 호출로 취한 시간을 계산할 수있는 일반적인 기능. (즉 Action 여기에서)

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

Lambda 표현식을 사용하여 위의 방법을 다음과 같이 호출 할 수 있습니다.

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

표현식은 메소드에서 반환 값을 얻고 Param도 얻을 수 있습니다.

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

많은 시간에, 당신은 한 곳에서 기능을 사용하고 있으므로 방법을 만들면 클래스를 클러 터트합니다.

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

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

마찬가지로, 왜 Foreach를 사용해야합니까? 루프를위한 평원으로 또는 직접 ienumerable을 사용할 수있는 모든 것을 foreach로 할 수 있습니다. 답 : 당신은 그렇지 않습니다 필요 그러나 코드를 더 읽기 쉽게 만듭니다.

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

예를 들어, SQL을 사용하고 SQL 주입 공격을 얻을 수 있기 전에 해커는 숫자가 일반적으로 예상되는 문자열을 전달했기 때문에 SQL 주입 공격을 얻을 수 있습니다. 이제 LINQ LAMBDA 표현을 사용하여 보호됩니다.

순수한 대의원에 LINQ API를 구축하는 것은 불가능합니다. 평가 트리를 평가하기 전에 표현 나무를 결합해야하기 때문입니다.

2016 년에는 대부분의 인기있는 언어가 있습니다 람다 표현 지원과 C#은 주류 명령 언어들 사이 에서이 진화에서 개척자 중 하나였습니다.

이것은 아마도 Lambda Expressions를 사용하는 이유에 대한 가장 좋은 설명 일 것입니다 -> https://youtu.be/j9nj5dto54q

요약하면 코드 가독성을 향상시키고 코드를 복제하는 대신 재사용하여 오류 가능성을 줄이며 무대 뒤에서 발생하는 최적화를 활용하는 것입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top