2009-12-20 34 views
5

Tôi có một số LINQ to sql phương pháp và khi nó truy vấn nó trả về một số loại vô danh.Làm cách nào để trả lại bộ sưu tập danh sách chung trong C#?

Tôi muốn trả lại loại ẩn danh đó trở lại lớp dịch vụ của mình để thực hiện một số logic và nội dung trên đó.

Tôi không biết cách trả lại.

Tôi nghĩ tôi có thể làm điều này

public List<T> thisIsAtest() 
{ 
    return query; 
} 

nhưng tôi nhận được lỗi này

Error 1 The type or namespace name 'T' could not be found (are you missing a using directive or an assembly reference?) 

Vì vậy, không chắc chắn những gì tôi đang lắp ráp thiếu hoặc nếu đó là ngay cả những trường hợp.

Cảm ơn

EDIT

Ok vấn đề đầu tiên của tôi đã được giải quyết nhưng bây giờ tôi có một vấn đề mới mà tôi không chắc chắn làm thế nào để sửa chữa kể từ khi tôi không biết nhiều về các loại vô danh.

tôi nhận được lỗi này

thể không mặc nhiên chuyển đổi loại 'System.Collections.Generic.List' để 'System.Collections.Generic.List

Dưới đây là truy vấn

DbContext.Table.Where(u => u.Table.UserId == userId && u.OutOFF != 0) 
     .GroupBy(u => new { u.Table.Prefix }) 
     .Select(group => new { prefix = group.Key, 
           Marks = group.Sum(item => (item.Mark * item.Weight)/item.OutOFF) }) 
     .ToList(); 

Chỉnh sửa 2

public class ReturnValue 
{ 
    string prefix { get; set; } 
    decimal? Marks { get; set; } 
} 

