我可以根据对象

时间:2015-11-26 21:10:12

标签: c# linq generics extension-methods

我有一个对象列表。 我有一个与列表类型相同的项目。

我想创建一个通用扩展方法(称为查找),以根据单个obj以及其强类型属性的任意列表从列表中查找项目。

以下是我想调用方法的方法:

var obj = new SomeObject() { ... } ;
var list = new List<SomeObject>() { ... };

// Find similar objects
list.Find(obj, x => x.Id,y => y.Description);

这种安排是否可行?

FirstOrDefault将在下面的评论中起作用。但是,我正在寻找一种在不同场景中使用该模式的方法,这可能不是简单的查找。

3 个答案:

答案 0 :(得分:2)

你可以这样做

public static T Find<T>(this IEnumerable<T> source, params Func<T,bool>[] condition)
{
    return source.FirstOrDefault(o => condition.All(f => f(o))); // use All for && or use Any for ||
}

并使用它

var item = list.Find(x=> x.Id == obj.Id,x=> x.Description == obj.Description);

如果您希望通过将属性强制转换为对象来更频繁地完成此工作,则可以使用Object。但顺便说一下,这会有点慢,你必须注意,必须覆盖自定义类型Equals方法才能使其正常工作。

public static T Find<T>(this IEnumerable<T> source, T obj, params Func<T, object>[] condition)
{
    return source.FirstOrDefault(o => condition.All(f => f(o).Equals(f(obj))));
}

然后你就可以这样称呼它。

var item = list.Find(obj, x => x.Id,y => y.Description);

如果要返回所有类似的项目,可以使用Where。只需将FirstOrDefault更改为Where,将方法的返回类型更改为IEnumerable<T>

答案 1 :(得分:1)

在我看来,与仅仅使用正常的Where子句来过滤您所追求的任何属性相比,您节省了大量时间/精力。

var findResults = list.Where(x => x.Id == obj.Id || x.Description == obj.Description);

答案 2 :(得分:0)

也许你应该考虑这样做:

<CustomAction Id="CA_RunBatchScript"
              BinaryKey="WixCA"
              DllEntry="CAQuietExec"
              Execute="deferred"
              Return="check" />