"Return value of a pure method not used" warning issued for a lambda expression.

A bit of an edge case... but I have a following snippets of code.  This forms part are of a simplistic C# to javascript converter using an ExpressionVisitor.  I didn't want to write the long version ( via reflection ) to get the MethodInfo instance so I used an expression instead.

Eval<string>(item => item.IndexOf(""))  


is equivalent to

typeof(string).GetMethod("IndexOf", new Type[] { typeof(string) })



  R# issues a warning ("Return value of a pure method not used") on the contents of the lambda expression ( the italic bits below).  I don't actually invoke the expression so the warning seems a bit moot.  

        internal static readonly Dictionary<MethodInfo, string> AllowedStringMethods = BuildStringMethods();

        private static Dictionary<MethodInfo, string> BuildStringMethods()
        {
            // Returns the MethodInfo key and the javascript method equivalent
            return new Dictionary<MethodInfo, string>()
                {
                    { Eval<string>(snippet => snippet.IndexOf("")), "indexOf" },
                    { Eval<string>(snippet => snippet.IndexOf("", 0)), "indexOf" },
                    { Eval<string>(snippet => snippet.LastIndexOf("")), "lastIndexOf" },
                    { Eval<string>(snippet => snippet.LastIndexOf("", 0)), "lastIndexOf" },
                    { Eval<string>(snippet => snippet.Substring(0)), "substr" },
                    { Eval<string>(snippet => snippet.Substring(0, 1)), "substr" },
                    { Eval<string>(snippet => snippet.ToLower()), "toLowerCase" },
                    { Eval<string>(snippet => snippet.ToUpper()), "toUpperCase" },
                    { Eval<string>(snippet => snippet.ToString()), "valueOf" },
                };
        }

        /// <summary>
        /// Convenient helper to resolve the MethodInfo definition for a method call.
        /// </summary>
        /// <typeparam name="TSource">type defining the method</typeparam>
        /// <param name="expression">Expression to evaluate.  It is not executed</param>
        /// <returns>MethodInfo</returns>
        private static MethodInfo Eval<TSource>(Expression<Action<TSource>> expression)
        {
            return (expression.Body as MethodCallExpression).Method;
        }

4 comments
Comment actions Permalink

Does it help if you change your code to use Expression<Func<TSource, TResult>> instead of Expression<Action<TSource>>?

private static Dictionary<MethodInfo, string> BuildStringMethods()
{
   return new Dictionary<MethodInfo, string>
   {
      { Eval((string snippet) => snippet.IndexOf("")), "indexOf" },
      { Eval((string snippet) => snippet.IndexOf("", 0)), "indexOf" },
      { Eval((string snippet) => snippet.LastIndexOf("")), "lastIndexOf" },
      { Eval((string snippet) => snippet.LastIndexOf("", 0)), "lastIndexOf" },
      { Eval((string snippet) => snippet.Substring(0)), "substr" },
      { Eval((string snippet) => snippet.Substring(0, 1)), "substr" },
      { Eval((string snippet) => snippet.ToLower()), "toLowerCase" },
      { Eval((string snippet) => snippet.ToUpper()), "toUpperCase" },
      { Eval((string snippet) => snippet.ToString()), "valueOf" },
   };
}

private static MethodInfo Eval<TSource, TResult>(Expression<Func<TSource, TResult>> expression)
{
   return (expression.Body as MethodCallExpression).Method;
}

0
Comment actions Permalink

No, Func and Action give the same result.

Just out of interest, some of those example statements return ints, not string

0
Comment actions Permalink

slaneyrw wrote:
Just out of interest, some of those example statements return ints, not string

The compiler is able to infer the return type (the TResult type parameter), and only needs you to specify the type of the input parameter  ("(string s) => ..." instead of "s => ...").

Eval((string snippet) => snippet.IndexOf(""))
// is equivalent to:
Eval<string, int>(snippet => snippet.IndexOf(""))

0
Comment actions Permalink

I've just tried with 6.1.1, and although I still get warnings with the Expression<Func<..>> code, they don't include the "return value of a pure method" warning.

With Expression<Action>:
Eval-Action.png
With Expression<Func>:
Eval-Func.png

0

Please sign in to leave a comment.