Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert dynamic value to type value in expression

public class Model1 {
    public String Value { get; set; }

}
public class Model2 {
    public dynamic Value { get; set; }
}

public static Expression<Func<Model2, Model1>> GetExpression() {
    return f => new Model1 {
        Value = f.Value
    };
}

I am writing a GetExpression() which convert Model2 property to Model1. When it comes to dynamic property, I try Convert.ToString(f.Value) or (String)f.Value but it said

"An expression tree may not contain a dynamic operation"

Anyone know what is the proper way to convert dynamic value to type value in expression?

like image 762
Kuroro Avatar asked Apr 17 '18 11:04

Kuroro


People also ask

What are dynamic values in C++?

Specifically, a dynamic value can be: Null. A value of any of the primitive scalar data types: bool, datetime, guid, int, long, real, string, and timespan. An array of dynamic values, holding zero or more values with zero-based indexing. A property bag that maps unique string values to dynamic values.

How do you get the underlying type of a dynamic value?

Accessing a sub-object of a dynamic value yields another dynamic value, even if the sub-object has a different underlying type. Use the gettype function to discover the actual underlying type of the value, and any of the cast function listed below to cast it to the actual type.

How do I add dynamic content to an expression?

What you can do is: 1 Go to "Expression" 2 Start entering your function 3 Click on "Dynamic Content" 4 Scroll and click on the attribute you need: it will add the value automatically in the expression

How do I select a type expression from the function dialogue?

The function dialogue doesn’t give an option to actually select or enter a type expression. This would be without quotes like so: So if I aim to feed my function a text value to dynamically create a type from it, I need a function that returns a type and accepts a text value to identify the actual type.


2 Answers

The only way to do this is to convince the expression compiler to overlook the dynamic:

return f => new Model1
{
    Value = (string)(object)f.Value
};

or

return f => new Model1
{
    Value = Convert.ToString((object)f.Value)
};

With anything else, there is going to be an implicit dynamic conversion, which isn't supported. This just does a hard cast instead.

However, frankly I wonder whether there's much value in f.Value being dynamic in the first place.

like image 157
Marc Gravell Avatar answered Oct 27 '22 09:10

Marc Gravell


You can move the code that builds Model1 from Model2 into a method, and use that method in your expression, like this:

private static Model1 FromMolde2(Model2 m2) {
    return new Model1 { Value = m2.Value };
}
public static Expression<Func<Model2, Model1>> GetExpression() {
    return f => FromMolde2(f);
}

One side benefit of this approach is that the code that copies properties from Model2 into Model1 is available for reuse.

Another possibility is to give Model1 an additional constructor that takes Model2, but this would introduce a potentially undesirable dependency between the two classes.

like image 36
Sergey Kalinichenko Avatar answered Oct 27 '22 10:10

Sergey Kalinichenko