2011-09-13 2 views
3

으음, 어떻게 설명할까요? 아마도 간단한 질문이지만 마음이 튀었을 것입니다. 여기.NET에서 입력 된 객체 목록에서 객체 속성의 모든 값을 선택하는 방법 C#

public class NestedObject 
{ 
    public string NestedName { get; set; } 
    public int NestedIntValue { get; set; } 
    public decimal NestedDecimalValue { get; set; } 
} 

public class SomeBigExternalDTO 
{ 
    public int Id { get; set; } 
    public int UserId { get; set; } 
    public int SomeIntValue { get; set; } 
    public long SomeLongValue { get; set; } 
    public decimal SomeDecimalValue { get; set; } 
    public string SomeStringValue { get; set; } 
    public NestedObject SomeNestedObject { get; set; } 
    // ... thousands more of these properties... inherited code 
} 

내가 채울하고자하는 클래스입니다 : 가정하자

나는이 클래스가

public class MyResult 
{ 
    public int UserId { get; set; } // user id from above object 
    public string ResultValue { get; set; } // one of the value fields from above with .ToString() executed on it 
} 

는 내가 뭘하려는 것은 돌려주는 도우미를 만드는 것입니다 이 객체의 목록에있는 모든 인스턴스의 속성 값 (교차 단면은 내가 추측 할 수있는 가장 좋은 방법입니다) :

var foo = new List<SomeBigExternalDTO>(); 
foo = GetMyListOfSomeBigExternalDTO(); 

public static List<MyResult> AwesomeHelper(List<SomeBigExternalDTO> input, SearchableProperty thePropertyIWant) 
{ 
    // some magic needs to happen here... 
} 

여기에 까다로운 부분은 내가 동적 링크 선택에 따라 속성에 전달해야한다 (나는이 작업을 수행하는 방법에 단서가 없다) :

var output = AwesomeHelper(GetMyListOfSomeBigExternalDTO(), x => x.SomeIntValue); 
var output2 = AwesomeHelper(GetMyListOfSomeBigExternalDTO(), x => x.SomeNestedObject.NestedIntValue); 

을 그리고 이것은 MyResult의 목록을 반환해야한다는 사용자 아이디와 객체 및 SomeIntValue.ToString() 입력 목록의 각 항목에 해당합니다.

와우, 나는 이것이 정말로 의미가 있기를 바랍니다. 이것이 명확하지 않으면 알려주십시오. 자세한 내용을 알려 드리겠습니다. 나는 이것이 내가 간과 한 도서관에 구워진 것이기를 정말로 바라고 있습니다.

나는 이것을 달성하기위한 아이디어가 있습니까?

+0

답변 해 주셔서 감사합니다. 내 후속 질문을 확인하십시오 : http://stackoverflow.com/questions/7396781/architecturally-speaking-how-should-i-replace-an-extremely-large-switch-statemen – longda

답변

2

종종 범용 목록 연산자를 만들려고하면 LINQ에서 제공하는 것을 다시 구현해야합니다. 매우 간단

var results = list.Select(l => new MyResult() 
{ 
    UserId = l.UserId, 
    ResultValue = l.SomeDecimalValue.ToString() 
}).ToList(); 

:

다음은 (AN AwesomeHelper 기능이없는) 후하는지에 대한 LINQ 코드입니다. 당신이 요청한대로 당신이 AwesomeHelper 기능을 갖고 싶어

은 다음은 다음과 같습니다

이 같은 호출 코드 모양
public static List<MyResult> AwesomeHelper(
    List<SomeBigExternalDTO> input, 
    Func<SomeBigExternalDTO, object> selector) 
{ 
    return input 
     .Select(i => new MyResult() 
     { 
      UserId = i.UserId, 
      ResultValue = selector(i).ToString() 
     }) 
     .ToList(); 
} 

: 그리고 나에게

var results = AwesomeHelper(list, x => x.SomeIntValue); 

는하지만, 이것이 지금 LINQ 옵션보다 읽기가 적은입니다. 이제 약간의 마술이 일어 났고, 무엇을 해결하기가 어렵습니다.

두 가지 장점을 모두 제공 할 대안이 있습니다.

먼저, 다음과 같이 필드 선택기로 하나의 MyResult에 하나의 SomeBigExternalDTO 인스턴스를 매핑 ToMyResult라는 확장 메서드를 정의

public static class AwesomeHelperEx 
{ 
    public static MyResult ToMyResult(
      this SomeBigExternalDTO input, 
      Func<SomeBigExternalDTO, object> selector) 
    { 
     return new MyResult() 
     { 
      UserId = input.UserId, 
      ResultValue = selector(input).ToString() 
     }; 
    } 
} 

이제 호출 코드는 크리스탈, 명확 유연하고 간결하다. 여기에 있습니다 :

var results = (
     from item in list 
     select item.ToMyResult(x => x.SomeLongValue) 
    ).ToList(); 

희망이 있습니다.

+0

이 답변을 주셔서 감사합니다! 이것은 제가 처음에 물어 본 것의 또 다른 측면, 구체적으로 어떻게 선택된 속성을 함수에 전달 하는지를 보여줍니다. 나는이 답변을 정말 좋아하며 프로젝트에서 약간 탐구 할 것입니다. 나는 그것이 어떻게되는지 알려줄 것이고, 나는 이것을 나중에 내가 선택한 대답으로 바꿀 수있을 것이다. 다시 한 번 감사드립니다! – longda

3

당신 확장 방법으로 구현할 수 :

public static IEnumerable<MyResult> AwesomeHelper(this IEnumerable<SomeBigExternalDTO> input, 
                Func<SomeBigExternalDTO, int> intMapper) 
{ 
    foreach (var item in input) 
     yield return new MyResult() 
     { 
      UserId = item.UserId, 
      ResultValue = intMapper(item) 
     }; 
} 

지금이처럼 사용할 수 있습니다 : - '그렇게 해달라고 -

var output = GetMyListOfSomeBigExternalDTO().AwesomeHelper(x => x.SomeIntValue); 
var output2 = GetMyListOfSomeBigExternalDTO().AwesomeHelper(x => x.SomeNestedObject.NestedIntValue); 

는 것을 말해 두 겠는데 어떻게 든처럼 보인다 당신 Linq가 이미 제공하는 것을 재발 명하고 있습니다. Linq만을 사용하여 동일하게 할 수 있습니다 :

var output = GetMyListOfSomeBigExternalDTO().Select(x=> new MyResult() 
      { 
       UserId = item.UserId, 
       ResultValue = x.SomeIntValue 
      }); 

var output2 = GetMyListOfSomeBigExternalDTO().Select(x=> new MyResult() 
      { 
       UserId = item.UserId, 
       ResultValue = x.SomeNestedObject.NestedIntValue 
      }); 
+0

감사합니다! 그래, 나는 이걸 완전히 생각한 것 같아. – longda

+0

@longda : 이것을 선택한 답의 표시를 해제 한 특별한 이유가 있습니까? – BrokenGlass

+0

답변 해 주셔서 다시 한 번 감사드립니다. Enigmativity에 선택기 기능을 만들기위한 코드가 있었기 때문에 표시된 대답을 바꿨습니다. – longda