首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >有没有办法使用部分填充的对象来搜索List<T>?

有没有办法使用部分填充的对象来搜索List<T>?
EN

Stack Overflow用户
提问于 2012-09-24 00:44:45
回答 7查看 167关注 0票数 3

希望能够填充对象的任何属性,并在集合中搜索与给定属性匹配的对象。

代码语言:javascript
复制
class Program
{
    static List<Marble> marbles = new List<Marble> { 
        new Marble {Color = "Red", Size = 3},
        new Marble {Color = "Green", Size = 4},
        new Marble {Color = "Black", Size = 6}
    };

    static void Main()
    {
        var search1 = new Marble { Color = "Green" };
        var search2 = new Marble { Size = 6 };
        var results = SearchMarbles(search1);
    }

    public static IEnumerable<Marble> SearchMarbles(Marble search)
    {
        var results = from marble in marbles
                      //where ???
                      //Search for marbles with whatever property matches the populated properties of the parameter
                      //In this example it would return just the 'Green' marble
                      select marble;
        return results;
    }

    public class Marble
    {
        public string Color { get; set; }
        public int Size { get; set; }
    }

}
EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2012-09-24 06:47:33

我将提出一个通用的解决方案,它可以处理任何数量的属性和任何对象。它还可以在Linq- to -Sql上下文中使用--它可以很好地转换为sql。

首先,首先定义一个函数,该函数将测试给定值是否被视为非集合,例如:

代码语言:javascript
复制
static public bool IsDefault(object o)
{
    return o == null || o.GetType().IsValueType && Activator.CreateInstance(o.GetType()).Equals(o);
}

然后,我们将有一个函数,它构造一个Lambda表达式,并对search对象中所有设置属性的值进行测试:

代码语言:javascript
复制
static public Expression<Func<T, bool>> GetComparison<T>(T search)
{
    var param = Expression.Parameter(typeof(T), "t");

    var props = from p in typeof(T).GetProperties()
                where p.CanRead && !IsDefault(p.GetValue(search, null))
                select Expression.Equal(
                    Expression.Property(param, p.Name),
                    Expression.Constant(p.GetValue(search, null))
                );

    var expr = props.Aggregate((a, b) => Expression.AndAlso(a, b));
    var lambda = Expression.Lambda<Func<T, bool>>(expr, param);         
    return lambda;
} 

我们可以在任何IQueryable上使用它

代码语言:javascript
复制
public static IEnumerable<Marble> SearchMarbles (Marble search)
{
    var results = marbles.AsQueryable().Where(GetComparison(search));
    return results.AsEnumerable();
}   
票数 2
EN

Stack Overflow用户

发布于 2012-09-24 01:44:27

诚然,这很有趣,而且花了我很多时间。首先,你需要获取search对象的所有属性,这些属性的值与默认值不同,这个方法是通用的,使用反射:

代码语言:javascript
复制
var properties = typeof (Marble).GetProperties().Where(p =>
                {
                    var pType = p.PropertyType;
                    var defaultValue = pType.IsValueType 
                            ? Activator.CreateInstance(pType) : null;

                    var recentValue = p.GetValue(search);

                    return !recentValue.Equals(defaultValue);
                });

然后,您可以使用LINQ All进行过滤:

代码语言:javascript
复制
var results = marbles.Where(m => 
                         properties.All(p => 
                         typeof (Marble).GetProperty(p.Name)
                                        .GetValue(m) == p.GetValue(search)));

附言:这段代码已经过测试

票数 5
EN

Stack Overflow用户

发布于 2012-09-24 01:21:09

您可以使用一个单独的过滤器类,如下所示:

代码语言:javascript
复制
class Filter
{
    public string PropertyName { get; set; }
    public object PropertyValue { get; set; }

    public bool Matches(Marble m)
    {
        var T = typeof(Marble);
        var prop = T.GetProperty(PropertyName);
        var value = prop.GetValue(m);
        return value.Equals(PropertyValue);
    }
}

您可以按如下方式使用此过滤器:

代码语言:javascript
复制
var filters = new List<Filter>();
filters.Add(new Filter() { PropertyName = "Color", PropertyValue = "Green" });

//this is essentially the content of SearchMarbles()
var result = marbles.Where(m => filters.All(f => f.Matches(m)));

foreach (var r in result)
{
    Console.WriteLine(r.Color + ", " + r.Size);
}

您可以使用DependencyProperties来摆脱键入属性名称的麻烦。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12554156

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档