在我的 WPF 應用程式中,我有一個可觀察的集合,我必須在 where 條件下過濾傳遞一個函式。我決定傳遞一個 Func,因為 where 中的過濾條件是動態創建的(傳遞的不僅僅是我的集合中的一個引數,過濾器和/或過濾器小于,等于等)。
在我重組代碼之前,該解決方案可以正常作業。在以前版本的應用程式中,我有一個模型,它在一個獨特的類中具有所有集合屬性。并且僅由屬性名稱創建的運算式。但是現在我已經引入了基類和介面,并且出現了問題。我不能使用屬性名稱來創建運算式,但是因為屬性速度是一個嵌套類,所以我引入了 CreateExpression 方法,并且我認為屬性型別(在我的示例中為雙精度)在我的嵌套類中沒有正確映射。
例如,在我的班級中,我有一個速度屬性(雙值),我想在我的集合中過濾我的速度屬性。
這是一個解釋我的問題的代碼示例
public interface ICommonData
{
DynamicData DynamicData { get; set; }
string Name { get; set; }
}
public class DynamicData
{
public double Speed { get; set; }
}
public class Data : ICommonData
{
public DynamicData DynamicData { get; set; }
public string Name { get ; set; }
}
public partial class MainWindow : Window
{
List<Data> datas = new List<Data>();
public MainWindow()
{
InitializeComponent();
for (int i = 0; i < 10; i )
{
datas.Add(new Data
{
DynamicData = new DynamicData { Speed = i},
Name = $"A{i}"
});
}
}
private void Button_Click(object sender, RoutedEventArgs e)
{
CreateFilter("2");
}
private void CreateFilter(string v)
{
var expression = CreateFilterExpression<ICommonData>(v).Compile();
datas.Where(expression);
}
public static Expression<Func<TInput, bool>> CreateFilterExpression<TInput>(string v)
{
Expression compareExpression = null;
ParameterExpression param = Expression.Parameter(typeof(TInput), "");
Expression lambdaBody = null;
var expression = CreateExpression(typeof(ICommonData), "DynamicData.Speed");
compareExpression = Expression.LessThan(expression, Expression.Constant(2D));
lambdaBody = compareExpression;
return Expression.Lambda<Func<TInput, bool>>(lambdaBody, param);
}
static LambdaExpression CreateExpression(Type type, string propertyName)
{
var param = Expression.Parameter(type, "x");
Expression body = param;
foreach (var member in propertyName.Split('.'))
{
body = Expression.PropertyOrField(body, member);
}
return Expression.Lambda(body, param);
}
}
這就是錯誤
System.InvalidOperationException: '沒有為型別'System.Func`2[FilterTest.ICommonData,System.Double]'和'System.Double'定義二元運算子LessThan。'
謝謝大家的幫助
uj5u.com熱心網友回復:
在代碼中創建Expression樹時,我建議使用注釋(而且我很少使用注釋)來顯示正在構建的內容。
public static Expression<Func<TInput, bool>> CreateFilterExpression<TInput>(string v) {
// (TInput p)
var param = Expression.Parameter(typeof(TInput), "p");
// p.DynamicData.Speed
var memberExp = ExpressionForPath(param, "DynamicData.Speed");
// p.DynamicData.Speed < 2D
var body = Expression.LessThan(memberExp, Expression.Constant(2D));
// (TInput p) => p.DynamicData.Speed < 2D
return Expression.Lambda<Func<TInput, bool>>(body, param);
}
static Expression ExpressionForPath(ParameterExpression param, string memberPath) =>
memberPath.Split('.').Aggregate((Expression)param, (exp, n) => Expression.PropertyOrField(exp, n));
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/497412.html
