Улучшение синтаксического сахара в C # (или обход "Не могу использовать параметр ref или out") - PullRequest
2 голосов
/ 05 марта 2012

Пожалуйста, не обращайте внимания, является ли подобный шаблон действительно хорошей идеей или нет.Обоснованием было то, что я хотел отловить выданную ошибку или несоответствие количества вставленных / обновленных / удаленных записей.Я не хотел повторять эту логику, и в то время казалось, что эта настройка будет применяться не более чем к четырем длинным «сценариям» методов.

Моим первым шагом было использование анонимной функции.

public void DoSqlAction(Func<bool> f, string task, string ctx, ref bool cont, List<ResultInfo> resultInfo) {
    if (cont) {
        bool ret = false;
        try {
            if (f.Invoke()) {
                resultInfo.Add(new ResultInfo(seq, task, "Success", ctx, true));
                cont = true;
            } else {
                resultInfo.Add(new ResultInfo(seq, task, "Fail", ctx, false));
                cont = false;
            }
        } catch (Exception ex) {
            resultInfo.Add(new ResultInfo(seq, task, "Error: " + ex.Message, ctx, false));
            cont = false;
        }
    }
}

, если я попытаюсь использовать это:

 DoSqlAction(() => 1 == cx.Execute(someSql, anonymousTypeWithClassInstanceInside), "add item", refinfo.ToString(),ref cont, resultInfo);

anonymousTypeWithClassInstanceInside <- источник ошибки </p>

Появляется ошибка:

Невозможно использовать параметр ref или out 'abc' внутри анонимного метода, лямбда-выражения или выражения запроса

Решениеэто избавиться от делегата Func<bool> f.Я пишу эту запись (возможно, это должна быть запись в блоге?), Потому что она чувствовала, что генерируемая ошибка во время компиляции является чем-то вроде дорожного блока.

В этом посте я обнаружил ссылку наСтатья Эрика:

C # Нельзя использовать параметр ref или out внутри тела анонимного метода

здесь

http://blogs.msdn.com/b/ericlippert/archive/2009/11/12/closing-over-the-loop-variable-considered-harmful.aspx

Послевидя, как реализован foreach, я подумал ... хм ... может быть, я ищу настраиваемый синтаксический сахар.

Возможно ли это сейчас в C # 4?Будет ли это возможно в C # 5?Это заставляет меня задуматься о том, чтобы заглянуть в http://nemerle.org в какой-то момент в будущем, но я бы очень хотел остаться в C #.

1 Ответ

0 голосов
/ 05 марта 2012

В отдельности, лучший способ написать этот код:

public ResultInfo DoSqlAction(Func<bool> f, string task, string ctx) {
    try {
        if (f.Invoke()) {
            return new ResultInfo(seq, task, "Success", ctx, true);
        } else {
            return new ResultInfo(seq, task, "Fail", ctx, false);
        }
    } catch (Exception ex) {
        return new ResultInfo(seq, task, "Error: " + ex.Message, ctx, false);
    }
}

А снаружи:

while (/* there's stuff to do */) {
    var result = DoSqlAction(/* the next stuff */);
    infos.Add(result);
    if (!result.Succeeded)
        break;
}

или эквивалент. Это устраняет нечетную побочную функцию, параметр ref и т. Д. И оно короче.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...