使用linq的c#扩展方法

时间:2012-05-31 21:48:06

标签: c# linq lambda

我想写一个扩展方法来过滤所有拥有商店对象中城镇的人物对象中城镇的人

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 个答案:

答案 0 :(得分: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();

答案 1 :(得分:1)

假设你有两个人和商店,你可以写下这个:

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;
        }

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

答案 2 :(得分: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);

答案 3 :(得分: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();