위임 키워드와 람다 표기법
일단 컴파일되면 다음과 같은 차이점이 있습니까?
delegate { x = 0; }
과
() => { x = 0 }
?
짧은 대답 : 아니오.
관련이 없을 수있는 더 긴 답변 :
- 람다를 델리게이트 유형 (
Func
또는 과 같은Action
)에 할당하면 익명의 델리게이트가 나타납니다. - 람다를 표현식 유형에 할당하면 익명 대리자 대신 표현식 트리가 나타납니다. 그런 다음 식 트리를 익명 대리자로 컴파일 할 수 있습니다.
편집 : 여기 Expressions에 대한 링크가 있습니다.
- System.Linq.Expression.Expression (TDelegate) (여기서 시작).
- 대리자가있는 Linq 인 메모리 (예 : System.Func)는 System.Linq.Enumerable을 사용합니다 . 표현식이있는 Linq to SQL (및 기타)은 System.Linq.Queryable을 사용합니다 . 해당 메소드의 매개 변수를 확인하십시오.
- ScottGu 의 설명 . 간단히 말해서 Linq 인 메모리는 쿼리를 해결하기위한 일부 익명 메소드를 생성합니다. Linq to SQL은 쿼리를 나타내는 식 트리를 생성 한 다음 해당 트리를 T-SQL로 변환합니다. Linq to Entities는 쿼리를 나타내는 표현식 트리를 생성 한 다음 해당 트리를 플랫폼에 적합한 SQL로 변환합니다.
나는 다윗의 대답이 마음에 들지만, 나는 욕설이라고 생각했다. 두 표현식이 제안하는 - 질문은 "이 컴파일되면"라고 했다 컴파일. 어떻게 컴파일 할 수는 있지만 하나는 대리자로 변환되고 다른 하나는 식 트리로 변환됩니까? 까다로운 방법입니다. 익명 메소드의 다른 기능을 사용해야합니다. 람다 식에서 공유하지 않는 유일한 것입니다. 매개 변수 목록 을 지정하지 않고 익명 메소드를 지정하면 void를 리턴하고 out
매개 변수 없이 모든 델리게이트 유형과 호환됩니다 . 이러한 지식으로 무장하지만 표현이 완전히 명확 해 지도록 두 개의 과부하를 구성 할 수 있어야합니다.
그러나 재난이 닥쳤습니다! 적어도 C # 3.0에서는 블록 본문이있는 람다 식을 식으로 변환 할 수 없으며 본문에 람다 식을 반환 값으로 사용하더라도 할당 할 수 없습니다. 이는 C # 4.0 및 .NET 4.0에서 변경 될 수 있으며,이를 통해 표현식 트리에서 더 많은 것을 표현할 수 있습니다. 다시 말해, MojoFilter가 제공 한 예제와 함께 두 개는 거의 항상 같은 것으로 변환됩니다. (분 후에 더 자세한 내용)
바디를 약간 변경하면 델리게이트 매개 변수 트릭을 사용할 수 있습니다.
using System;
using System.Linq.Expressions;
public class Test
{
static void Main()
{
int x = 0;
Foo( () => x );
Foo( delegate { return x; } );
}
static void Foo(Func<int, int> action)
{
Console.WriteLine("I suspect the anonymous method...");
}
static void Foo(Expression<Func<int>> func)
{
Console.WriteLine("I suspect the lambda expression...");
}
}
하지만 기다려! 충분히 교활한 경우 식 트리를 사용하지 않아도 둘을 구별 할 수 있습니다. 아래 예는 과부하 해결 규칙과 익명 대리자 일치 트릭을 사용합니다.
using System;
using System.Linq.Expressions;
public class Base
{
public void Foo(Action action)
{
Console.WriteLine("I suspect the lambda expression...");
}
}
public class Derived : Base
{
public void Foo(Action<int> action)
{
Console.WriteLine("I suspect the anonymous method...");
}
}
class Test
{
static void Main()
{
Derived d = new Derived();
int x = 0;
d.Foo( () => { x = 0; } );
d.Foo( delegate { x = 0; } );
}
}
Ouch. Remember kids, every time you overload a method inherited from a base class, a little kitten starts crying.
In the two examples above there's no difference, zero.
The expression:
() => { x = 0 }
is a Lambda expression with statement body, so it can't be compiled as an expression tree. In fact it doesn't even compile because it needs a semicolon after 0:
() => { x = 0; } // Lambda statement body
() => x = 0 // Lambda expression body, could be an expression tree.
Amy B is correct. Note that there can be advantages to using expression trees. LINQ to SQL will examine the expression tree and convert it to SQL.
You can also play tricks with lamdas and expression trees to effectively pass the names of class members to a framework in a refactoring-safe way. Moq is an example of this.
There is a difference
Example:
var mytask = Task.Factory.StartNew(() =>
{
Thread.Sleep(5000);
return 2712;
});
mytask.ContinueWith(delegate
{
_backgroundTask.ContinueTask(() =>lblPercent.Content = mytask.Result.ToString(CultureInfo.InvariantCulture));
});
And I replace with lambda:(error)
var mytask = Task.Factory.StartNew(() =>
{
Thread.Sleep(5000);
return 2712;
});
mytask.ContinueWith(()=>
{
_backgroundTask.ContinueTask(() =>lblPercent.Content = mytask.Result.ToString(CultureInfo.InvariantCulture));
});
Some basics here.
This is a anonymous method
(string testString) => { Console.WriteLine(testString); };
As anonymous methods do not have names we need a delegate in which we can assign both of these methods or expressions. e.g.
delegate void PrintTestString(string testString); // declare a delegate
PrintTestString print = (string testString) => { Console.WriteLine(testString); };
print();
Same with the lambda expression. Usually we need a delegate to use them
s => s.Age > someValue && s.Age < someValue // will return true/false
We can use a func delegate to use this expression.
Func< Student,bool> checkStudentAge = s => s.Age > someValue && s.Age < someValue ;
bool result = checkStudentAge ( Student Object);
참고URL : https://stackoverflow.com/questions/299703/delegate-keyword-vs-lambda-notation
'IT story' 카테고리의 다른 글
캐치되지 않는 구문 에러 : 예기치 않은 토큰 : (0) | 2020.05.22 |
---|---|
#! / usr / bin / env bash가 #! / bin / bash보다 우수한 이유는 무엇입니까? (0) | 2020.05.22 |
JSON 객체로 TypeScript 객체를 초기화하는 방법 (0) | 2020.05.22 |
플러그인이 너무 오래되었습니다. 최신 버전으로 업데이트하거나 ANDROID_DAILY_OVERRIDE 환경 변수를 (0) | 2020.05.22 |
전달 매개 변수 JavaFX FXML (0) | 2020.05.22 |