System.Linq.Dynamic.Core icon indicating copy to clipboard operation
System.Linq.Dynamic.Core copied to clipboard

Support for implicit operators

Open victorr99 opened this issue 11 months ago • 1 comments

I would like to submit a feature request to add support for implicit operators.

To my understanding, implicit operators are only supported for booleans at the moment. We have a use case were we need to support implicit operators to cast from and to a structure.

We would like to be able to run the following example:

class Program
{
    static void Main(string[] args)
    {
        var parser = new ExpressionParser(
            [],
            "MyMethods.UsesMyStruct(\"Foo\")",
            [],
            new ParsingConfig());
        
        var expression = parser.Parse(typeof(MyStruct));
        var lambda = Expression.Lambda<Func<MyStruct>>(expression);
        var method = lambda.Compile();

        var result = method();
        // result == MyStruct with Value = "Foo"
    }

    [DynamicLinqType]
    public static class MyMethods
    {
        public static string UsesMyStruct(MyStruct myStruct)
        {
            return myStruct.Value;
        }
    }

    public readonly struct MyStruct(string value)
    {
        private readonly string _value = value;

        public static implicit operator MyStruct(string value)
        {
            return new MyStruct(value);
        }
        
        public static implicit operator string(MyStruct myStruct)
        {
            return myStruct._value;
        }
        
        public string Value => _value;
    }
}

In plain C# this is also possible:

string result = MyMethods.UsesMyStruct("foo");

Running the example above results in the following exception:

Unhandled exception. No applicable method 'UsesMyStruct' exists in type 'MyMethods' (at index 10)
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseMemberAccess(Type type, Expression expression, String id)
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseTypeAccess(Type type, Boolean getNext)
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseIdentifier()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParsePrimaryStart()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParsePrimary()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseUnary()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseArithmetic()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseAdditive()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseShiftOperator()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseComparisonOperator()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseLogicalAndOrOperator()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseIn()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseAndOperator()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseOrOperator()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseLambdaOperator()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseNullCoalescingOperator()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseConditionalOperator()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.Parse(Type resultType, Boolean createParameterCtor)

victorr99 avatar Jan 24 '25 10:01 victorr99

I would like this feature as well, this would be a great addition to the library

git-bone avatar Jan 31 '25 08:01 git-bone