![](/img/trans.png)
[英]Convert Expression<Func<T,T,bool>> to Expression<Func<T,bool>>
[英]Modifying Expression<Func<T, bool>>
我沒有使用過太多的表達式,所以我無法說出我的意圖是否有意義。 我環顧了整個網絡,因此毫無用處。
說我有這樣的方法
public async Task<T> GetFirstWhereAsync(Expression<Func<T, bool>> expression)
{
// this would be a call to 3rd party dependency
return await SomeDataProvider
.Connection
.Table<T>()
.Where(expression)
.FirstOrDefaultAsync();
}
從我的其他代碼中,我可以稱其為
private async Task<User> GetUser(Credentials credentials)
{
return await SomeDataSource
.GetFirstWhereAsync(u => u.UserName.Equals(credentials.UserName));
}
因此,我SomeDataProvider
與給定表達式匹配的SomeDataProvider
中接收第一個User
。
我的實際問題是,我將如何修改GetFirstWhereAsync
以便將一些SecretSauce
應用於傳遞給它的任何表達式? 我可以在呼叫者中執行此操作,但這將很丑陋,並且不會帶來很多樂趣。
因此,如果我傳遞類似
u => u.UserName.Equals(credentials.UserName);
p => p.productId == 1;
我希望這些可以修改為
u => u.UserName.Equals(SecretSauce.Apply(credentials.UserName));
p => p.productId == SecrectSauce.Apply(1);
您可以在方法內部修改表達式,但這有點復雜,您需要根據具體情況進行修改。
下面的示例將處理從x => x.Id == 1
到x => x.Id == SecretSauce.Apply(1)
class User
{
public int Id { get; set; }
public string Name { get; set;}
public override string ToString()
{
return $"{Id}: {Name}";
}
}
class SquareSauce
{
public static int Apply(int input)
{
// square the number
return input * input;
}
}
User[] user = new[]
{
new User{Id = 1, Name = "One"},
new User{Id = 4, Name = "Four"},
new User{Id = 9, Name = "Nine"}
};
User GetFirstWhere(Expression<Func<User, bool>> predicate)
{
//get expression body
var body = predicate.Body;
//get if body is logical binary (a == b)
if (body.NodeType == ExpressionType.Equal)
{
var b2 = ((BinaryExpression)body);
var rightOp = b2.Right;
// Sauce you want to apply
var methInfo = typeof(SquareSauce).GetMethod("Apply");
// Apply sauce to the right operand
var sauceExpr = Expression.Call(methInfo, rightOp);
// reconstruct equals expression with right operand replaced
// with "sauced" one
body = Expression.Equal(b2.Left, sauceExpr);
// reconstruct lambda expression with new body
predicate = Expression.Lambda<Func<User, bool>>(body, predicate.Parameters);
}
/*
deals with more expression type here using else if
*/
else
{
throw new ArgumentException("predicate invalid");
}
return user
.AsQueryable()
.Where(predicate)
.FirstOrDefault();
}
Console.WriteLine(GetFirstWhere(x => x.Id == 2).ToString());
該方法將x => x.Id == 2
變為x => x.Id == SquareSauce.Apply(2)
並將產生:
4:四
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.