4

I have next LINQ query to read App.config to instantiate objects using fully qualified types stated 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 each time inside the strategy I call

indicatorList.Select(i => i.Operation)

this instantiation occurs:

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

and appropriate class's constructor is called.

But an indicator stated in App.config first is instantiated twice, all other - once. How can it be?? I will be happy to provide any additional information required.


My indicator collection:

public class IndicatorElementCollection : ConfigurationElementCollection, IEnumerable<IndicatorElement>
{
    ...

    public new IEnumerator<IndicatorElement> GetEnumerator()
    {
        return this.OfType<IndicatorElement>().GetEnumerator();
    }
}

Implementation of GetEnumerator() conversion from non-generic to generic is taken from this question on SO.

Another implementation:

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

works in the same manner.

Community
  • 1
  • 1
abatishchev
  • 98,240
  • 88
  • 296
  • 433

1 Answers1

1

The LINQ expression indicators will be re-evaluated every time you call GetEnumerator. You need to force a single evaluation by invoking ToList or ToArray. This could of course result in memory space issues if you are expecting many indicators.

ChaosPandion
  • 77,506
  • 18
  • 119
  • 157
  • I rework `IIndicatorReader` and use `ToArray()` for both sub-queries but still get duplicated instances. Thought in debugger I see an array of 2 indicators before the strategy instantiation. May it be caused by my implementation of non-generic to generic `GetEnumerator()` conversion? (I updated my post) – abatishchev Dec 21 '10 at 20:57
  • @abatishchev - I get the feeling that I'm missing some small detail. Could you post a bit more information within reason? Or possibly post to something like this: https://gist.github.com/ – ChaosPandion Dec 21 '10 at 21:02
  • What do I have: myapp reads custom section from app.config (a strategy with the number of indicators and orders), instantiates all of them, connects to an external server, subscribes to its event and each time the event fires notifies all strategies about that (sends some data). Each strategy inquires its indicators and decides what to do with its orders. In addition, the indicators write data they have read to the trace source. And as it happens in the trace first indicator appears twice, all other - just once. I can't imagine why. I can post any code you required. TIA! – abatishchev Dec 22 '10 at 20:31