2012-05-31 36 views
1

我想寫一個擴展方法給所有的人濾波器的人城鎮店鋪對象的城鎮對象#擴展方法c。與LINQ

class people 
    string name 
    string town 

class shops 
    string category 
    string town 

我知道我可以寫

var x = from p in people 
     from s in shops 
     where p.town == s.town 

,但我想知道如何寫

var x = from p in people.FilterByTown(p) or FilterByTown(p => p.town) or however it is!! 

其中FilterByTown是擴展方法,所有的MAG ic在那裏工作,我傳入的對象與商店對象進行比較。

它需要與不同的對象被送入方法

希望所有有意義的工作,上面的代碼顯然是假!

+0

爲什麼AREN你的班級叫Person and Shop,不應該把「從人身上」的人作爲某種集合(IQuery)能夠或IEnumerable )? – hatchet

+1

「FilterByTown」應該做什麼?與查詢完全一樣的東西? –

+0

我想,如果你問這個,也許你還沒有很好地理解擴展方法是如何工作的。你應該看看[this](http://msdn.microsoft.com/zh-cn/library/bb383977 .aspx),然後你將能夠自己回答這個問題! – Mones

回答

1

假設你有2集人,商店,你可以這樣寫:

List<People> people = ... 
List<Shops> shops = ... 

IEnumerable<People> Filter(this IEnumerable<People> people, IEnumerable<Shops> shops){ 
var result = people.Where(p=>shops.Any(s=>s.town == p.town)); 
return result; 
} 

如果您想通過一些任意屬性的所有類排序,你可以試試這個版本:

public static IEnumerable<T1> Filter<T1, T2>(
    this IEnumerable<T1> one, 
    IEnumerable<T2> two, string property) 
     { 
      var result = one.Where(o => two.Any(t => 
       o.GetType().GetProperty(property). 
       GetValue(o, null).Equals(t.GetType(). 
       GetProperty(property).GetValue(t, null)))); 
      return result; 
     } 

當然你需要確定屬性是有效的,並且兩個對象都有它。

+0

什麼我有幾個對象,而不是人以外的對象。那麼我將不得不通過T來傳遞各種類型的東西?我如何在不知道類型的情況下訪問它們的屬性 –

+0

您是否想要比較實體(例如,人和商店)由任意屬性? – Blablablaster

+0

這是我以後的答案,這要歸功於所有的貢獻,特別是blablablaster –

2

使用反射,你可以過濾基於任何類型的任何屬性:

public static IEnumerable<T> FilterByProperty<T>(this IEnumerable<T> source, 
               string property, 
               object value) 
{ 
    var propertyInfo = typeof(T).GetProperty(property); 

    return source.Where(p => propertyInfo.GetValue(p, null) == value); 
} 

用法:

IEnumerable<People> cityPeople = myPeople.FilterByTown("Town", "MyCity"); 

如果你想有一個清單:

List<People> cityPeopleList = myPeople.FilterByTown("MyCity").ToList(); 
+0

以上方法不起作用,因爲我想採用其他對象,這些對象也可能有城鎮屬性,所以我期待T型方法在方法中籤名但是當你這樣做時,你失去了類型,所以不能拿起鎮屬性 –

+0

@MarkLawson我想我現在對你的瞭解要好得多。看我的編輯。 – SimpleVar

+0

幾乎在那裏,我們已經通過了一個人的名單,但在方法內,我們需要將該列表與商店列表進行比較,並找到匹配的城鎮 –

0

如果我正確理解你的問題,你想要這樣的事情:

public static IEnumerable<People> FilterByTown(this IEnumerable<People> people, IList<Shop> shops) 
{ 
    return people.Where(p => shops.Any(s => s.Town == p.Town)); 
} 

用法:

peoples.FilterByTown(shops); 
+0

這非常接近,但我希望該方法能夠採用其他物體有一個城鎮的財產,所以我期待一個類型T的方法簽名,但當你這樣做,你失去了類型,所以不能拿起鎮屬性 –

0

如果你創建了獨特的城鎮

public static class PeopleExtensions 
{        
    private static List<string> _distinctShopTowns; 

    private static List<Shop> _shops; 
    public static List<Shop> Shops 
    { 
     get { return _shops; } 
     set { 
      _shops = value; 
      _distinctShopTowns = _shops 
       .Select(shop => shop.town) 
       .Distinct() 
       .ToList(); 
     } 
    } 

    public static IEnumerable<Person> PeopleInTownsWithShops(this IEnumerable<Person> people) 
    { 
     return people.Where(p => _distinctShopTowns.Contains(p.town)); 
    } 
} 

列表您可以加快查詢你可以這樣調用

List<Shop> shops = ...; 
List<Person> people = ...; 

PeopleExtensions.Shops = shops; // Do every time the shop list changes. 

var x = from p in people.PeopleInTownsWithShops();