2010-08-09 14 views
19

Tengo una función utilizada al llamar a un servicio. Antes de que llame al servicio, se creará una entrada de registro:Alternativa al tipo anidado de tipo Expresión <Func<T>>

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

El Visual Studio 2010 Código Analizador me informa que no debería usar anidado Escriba el siguiente mensaje:

CA1006: Microsoft .design: Considere un diseño donde 'ServiceManager.CallService < TService, Resultado > (TService, Expresión < Func < TService, TResult > >)' no anida el tipo genérico 'Expresión < Func < TService, TResult > >'.

Si bien podría simplemente crear una regla de supresión para esta entrada, ¿existe una alternativa que impida la visualización de dicha advertencia?

Respuesta

25

Lo suprimiría en este caso, con el motivo de que la persona que llama no tiene que lidiar con genéricos anidados, simplemente está pasando una expresión lambda, que es fácil de usar.

CA no hace excepciones para expresiones lambda. Algunas veces es mejor suprimirlo y luego escribir un código extraño.

6

Seré honesto, suprimo that rule la mayoría del tiempo. Si bien puedo entender que se puede evitar parte de la construcción de los tipos anidados, a menudo es el caso; por lo general, desea dejarlo en el sitio de llamadas porque no puede garantizar que el sitio de llamadas quiera crear una instancia del tipo genérico anidado de la misma manera.

Esta es una de esas reglas que considero un poco pretenciosa; Generalmente estoy de acuerdo con la mayoría de ellos, pero no con este.

0

Puede suprimir la advertencia de mensaje con SuppressMessageAttribute.

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

Lo sé totalmente, estaba buscando una alternativa. El objetivo del análisis de código no es suprimir todo, pero eventualmente aprender una mejor manera. –

2

Métodos como la suya se utilizan ampliamente en LINQ, por ejemplo:

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

La alternativa sería declarar un tipo de delegado para reemplazar el anidado Func<TService, TResult>, pero eso es tan probable que confundir a un mayor desarrollador experimentado que está acostumbrado a trabajar con árboles de expresiones.

Microsoft obviamente hace una excepción a CA1006 para los tipos de expresiones genéricas anidadas, y nosotros también deberíamos hacerlo.

Cuestiones relacionadas