Доступ к объектам анонимного типа в C # - PullRequest
12 голосов
/ 03 апреля 2009

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

например,

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

Ответы [ 7 ]

27 голосов
/ 03 апреля 2009

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

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

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

7 голосов
/ 03 апреля 2009

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

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

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

2 голосов
/ 24 марта 2010

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

1 голос
/ 03 апреля 2009

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

1 голос
/ 03 апреля 2009

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

0 голосов
/ 02 марта 2011

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

0 голосов
/ 24 марта 2010

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

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