Se ho un metodo che prende un booleano come:
public void Foo(boolean condition)
E chiamalo così:
Foo("MyField" == "MyValue");
Posso compilarlo in un albero di espressioni per costruire una query su un'altra origine dati che utilizzerà MyField come un parametro e MyValue e un altro. Posso solo sembrare quella condizione in un'espressione che giudica falsa.
AGGIORNARE
var param = Expression.Parameter(typeof(Field), field);
var prop = Expression.PropertyOrField(param, "Name");
ConstantExpression @const = Expression.Constant(value, typeof(string));
var body = Expression.Equal(prop, @const);
var lambda = Expression.Lambda<Func<Field, bool>>(body, param);
Dove Field è una classe con due proprietà, Name e Value
Foo("MyField" == "MyValue")
è, come indicato in fondo alla domanda, una costante false
(a destra al compilatore). Hai alcune scelte qui - il più semplice naturalmente è fare qualcosa come:
void Foo(Expression<Func<YourType,bool>> predicate) {...}
e chiama con
Foo(x => x.MyField == "MyValue");
allora qui , non c'è più niente da fare; abbiamo già l'espressione. Quindi presumo tu voglia dire "MyField" è una stringa conosciuta solo in fase di esecuzione, nel qual caso:
void Foo<T>(string fieldName, T value) {
var param = Expression.Parameter(typeof(YourType), "x");
var body = Expression.Equal(
Expression.PropertyOrField(param, fieldName),
Expression.Constant(value, typeof(T))
);
var lambda = Expression.Lambda<Func<YourType, bool>>(body, param);
}
e chiama con Foo("MyField", "MyValue)
(con un <string>
implicito in là, per gentile concessione del compilatore), o Foo("MyField", 123)
se il prop è un int
(implicito <int>
),
Lo scenario finale è dove "MyValue"
è anche una stringa conosciuta solo in fase di esecuzione (emph: string
) - nel qual caso dovremo analizzarla:
void Foo(string fieldName, string value) {
var param = Expression.Parameter(typeof(YourType), "x");
var prop = Expression.PropertyOrField(param, fieldName);
ConstantExpression @const;
if(prop.Type == typeof(string)) {
@const = Expression.Constant(value, typeof(string));
} else {
object parsed = TypeDescriptor.GetConverter(prop.Type)
.ConvertFromInvariantString(value);
@const = Expression.Constant(parsed, prop.Type);
}
var body = Expression.Equal(prop,@const);
var lambda = Expression.Lambda<Func<YourType, bool>>(body, param);
}
Qui la chiamata è sempre a 2 stringhe - quindi Foo("MyField", "123")
anche se int
.
In può creare alberi di espressione dai delegati. Ad esempio, se si definisce il metodo in modo che richieda un delegato come parametro, è possibile utilizzarlo come segue:
public void Foo(Func<bool> fn)
{
// invoke the passed delegate
var result = fn();
}
Foo(() => "MyField" == "MyValue");
Per creare un albero di espressioni, anziché eseguire il delegato, modificare il metodo nel modo seguente:
public void Foo(Expression<Func<bool>> expression)
{
// inspect your expression tree here
}
Tuttavia, nel tuo caso, troverai che la tua espressione è una costante booleana con valore 'false', questo perché il compilatore ha valutato "MyField" == "MyValue"
che è ovviamente falso.
Se vuoi solo coppie nome-valore, che non usano solo un Dictionary<string, string>
?