Есть ли способ определить неявный оператор в C#, который определяет приведение из выражения в выбранный класс - PullRequest
1 голос
/ 14 февраля 2020

Я пытаюсь реализовать класс, который определяет фильтр, чтобы сделать его более явным, когда он будет передан в качестве аргумента методам в моем классе репозитория (EF).

И у меня есть проблема с определением неявный оператор из Expression в мой класс. Можно ли сделать реализацию для синтаксиса рядом с переменной fd4?

public class FilterDefinition<TEntity>
    where TEntity : class
{
    public FilterDefinition() { }

    public FilterDefinition(Expression<Func<TEntity, bool>> filter)
    {
        this.Filter = filter;
    }

    public virtual Expression<Func<TEntity, bool>> Filter { get; set; }

    public static implicit operator FilterDefinition<TEntity>(Expression<Func<TEntity, bool>> filter) => new FilterDefinition<TEntity>(filter);
}

public class SomeEntity
{
    public bool SomeBool { get; set; }
}

class Program
{
    static void Main()
    {
        FilterDefinition<SomeEntity> fd1 = new FilterDefinition<SomeEntity>(x => x.SomeBool);
        FilterDefinition<SomeEntity> fd2 = new FilterDefinition<SomeEntity> { Filter = x => x.SomeBool };
        FilterDefinition<SomeEntity> fd3 = (Expression<Func<SomeEntity, bool>>)(x => x.SomeBool);
        //FilterDefinition<SomeEntity> fd4 = x => x.SomeBool;

        Console.ReadKey();
    }
}

Цель класса FilterDefinition - передать в качестве аргумента хранилище запросов generi c. А с помощью наследования определяют часто используемые фильтры.

public class Repository<TEntity> : IRepository<TEntity>
    where TEntity : class
{
    private readonly DbSet<TEntity> dbSet;

    public Repository(DbContext context)
    {
        this.dbSet = context.Set<TEntity>();
    }

    public async Task<IEnumerable<TEntity>> GetAsync(
        FilterDefinition<TEntity> filter = null,
        OrderDefinition<TEntity> order = null,
        PagingDefinition paging = null)
    {
        return await new QueryBuilder<TEntity>(this.dbSet)
            .ApplyFilter(filter)
            .ApplyOrder(order)
            .ApplyPaging(paging)
            .ToQuery()
            .ToListAsync();
    }

1 Ответ

3 голосов
/ 14 февраля 2020

Короткий ответ будет "не в этом сценарии", потому что синтаксически , в fd4 вы на самом деле не преобразуете Expression[...] в ваш тип. Компилятор не знает, что лямбда представляет Expression[...], пока не узнает, что он пытается сделать со значением; лямбда (x => x.SomeBool) может интерпретироваться как широкий диапазон обоих типов дерева выражений и типов делегатов (для анонимных методов), и компилятор здесь не поймет, что вы означает «обрабатывать лямбду как Expression<Func<SomeEntity, bool>>, а затем использовать оператор неявного преобразования, чтобы изменить выражение на FilterDefinition». Он просто не может (и не делает) этот скачок. Вы можете подойти ближе, как с вашим примером fd3, но ... большая часть меня задается вопросом, что на самом деле FilterDefinition 1017 * делает здесь, потому что внешнему наблюдателю это на самом деле не кажется добавить что-нибудь поверх необработанного дерева выражений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...