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);
});