Вы не можете использовать параметр ByRef
в лямбда-выражениях, поскольку он может указывать на местоположение в стеке, которое больше не существует после того, как лямбда-выход освобождается.Все, что вам нужно сделать, это использовать более «постоянное» хранилище.Вы можете передать объект со свойством IEnumerable(Of T)
, которое можно установить для присвоения результата.
Вероятно, лучшим вариантом будет передать делегат (Action<IEnumerable<T>>
), который принимает результат ивыполняет любое действие, которое требует вызывающий с результатом.Вот пример на C #:
void LoadData<T>(ObjectQuery<T> query, Action<IEnumerable<T>> action)
{
if (Connection.State == ConnectionState.Open)
action(query.ToArray());
else
{
// create a lambda to handle the next state change
StateChangeEventHandler lambda = null;
lambda = (sender, e) =>
{
// only perform our action on transition to Open state
if (Connection.State == ConnectionState.Open)
{
// unsubscribe when we're done
Connection.StateChange -= lambda;
action(query.ToArray());
}
}
// subscribe to connection state changes
Connection.StateChange += lambda;
}
}
И вы бы вызвали LoadData
так:
LoadData(query, results => listBox.DataSource = results);
Обратите внимание на нюансы моей реализации.Например, он не вызывает себя в обработчике события, потому что это заставит его повторно подписаться на событие, если обработчик когда-либо вызывается с состоянием, отличным от Open
.Он также отписывается от события, как только соединение открывается.Я не уверен, как это будет переводиться на VB, но в C # это трехэтапный процесс.Сначала вы должны объявить переменную для хранения лямбды и установить ее значение в ноль.Затем вы создаете лямбду, которая теперь может ссылаться на себя, чтобы отписаться.И, наконец, вы можете использовать лямбду, чтобы подписаться на событие.