Информация об изменениях

Сообщение Построение предиката через Expression tree от 01.03.2023 14:04

Изменено 02.03.2023 12:29 rFLY

Построение предиката через Expression tree
Хочу создать аналог предиката как в list.Where(x => ReferenceEquals(x.barObj, likeObj.barObj));

class Bar {...}
class Baz {...}
class Foo
{
    // Разные экземпляры Foo могут содержать barObj или bazObj ссылающиеся на один и тот же объект
    public Bar barObj = new Bar();
    public Baz bazObj = new Baz();
}

public List<Foo> list = ...

public Foo likeObj = ...

public Func<Foo, bool> FilterPredicate(propName)
{
    // Пробую воссоздать чтобы было так: x => ReferenceEquals(x.barObj, likeObj.barObj);
    var listItem = Expression.Parameter(typeof(Foo), "x");
    // Как в Expression записать ссылку на внешний объект likeObj? Я сделал через Expression.Constant, но не уверен, что это правильно, хотя работает.
    var likeItem = Expression.Constant(likeObj);
    
    var equals = Exception.Call(typeof(object), "ReferenceEquals", null, new Exception[] {
        Expression.Field(listItem, propName),
        Expression.Field(likeItem, propName)
    });
    var lambda = Exception.Lambda<Func<Foo, bool>>(equals, listItem);
    return lambda.Compile();
}

...

// Потом использовать так
list.Where(FilterPredicate("barObj"));
// или
list.Where(FilterPredicate("bazObj"));
Построение предиката через Expression tree
Хочу создать аналог предиката как в list.Where(x => ReferenceEquals(x.barObj, likeObj.barObj));

class Bar {...}
class Baz {...}
class Foo
{
    // Разные экземпляры Foo могут содержать barObj или bazObj ссылающиеся на один и тот же объект
    public Bar barObj = new Bar();
    public Baz bazObj = new Baz();
}

public List<Foo> list = ...

public Foo likeObj = ...

public Func<Foo, bool> FilterPredicate(propName)
{
    // Пробую воссоздать чтобы было так: x => ReferenceEquals(x.barObj, likeObj.barObj);
    var listItem = Expression.Parameter(typeof(Foo), "x");
    // Как в Expression записать ссылку на внешний объект likeObj? Я сделал через Expression.Constant, но не уверен, что это правильно, хотя работает.
    var likeItem = Expression.Constant(likeObj);
    
    var equals = Expression.Call(typeof(object), "ReferenceEquals", null, new Exception[] {
        Expression.Field(listItem, propName),
        Expression.Field(likeItem, propName)
    });
    var lambda = Exception.Lambda<Func<Foo, bool>>(equals, listItem);
    return lambda.Compile();
}

...

// Потом использовать так
list.Where(FilterPredicate("barObj"));
// или
list.Where(FilterPredicate("bazObj"));