"DO"/ACTION LINQ 연산자에 대한 계획이 있습니까?
문제
다음은 다음과 같은 간단한 방법입니다 foreach
고리:
IEnumerable<XElement> FieldsToXElements(object instance)
{
var fieldElements = new List<XElement>();
foreach (var field in instance.GetType().GetFields(instance))
{
fieldElements.Add(new XElement(field.Name, field.GetValue(instance)));
}
return fieldElements;
}
일종의 못생긴. LINQ에 "무언가를하는"것을 의미하는 일부 연산자가 있다면 Action
LINQ 문에서 선택한 각각에 대해), 그것은 더 멋지게 보일 것입니다.
IEnumerable<XElement> FieldsToXElements(object instance)
{
var fieldElements = new List<XElement>();
from field in instance.GetType().GetFields(instance))
let name = field.Name
let value = field.GetValue(instance)
do fieldElements.Add(new XElement(name, value));
return fieldElements;
}
나는 그것이 주관적이며 내 의견을 알고 있습니다. 단순히 메소드를 호출하는 한 줄이있는 Foreach 루프의 경우 A "do
"제 생각에는 운영자가 의미가 있습니다. 그러나 MS의 누군가가 같은 생각을했는지 궁금합니다. 이러한 LINQ 운영자는 다가오는 릴리스에서 계획되어 있습니까 (예 : C# 4.0 데뷔와 함께)?
여기에는 가상의 do
연산자는 실제로 코드를 깨끗하게 보이게합니다. 이것:
IEnumerable<XElement> FieldsToXElements
(object instance, Func<FieldInfo, bool> predicate)
{
var fieldElements = new List<XElement>();
foreach (var field in instance.GetType().GetFields(instance).Where(predicate))
{
fieldElements.Add(new XElement(field.Name, field.GetValue(instance)));
}
return fieldElements;
}
vs. 이것은 :
IEnumerable<XElement> FieldsToXElements
(object instance, Func<FieldInfo, bool> predicate)
{
var fieldElements = new List<XElement>();
from field in instance.GetType().GetFields(instance))
let name = field.Name
let value = field.GetValue(instance)
where predicate(field)
do fieldElements.Add(new XElement(name, value));
return fieldElements;
}
해결책
아니, 나는 직접적인 것을 기대하지 않습니다 언어 Suport (즉, 쿼리 구문 내부)는 곧 언제든지.
신화를 의미하는 것 같네요 ForEach
확장 방법; 추가하기가 좋지만 Eric Lippert는 부작용이없는 기능 코드와 Action<T>
부작용으로. 특히, C# 3.0 / .NET 3.5 발현 트리는 측면 효과에서 끈적 끈적합니다 (전체 Lambda 지원을 까다 롭게 함). 런타임 측 .NET 4.0에서 훨씬 좋습니다, 그러나 현재 C# 4.0의 언어 (Lambda Compiler)로 얼마나 많은 것을 만들 것인지는 확실하지 않습니다.
(대표 버전의 경우) 필요한 것은 다음과 같습니다.
public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
{ // note: omitted arg/null checks
foreach(T item in source) { action(item); }
}
그런 다음 쿼리에서 간단히 사용할 수 있습니다 .ForEach(x => /* do something */)
.
다른 팁
당신의 구체적인 예를 위해 (포기 a List<XElement>
), 나는 이런 식으로 할 것이다.
IEnumerable<XElement> FieldsToXElements(object instance)
{
List<XElement> fieldElements =
(
from field in instance.GetType().GetFields(instance))
let name = field.Name
let value = field.GetValue(instance)
select new XElement(name, value)
).ToList(); //Another Option is List<T>.AddRange()
return fieldElements;
}
또한 : 그것을 잊지 마십시오 List<T>
이미 구현됩니다 .ForEach<T>()
, 그래서 그것을 사용하기 위해 Enumerable<T>
, 이것은 필요한 모든 코드입니다.
myEnumerable.ToList().ForEach( x => myAction(x) );
나는 이것이 너무 어렵다고 생각하지 않거나 내가 뭔가를 놓치고 있을지도 모른다 ...
IEnumerable<XElement> FieldsToXElements(object instance)
{
return instance.GetType()
.GetFields(instance)
.Select( f => new XElement( f.Name,
f.GetValue(instance) ) );
}
LINQ 문 내에서 함수를 호출하려는 경우 이미 그렇게 할 수 있습니다. LET 할당에서 함수를 호출 할 수 있습니다.
var qry = from e in somelist
let errorcode = DoSomeProcessing(e)
select e;