LINQ and Activator.CreateInstance () creates duplicates

I have the following LINQ query to read App.config to create objects using the fully defined types specified inside:

var strategies = from strategy in section.Strategies let indicators = ( from indicator in strategy.Indicators select (IIndicatorReader)Activator.CreateInstance(Type.GetType(indicator.Type), bot.Mt, section.Symbol)) let orders = ( from order in strategy.Orders select new OrderInfo(order.Id, order.Operation.Value, order.Amount)) select (IStrategy)Activator.CreateInstance(Type.GetType(strategy.Type), section.Symbol, strategy.Amount, strategy.Limit, indicators, orders); 

So, every time inside the strategy I call

 indicatorList.Select(i => i.Operation) 

this creation is performed:

 (IIndicatorReader)Activator.CreateInstance(Type.GetType(indicator.Type), bot.Mt, section.Symbol)) 

and the corresponding class constructor is called.

But the indicator specified in the first version of App.config is created twice, and all the rest - once. How can it be?? I will be happy to provide any additional information.


My collection of indicators:

 public class IndicatorElementCollection : ConfigurationElementCollection, IEnumerable<IndicatorElement> { ... public new IEnumerator<IndicatorElement> GetEnumerator() { return this.OfType<IndicatorElement>().GetEnumerator(); } } 

The implementation of the GetEnumerator() conversion from a non-generic type is taken from this question in SO .

Another implementation:

 foreach (OrderElement element in (System.Collections.IEnumerable)this) { yield return element; } 

works the same way.

+4
source share
1 answer

the LINQ indicators expression will be re-read every time you call GetEnumerator . You need to force one evaluation by calling ToList or ToArray . Of course, this can lead to memory problems if you expect many indicators.

+1
source

Source: https://habr.com/ru/post/1332951/


All Articles