Алтернатива на вложен тип тип 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