Доступ к объектам анонимного типа С#
Как мне получить доступ к объектам анонимного типа за пределами области видимости?
например,
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.