Я ищу рекомендации относительно того, как обращаться со следующей ситуацией.
Я создаю методы для попыток получить некоторые данные, следуя этому шаблону:
// Typical pattern
public bool TryBlah(string key, out object value)
{
// ... set value and return boolean
}
У меня возникла проблема при попытке следовать этому шаблону в асинхронных версиях, потому что вы не можете использовать out
для методов async:
// Ideal async pattern (not allowed to use an 'out' parameter, so this fails)
public async Task<bool> TryBlah(string key, out object value)
{
// ... set value, perform some slow io operation, return bool
}
Обходным путем является возврат кортежа, содержащего ваши данные. Это работает для методов, которые возвращают один тип данных, например:
// Tuple version
public async Task<Tuple<bool, object>> TryBlah(string key)
{
// ... perform some slow io, return new Tuple<bool, object>(...)
}
Проблема заключается в том, когда вы хотите вернуть разные типы данных. Без использования async вы можете создать несколько методов с почти одинаковыми сигнатурами:
public bool TryBlah(string key, out byte[] value)
{
// ...
}
public bool TryBlah(string key, out string value)
{
// ...
}
Это здорово. Это то, что я ищу. Этот api очень прост и удобен в работе (имена методов все одинаковы, только данные, которые передаются в изменениях).
Невозможность использовать out
с помощью методов async все равно испортит это.
Один из способов обойти это - вернуть Tuple
ваших данных. Однако теперь вы не можете иметь почти идентичные сигнатуры методов, например:
// The suck... the signatures match, but you want to return different values.
// You can't do this:
public async Task<Tuple<bool, byte[]>> TryBlah(string key)
{
// ...
}
public async Task<Tuple<bool, string>> TryBlah(string key)
{
// ...
}
Эти методы терпят неудачу, потому что они имеют одинаковые подписи. Единственный способ обойти это, что приходит на ум, - дать каждому методу отличное имя, например:
public async Task<Tuple<bool, byte[]>> TryBlahByteArray(string key)
{
// ...
}
public async Task<Tuple<bool, string>> TryBlahString(string key)
{
// ...
}
Моя проблема в том, что теперь это создает то, что я считаю неприятным api, где у вас теперь есть много разных методов. Да, это не так уж и важно, но я считаю, что должен быть лучший способ.
Существуют ли другие шаблоны, которые поддаются лучшему api при работе с такими асинхронными методами? Я открыт для любых предложений.