2010-08-09 25 views
19

Ho una funzione utilizzata quando si chiama un servizio. Prima che chiamare il servizio, si creerà una voce di registro:Alternativa al tipo di tipo annidato Espressione <Func<T>>

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

Il Visual Studio 2010 Code Analyzer mi informa che non dovrei usare tipo annidato nel seguente messaggio:

CA1006: Microsoft .Design: Si consideri un disegno dove 'ServiceManager.CallService < TService, Risultato > (TService, Espressione < Func < TService, TResult > >)' 012.non annida il tipo generico 'Expression < Func < TService, TResult > >'.

Mentre potevo semplicemente creare una regola di soppressione per questa voce, esiste un'alternativa che impedisca di visualizzare tale avviso?

risposta

25

In questo caso lo sopprimerei, con il motivo che il chiamante non deve far fronte a generici annidati, sta solo passando un'espressione lambda, che è facile da usare.

CA non fa eccezioni per le espressioni lambda. A volte è meglio sopprimerlo per scrivere codice strano.

6

Sarò onesto, io sopprimo il that rule la maggior parte del tempo. Mentre posso capire che alcuni dei tipi costruttivi annidati possono essere evitati, è il più delle volte il caso; di solito lo si vuole lasciare al sito di chiamata perché non è possibile garantire che il sito di chiamata desideri che il tipo generico nidificato venga istanziato nello stesso modo.

Questa è una di quelle regole che trovo un po 'prepotente; Generalmente sono d'accordo con la maggior parte di loro, ma non con questo.

0

È possibile sopprimere il messaggio di avviso con SuppressMessageAttribute.

[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design","CA1006:<rule name>")] 
protected TResult CallService<...Snip... 
+2

So perfettamente che stavo cercando un'alternativa. L'obiettivo dell'analisi del codice non è quello di eliminare tutto, ma alla fine imparare un modo migliore. –

2

metodi come la vostra sono ampiamente utilizzati in LINQ, per esempio:

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

L'alternativa sarebbe quella di dichiarare un tipo delegato per sostituire il nidificato Func<TService, TResult>, ma che è altrettanto probabile che confondere un altro sviluppatore esperto che è abituato a lavorare con gli alberi di espressione.

Microsoft ovviamente fa un'eccezione a CA1006 per i tipi di espressioni generiche nidificate, e così dovremmo.

Problemi correlati