Альтернатива вложенному типу Expression‹Func‹T››

У меня есть функция, используемая при вызове службы. Прежде чем вызвать службу, она создаст запись в журнале:

protected TResult CallService<TService, TResult>(TService service,
    Expression<Func<TService, TResult>> functionSelector)
{
    Logger.LogServiceCall(service, functionSelector);
    return functionSelector.Compile()(service);
}

Анализатор кода Visual Studio 2010 сообщает мне, что я не должен использовать вложенный тип в следующем сообщении:

CA1006: Microsoft.Design: рассмотрите дизайн, в котором «ServiceManager.CallService‹TService, Result›(TService, Expression‹Func‹TService, TResult››)» не вложен общий тип «Expression‹Func‹TService, TResult››» .

Хотя я мог бы просто создать правило подавления для этой записи, существует ли альтернатива, которая предотвратила бы отображение такого предупреждения?


person Pierre-Alain Vigeant    schedule 09.08.2010    source источник


Ответы (4)


Я бы подавил его в этом случае по той причине, что вызывающему абоненту не нужно справляться с вложенными дженериками, он просто передает лямбда-выражение, которое легко использовать.

CA не делает исключений для лямбда-выражений. Иногда лучше его подавить, чем писать странный код.

person Stefan Steinegger    schedule 09.08.2010

Честно говоря, большую часть времени я подавляю это правило. Хотя я могу понять, что некоторых конструкций вложенных типов можно избежать, чаще всего это так; обычно вы хотите оставить это для сайта вызова, потому что вы не можете гарантировать, что сайт вызова захочет, чтобы вложенный универсальный тип был создан таким же образом.

Это одно из тех правил, которые я нахожу немного властными; Я в целом согласен с большинством из них, но не с этим.

person casperOne    schedule 09.08.2010

Такие методы, как ваш, широко используются в Linq, например:

public static IQueryable<TSource> Where<TSource>(this IQueryable<TSource> source, 
    Expression<Func<TSource, bool>> predicate)

Альтернативой может быть объявление типа делегата для замены вложенного Func<TService, TResult>, но это также может запутать более опытного разработчика, привыкшего работать с деревьями выражений.

Очевидно, Microsoft делает исключение из CA1006 для вложенных универсальных типов выражений, и мы должны делать то же самое.

person Rory MacLeod    schedule 28.09.2011

Вы можете отключить предупреждение о сообщении с помощью SuppressMessageAttribute. .

[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design","CA1006:<rule name>")]
protected TResult CallService<...Snip...
person Sam    schedule 09.08.2010
comment
Я прекрасно это знаю, я искал альтернативу. Цель анализа кода не в том, чтобы подавить все, а в том, чтобы в конце концов научиться лучше. - person Pierre-Alain Vigeant; 09.08.2010