2013-07-18 3 views
0

저는 C#을 처음 접했고 람다 식을 사용하려고했습니다.Select and ForEach List <>

개체 목록이 있습니다. 목록에서 항목을 선택하고 선택한 항목에 대해 foreach 작업을 수행하려고합니다. 난 람다 표현을 사용하지 않고 그것을 할 수 있지만 람다 표현을 사용하여 가능했다 싶었어요.

그래서 나는 누군가가이 동작을 설명 할 수이

 users.select(i => i.UserName=="").ForEach(i=>i.UserName="NA"); 

같은

 users.Where(i => i.UserName=="").ToList().ForEach(i=>i.UserName="NA"); 

하지만 무언가를하는 것이 가능했다 유사한 결과

 List<UserProfile> users = new List<UserProfile>(); 
     ..load users with list of users 
     List<UserProfile> selecteditem = users.Where(i => i.UserName=="").ToList(); 
     foreach(UserProfile item in selecteditem) 
     { 
      item.UserName = "NA"; 
     } 

를 달성하기 위해 노력했다. .

+0

[이 질문에 대한 답변] (http://stackoverflow.com/questions/200574/linq-equivalent-of-foreach-for-ienumerablet) – Blorgbeard

+5

http://blogs.msdn.com/b/ericlippert/archive/ 2009/05/18/foreach-vs-foreach.aspx – I4V

+0

마지막 코드 스 니펫은 아마도'선택 '이 아니라'Where'를 첫 번째 연산자로 사용한다는 뜻입니까? – Servy

답변

10

의 여기에서 시작하자 : 나는 개체의 목록을 데

합니다.

정확한 내용이지만 정확한 내용은 C# 프로그래머가 더 많은 것을 원한다는 것을 이해하는 것이 중요합니다. 어떤 종류의 물건? 닷넷 세계에서, 당신이 작업하고있는 특정 유형의 객체를 항상 염두에 두어야합니다. 이 경우 해당 유형은 UserProfile입니다. 이것은 부수적 인 문제처럼 보일지 모르지만 특정 문제에 대해 매우 신속하게 관련성이 높아집니다. 대신에 다음과 같이 말하고 싶습니다.

나는 UserProfile 개체의 목록을 가지고 있습니다. 이제

의이 두 식을 살펴 보자 :

users.Where (I => i.UserName == "").. ToList()를 ForEach (I => i.UserName = " NA ");

users.Where (I => i.UserName == ''). foreach는 (ⅰ => i.UserName = "NA");

당신이 목록 유형에 Where() 함수의 결과를 변환 .ToList()를 호출 할 필요가있다 (첫 번째 컴파일 또는 작품 것을 제외)의 차이. 이제 우리는 을 볼 수 있습니다. 왜입니다. 닷넷 코드로 작업 할 때 항상 유형에 관해 생각하고 싶습니다. 이제는 어떤 유형의 코드를 사용했는지 궁금해 할 것입니다. 네가 물어 줘서 다행이다.

.Where() 함수의 결과는 IEnumerable<T> 유형이며 실제로는 전체 유형이 아닙니다.인터페이스은 계약서를 구현하는 유형이 수행 할 수있는 특정 작업을 설명합니다. IEnumerable 인터페이스는 처음에는 혼란 스러울 수 있지만 기억해야 할 점은 foreach 루프와 함께 사용할 수있는 무언가를 정의한다는 것입니다. 그것이 유일한 목적입니다. .Net에서 foreach 루프와 함께 사용할 수있는 것 : 배열, 목록, 컬렉션 — 그들은 모두 거의 모든 IEnumerable 인터페이스를 구현합니다. 반복 할 수있는 다른 것들이 있습니다. 예를 들어 문자열. 인수 또는 목록을 인수로 필요로하는 오늘날 많은 메서드는 인수 형식을 IEnumerable로 변경하여 더 강력하고 유연하게 만들 수 있습니다.

.Net은 또한이 인터페이스에서 작동 할 상태 기반 컴퓨터 기반 반복기를 쉽게 만들 수 있습니다. 이 기능은 항목을 보유하지는 않지만 특정 방식으로 다른 모음의 항목을 반복하는 방법을 알고있는 객체를 만드는 데 특히 유용합니다. 예를 들어 크기가 20 인 배열에서 항목 3에서 12까지 반복 할 수 있습니다. 또는 항목을 알파벳 순서로 반복 할 수 있습니다. 여기서 중요한 것은 원본을 복사하거나 복제 할 필요없이이 작업을 수행 할 수 있다는 것입니다. 이것은 메모리 측면에서 매우 효율적이며, 다른 반복자를 함께 구성하여 매우 강력한 결과를 얻을 수있는 구조로되어 있습니다.

IEnumerable<T> 유형은 linq 시스템의 핵심을 구성하는 두 가지 유형 (다른 하나는 IQueryable 임) 중 하나이기 때문에 특히 중요합니다. .Where(), .Select(), .Any() 등 대부분 linq 연산자는 확장자로 정의되어 있습니다.을 IEnumerable로 정의합니다.

하지만 지금은 예외가 있습니다 : ForEach(). 이 메서드는 이 아니며 IEnumerable의 일부가입니다. 이것은 List<T> 유형의 일부로 직접 정의됩니다. 따라서 우리는 완전한 진술을 구성하는 각각의 다른 표현식의 결과를 포함하여 언제 어떤 유형의 작업을하는지 이해하는 것이 중요하다는 것을 다시 알 수 있습니다.

또한 에 들어가는 것이 좋습니다.이 특별한 방법은 IEnumerable의 일부가 아닙니다. 나는 대답은 linq 시스템이 Functional Programming 세계로부터 많은 영감을 얻는다는 사실에 있다고 믿습니다. 함수형 프로그래밍에서는 부작용없이 정확히 한 가지 작업 (함수)을 사용하고자합니다. 이상적으로 이러한 함수 은 원래 데이터 인을 변경하지 않지만 새로운 데이터를 반환합니다. ForEach() 메서드는 암시 적으로 데이터를 변경하는 나쁜 부작용을 만드는 것에 관한 것입니다. 그것은 단지 나쁜 기능적 스타일입니다. 또한 ForEach()는 새 IEnumerable을 반환하지 않는다는 점에서 메서드 체이닝을 중단합니다.

여기에서 배울 점이 하나 더 있습니다. 원래 스 니펫을 살펴 보겠습니다 :

List<UserProfile> users = new List<UserProfile>(); 
// ..load users with list of users 
List<UserProfile> selecteditem = users.Where(i => i.UserName=="").ToList(); 
foreach(UserProfile item in selecteditem) 
{ 
    item.UserName = "NA"; 
} 

이 코드를 크게 개선하는 데 도움이 될만한 내용이 있습니다. 컬렉션을 반복하지 않고 IEnumerable 항목을 루프 할 수있는 방법에 대해 조금 기억하십니까? 대신,이 방법이 코드를 작성하는 경우 어떻게되는지에 대해 생각 :

List<UserProfile> users = new List<UserProfile>(); 
// ..load users with list of users 
var selecteditem = users.Where(i => i.UserName==""); 
foreach(UserProfile item in selecteditem) 
{ 
    item.UserName = "NA"; 
} 

은 내가 한 모든 .ToList()에 전화를 제거했지만, 모든 것이 여전히 작동합니다. 변경된 유일한 것은 이므로 전체 목록을 복사 할 필요가 없습니다. 이 코드는 보다 빠릅니다.. 경우에 따라 코드을 더 빠르게 만들 수 있습니다.염두에 두어야 할 점 : linq 연산자 메서드로 작업 할 때는 가능하면 언제든지 .ToArray() 또는 .ToList()을 호출하는 것을 피하는 것이 좋습니다. 생각할 수있는 것보다 훨씬 더 많은 가능성이 있습니다.

foreach() {...}.Foreach(...)의 경우 : 전자는 여전히 완벽하게 적절한 스타일입니다.

4

물론, 아주 간단합니다. ListForEach 방법을 사용합니다. IEnumerable에 대한 방법이나 확장 방법이 없습니다.

왜 하나는 방법이 있고 다른 하나는 그렇지 않은지에 대해서는 의견입니다. 에릭 리 퍼트 blogged on the topic.