2011-07-20 13 views
25

Próbuję stworzyć makiety dla mojego IRepository interfejsu:Lista <T> wdrożyć IQueryable <T>

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

Z tej realizacji:

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; 
     } 
    } 
} 

Ale kiedy go używać, jestem coraz StackOverflow wyjątek. Jak poprawnie zaimplementować ten interfejs, aby móc korzystać z repozytorium tylko z wersji List?

Użycie jest bardzo proste

[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); 
} 

Oto zrzut ekranu z wyjątkiem:

Exception

+2

"Ale kiedy go użyję" - pokaż nam kod? Pokaż nam ślad stosu? – cdhowie

+0

Co próbujesz zrobić? Domyślam się, że masz nadzieję na magię. Zachowanie jest całkowicie oczekiwane. – leppie

Odpowiedz

29

Przyczyną problemu jest to, że jeśli wykonuje AsQueryable sprawdza, czy obiekt już implementuje IQueryable i jeśli tak, zwraca to.

Użyj new EnumerableQuery<T>(this) zamiast AsQueryable, który nie wykonuje tego sprawdzenia.


Obejście dla .NET 3.5:

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

pierwsze rzuca się IEnumerable<T> tak wybrana Select metoda będzie Enumerable.Select nie Queryable.Select. Wybór tożsamości zwróci następnie nowy obiekt, który nie implementuje IQueryable<T>, więc sprawdzenie, czy jest zaimplementowane w AsQueryable, kończy się niepowodzeniem.

+0

Ma chronione contructor? .. – Sly

+0

Konstruktor biorąc "IEnumerable " jest publiczne. Sprawdź http://msdn.microsoft.com/en-us/library/cc190806.aspx Przynajmniej na .net 4 – CodesInChaos

+0

@CodeInChaos: Nowość w .NET 4. – leppie

1

Spróbuj użyć base.AsQueryable() zamiast this.AsQueryable().

+0

Klasa podstawowa nie ma takiego rozszerzenia. – Sly

+0

Nie pomoże, ponieważ sprawdzanie, czy 'IQueryable ' jest już zaimplementowane, używa typu środowiska wykonawczego. To nie jest metoda wirtualna. – CodesInChaos

Powiązane problemy