1

我想编写一个扩展方法来过滤所有在人员对象中具有城镇的人以及商店对象中的城镇

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 是扩展方法,所有的魔法都在那里工作,我传入的对象与商店对象进行比较。

它需要处理被提供给方法的不同对象

希望一切都说得通,上面的代码显然是伪代码!

4

4 回答 4

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();
于 2012-05-31T21:59:15.697 回答
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;
        }

当然,您需要确保该属性有效并且两个对象都具有它。

于 2012-05-31T21:56:10.030 回答
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);
于 2012-05-31T22:10:41.750 回答
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();
于 2012-05-31T22:22:23.150 回答