views:

1529

answers:

7

Hi,

How do i access objects of an anonymous type outside the scope where its declared?

for e.g.

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;
}
+6  A: 

You can't return an anonymous type from a function.

From the MSDN documentation:

To pass an anonymous type, or a collection that contains anonymous types, outside a method boundary, you must first cast the type to object. However, this defeats the strong typing of the anonymous type. If you must store your query results or pass them outside the method boundary, consider using an ordinary named struct or class instead of an anonymous type.

Paul Suart
A: 

Anonymous type is just a compiler-generated class, and the compiler is not willing to tell you the name of the class itself. Therefore, there's no way you can return an instance of this class from a function other than returning a reference to an object.

Anton Gogolev
A: 

Well, I think the answer is: Don't use an anonymous type outside the scope where its declared. In this case create a simple type.

bruno conde
+9  A: 

As the other answers have stated, you really shouldn't do this. But, if you insist, then there's a nasty hack known as "cast by example" which will allow you to do it. The technique is mentioned in a couple of articles, here and 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;
}

(I can't take the credit for this hack, although the author of one of those articles says that he doesn't want to be associated with it either. His name might be familiar.)

LukeH
Beaten by 8 seconds! I've deleted mine (no benefit in duplicating it). But to stress:: ***do not do this*** ;-p
Marc Gravell
So you've accepted this as your preferred answer. Although it's an interesting technique, I strongly recommend against using it in any important/production code!
LukeH
Ya. Good to know that this can be done. Is really evil though but so am I. muhahhhhahahaaaa.
Ali Kazmi
If you use this hack, the terrorists win.
Sterno
Thanks for this, I didn't use it :)) I ended up just using immutable structs.
Igor Zevaka
There **are** valid reasons for wanting to do this. See https://connect.microsoft.com/VisualStudio/feedback/details/542278/ability-to-return-strongly-typed-anonymous-classes#
BlueRaja - Danny Pflughoeft
A: 

I would create a class for this case: public class LISTFUNCA {

public int identificacion;
public string nombre;
}

then :

public List '' FuncA() { List '' lista = new List'' (from e in DB.Entities where e.Id == 1) select new '' { identificacion = e.Id, nombre = e.Name}).FirstOrDefault(); return lista.ToList(); } }

that`s all

by DayChucatiny

DayChucatiny
A: 

would create a class for this case:
public class LISTFUNCA
{

public int identificacion;  
public string nombre;  

}

then :

public List <LISTFUNCA> FuncA()
{
List <LISTFUNCA> lista = new List<LISTFUNCA> (from e in DB.Entities where e.Id == 1)
select new <LISTFUNCA> { identificacion = e.Id, nombre = e.Name}).FirstOrDefault();
return lista.ToList(); }
}

that`s all

by DayChucatiny

DayChucatiny
A: 

If you are using .NET 4.0, you can use Tuples for this, you'd return a Tuple<int, string>. You can implement your own Tuples for 2.0/3.5, and actually other people already have, so you should be able to do that if you like.

Richard Hein