2012-02-14 3 views
5

람다 표현식으로 지정된 속성에 값을 할당하는 일반적인 방법을 찾으려면 아래 예제 코드를 참조하십시오. ConverToEntities 메소드 모양과 어떻게 호출 될까요?표현식/lambda를 사용하여 속성 값을 설정하는 일반적인 방법

static void Main() 
{ 
    List<long> ids = new List<long> {1, 2, 3}; 

    //Non generic way 
    List<Data> dataItems = ids.ConvertToDataItems(); 

    //Generic attempt!! 
    List<Data> differntDataItems = 
     ids.ConvertToEntities<Data>(p => p.DataId); 
} 

public class Data 
{ 
    public long DataId; 
    public string Name; 
} 

public static class ExtensionMethods 
{ 
    public static List<Data> ConvertToDataItems(this List<long> dataIds) 
    { 
     return dataIds.Select(p => new Data { DataId = p }).ToList(); 
    } 

    public static List<T> ConvertToEntities<TProp>(
     this List<long> entities, Func<TProp> lambdaProperty) 
    { 
     return entities.Select(p => new T {lambdaProperty}).ToList(); 
    } 
} 
+0

입니까? .. 당신이 실제로 원하는 것은 public static리스트입니다. List ConvertToEntities ... 또는 아닙니다? –

+0

ConvertToEntities는 일반적인 메서드에서의 시도입니다. 구문이 올바르지 않습니다.이 메서드를 일반화하려고합니다. –

+0

해결책이 주어지면, 닷넷과 함께 제공되는'.Select'는 코드가 적습니다. –

답변

4

확인. 가장 가까운 곳은 다음과 같습니다.

class Program 
    { 
     static void Main(string[] args) 
     { 
      List<long> ids = new List<long> { 1, 2, 3 }; 

      //Non generic way 
      List<Data> dataItems = ids.ConvertToDataItems(); 

      //Generic attempt!! 

      Func<long, Data> selector = (p => new Data { DataId = p }); 
      List<Data> differntDataItems = ids.ConvertToEntities<Data>(selector); 
     } 
    } 

    public class Data 
    { 
     public long DataId; 
     public string Name; 
    } 

    public static class ExtensionMethods 
    { 
     public static List<Data> ConvertToDataItems(this List<long> dataIds) 
     { 
      return dataIds.Select(p => new Data { DataId = p }).ToList(); 
     } 

     public static List<TProp> ConvertToEntities<TProp>(this List<long> entities, Func<long, TProp> selector) 
     { 
      return entities.Select(selector).ToList(); 
     } 
    } 

이것은 작동합니다.

나는 실제로 당신이 반환 유형으로 원하는 것과 약간 혼란스러워했다. 메소드 호출이나 smth에서 우리가 원하는 것을 지정할 수 있다는 것은 멋지다. 예를 들면 다음과 같습니다.

public static List<TProp> ConvertToEntities<T, TProp>(List<T> entities, Func<T, TProp> selector) 
    { 
     return entities.Select(selector).ToList(); 
    } 

이렇게하면 반환 유형을보다 유연하게 지정할 수 있습니다. 그러나 우리는이 사용하는 확장을하고 있기 때문에, 우리는 우리가 확장하는 유형을 알 필요가 있기 때문에이 비현실적 가정

this List<long> entities, 

좋은 질문을.

수정 코드 제안 사항.

+0

그건 훌륭합니다 !! 훌륭한 해결책; 대단히 감사합니다 :-) –

+0

고마워요. 고마워, 우리를위한 좋은 수수께끼였다. –

1

@ Zortkun이 반환 유형에 대해 정확하다고 생각합니다.

public static List<TProp> ConvertToEntities<TProp>(
    this List<long> entities, Func<long, TProp> lambdaProperty) 
{ 
    return entities.Select(lambdaProperty).ToList(); 
} 

을 다음과 같이 당신은 그것을 부를 것이다 : :이 따라와 시도

ids.ConvertToEntities<Data>(p => new Data { DataId = p }); 
2

당신이 뭔가를 할 수 있지만, 간단하거나 좋은 아니에요. 람다 p => p.DataId 당신에게 재산의 접근을 제공합니다. 당신은 세터를 얻을 수 Expression의를 사용할 수 있지만, 람다에서 직접 세터를 사용하는 것이 아마도 더 나은 :

List<Data> differntDataItems = 
    ids.ConvertToEntities<long, Data>((p, i) => p.DataId = i); 

구현은 다음과 같습니다 목록 상점 무엇

public static List<T> ConvertToEntities<TProp, T>(
    this List<TProp> dataIds, Action<T, TProp> lambdaProperty) 
    where T : new() 
{ 
    return dataIds.Select(
     p => 
     { 
      var result = new T(); 
      lambdaProperty(result, p); 
      return result; 
     }).ToList(); 
} 
관련 문제