12

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;
}
Ali Kazmi
  • 3,610
  • 6
  • 35
  • 51
  • Possible duplicate of [Is there a way to return Anonymous Type from method?](https://stackoverflow.com/questions/1329672/is-there-a-way-to-return-anonymous-type-from-method) – cdiggins Oct 05 '18 at 21:20

7 Answers7

28

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.)

StayOnTarget
  • 11,743
  • 10
  • 52
  • 81
LukeH
  • 263,068
  • 57
  • 365
  • 409
  • Beaten by 8 seconds! I've deleted mine (no benefit in duplicating it). But to stress:: ***do not do this*** ;-p – Marc Gravell Apr 03 '09 at 11:47
  • 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 Apr 03 '09 at 12:25
  • 2
    Ya. Good to know that this can be done. Is really evil though but so am I. muhahhhhahahaaaa. – Ali Kazmi Apr 03 '09 at 22:29
  • Thanks for this, I didn't use it :)) I ended up just using immutable structs. – Igor Zevaka Feb 18 '10 at 11:28
  • 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 Apr 09 '10 at 21:36
  • 1
    This hack does have a specific caveat that it won't work across assembly boundaries. This is because the compiler generates the types based on the signature once per assembly so if you use `var example = new { Id = 0, Name = string.Empty };` in a different assembly than `FuncA()` the types won't match. – jbtule Mar 02 '11 at 04:30
  • @LukeH, one link is "dead", it moved to [here](https://codeblog.jonskeet.uk/2009/01/09/horrible-grotty-hack-returning-an-anonymous-type-instance/) – ASh Nov 16 '18 at 08:45
7

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
  • 6,505
  • 7
  • 44
  • 65
2

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 Anthony Hein
  • 10,550
  • 3
  • 42
  • 62
1

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
  • 113,561
  • 39
  • 200
  • 288
1

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
  • 47,767
  • 15
  • 98
  • 117
0

would create a class for this case:

public class LISTFUNCA   
{                         
    public int identificacion;  
    public string nombre;      
}     

then:

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(); 
}     
  • 1
    Please review your code; I reformatted it, but I believe it isn't correct. Also, please read the [faq] for details about how to format your code correctly. And, when you post something, and it looks awful, don't forget you can [edit your post to fix it.](http://stackoverflow.com/posts/2509405/edit) –  Sep 19 '11 at 11:53
0

The open source framework Impromptu-Interface will allow you to duck cast an anonymous object to an interface. It has the advantage of being less hacky because it will work as expected across assembly boundaries. It accomplishes this using a lightweight proxy and the dlr.

jbtule
  • 31,383
  • 12
  • 95
  • 128