Захваченная переменная проблема создания
В настоящее время я думаю о какой-то идее, которую не могу понять.
Проблема заключается в том, что я хочу использовать одну лямбда-функцию для создания экземпляра захваченной переменной, а другую лямбду - для доступа к свойству этой переменной.
Поскольку создание экземпляров происходит внутри лямбды, переменная фактически не создается, когда я хочу использовать ее во второй лямбде. Это своего рода проблема курицы и яйца.
Я знаю, что переменная будет создана во время ее использования во второй лямбде, но компилятор этого не делает.
Может ли моя идея сработать? Вот фактический код:
class Program
{
static void Main(string[] args)
{
SqlCommand cmd;
using (new DisposableComposite(
() => cmd = new SqlCommand(),
() => cmd.Connection)) // <- compiler error - variable not instantiated
{
// code
}
}
}
class DisposableComposite : IDisposable
{
private List<IDisposable> _disposables = new List<IDisposable>();
public DisposableComposite(params Func<IDisposable>[] disposableFuncs)
{
// ensure the code is actually executed
foreach (var func in disposableFuncs)
{
IDisposable obj = func.Invoke();
_disposables.Add(obj);
}
}
public void Dispose()
{
foreach (var disposable in _disposables)
{
disposable.Dispose();
}
}
}
3 ответа
Вы имеете в виду просто добавление:
SqlCommand cmd = null;
(который решает проблему "определенного назначения"; он определенно назначен... null;-p Затем мы обновляем значение перед его использованием).
ИМО, однако, вы бы лучше с вложенными using
заявления... и не ясно (из кода), откуда будет происходить фактическое соединение...
using(var conn = new SqlConnection(...))
using(var cmd = conn.CreateCommand()) {
// ...
}
Вы можете избежать этого только установив cmd в null перед использованием блока:
SqlCommand cmd=null;
using (new DisposableComposite(
() => cmd = new SqlCommand(),
() => cmd.Connection)) // <- compiler error - variable not instantiated
{
// code
}
Согласитесь с Марком, что это не совсем правильно.
Другим вариантом может быть определение нового объекта типа Context, который при утилизации удаляет все объекты, которые он предоставляет.
Например.
using (var ctx = GetContext()) {
var cmd = ctx.CreateCommand();
cmd.Connection = ctx.CreateConnection();
}
// cmd is Disposed
// cmd.Connection is Disposed