Доступ к объектам анонимного типа 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;
}

person Ali Kazmi    schedule 03.04.2009    source источник
comment
Возможный дубликат Есть ли способ вернуть анонимный тип из метод?   -  person cdiggins    schedule 06.10.2018


Ответы (7)


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

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

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

person LukeH    schedule 03.04.2009
comment
Битый на 8 секунд! Я удалил свой (дублировать нет смысла). Но чтобы подчеркнуть :: не делайте этого ;-p - person Marc Gravell; 03.04.2009
comment
Итак, вы приняли это как свой предпочтительный ответ. Хотя это интересный метод, я настоятельно рекомендую не использовать его в любом важном / производственном коде! - person LukeH; 03.04.2009
comment
Я. Приятно знать, что это можно сделать. Это действительно зло, но я тоже. Muhahhhhahahaaaa. - person Ali Kazmi; 04.04.2009
comment
Спасибо за это, не использовал :)) В итоге я просто использовал неизменяемые структуры. - person Igor Zevaka; 18.02.2010
comment
Для этого есть веские причины. См. connect.microsoft. ru / VisualStudio / feedback / details / 542278 / - person BlueRaja - Danny Pflughoeft; 10.04.2010
comment
У этого хака есть особая оговорка, что он не будет работать за пределами сборки. Это связано с тем, что компилятор генерирует типы на основе сигнатуры один раз для каждой сборки, поэтому, если вы используете var example = new { Id = 0, Name = string.Empty }; в сборке, отличной от FuncA(), типы не будут совпадать. - person jbtule; 02.03.2011
comment
@LukeH, одна ссылка мертва, переехала на здесь - person ASh; 16.11.2018

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

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

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

person Paul Suart    schedule 03.04.2009

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

person DoctorFoo    schedule 24.03.2010

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

person Anton Gogolev    schedule 03.04.2009

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

person bruno conde    schedule 03.04.2009

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

person jbtule    schedule 02.03.2011

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

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(); 
}     
person DayChucatiny    schedule 24.03.2010
comment
Пожалуйста, проверьте свой код; Я его переформатировал, но считаю, что это неправильно. Кроме того, прочтите часто задаваемые вопросы о том, как правильно отформатировать код. И если вы публикуете что-то, а это выглядит ужасно, не забывайте, что вы можете отредактировать свое сообщение, чтобы исправить это. - person ; 19.09.2011