0

How can I return IEnumerable from a method.

 public IEnumerable<dynamic> GetMenuItems()
        {

            dynamic menuItems = new[]
                                    {
                                         new { Title="Home" },
                                    new { Title = "Categories"} 
                                    };

            return menuItems; 

        }

The above code returns IEnumerable but when I use it in the View it does not recognize the Title property.

@foreach(var item in @Model) 
{  
   <span>item.Title</span>
}  
5
  • 2
    Just curious. Why does the menu have to be dynamic? I know some reasons why it might be, but I am curious why it is in your application. Commented Jun 15, 2011 at 20:02
  • 4
    He's using dynamic in order to surface anonymous types outside of the current method. This is an enormous code smell and should always be avoided. Just create a proper type. Commented Jun 15, 2011 at 20:05
  • I can create a Menu class which will represent a menu but for my application the Menu items are fixed at 5 so I do not want to perform extra work to create a separate class for Menu. Commented Jun 15, 2011 at 20:08
  • then just use a tuple instead of an anonymous type and your problem is fixed. Commented Jun 15, 2011 at 20:09
  • trying to get this to work (including the time posting on SO) will take more time than implimenting a proper type. A proper type will also give your templating. There are also built in types like Tuple, KeyValuePair (string, url I'm guessing) that would work fine for this use. Commented Jun 16, 2011 at 9:57

2 Answers 2

9

Don't do this..

If you need to use the result of an anonymous type outside of the method that creates it, it is time to define a concrete type.

class Foo 
{
    public string Bar { get; set; }
}

Short of doing that, you can return a sequence of Tuple<> objects.

Anonymous types are nice when you're doing some processing inside a method, you need a projection of data that doesn't conform to your existing object graph, and you don't need to expose such a projection to the outside world. Once you start passing that projection around, go ahead and take the extra time to define a proper type and enjoy its benefits. Future You will thank you.

Sign up to request clarification or add additional context in comments.

3 Comments

Does that mean I cannot access the Anonymous type properties outside the current method?
@john, there are hacks that can allow you to do it. That doesn't make those hacks a good idea! It does not take very long to construct a class that merely encapsulates data, go ahead and spend that time to do so. When you need to pass data around your application, you really do need to go ahead and create a self-documenting, encapsulating data type.
@AnthonyPegram So what's the hack you are talking about? Care to share? I am genuinely interested on what you might come up with
0

Anonymous types are marked internal, so you can't access them from a different assembly. You can use an ExpandoObject instead although the default creation syntax doesn't work inline which can be annoying. However, the opensource framework impromptu-interface has a syntax for creating it inline.

using ImpromptuInterface.Dynamic;
using System.Dynamic;
...
public IEnumerable<dynamic> GetMenuItems()
   {
       var @new = Builder.New<ExpandoObject>();

       dynamic menuItems = new[]{
                   @new.Object(Title:"Home"),
                   @new.Object(Title:"Categories")
                };

       return menuItems; 

   }

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.