Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

System.ArgumentException : Argument types do not match #129

Closed
EvgenyMarchuk opened this issue Sep 6, 2023 · 9 comments
Closed

System.ArgumentException : Argument types do not match #129

EvgenyMarchuk opened this issue Sep 6, 2023 · 9 comments

Comments

@EvgenyMarchuk
Copy link

EvgenyMarchuk commented Sep 6, 2023

Hello. Thanks for the project
I have some problem. So the following problem occurs when I try to call with settings

public static string GetMemberName(this LambdaExpression memberSelector)
{
            var i = new Func<ITranslationSettings, ITranslationSettings>(s => s.ShowCapturedValues);

            return memberSelector.ToReadableString(i);
}

for the expression like
x => x.First().Currency

Stack Trace: 
Expression.Constant(Object value, Type type)
MemberAccessTranslation.For(MemberExpression memberAccess, ITranslationContext context)
ExpressionTranslation.GetDefaultTranslation(Expression expression)
ExpressionTranslation.GetTranslationFor(Expression expression)
PublicTranslationContextExtensions.GetCodeBlockTranslationFor(ITranslationContext context, Expression expression)
LambdaTranslation.ctor(LambdaExpression lambda, ITranslationContext context)
ExpressionTranslation.GetDefaultTranslation(Expression expression)
ExpressionTranslation.GetTranslationFor(Expression expression)
ExpressionTranslation.GetTranslation()
ExpressionExtensions.ToReadableString(Expression expression, Func`2 configuration)
LambdaExpressionExtension.GetMemberName(LambdaExpression memberSelector) line 138

Can you tell me what kind of settings I need to use for this expression?
Thanks

@EvgenyMarchuk
Copy link
Author

EvgenyMarchuk commented Sep 6, 2023

UPD: I'm not sure if this is correct but if you add it to the settings, it works

                    .AddTranslatorFor(ExpressionType.MemberAccess, (expr, _) =>
                    {
                        var member = (MemberExpression)expr;
                        return member.ToReadableString();
                    }));

@SteveWilkes
Copy link
Member

Hi, thanks for the bug report! Could you let me know the type of your x variable? Maybe make a dotnetfiddle reproducing the issue? Thanks!

@EvgenyMarchuk
Copy link
Author

I will try to reproduce the issue.
x is a list of objects with 2 properties
BalanceModel

  1. Enum Currency
  2. double Amount

@EvgenyMarchuk
Copy link
Author

EvgenyMarchuk commented Sep 11, 2023

Sorry for the long answer.
Now you can repoduce the bug
So when you try to get value here

.ResponseValue(x => x.First().Currency == CurrencyType.EUR);
namespace ConsoleApp2
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            var balances = new List<BalanceModel>
                {
                    new()
                    {
                        Amount = 1,
                        Currency = CurrencyType.EUR
                    },
                    new()
                    {
                        Amount = 5,
                        Currency = CurrencyType.USD
                    },
                    new()
                    {
                        Amount = 10,
                        Currency = CurrencyType.GBP
                    }
            };

            new ResponseValidator<List<BalanceModel>>(balances)
                .ResponseValue(x => x.Count > 0)
                .ResponseValue(x => x.Any(c => c.Currency == CurrencyType.EUR))
                .ResponseValue(x => x.First().Currency == CurrencyType.EUR);
        }
    }

    public class ResponseValidator<T>
    {
        private readonly T _response;

        public ResponseValidator(T response)
        {
            _response = response;
        }

        public ResponseValidator<T> ResponseValue<TProperty>(Expression<Func<T, TProperty>> property)
        {
            var member = property.GetMember();
            var compiledProperty = property.Compile()(_response);

            Console.WriteLine($"{member}: {compiledProperty}");
            return this;
        }
    }

    public class BalanceModel
    {
        public double Amount { get; set; }
        public CurrencyType Currency { get; set; }
    }

    public enum CurrencyType
    {
        EUR,
        GBP,
        USD
    }

    public static class LambdaExpressionExtension
    {
        public static string GetMember(this LambdaExpression memberSelector)
        {
            var i = new Func<ITranslationSettings, ITranslationSettings>(s => s.ShowCapturedValues);

            return memberSelector.ToReadableString(i);
        }
    }
}

Console log

x => x.Count > 0: True
x => x.Any(c => ((int)c.Currency) == 0): True
Unhandled exception. System.ArgumentException: Argument types do not match

And small request, if it's posible - How to show string enum value not int?
x => x.Any(c => ((int)c.Currency) == 0): True - 0 is EUR
Thanks

@EvgenyMarchuk
Copy link
Author

any updates?

@SteveWilkes
Copy link
Member

Should all be possible to sort out - just a matter of getting around to it :)

SteveWilkes added a commit that referenced this issue Oct 8, 2023
@SteveWilkes SteveWilkes added the in-branch A feature or bug fix exists in code, and a release will follow label Oct 8, 2023
SteveWilkes added a commit that referenced this issue Oct 14, 2023
* Fixing static method access when showing captured value / Translating enum comparisons as enum constants re: #129

* Updating version number

* v4.1.1 NuGet package

---------

Co-authored-by: Steve Wilkes <[email protected]>
@SteveWilkes SteveWilkes removed the in-branch A feature or bug fix exists in code, and a release will follow label Oct 14, 2023
@SteveWilkes
Copy link
Member

The bug is fixed and the enum compairson shows the enum constant rather than its int value as of v4.1.1, which is now on NuGet.

Thanks for the feedback and patience!

Steve

@EvgenyMarchuk
Copy link
Author

Thanks. Looks great!

@EvgenyMarchuk
Copy link
Author

EvgenyMarchuk commented Oct 17, 2023

Hello! It's ma again. Found a new defect with the same problem. Open a new defect or reopen this one?

.ResponseValue(x => x.Any(c => c.Currency == source.Currency.First().Code));
Unhandled exception. System.ArgumentException: Argument types do not match
   at System.Linq.Expressions.Expression.Constant(Object value, Type type)
   at AgileObjects.ReadableExpressions.Translations.MemberAccessTranslation.For(MemberExpression memberAccess, ITranslationContext context)
   at AgileObjects.ReadableExpressions.Translations.ExpressionTranslation.GetDefaultTranslation(Expression expression)
   at AgileObjects.ReadableExpressions.Translations.ExpressionTranslation.GetTranslationFor(Expression expression)
   at AgileObjects.ReadableExpressions.Translations.BinaryTranslation..ctor(BinaryExpression binary, ITranslationContext context)
   at AgileObjects.ReadableExpressions.Translations.BinaryTranslation.For(BinaryExpression binary, ITranslationContext context)
   at AgileObjects.ReadableExpressions.Translations.ExpressionTranslation.GetDefaultTranslation(Expression expression)
   at AgileObjects.ReadableExpressions.Translations.ExpressionTranslation.GetTranslationFor(Expression expression)
   at AgileObjects.ReadableExpressions.Extensions.PublicTranslationContextExtensions.GetCodeBlockTranslationFor(ITranslationContext context, Expression expression)
   at AgileObjects.ReadableExpressions.Translations.LambdaTranslation..ctor(LambdaExpression lambda, ITranslationContext context)
   at AgileObjects.ReadableExpressions.Translations.ExpressionTranslation.GetDefaultTranslation(Expression expression)
   at AgileObjects.ReadableExpressions.Translations.ExpressionTranslation.GetTranslationFor(Expression expression)
   at AgileObjects.ReadableExpressions.Translations.ParameterSetTranslation.GetParameterTranslation(Expression parameter, IParameter info, ITranslationContext context)
   at AgileObjects.ReadableExpressions.Translations.ParameterSetTranslation.<>c__DisplayClass7_0.<.ctor>b__0(Expression p, Int32 index)
   at AgileObjects.ReadableExpressions.Extensions.InternalEnumerableExtensions.Project[TItem,TResult](IEnumerable`1 items, Func`3 projector)+MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at AgileObjects.ReadableExpressions.Translations.ParameterSetTranslation..ctor(IMethodBase method, IEnumerable`1 parameters, Boolean showParameterTypeNames, Int32 count, ITranslationContext context)
   at AgileObjects.ReadableExpressions.Translations.ParameterSetTranslation.For[TParameterExpression](IMethodBase method, ICollection`1 parameters, Boolean showParameterTypeNames, ITranslationContext context)
   at AgileObjects.ReadableExpressions.Translations.ParameterSetTranslation.For[TParameterExpression](IMethod method, ICollection`1 parameters, ITranslationContext context)
   at AgileObjects.ReadableExpressions.Translations.MethodCallTranslation.For(MethodCallExpression methodCall, ITranslationContext context)
   at AgileObjects.ReadableExpressions.Translations.ExpressionTranslation.GetDefaultTranslation(Expression expression)
   at AgileObjects.ReadableExpressions.Translations.ExpressionTranslation.GetTranslationFor(Expression expression)
   at AgileObjects.ReadableExpressions.Extensions.PublicTranslationContextExtensions.GetCodeBlockTranslationFor(ITranslationContext context, Expression expression)
   at AgileObjects.ReadableExpressions.Translations.LambdaTranslation..ctor(LambdaExpression lambda, ITranslationContext context)
   at AgileObjects.ReadableExpressions.Translations.ExpressionTranslation.GetDefaultTranslation(Expression expression)
   at AgileObjects.ReadableExpressions.Translations.ExpressionTranslation.GetTranslationFor(Expression expression)
   at AgileObjects.ReadableExpressions.Translations.ExpressionTranslation.GetTranslation()
   at AgileObjects.ReadableExpressions.ExpressionExtensions.ToReadableString(Expression expression, Func`2 configuration)
   at ConsoleApp2.LambdaExpressionExtension.GetMember(LambdaExpression memberSelector) in C:\Users\EV\source\repos\ConsoleApp2\Program.cs:line 97
   at ConsoleApp2.ResponseValidator`1.ResponseValue[TProperty](Expression`1 property) in C:\Users\EV\source\repos\ConsoleApp2\Program.cs:line 60
   at ConsoleApp2.Program.Main(String[] args) in C:\Users\EV\source\repos\ConsoleApp2\Program.cs:line 40
namespace ConsoleApp2
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            var source = new BalanceSource
            {
                Currency = new List<ExcludedCurrency>
                {
                    new()
                    {
                        Code = CurrencyType.USD
                    }
                }
            };

            var balances = new List<BalanceModel>
                {
                    new()
                    {
                        Amount = 1,
                        Currency = CurrencyType.EUR
                    },
                    new()
                    {
                        Amount = 5,
                        Currency = CurrencyType.USD
                    },
                    new()
                    {
                        Amount = 10,
                        Currency = CurrencyType.GBP
                    }
            };

            new ResponseValidator<List<BalanceModel>>(balances)
                .ResponseValue(x => x.Count > 0)
                .ResponseValue(x => x.First().Currency == CurrencyType.EUR)
                .ResponseValue(x => x.Any(c => c.Currency == CurrencyType.EUR))
                
                .ResponseValue(x => x.Any(c => c.Currency == source.Currency.First().Code));
        }
    }

    public class ResponseValidator<T>
    {
        private readonly T _response;

        public ResponseValidator(T response)
        {
            _response = response;
        }

        public ResponseValidator<T> ResponseValue<TProperty>(Expression<Func<T, TProperty>> property)
        {
            var member = property.GetMember();
            var compiledProperty = property.Compile()(_response);

            Console.WriteLine($"{member}: {compiledProperty}");
            return this;
        }
    }

    public class BalanceModel
    {
        public double Amount { get; set; }
        public CurrencyType Currency { get; set; }
    }

    public class BalanceSource
    {
        public List<ExcludedCurrency> Currency { get; set; }
    }

    public class ExcludedCurrency
    {
        public CurrencyType Code { get; set; }
    }

    public enum CurrencyType
    {
        EUR,
        GBP,
        USD
    }

    public static class LambdaExpressionExtension
    {
        public static string GetMember(this LambdaExpression memberSelector)
        {
            var i = new Func<ITranslationSettings, ITranslationSettings>(s => s.ShowCapturedValues);

            return memberSelector.ToReadableString(i);
        }
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants