none
Compare the Results of Two Expressions RRS feed

  • Question

  • I'd like to compare the results of two expressions to determine if they are equal.  The below code compiles but I get an exception that there is an incorrect number of parameters.  With that in mind I have two questions.

    1. What is the correct Lambda Expression method to compare two expressions?
    2. Is there a better/simpler way to compare the results of two expressions?

    Thank you for your help.

    Ryan

    public static void SaveValue<T>(this Something first, ref Something second, Expression<Func<Something, T>> outExpr)
    {
    	Expression.Lambda<Func<Something, Something, bool>>(
    		Expression.Equal(
    			Expression.Invoke(outExpr, Expression.Parameter(typeof(Something))),
    			Expression.Invoke(outExpr, Expression.Parameter(typeof(Something)))
    	)).Compile()(first, second);				
    }
    
    public class Something
    {
    	public Something() {}
    	public Something(string here) { Here = here; }
    	public Something(int there ) { There = there; }
    	public Something(string here, int there) { Here = here; There = there; }
            
    	public string Here  { get; set; }
    	public int    There { get; set; }
    }
    
    public class Program
    {
    	public static void Main(string[] args)
    	{
    		var mySomething = new Something("Hello");
    		var mySomething3 = new Something("World", 3);
    
                	mySomething3.SaveValue(ref mySomething, s => s.Here);
                	mySomething3.SaveValue(ref mySomething, s => s.There);
                
                	Console.WriteLine(mySomething3.Here + ", " + mySomething3.There);
                	Console.WriteLine(mySomething.Here + ", " + mySomething.There);
            }
        }
    


    Wednesday, April 5, 2017 9:53 PM

All replies

  • Hi Ryan Software,

    Based on your description and related code, I create a demo and it throws an exception. which need to add parameters on your method named Expression.Lambda. please modify the code like this:

      public static void SaveValue<T>(this Something first, ref Something second, Expression<Func<Something, T>> outExpr)
            {
                ParameterExpression param1 = Expression.Parameter(typeof(Something));
                ParameterExpression param2 = Expression.Parameter(typeof(Something));
    
                var val1 = Expression.Invoke(outExpr, param1);
                var val2 = Expression.Invoke(outExpr, param2);
                var andExp = Expression.Equal(val1, val2);
                Expression.Lambda<Func<Something, Something, bool>>(
                     andExp, param1, param2
                 ).Compile()(first, second);
            }

    Best regards,

    Cole Wu


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Thursday, April 6, 2017 9:30 AM
    Moderator
  • Thank for your reply.  With your modifications this does what I'm wanting.  I have a follow up question though.

    Why can't I substitute param1 for Expression.Parameter(typeof(Something)) in the Expression.Lambda code?  It gives me a run-time exception.  Shouldn't the substitution be the same code?

    Expression.Lambda<Func<Something, Something, bool>>(
    	Expression.Equal(
    		Expression.Invoke(outExpr, param1),
    		Expression.Invoke(outExpr, param2)),
    	param1,
    	param2
    ).Compile()(first, second);

    Thank you for your help.

    Ryan
    Thursday, April 6, 2017 5:44 PM
  • Hi Ryan Software,

    I use the code that you provide, it works well, Here is the complete code for your reference.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Linq.Expressions;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace LamdaExpressionDemo
    {
        public class Something
        {
            public Something() { }
            public Something(string here) { Here = here; }
            public Something(int there) { There = there; }
            public Something(string here, int there) { Here = here; There = there; }
    
            public string Here { get; set; }
            public int There { get; set; }
        }
    
        public static class extendion
        {
            public static void SaveValue<T>(this Something first, ref Something second, Expression<Func<Something, T>> outExpr)
            {
                ParameterExpression param1 = Expression.Parameter(typeof(Something));
                ParameterExpression param2 = Expression.Parameter(typeof(Something));
    
                var val1 = Expression.Invoke(outExpr, param1);
                var val2 = Expression.Invoke(outExpr, param2);
                var andExp = Expression.Equal(val1, val2);
    
                Expression.Lambda<Func<Something, Something, bool>>(
                    Expression.Equal(
                        Expression.Invoke(outExpr, param1),
                        Expression.Invoke(outExpr, param2)),
                    param1,
                    param2
                ).Compile()(first, second);
            }
        }
        class Program
        {
            static void Main(string[] args)
            {
                var mySomething = new Something("Hello");
                var mySomething3 = new Something("World", 3);
    
                mySomething3.SaveValue(ref mySomething, s => s.Here);
                mySomething3.SaveValue(ref mySomething, s => s.There);
    
                Console.WriteLine(mySomething3.Here + ", " + mySomething3.There);
                Console.WriteLine(mySomething.Here + ", " + mySomething.There);
    
            }
    
    
        }
    }
    

    Best regards,

    Cole Wu


    MSDN Community Support<br/> Please remember to click &quot;Mark as Answer&quot; the responses that resolved your issue, and to click &quot;Unmark as Answer&quot; if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact <a href="mailto:MSDNFSF@microsoft.com">MSDNFSF@microsoft.com</a>.

    Tuesday, April 25, 2017 2:09 AM
    Moderator