2010-04-29 7 views
2

나는 다음과 같은 확장 메서드에게이 반사를 사용하는 것입니다 무엇을이 확장 방법을 개선 할 수 있습니까?

public static class ListExtensions 
    { 

     public static IEnumerable<T> Search<T>(this ICollection<T> collection, string stringToSearch) 
     { 
      foreach (T t in collection) 
      { 
       Type k = t.GetType(); 
       PropertyInfo pi = k.GetProperty("Name"); 
       if (pi.GetValue(t, null).Equals(stringToSearch)) 
       { 
        yield return t; 
       } 
      } 
     } 

    } 

을 가지고, 그것은 이름 속성을 발견 한 후 일치하는 문자열을 기반으로 컬렉션에서 기록을 filteres.

이 방법은 그것은 잘 작동

List<FactorClass> listFC = new List<FactorClass>(); 
    listFC.Add(new FactorClass { Name = "BKP", FactorValue="Book to price",IsGlobal =false }); 
    listFC.Add(new FactorClass { Name = "YLD", FactorValue = "Dividend yield", IsGlobal = false }); 
    listFC.Add(new FactorClass { Name = "EPM", FactorValue = "emp", IsGlobal = false }); 
    listFC.Add(new FactorClass { Name = "SE", FactorValue = "something else", IsGlobal = false });  
    List<FactorClass> listFC1 = listFC.Search("BKP").ToList(); 

로 불리는되고있다.

그러나 확장 방법에 대해 자세히 살펴은

Type k = t.GetType(); 
PropertyInfo pi = k.GetProperty("Name"); 

실제로는 필요가없는 foreach 루프 내부에서 실제로 것을 발표 할 예정이다. 나는 우리가 그것을 바깥으로 가져갈 수 있다고 생각한다.

하지만 어떻게?

도움 말. (C# 3.0)

+0

'.Where (Func )'을 사용하지 않는 이유는 무엇입니까? –

답변

2

는 T의 종류를 얻을 - 먼저가에 제약을 제기 할 수 제네릭 형식을 name 속성이있는 인터페이스로 보냅니다. FactorClass 만 사용할 수 있다면 generic 형식이 필요하지 않습니다.이 형식을 ICollection<FactorClass>의 확장자로 사용할 수 있습니다. 인터페이스 경로 (또는 비 제네릭 버전)를 사용하는 경우 속성을 참조하기 만하면 반영 할 필요가 없습니다. 경우, 어떤 이유로, 이것은 당신이 할 수있는 작동하지 않습니다

var k = typeof(T); 
var pi = k.GetProperty("Name"); 
foreach (T t in collection) 
{ 
     if (pi.GetValue(t, null).Equals(stringToSearch)) 
     { 
      yield return t; 
     } 
} 

인터페이스를 사용하여이

public static IEnumerable<T> Search<T>(this ICollection<T> collection, string stringToSearch) where T : INameable 
{ 
    foreach (T t in collection) 
    {  
     if (string.Equals(t.Name, stringToSearch)) 
     { 
      yield return t; 
     } 
    } 
} 

편집과 같습니다 제프의 코멘트 @ 본 후,이 정말 아니라 속성 중 하나에 대해 값을 단순히 확인하는 것보다 더 복잡한 작업을 수행하는 경우 유용합니다. 그는 Where을 사용하는 것이 그 문제에 대한 더 나은 해결책이라는 점에서 절대적으로 맞습니다.

3

이런 방식으로 반사를 사용하는 것은 나에게보기 흉한 행위입니다.

100 % 일반 "T"가 필요하며 기본 클래스 또는 인터페이스를 사용할 수 없습니까?

내가 너라면 필자는 자신의 검색 기능을 쓰는 대신 .Where<T>(Func<T, Boolean>) LINQ 메서드를 사용할 것을 고려할 것입니다.

사용하는 대표적인 예는 다음과 같습니다

List<FactorClass> listFC1 = listFC.Where(fc => fc.Name == "BKP").ToList(); 
+0

은 그가 어디로 가고 있는지에 따라 다르며, 오브젝트의 모든 문자열을 검색하기 위해 그것을 확장하려고 할 것입니다. –

1

그냥 당신이 할 수있는 몇 가지가있다

 Type k = typeof(T); 
     PropertyInfo pi = k.GetProperty("Name"); 
     foreach (T t in collection) 
     {     
      if (pi.GetValue(t, null).Equals(stringToSearch)) 
      { 
       yield return t; 
      } 
     } 
2
 public static IEnumerable<T> Search<T>(this ICollection<T> collection, string stringToSearch) 
    { 

      Type k = typeof(T); 
      PropertyInfo pi = k.GetProperty("Name"); 

      foreach (T t in collection) 
      { 
      if (pi.GetValue(t, null).Equals(stringToSearch)) 
      { 
       yield return t; 
      } 
      } 
    } 
관련 문제