unquote()

When writing Aspects with Cirrus or doing dynamic LINQ expressions (such as for LINQ to SQL or DA LINQ), expressions and statements are sometimes expressed not in code but using special data structures such as System.Linq.Expressipms.Expression or RemObjects.Elements.Cirrus.Values.Value that describe the code. The unquote() compiler function can be used to turn such a description of a statement or an expression into compiled code, as if it had bene written inline.

unquote() has two overloads, one takes a generic parameter which will be the result type of the expression at runtime, and one that will be treated as having no result. The latter is useful to insert dynamically generated statements with Cirrus.

LINQ Example

method FetchCustomer(aCondition: Expression): queryable sequence of Customer;
begin
  result := from x in fDatabase.Customers where unquote<Boolean>(aCondition);
end;
IQueryable<Customer> FetchCustomer(Expression condition)
{
    return from x in fDatabase.Customers where unquote<Boolean>(condition);
}
func FetchCustomer(_ condition: Expression) -> IQueryable<Customer>{
    return fDatabase.Customers.Where({ x in return unquote<Boolean>(condition) });
}
IQueryable<Customer> FetchCustomer(Expression condition) {
    return fDatabase.Customers.Where( x => unquote<Boolean>(condition) });
}

In this example above, a condition encoded in form of a System.Linq.Expressions.Expression is passed into the function to fetch customers. This might have been created from parsing SQL or using some other dynamic mechanism (such asa GUI condition builder).

Using unquote(), this expression is used as if it where regular code, in the where clause of a LINQ from expression.

Cirrus Example:

Here we create a Cirrus expression on with the regular Cirrus statements and values, and then use those values inside the SetBody call.

var lAssignment := new AssignmentStatement(lField, lExpr);
var lSelf := if aProperty.Static then 
               new TypeOfValue(aProperty.Owner.GetSelfType) 
             else 
               new SelfValue());
aRead.SetBody(Services, method begin
  if not unquote<Boolean>(lFieldSet) then begin
    locking unquote<object>(lSelf) do begin
      if not unquote<Boolean>(lFieldSet) then begin
        unquote(lAssignment);
        unquote<Boolean>(lFieldSet) := true;
      end;
    end;
  end;
  exit unquote(lField);
end);
var assignment = new AssignmentStatement(field, expression);
var self := property.Static ? new TypeOfValue(aProperty.Owner.GetSelfType) : new SelfValue());
aRead.SetBody(Services, () => {
    if (!unquote<Boolean>(fieldSet))
    {
        lock (unquote<object>(self))
        {
            if (!unquote<Boolean>(fieldSet))
            {
                unquote(assignment);
                unquote<Boolean>(fieldSet) = true;
            }
        }
    };
    return unquote(field);
});
var assignment = AssignmentStatement(field, expression);
var self := property.Static ? TypeOfValue(aProperty.Owner.GetSelfType) : SelfValue());
aRead.SetBody(Services) {
    if (!unquote<Boolean>(fieldSet))
    {
        __lock (unquote<object>(self))
        {
            if (!unquote<Boolean>(fieldSet))
            {
                unquote(assignment);
                unquote<Boolean>(fieldSet) = true;
            }
        }
    };
    return unquote(field);
});
var assignment = new AssignmentStatement(field, expression);
var self := property.Static ? new TypeOfValue(aProperty.Owner.GetSelfType) : new SelfValue());
aRead.SetBody(Services, () => {
    if (!unquote<Boolean>(fieldSet))
    {
        lock (unquote<object>(self))
        {
            if (!unquote<Boolean>(fieldSet))
            {
                unquote(assignment);
                unquote<Boolean>(fieldSet) = true;
            }
        }
    };
    return unquote(field);
});

See Also