我有以下可能性来检索列表中的值:
使用反射:
foreach (var item in items) {
var property=item.Fields[fieldName].GetType().GetProperty("Id");
var value=property.GetValue(item.Fields[fieldName]);
if (value==searchValue) {
filtered.Add(item);
}
}
使用动态:
foreach (var item in items) {
dynamic itemProperty=item.Fields[fieldName];
if (itemProperty.Id==searchValue) {
filtered.Add(item);
}
}
两个循环都是一样的。它们按字段[fieldName]过滤IEnumerable(或List),字段[fieldName]可以是不同类型,但都包含一个名为" Id"的int属性。
我想知道哪一个会有更好的表现。 另外:将其中一个更改为LinQ-Query会增加性能吗?
答案 0 :(得分:5)
执行此操作的最简单方法IMO是定义一个具有int Id {get;}
属性的接口,并让您的类型实现它。然后编码到界面。如果您的现有代码是通用的,您甚至可以添加where T : IYourInterface
约束,但您可以以任一方式转换为IYourInterface
(假设T
实际上实现了接口)。
如果接口不是选项:
反思和dynamic
都有开销; dynamic
有更好的优化(重新使用缓存策略)。
如果您的items
列表是针对特定T
的强列表(此处T
未知),那么您可以可能进一步优化此概念用于编译委托的LINQ表达式:
static class IdFetcher
{
public static int Fetch<T>(T item) => IdFetcher<T>.Fetch(item);
}
static class IdFetcher<T>
{
public static int Fetch(T item) => fetch(item);
static readonly Func<T, int> fetch;
static IdFetcher()
{
var p = Expression.Parameter(typeof(T), "item");
fetch = Expression.Lambda<Func<T, int>>(
Expression.PropertyOrField(p, "Id"), p).Compile();
}
}
然后只使用IdFetcher<T>.Fetch(obj)
或IdFetcher.Fetch(obj)
(第一个更直接;第二个对于无法指定T
的匿名类型非常有用)
除此之外:如果你想知道哪个更快:为它们计时(对于大量的迭代)。