2009-04-03 5 views
11

Как мне получить доступ к объектам анонимного типа за пределами области, где объявлено?Доступ к объектам анонимного типа C#

, например.

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

ответ

26

Как уже сообщалось, вы действительно не должны это делать. Но, если вы настаиваете, тогда есть неприятный хак, известный как «набросок на пример», который позволит вам это сделать. Эта техника упоминается в нескольких статьях, here и here.

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

(я не могу взять кредит на эту хака, хотя the author of one of those articles says that he doesn't want to be associated with it either Его имя может быть знакомо.).

+0

Избито на 8 секунд! Я удалил мой (нет никакой пользы в его дублировании). Но подчеркнуть: *** не делайте этого *** ;-p –

+0

Итак, вы приняли это как ваш предпочтительный ответ. Хотя это интересная техника, я настоятельно рекомендую не использовать ее в любом важном/производственном коде! – LukeH

+1

Ya. Приятно знать, что это можно сделать. Действительно ужасно, но я тоже. Muhahhhhahahaaaa. –

7

Вы не можете вернуть анонимный тип из функции.

Из MSDN documentation:

Чтобы передать анонимный тип или коллекцию, содержащую анонимные типы, вне границы методы, вы должны сначала привести тип к объекту. Однако это приводит к сильной типизации анонимного типа. Если вы должны сохранить результаты запроса или передать их вне границы метода, рассмотрите возможность использования обычной именованной структуры или класса вместо анонимного типа.

1

Анонимный тип - это только класс, сгенерированный компилятором, и компилятор не желает сообщать вам имя самого класса. Таким образом, вы не можете вернуть экземпляр этого класса из функции, отличной от возврата ссылки на object.

1

Ну, я думаю, что ответ таков: не используйте анонимный тип вне области, где его объявили. В этом случае создайте простой тип.

0

бы создать класс для этого случая:

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

тогда:

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

Просмотрите свой код; Я переформатировал его, но считаю, что это неверно. Кроме того, пожалуйста, прочитайте [faq], чтобы узнать, как правильно отформатировать код. И, когда вы публикуете что-то, и это выглядит ужасно, не забывайте, что вы можете [отредактировать свой пост, чтобы исправить это.] (Http://stackoverflow.com/posts/2509405/edit) – Will

2

Если вы используете .NET 4.0, вы можете использовать Tuples для этого, вы вернетесь a Tuple<int, string>. Вы можете реализовать свои собственные Tuples для 2.0/3.5, и на самом деле другие люди уже есть, поэтому вы должны быть в состоянии сделать это, если хотите.

0

Рамка с открытым исходным кодом Impromptu-Interface позволит вам уклониться от анонимного объекта к интерфейсу. Преимущество этого заключается в том, что он менее хакен, потому что он будет работать как ожидается на границах сборок. Он выполняет это, используя легкий прокси и dlr.

Смежные вопросы