code

C # 7 튜플과 람다

codestyles 2020. 12. 31. 08:18
반응형

C # 7 튜플과 람다


새로운 C # 7 튜플 구문을 사용하면 튜플을 매개 변수로 사용하여 람다를 지정하고 람다 내에서 압축 해제 된 값을 사용할 수 있습니까?

예:

var list = new List<(int,int)>();

람다에서 튜플을 사용하는 일반적인 방법 :

list.Select(value => value.Item1*2 + value.Item2/2);

나는 피해야 할 새로운 설탕을 기대했습니다 .Item1 .Item2.

list.Select((x,y) => x*2 + y/2);

마지막 줄은 람다에 대한 두 개의 매개 변수로 처리되기 때문에 작동하지 않습니다. 실제로 할 방법이 있는지 잘 모르겠습니다.

편집하다:

람다 정의에서 ((x,y)) => ...이중 괄호를 시도했지만 작동하지 않았습니다. , 시도하는 것이 어리석은 일 이었지만 이중 괄호는 실제로 여기에서 작동합니다.

list.Add((1,2));

또한 내 질문은 추악한 기본 이름을 피하는 것이 아니라 .Item .Item2람다에서 튜플을 실제로 풀고 (그리고 구현되지 않거나 불가능한 이유)에 관한 것입니다. 기본 이름에 대한 솔루션을 위해 여기에 온 경우 Sergey Berezovskiy의 답변을 읽어보십시오 .

편집 2 :

좀 더 일반적인 사용 사례를 생각해보십시오. 메서드에 전달 된 튜플을 "해체"하는 것이 가능합니까 (또는 왜 안 되는가)? 이렇게 :

void Foo((int,int)(x,y)) { x+y; }

대신 :

void Foo((int x,int y) value) { value.x+value.y }

당신이 관찰 한 바와 같이 :

var list = new List<(int,int)>();

최소한 다음을 수행 할 수있을 것으로 기대합니다.

list.Select((x,y) => x*2 + y/2);

그러나 C # 7 컴파일러는 (아직) 이것을 지원하지 않습니다. 다음을 허용하는 설탕을 원하는 것도 합리적입니다.

void Foo(int x, int y) => ...

Foo(list[0]);

컴파일러 Foo(list[0]);Foo(list[0].Item1, list[0].Item2);자동으로 변환 됩니다.

현재 둘 다 가능하지 않습니다. 그러나 Proposal : Tuple deconstruction in lambda argument list 문제 dotnet/csharplang는 GitHub 리포지토리에 존재 하여 언어 팀이 향후 버전의 C #에서 이러한 기능을 고려하도록 요청합니다. 당신도 이것에 대한 지원을 받고 싶다면 그 스레드에 당신의 목소리를 추가하십시오.


튜플 속성의 이름을 지정해야합니다 (글쎄요, ValueTuple에는 필드가 있습니다). 그렇지 않으면 기본 이름이 사용됩니다.

var list = new List<(int x, int y)>();

이제 튜플에는 사용할 수있는 멋지게 명명 된 필드가 있습니다.

list.Select(t => t.x * 2 + t.y / 2)

NuGet에서 System.ValueTuple 패키지 를 추가하는 것을 잊지 말고 ValueTuples는 변경 가능한 구조체라는 점을 기억하세요.


업데이트 : 현재 Deconstruction은 기존 변수 (deconstructon-assignment) 또는 새로 생성 된 지역 변수 (deconstruction-declaration)에 대한 할당으로 만 표시됩니다. 적용 가능한 함수 멤버 선택 알고리즘은 이전과 동일합니다.

인수 목록의 각 인수는 §7.5.1.1에 설명 된 함수 멤버 선언의 매개 변수에 해당하며 인수가 해당되지 않는 모든 매개 변수는 선택적 매개 변수입니다.

튜플 변수는 단일 인수입니다. 메서드의 형식 매개 변수 목록에있는 여러 매개 변수에 대응할 수 없습니다.


C # 7.0의 해체는 세 가지 형식을 지원합니다.

  • 분해 선언 (예 :) (var x, var y) = e;,
  • 해체 할당 (예 :) (x, y) = e;,
  • 및 deconstruction-foreach (예 :) foreach(var(x, y) in e) ....

다른 컨텍스트가 고려되었지만 유용성이 감소하고 C # 7.0 기간 내에 완료 할 수 없었습니다. let 절 ( let (x, y) = e ...)과 람다의 분해는 향후 확장을위한 좋은 후보로 보입니다.

후자는 https://github.com/dotnet/csharplang/issues/258 에서 논의되고 있습니다.

챔피언 제안에 도움이 될 것이므로 피드백과 관심을 표명하십시오.

C # 7.0 분해에 포함 된 내용에 대한 자세한 내용은 디자인 문서를 참조 하세요.


실행중인 프로그램은 컴파일러가이 표현식에서 유형을 추론 할 수 없다는 것입니다.

list.Select(((int x, int y) t) => t.x * 2 + t.y / 2);

그러나 이후 (int, int)(int x, int y)같은 CLR 유형 (하다 System.ValueType<int, int>), 당신은 유형 매개 변수를 지정하는 경우 :

list.Select<(int x, int y), int>(t => t.x * 2 + t.y / 2);

작동합니다.

ReferenceURL : https://stackoverflow.com/questions/43082026/c-sharp-7-tuples-and-lambdas

반응형