I have the following possibilities to retrieve values in a list:
using reflection:
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);
}
}
using dynamic:
foreach (var item in items) {
dynamic itemProperty=item.Fields[fieldName];
if (itemProperty.Id==searchValue) {
filtered.Add(item);
}
}
Both loops do the same. They filter the IEnumerable (or List) by Field[fieldName] which can be of different types but which all contain a int-property called "Id".
I wonder, which one would have a better performance. In addition: Would changing one of those to a LinQ-Query increase the performance?
The easiest way to do this IMO is to define an interface that has an int Id {get;}
property and have your types implement it. Then code to the interface. If your existing code is generic you might even be able to add a where T : IYourInterface
constraint, but you can cast to IYourInterface
either way (assuming T
actually does implement the interface).
If interfaces aren't an option:
Reflection and dynamic
both have overheads; dynamic
has better optimization (re-using a cached strategy).
If your items
list is strongly typed to a specific T
(where T
is unknown here), then you can possibly further optimize this concept using LINQ expressions to compile delegates:
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();
}
}
Then just use IdFetcher<T>.Fetch(obj)
or IdFetcher.Fetch(obj)
(the first is more direct; the second is useful for anonymous types where you can't specify the T
)
Other than that: if you want to know which is faster: time them (for large numbers of iterations).
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.