LINQ y Activator.CreateInstance () crea duplicados
-
12-10-2019 - |
Pregunta
Tengo siguiente consulta LINQ para leer App.config a instancias de objetos usando los tipos completos indicados en el interior:
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);
Así que cada vez que el interior de la llamada estrategia de I
indicatorList.Select(i => i.Operation)
se produce este instanciación:
(IIndicatorReader)Activator.CreateInstance(Type.GetType(indicator.Type), bot.Mt, section.Symbol))
constructor y de la clase apropiada se llama.
Sin embargo, un indicador indica en App.config primero se crea una instancia de dos veces , todos los demás - una vez . ¿¿Cómo puede ser?? Yo estaré encantado de proporcionar cualquier información adicional necesaria.
Mi colección indicador:
public class IndicatorElementCollection : ConfigurationElementCollection, IEnumerable<IndicatorElement>
{
...
public new IEnumerator<IndicatorElement> GetEnumerator()
{
return this.OfType<IndicatorElement>().GetEnumerator();
}
}
Aplicación de conversión GetEnumerator()
de no genérico para genérico se toma de esta pregunta en SO .
Otra aplicación:
foreach (OrderElement element in (System.Collections.IEnumerable)this)
{
yield return element;
}
funciona de la misma manera.
Solución
La expresión LINQ indicators
será re-evaluado cada vez que llame GetEnumerator
. Es necesario para forzar una única evaluación invocando ToList
o ToArray
. Esto podría resultado del curso de los problemas de espacio de memoria si están esperando muchos indicadores.