Подтвердить что ты не робот

Список <T> для реализации IQueryable <T>

Я пытаюсь создать макет для моего интерфейса IRepository:

public interface IRepository<T> : ICollection<T>, IQueryable<T>
{
}

С помощью этой реализации:

public class RepositoryFake<T> : List<T>, IRepository<T>
{
    public Expression Expression
    {
        get
        {
            return this.AsQueryable().Expression;
        }
    }

    public Type ElementType
    {
        get
        {
            return this.AsQueryable().ElementType;
        }
    }

    public IQueryProvider Provider
    {
        get
        {
            return this.AsQueryable().Provider;
        }
    }
}

Но когда я его использую, я получаю исключение StackOverflow. Как правильно реализовать этот интерфейс, чтобы иметь возможность использовать только List в качестве репозитория?

Использование очень просто

[Test]
public void Test()
{
    RepositoryFake<User> users = new RepositoryFake<User>();
    users.Add(new User());

    List<User> list = (from user in users 
                 where user.Id == "5"
                 select user).ToList();

    Assert.That(list, Is.Empty);
}

Вот скриншот исключения:

Exception

4b9b3361

Ответ 1

Причиной вашей проблемы является то, что если вы выполняете AsQueryable, он проверяет, реализует ли объект IQueryable, и если да возвращает его.

Используйте new EnumerableQuery<T>(this) вместо AsQueryable, который не выполняет эту проверку.


Обходной путь для .net 3.5:

return ((IEnumerable<T>)this).Select(x=>x).AsQueryable()

Сначала добавляется IEnumerable<T>, поэтому выбранный Select метод будет Enumerable.Select not Queryable.Select. Затем идентификатор выбирает новый объект, который не реализует IQueryable<T>, поэтому проверка, выполнена ли в AsQueryable, не выполняется.

Ответ 2

Попробуйте использовать base.AsQueryable() вместо this.AsQueryable().