public List<ReturnValue> MyTest(Guid userId) 
{ 
    try 
    { 
     var result = dbContext.Table.Where(u => u.Table.UserId == userId && u.OutOFF != 0).GroupBy(u => new { u.Table.Prefix }) 
     .Select(group => new { prefix = group.Key, Marks = group.Sum(item => (item.Mark * item.Weight)/item.OutOFF) }).ToList(); 
     return result; 
    } 
    catch (SqlException) 
    { 
     throw; 
    } 

select có này trong đó

Anonymous Types: 

a is new{string Prefix} 
b is new{ 'a prefix, decimal? marks} 
+0

lý do tại sao bạn không thể xác định loại mới 'lớp ReturnValue {int prefix; dấu thập phân; } 'và sau đó trả về một' ReturnValue mới (....) 'thay vì một kiểu vô danh ?? –

+0

Tôi cần một ví dụ. Tôi nhận được trợ giúp làm cho truy vấn này nó làm những gì tôi muốn nhưng nếu nó có thể được thay đổi hoặc một cái gì đó thêm vào để làm cho nó không vô danh tôi tất cả cho điều đó. – chobo2

+0

Bạn không sử dụng mã tôi đã đề cập! Trong '.Select()', bạn cần sử dụng: '.Select (group => new RETURNVALUE {prefix = group.Key, ...' - đây là * NOT * những gì bạn có! Bạn đã không thêm ** TYPE ** được tạo ra trong .Select() - đó là vấn đề của bạn –

Trả lời

8

Bạn không thể - thời gian. Bạn không thể sử dụng các loại ẩn danh ngoài phạm vi của riêng chúng, ví dụ: bạn không thể trả lại chúng dưới dạng giá trị trả về từ một phương thức.

Nếu bạn cần trả lại chúng, bạn cần xác định một lớp bê tông mới thay vì loại ẩn danh và sử dụng nó ở vị trí của loại ẩn danh.

Xem Rick của blog post trên Phạm vi của các loại vô danh, và xem Strahl các MSDN docs here đó nêu rõ:

Một loại vô danh có phạm vi phương pháp. Để chuyển một loại ẩn danh hoặc bộ sưu tập có chứa các loại vô danh , bên ngoài ranh giới phương thức, trước tiên bạn trước tiên phải truyền loại đối tượng. Tuy nhiên, điều này đánh bại việc gõ mạnh mẽ của loại ẩn danh.Nếu bạn phải lưu trữ kết quả truy vấn của bạn hoặc vượt qua chúng bên ngoài ranh giới phương thức, xem xét sử dụng một cấu trúc hoặc lớp thông thường có tên là thay vì loại ẩn danh.

OK, chắc chắn - có những hacks khủng khiếp để thực sự trả về các loại ẩn danh. Nhưng nếu MSDN AND của Microsoft không khuyến khích thực hành đó, thì - chỉ cần không làm điều đó. Theo định nghĩa và ý định, các loại ẩn danh được ràng buộc theo phương pháp mà chúng được xác định trong.

CẬP NHẬT cho chobo2: Tôi không biết kiểu dữ liệu của bạn là gì - chỉ đoán - nhưng giả sử "tiền tố" là một int và "đánh dấu" là một chữ số thập phân, bạn có thể định nghĩa một lớp mới:

public class ReturnValue 
{ 
    int prefix { get; set; } 
    decimal Marks { get; set; } 
} 

và sau đó mã của bạn sẽ là một phương thức trả về một List<ReturnValue>:

public List<ReturnValue> thisIsAtest() 
{ 
    DbContext.Table.Where(u => u.Table.UserId == userId && u.OutOFF != 0) 
    .GroupBy(u => new { u.Table.Prefix }) 
    .Select(group => new ReturnValue 
          { prefix = group.Key, 
          Marks = group 
           .Sum(item => (item.Mark * item.Weight)/item.OutOFF) }) 
    .ToList(); 
} 

Mấu chốt ở đây là: trongcủa bạn 0 phương pháp, thay vì tạo ra một thể hiện mới của một loại vô danh:

 .Select(group => new { prefix = group.Key, marks = .... } 

bạn tạo một thể hiện của một kiểu dữ liệu cụ:

 .Select(group => new ReturnValue { prefix = group.Key, marks = .... } 

Bằng cách này, bạn sẽ có một lớp bê tông ReturnValue - đặt tên cho bất kỳ thứ gì bạn thích - và sau đó bạn có thể dễ dàng trả lại danh sách loại đó và sử dụng loại đó ở nơi khác.

+0

Thực ra, bạn có thể: http://msmvps.com/blogs/jon_skeet/archive/2009/01/09/horrible-grotty-hack-returning-an-anonymous-type-instance.aspx Không phải tôi muốn giới thiệu nó Tuy nhiên. –

+0

Hmm tôi có thể xem ví dụ. Tôi nhận được điều này ngay bây giờ. Tôi không muốn làm logic trong lớp kho lưu trữ của tôi khôn ngoan khác tôi phải làm cho 2 của cùng một phương pháp vì tôi sử dụng nó vào vị trí nhưng cần phải sử dụng dữ liệu theo 2 cách khác nhau. Không thể chuyển đổi hoàn toàn loại 'System.Collections.Generic.List ' thành 'System.Collections.Generic.List chobo2

+0

@MarkByers: nhưng bản thân Jon nói: "không sử dụng mã này" .. .... thực sự, vì tất cả ý định và mục đích: ** KHÔNG ** - thậm chí không thử. –

6
public List<T> thisIsAtest<T>() 
{ 
    return query; 
} 
+0

Điều đó giải quyết được vấn đề đó nhưng bây giờ tôi nhận được điều này Không thể chuyển đổi hoàn toàn loại 'System.Collections.Generic.List ' thành 'System .Collections.Generic.List chobo2

+1

Truy vấn bạn đang quay trở lại là danh sách các loại ẩn danh, bạn chỉ có thể trả về danh sách .Bạn có thể sử dụng các đối tượng và truyền hack bởi Jon Skeet, nhưng nó không được khuyến khích. –

2

Bạn muốn trả lại loại ẩn danh từ phương pháp thông thường? Tôi khá chắc chắn bạn có thể với Reflection, nhưng sẽ không có loại an toàn và một loạt các vấn đề khác. Không phải đề cập đến nó trông lạ từ quan điểm mã gọi. Về cơ bản bạn sẽ phải trả lại vật mà tôi nghĩ.

Bạn sẽ sử dụng tốt hơn một lớp hoặc cấu trúc và đưa các giá trị vào đó.

0

Các loại vô danh rất hạn chế, bạn chỉ có thể sử dụng chúng trong phạm vi của phương thức là chúng được khai báo.

Bạn có thể chuyển chúng trở lại dưới dạng đối tượng đơn giản, nhưng sau đó bạn sẽ mất thông tin loại. Tôi đã thấy một số giải pháp đi qua một loại ẩn danh xung quanh; nhưng họ sử dụng sự phản chiếu để lấy các thuộc tính tại một điểm sau này.

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