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

NullReferenceException using variables in custom functions #284

Open
ArdenCarl opened this issue May 5, 2023 · 6 comments
Open

NullReferenceException using variables in custom functions #284

ArdenCarl opened this issue May 5, 2023 · 6 comments

Comments

@ArdenCarl
Copy link

We have a use case where we are defining our own custom IF function and then making use of it using an expression like so:

IF(CUST1 != null, CUST1.Name, "Cust1 is null")

The problem we are facing is when the CUST1 variable turns out to be a null instance then we get a null reference exception when we call Interpreter.Eval for the expression.

Here's the complete code:

image

I've also attached the .cs file for it as a .txt file since I don't seem to be able to attach .cs files directly. See Tester.txt.

Tester.txt

@ArdenCarl
Copy link
Author

I forgot to mention, I appreciate the interpreter doesn’t know not to deference CUST1 and so hence the exception. My question is, is it possible somehow to implement such an IF function?

If not, then how would we write an if block? I know we could use a ternary operator but I’m trying to avoid my users having to use that.

@davideicardi
Copy link
Member

Adding the relavant code here:

using System;
using DynamicExpresso;

namespace DETest
{
    public class Tester
    {
        public class Customer
        {
            public string Name { get; set; }
        }

        public void Test()
        {
            var interpreter = new Interpreter();

            Func<bool, object, object, object> ifFunction = (b, x, y) => If(b, x, y);
            interpreter.SetFunction("IF", ifFunction);

            var cust1 = new Customer { Name = "Customer1" };

            interpreter.SetVariable("CUST1", cust1, typeof(Customer));

            // note. how I pass null for the CUST2 variable value here
            interpreter.SetVariable("CUST2", null, typeof(Customer));

            var exp1 = interpreter.Parse("IF(CUST1 != null, CUST1.Name, \"Cust1 is null\")").Expression;
            interpreter.SetExpression("EXP1", exp1);

            var exp2 = interpreter.Parse("IF(CUST2 != null, CUST2.Name, \"Cust2 is null\")").Expression;
            interpreter.SetExpression("EXP2", exp2);

            // this works
            System.Diagnostics.Debug.WriteLine(interpreter.Eval("EXP1"));

            // this throws an exception
            System.Diagnostics.Debug.WriteLine(interpreter.Eval("EXP2"));
        }

        private object If(bool b, object x, object y)
        {
            return b ? x : y;
        }
    }
}

@davideicardi
Copy link
Member

The problem is that the parameter is evaluated always, it is not dependent on the condition.

Why not using the standard ?: conditional operator? Something like:

CUST2 != null ? CUST2.Name : "Cust2 is null"

@ArdenCarl
Copy link
Author

Many thanks for your prompt response @davideicardi.

As mentioned in my comment, we could use the ternary operator but the reason being our end users are much more familiar with Excel style functions. I guess it's asking a bit much for the interpreter to understand the desired IF function, which I appreciate.

Is it at all possible to write an if/else statement? My users would understand this more. I have tried but do not seem to get it to work.

@davideicardi
Copy link
Member

Writing an if/else is not supported. Maybe you can try to do some kind of custom "pre processing" of the expression and convert the IF() function to a ternary?

@hzy-6
Copy link

hzy-6 commented Nov 25, 2023

You may need it https://github.com/ncalc/ncalc

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

No branches or pull requests

3 participants