Доступ к объектам анонимного типа С#

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

например,

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

Ответ 1

Как говорилось в других ответах, вы действительно не должны этого делать. Но, если вы настаиваете, то есть неприятный хак, известный как "приведение примера", который позволит вам это сделать. Техника упоминается в нескольких статьях, здесь и здесь.

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

(Я не могу взять на себя ответственность за этот взлом, хотя автор одной из этих статей говорит, что он также не хочет быть связанным с ним. Его имя может быть знакомо.)

Ответ 2

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

Из Документация MSDN:

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

Ответ 3

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

Ответ 4

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

Ответ 5

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

Ответ 6

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

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

Ответ 7

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