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?
dynamic obj = new SampleObject(); Console. WriteLine(obj. SampleProperty); //Prints "SampleProperty". So, you don't have anything to reflect over - this object doesn't have any properties, and at the same time all valid property names will work.
Reflection is not THAT slow. Invoking a method by reflection is about 3 times slower than the normal way. That is no problem if you do this just once or in non-critical situations. If you use it 10'000 times in a time-critical method, I would consider to change the implementation.
You can use reflection to dynamically create an instance of a type, bind the type to an existing object, or get the type from an existing object and invoke its methods or access its fields and properties. If you are using attributes in your code, reflection enables you to access them.
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 awhere 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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With