2009-04-03 38 views
11

Làm cách nào để truy cập các đối tượng thuộc loại ẩn danh ngoài phạm vi được khai báo?Truy cập C# Loại đối tượng ẩn danh

ví dụ:

void FuncB() 
{ 
var obj = FuncA(); 
Console.WriteLine(obj.Name); 
} 

??? FuncA() 
{ 
var a = (from e in DB.Entities 
where e.Id == 1 
select new {Id = e.Id, Name = e.Name}).FirstOrDefault(); 

return a; 
} 

Trả lời

26

Khi các câu trả lời khác đã nêu, bạn thực sự không nên làm điều này. Nhưng, nếu bạn nhấn mạnh, sau đó có một hack khó chịu được gọi là "đúc bằng ví dụ" mà sẽ cho phép bạn làm điều đó. Kỹ thuật này được đề cập trong một vài bài báo, herehere.

public void FuncB() 
{ 
    var example = new { Id = 0, Name = string.Empty }; 

    var obj = CastByExample(FuncA(), example); 
    Console.WriteLine(obj.Name); 
} 

private object FuncA() 
{ 
    var a = from e in DB.Entities 
      where e.Id == 1 
      select new { Id = e.Id, Name = e.Name }; 

    return a.FirstOrDefault(); 
} 

private T CastByExample<T>(object target, T example) 
{ 
    return (T)target; 
} 

(Tôi không thể lấy tín dụng cho hack này, mặc dù the author of one of those articles says that he doesn't want to be associated with it either Tên của ông có thể quen..)

+0

Bị đánh bại sau 8 giây! Tôi đã xóa của tôi (không có lợi ích trong việc sao chép nó). Nhưng để căng thẳng :: *** không làm điều này *** ;-p –

+0

Vì vậy, bạn đã chấp nhận điều này như là câu trả lời ưa thích của bạn. Mặc dù đó là một kỹ thuật thú vị, tôi khuyên bạn không nên sử dụng nó trong bất kỳ mã sản xuất/quan trọng nào! – LukeH

+1

Ya. Tốt để biết rằng điều này có thể được thực hiện. Thực sự là điều ác nhưng dù sao tôi cũng vậy .... muhahhhhahahaaaa. –

7

Bạn không thể trả lại loại ẩn danh từ một hàm.

Từ MSDN documentation:

Để vượt qua một loại vô danh, hoặc một bộ sưu tập có chứa các loại vô danh, bên ngoài một ranh giới phương pháp, trước tiên bạn phải ép kiểu để phản đối. Tuy nhiên, điều này đánh bại việc gõ mạnh mẽ của loại vô 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 pháp, hãy xem xét sử dụng cấu trúc hoặc lớp được đặt tên thông thường thay vì loại ẩn danh.

1

Loại ẩn danh chỉ là lớp do trình biên dịch tạo ra và trình biên dịch không sẵn lòng cho bạn biết tên của lớp đó. Vì vậy, không có cách nào bạn có thể trả về một thể hiện của lớp này từ một hàm khác ngoài việc trả về một tham chiếu đến một số object.

1

Vâng, tôi nghĩ câu trả lời là: Không sử dụng loại ẩn danh ngoài phạm vi được khai báo. Trong trường hợp này tạo một kiểu đơn giản.

0

sẽ tạo ra một lớp cho trường hợp này:

public class LISTFUNCA 
{       
    public int identificacion; 
    public string nombre;  
}  

sau đó:

public List<LISTFUNCA> FuncA() 
{           
    var lista = (from e in DB.Entities where e.Id == 1       
       select new { identificacion = e.Id, nombre = e.Name}) 
       .FirstOrDefault(); 
    return lista.ToList(); 
}  
+1

Vui lòng xem lại mã của bạn; Tôi đã định dạng lại nó, nhưng tôi tin nó không đúng. Ngoài ra, vui lòng đọc [faq] để biết chi tiết về cách định dạng mã của bạn một cách chính xác. Và, khi bạn đăng một cái gì đó, và nó trông khủng khiếp, đừng quên bạn có thể [sửa bài viết của bạn để sửa chữa nó.] (Http://stackoverflow.com/posts/2509405/edit) – Will

2

Nếu bạn đang sử dụng .NET 4.0, bạn có thể sử dụng Tuples cho điều này, bạn sẽ quay lại a Tuple<int, string>. Bạn có thể thực hiện Tuples của riêng bạn cho 2.0/3.5, và thực sự những người khác đã có, vì vậy bạn sẽ có thể làm điều đó nếu bạn thích.

0

Khung nguồn mở Impromptu-Interface sẽ cho phép bạn truyền một đối tượng ẩn danh tới giao diện. Nó có lợi thế là ít bị hack vì nó sẽ hoạt động như mong đợi trên các ranh giới lắp ráp. Nó hoàn thành điều này bằng cách sử dụng một proxy nhẹ và dlr.

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