Alternative to nested type of type Expression<Func<T>>
Asked Answered
K

4

20

I have a function used when calling a service. Before it call the service, it will create a log entry:

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

The Visual Studio 2010 Code Analyzer informs me that I shouldn't use Nested Type in the following message:

CA1006 : Microsoft.Design : Consider a design where 'ServiceManager.CallService<TService, Result>(TService, Expression<Func<TService, TResult>>)' doesn't nest generic type 'Expression<Func<TService, TResult>>'.

While I could simply create a suppression rule for this entry, is there is an alternative that exist that would prevent displaying such warning?

Kirkpatrick answered 9/8, 2010 at 15:26 Comment(0)
C
26

I would suppress it in this case, with the reason that the caller doesn't have to cope with nested generics, he is just passing a lambda expression, which is easy to use.

CA does not make exceptions for lambda expressions. Sometimes It is better to suppress it then to write weird code.

Colous answered 9/8, 2010 at 15:37 Comment(0)
H
6

I'll be honest, I suppress that rule most of the time. While I can understand that some of the construction of the nested types can be avoided, it is more often than not the case; you usually want to leave that to the call site because you can't guarantee that the call site will want the nested generic type to be instantiated in the same way.

This is one of those rules that I find a bit overbearing; I generally agree with most of them, but not this one.

Henbane answered 9/8, 2010 at 15:38 Comment(0)
D
2

Methods like yours are used extensively in Linq, for example:

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

The alternative would be to declare a delegate type to replace the nested Func<TService, TResult>, but that's just as likely to confuse a more experienced developer who's used to working with expression trees.

Microsoft obviously makes an exception to CA1006 for nested generic expression types, and so should we.

Death answered 28/9, 2011 at 20:50 Comment(0)
M
0

You can suppress the message warning with SuppressMessageAttribute.

[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design","CA1006:<rule name>")]
protected TResult CallService<...Snip...
Medial answered 9/8, 2010 at 16:35 Comment(1)
I totally know that, I was looking for an alternative. The goal of the code analysis is not to suppress everything, but eventually learn a better way.Kirkpatrick

© 2022 - 2024 — McMap. All rights reserved.