IENumerable에 ForEth 확장 방식이 없는 이유는 무엇입니까?
것에 묻는 다른 질문에서 을 얻어Zip
★★★★
왜요?가 없는 거죠?ForEach
IEnumerable
터페? 니면아??? ??「」를 .ForEach
는 「」입니다.List<>
퍼포먼스나 퍼포먼스 같은 것이 없는 이유가 있나요?
이이있 there there there 가 있어요.foreach
대부분의 시간 동안 작업을 수행하는 언어에 포함된 문장입니다.
다음을 보고 싶지 않습니다.
list.ForEach( item =>
{
item.DoSomething();
} );
대신:
foreach(Item item in list)
{
item.DoSomething();
}
후자가 더 명확하고 대부분의 경우 읽기 쉽지만 타이핑하는 데 시간이 좀 더 걸릴 수 있습니다.
문제에 것을 해야겠다.ForEach()
확장 방법은 실제로 상황에 따라 유용할 수 있습니다.
스테이트먼트와 메서드의 주요 차이점은 다음과 같습니다.
- 체크됩니다.foreach:foreach는 실행 시 실행됩니다.
ForEach()
빅 플러스! - 대리인을 호출하는 구문은 훨씬 더 간단합니다. 객체입니다.각 (Do Something);
- ForEach()는 체인이 될 수 있습니다.단, 이러한 기능의 악질성/유용성은 논의의 여지가 있습니다.
이 모든 것들이 여기 있는 많은 사람들이 만든 훌륭한 점들이고 나는 왜 사람들이 그 기능을 놓치고 있는지 알 수 있다.Microsoft는 다음 프레임워크 반복에서 표준 ForEach 메서드를 추가해도 상관없습니다.
각 메서드는 LINQ 이전에 추가되었습니다.ForEth 확장자를 추가하면 확장 메서드의 제약으로 인해 목록 인스턴스가 호출되지 않습니다.그것이 추가되지 않은 이유는 기존의 것에 간섭하지 않기 위해서라고 생각합니다.
하지만 이 작고 멋진 기능을 놓치면 자신만의 버전을 출시할 수 있습니다.
public static void ForEach<T>(
this IEnumerable<T> source,
Action<T> action)
{
foreach (T element in source)
action(element);
}
다음과 같은 확장 방법을 쓸 수 있습니다.
// Possibly call this "Do"
IEnumerable<T> Apply<T> (this IEnumerable<T> source, Action<T> action)
{
foreach (var e in source)
{
action(e);
yield return e;
}
}
장점
체인을 허용합니다.
MySequence
.Apply(...)
.Apply(...)
.Apply(...);
단점
반복을 강요할 때까지 실제로는 아무것도 하지 않습니다.때문에 이렇게 안 됩니다..ForEach()
쓰면 돼요..ToList()
도 쓸 수
// possibly call this "Realize"
IEnumerable<T> Done<T> (this IEnumerable<T> source)
{
foreach (var e in source)
{
// do nothing
;
}
return source;
}
이것은 출하되고 있는 C# 라이브러리에서 너무 큰 차이가 날 수 있습니다.확장 방법을 잘 모르는 독자는 코드를 어떻게 해야 할지 모릅니다.
여기서의 논의는 다음과 같은 답을 제시합니다.
실제로 제가 목격한 구체적인 논의는 기능적 순수성에 달려 있습니다.부작용은 없을 것이라는 추측이 자주 나오는 표현이다.ForEvery를 보유하는 것은 단순히 참고 있는 것이 아니라 특히 부작용을 초래하는 것입니다.-Keith Farmer (파트너)
기본적으로 확장 방법을 기능적으로 "순수"하게 유지하도록 결정이 내려졌습니다.ForEvery는 Enumerable 확장 방법을 사용할 때 부작용을 유발할 수 있지만, 이는 의도하지 않았습니다.
빌트인 사용법을 사용하는 .foreach
이인 인덱스를 더 foreach
관리:
public static int ForEach<T>(this IEnumerable<T> list, Action<int, T> action)
{
if (action == null) throw new ArgumentNullException("action");
var index = 0;
foreach (var elem in list)
action(index++, elem);
return index;
}
Example
var people = new[] { "Moe", "Curly", "Larry" };
people.ForEach((i, p) => Console.WriteLine("Person #{0} is {1}", i, p));
다음과 같은 이점이 있습니다.
Person #0 is Moe
Person #1 is Curly
Person #2 is Larry
중 하나는 이렇게 쓰는 예요..ToList().ForEach(x => ...)
프로
알기 쉬움 - C#에 부속되어 있는 것만 알면 됩니다.추가 확장 방식은 필요 없습니다.
구문 노이즈는 매우 약합니다(조금 이상한 코드만 추가).
에 보통 추가 비용이 원어민이기 때문입니다..ForEach()
어쨌든 전체 컬렉션을 깨달아야 할 거야
단점
작업 순서가 이상적이지 않습니다.한 가지 요소를 깨닫고 행동하고 반복하는 게 낫겠어이 코드는 먼저 모든 요소를 인식한 후 순서대로 각 요소에 작용합니다.
목록에 예외가 발생하는 경우 단일 요소에 대해 작업을 수행할 수 없습니다.
열거가 무한하다면(자연수처럼) 운이 없는 것입니다.
항상 궁금했어요. 그래서 항상 이걸 가지고 다니죠.
public static void ForEach<T>(this IEnumerable<T> col, Action<T> action)
{
if (action == null)
{
throw new ArgumentNullException("action");
}
foreach (var item in col)
{
action(item);
}
}
작고 멋진 확장 방법.
따라서 ForEach 확장 방식은 LINQ 확장 방식과 같은 값을 반환하지 않기 때문에 적절하지 않다는 지적이 많이 있었습니다.이것은 사실적인 진술이지만 완전히 사실이 아니다.
LINQ 확장 메서드는 모두 값을 반환하므로 체인으로 연결할 수 있습니다.
collection.Where(i => i.Name = "hello").Select(i => i.FullName);
단, LINQ가 확장 메서드를 사용하여 구현되었다고 해서 확장 메서드를 동일한 방법으로 사용하여 값을 반환해야 하는 것은 아닙니다.값을 반환하지 않는 일반적인 기능을 표시하기 위해 확장 메서드를 작성하는 것은 완전히 유효한 사용법입니다.
ForEach에 대한 구체적인 주장은 확장 메서드의 제약(즉 확장 메서드가 동일한 시그니처를 가진 상속 메서드를 덮어쓰지 않음)에 따라 IEnumerable을 실행하는 모든 클래스에서 커스텀 확장 메서드를 사용할 수 있는 상황이 발생할 수 있다는 것입니다.<T
> > ( 록 > >)<T
또는 되었는지 여부에 할 수 .> 확장 메서드가 호출되는지 상속 메서드가 호출되는지 여부에 따라 다른 동작이 시작되면 혼란이 발생할 수 있습니다.
평가됨)을할 수 .Select
아이덴티티원하시면)를
IEnumerable<string> people = new List<string>(){"alica", "bob", "john", "pete"};
people.Select(p => { Console.WriteLine(p); return p; });
되고 있는지 .Count()
하는 가장 ) 또는 (afaik)입니다
표준 라이브러리로 가져오고 싶습니다만,
static IEnumerable<T> WithLazySideEffect(this IEnumerable<T> src, Action<T> action) {
return src.Select(i => { action(i); return i; } );
}
후, 는 「」가 됩니다.people.WithLazySideEffect(p => Console.WriteLine(p))
사실상 전치(foreach)와 맞먹지만 게으르고 쇠사슬에 묶일 수 있습니다.
MoreLINQ NuGet은 다음과 같은 기능을 제공합니다.ForEach
확장 및 「」의 확장 방식)Pipe
위임자를 실행하고 그 결과를 산출하는 메서드).
@코인
은 Foreach의 과 관련이 .Action<>
불필요한 메서드를 코드에 추가하지 않아도 됩니다.리스트가 10개 있는데 그 리스트에서 같은 논리를 실행하려고 하는데 대응하는 함수가 클래스에 맞지 않아 재사용되지 않는다고 합니다. 것, 또는 않은 가 되는 , 로직을 한해 둘 수 ( 「10」, 「10」, 「10」, 「10」).Action<>
수십 됩니다.
Action<blah,blah> f = { foo };
List1.ForEach(p => f(p))
List2.ForEach(p => f(p))
기타...
논리는 한 곳에 있고 너는 반을 오염시키지 않았어.
LINQ 확장 메서드의 대부분은 결과를 반환합니다.For Each는 아무것도 반환하지 않기 때문에 이 패턴에 맞지 않습니다.
F#이 있는 경우(의 다음 버전에 있습니다).NET)를 사용할 수 있습니다.
Seq.iter doSomething myIEnumerable
그것은 부분적으로 언어 디자이너들이 철학적인 관점에서 그것에 동의하지 않기 때문이다.
- 기능이 없는(및 테스트...) 것은 기능이 있는 것보다 작업이 덜 됩니다.
- 그다지 짧지 않다(일부 기능적인 경우는 있지만, 주된 용도는 아니다).
- 그건 부작용이 있는 거지 린크는 그런 게 아니야
- 기존 기능과 동일한 기능을 사용할 수 있는 다른 방법이 있는 이유는 무엇입니까? (foreach 키워드)
https://blogs.msdn.microsoft.com/ericlippert/2009/05/18/foreach-vs-foreach/
반환할 때 Select를 사용할 수 있습니다.그렇지 않으면 ToList를 먼저 사용할 수 있습니다. 컬렉션에서 아무것도 수정하고 싶지 않을 수 있습니다.
블로그에 글을 올렸습니다.http://blogs.msdn.com/kirillosenkov/archive/2009/01/31/foreach.aspx
에서 이 방법을 참조하는 경우는, 여기서 투표할 수 있습니다.NET 4.0 : http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=279093
3.5에서는 IEnumerable에 추가된 모든 확장 방식이 LINQ 지원을 위해 제공됩니다(시스템에 정의되어 있음에 유의하십시오).Linq.Enumable 클래스).이 포스트에서 LINQ 확장 방법을 설명합니다. 기존 LINQ 확장 방법을 설명합니다.- 그렇죠 - 기초부터 시작하자
내 말은, 목록<T>린Q에 의해 만들어진 것은 린q에 의해 만들어졌다.원래 거기에 있었다.
foreach(X x in Y)
IENum}이(를)하고 있어야 하는 경우 Gumer(예 2.0)를 구현합니다.생성된 MSIL을 보면 정확히 볼 수 있습니다.
IEnumerator<int> enumerator = list.GetEnumerator();
while (enumerator.MoveNext())
{
int i = enumerator.Current;
Console.WriteLine(i);
}
(MSIL)
그 후, DotNet2.0 Generics가 등장해, 리스트가 작성되었습니다.Forech는 항상 Vistor 패턴의 구현이라고 느껴왔다(감마, 헬름, 존슨, Vlissides에 의한 설계 패턴 참조).
물론 3.5에서는 같은 효과의 람다를 대신 사용할 수 있습니다. 예를 들어 http://dotnet-developments.blogs.techtarget.com/2008/09/02/iterators-lambda-and-linq-oh-my/를 사용해 보십시오.
먼저 전체 열거형을 반복하지 않고 부작용만을 목적으로 메서드를 호출하려면 다음을 사용할 수 있습니다.
private static IEnumerable<T> ForEach<T>(IEnumerable<T> xs, Action<T> f) {
foreach (var x in xs) {
f(x); yield return x;
}
}
My version은 T의 IENumerable에서 ForEach를 사용할 수 있는 확장 방식입니다.
public static class EnumerableExtension
{
public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
source.All(x =>
{
action.Invoke(x);
return true;
});
}
}
For Each에 대해서는 아직 아무도 지적하지 않았습니다.T > 에 의해, foreach 키워드가 런타임 체크되고 있는 장소의 컴파일 시간 타입이 체크됩니다.
코드에서 두 가지 방법이 모두 사용된 리팩터링을 수행했기 때문에, 저는 찬성합니다.각각 테스트 실패/실행 시 실패를 찾아내야 했기 때문에 포어치 문제를 찾을 수 있었습니다.
언급URL : https://stackoverflow.com/questions/101265/why-is-there-no-foreach-extension-method-on-ienumerable
'programing' 카테고리의 다른 글
인수 목록을 가져오려면 어떻게 해야 합니까? (0) | 2023.04.13 |
---|---|
WPF 텍스트 상자 바인딩 업데이트 (0) | 2023.04.13 |
Bash에서 변수에 대한 사용자 입력을 읽으려면 어떻게 해야 합니까? (0) | 2023.04.13 |
레코드를 검색하기 위한 SQL 쿼리(count > 1 ) (0) | 2023.04.13 |
Git의 다른 브랜치에서 선택적으로 마지 또는 변경 사항을 선택하려면 어떻게 해야 합니까? (0) | 2023.04.13 |