2011-07-20 36 views
25

Tôi đang cố gắng để tạo ra một mô hình cho giao diện của tôi IRepository:Danh sách <T> để thực hiện IQueryable <T>

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

Với thực hiện điều này:

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

Nhưng khi tôi sử dụng nó, tôi nhận được StackOverflow ngoại lệ. Làm cách nào để triển khai giao diện này một cách chính xác để có thể sử dụng chỉ một kho lưu trữ List?

Cách sử dụng rất đơn giản

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

Dưới đây là ảnh chụp màn hình của ngoại lệ:

Exception

+2

"Nhưng khi tôi sử dụng nó" - hiển thị mã cho chúng tôi? Hiển thị cho chúng tôi theo dõi ngăn xếp? – cdhowie

+0

Bạn đang cố gắng làm gì? Đoán tốt nhất của tôi là bạn đang hy vọng cho một số phép thuật. Hành vi này hoàn toàn được mong đợi. – leppie

Trả lời

29

Lý do cho vấn đề của bạn là nếu bạn thực hiện AsQueryable nó sẽ kiểm tra nếu đối tượng đã thực hiện IQueryable và nếu có trả lại nó.

Sử dụng new EnumerableQuery<T>(this) thay vì AsQueryable không thực hiện kiểm tra này.


Giải pháp cho .net 3.5:

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

Đầu phôi để IEnumerable<T> nên chọn phương pháp Select sẽ Enumerable.Select không Queryable.Select. Nhận dạng chọn sau đó sẽ trả về một đối tượng mới không thực hiện IQueryable<T>, vì vậy việc kiểm tra nếu nó được thực hiện trong AsQueryable không thành công.

+0

Nó đã được bảo vệ contructor? .. – Sly

+0

Các nhà xây dựng tham gia một 'IEnumerable ' là công khai. Kiểm tra http://msdn.microsoft.com/en-us/library/cc190806.aspx Ít nhất là trên .net 4 – CodesInChaos

+0

@CodeInChaos: Mới trong .NET 4. – leppie

1

Hãy thử sử dụng base.AsQueryable() thay vì this.AsQueryable().

+0

Lớp cơ sở không có phần mở rộng như vậy – Sly

+0

Sẽ không giúp ích gì khi kiểm tra nếu 'IQueryable ' đã được triển khai sử dụng kiểu thời gian chạy. Đây không phải là phương pháp ảo. – CodesInChaos

Các vấn đề liên quan