문제

다음은 다음과 같은 간단한 방법입니다 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;
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top