Как обойти использование параметра out в блоке анонимного метода?

Следующий метод не компилируется. Visual Studio предупреждает: «Выходной параметр нельзя использовать в анонимном методе». Метод WithReaderLock(Proc action) принимает delegate void Proc().

public Boolean TryGetValue(TKey key, out TValue value)
{
    Boolean got = false;
    WithReaderLock(delegate
    {
        got = dictionary.TryGetValue(key, out value);
    });
    return got;
}

Как лучше всего добиться такого поведения? (Пожалуйста, воздержитесь от советов по словарям, защищенным потоками, этот вопрос предназначен для решения проблемы параметров out в целом).


person Anthony Mastrean    schedule 21.12.2008    source источник


Ответы (2)


public bool TryGetValue(TKey key, out TValue value)
{
    bool got = false;            
    TValue tmp = default(TValue); // for definite assignment
    WithReaderLock(delegate
    {
        got = dictionary.TryGetValue(key, out tmp);
    });
    value = tmp;
    return got;
}

(отредактировано - небольшая ошибка)

Для информации: в .NET 3.5 вы, возможно, захотите использовать делегат Action вместо того, чтобы катить свой собственный, поскольку люди будут узнавать его больше. Даже в 2.0 есть много void Foo() делегатов: ThreadStart, MethodInvoker и т. Д., Но за Action проще всего следовать ;-p

person Marc Gravell    schedule 21.12.2008
comment
Извините за глюк в оригинальной версии; фиксированный - person Marc Gravell; 21.12.2008
comment
Я вижу delegate void Action<T>(T obj) в .NET 2.0, но он работает с объектом. Мне нужны операции вокруг действия. Следовательно, delegate void Proc(). Я мог бы назвать это delegate void Action(), чтобы быть последовательным. - person Anthony Mastrean; 22.12.2008

Простой ответ - просто скопировать логику внутри метода. Но затем мы расширяем принцип DRY и должны поддерживать поведение внутри обоих методов.

public Boolean TryGetValue(TKey key, out TValue value)
{
    internalLock.AcquireReaderLock(Timeout.Infine);
    try
    {
        return dictionary.TryGetValue(key, out value);
    }
    finally
    {
        internalLock.ReleaseReaderLock();
    }
}
person Anthony Mastrean    schedule 21.12.2008