2010-04-29 33 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; 
       } 
      } 
     } 

    } 

它通過使用反射做什麼,它找到的name屬性,然後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循環這實際上是沒有必要的內部。我想我們可以把它放在循環之外。

但是如何?

PLease help。 (C#3.0)

+0

爲什麼不使用'.Where (Func )'? – 2010-04-29 03:21:50

回答

2

有幾件事情你可以做的 - 首先,你可以在制定約束泛型類型轉換爲具有name屬性的接口。如果它只能使用FactorClass,那麼你並不需要一個通用類型 - 你可以將它作爲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

取決於他要去哪裏,也許他想擴展它來搜索對象上的所有字符串? – 2010-04-29 03:21:28

1

剛剛獲得T的類型

 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; 
      } 
      } 
    } 
相關問題