当前位置: 动力学知识库 > 问答 > 编程问答 >

c# extension method with linq

问题描述:

I want to write an extension method to filter all the people with towns in a people object with the towns in shop object

class people

string name

string town

class shops

string category

string town

i know i can write

var x = from p in people

from s in shops

where p.town == s.town

but i would like to know how to write

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

where FilterByTown is the extension method and all the magic works in there and the object i pass in gets compared with the shop object.

It needs to work with different objects being fed to the method

Hope that all makes sense, the code above is obviously pseudo!

网友答案:

Assuming you have 2 collections people and shops you can write this:

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

If you want to sort all classes by some arbitrary property you can try this version:

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

Of course you need to be sure that property is valid and both objects have it.

网友答案:

Using reflection, you can filter based on any property of any type:

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

Usage:

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

And if you want a list:

List<People> cityPeopleList = myPeople.FilterByTown("MyCity").ToList();
网友答案:

If I understand your question correctly you want something like this:

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

Usage:

peoples.FilterByTown(shops);
网友答案:

You can speed up the queries if you create a list of unique towns

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

You can call it like this

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

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

var x = from p in people.PeopleInTownsWithShops();
分享给朋友:
您可能感兴趣的文章:
随机阅读: