locked
IEnumerable problem. RRS feed

  • Question

  • //Class
    public static IEnumerable GetRootMenu()
    {
                myDataContext db = new myDataContext();

                var query = from t in db.myTables
                            select new {                            
                                t.field1, t.field2,
                                field3Count = (from s in db.myTables
                                                  where s.field3 == t.field1
                                                  select s).Count(),
                            };            
                return query;
            }


    //My Program
    Populate(myClass.GetRootMenu());

    private void PopulateRootLevel(IEnumerable mainArray)
            {
                foreach (var cc in mainArray)
                {
                    Text1.Text = cc.field1;              
                }
            }


    The above code show the error 'object' does not contain a definition for 'field1' and no extension method 'field1' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?)

    I am new in C# and LINQ. Pls help me....

    Thanks

    Thursday, December 18, 2008 10:09 AM

Answers

  • There isn't a way to do this currently. Returning LINQ queries generating anonymous types is a "rough corner" case in C#. Things will probably improve with the introduction of dynamic in C# 4.0.

    For now, you'll have to either:
    1) Refactor your code to not return LINQ queries, or
    2) Explicitly define the type (with properties "field1", "field2", "field3Count")

            -Steve
    • Proposed as answer by Stephen ClearyMVP Wednesday, December 24, 2008 3:33 AM
    • Marked as answer by Guo Surfer Wednesday, December 24, 2008 8:19 AM
    Friday, December 19, 2008 3:16 AM

All replies

  • IEnumerable (rather than IEnumerable<T>) does not have any type information about the type of thing being enumerated, other than the fact that the type is derived from object.

    Therefore, you will only be able to use members of the object type within your foreach loop.

    In other words, your foreach (var cc in mainArray) is the same as foreach (object cc in mainArray)

    Fixing that requires somewhat of a rewrite. Maybe your best bet is to define a named type to return from GetRootMenu and use that type for IEnumerable<T>.
    Thursday, December 18, 2008 10:21 AM
  •  

    Hi Matthew,

    Thanks for your reply.

    One thing I want to know is how I can return the IEnumerable<T>. I mean normally I can return my function is IEnumerable<myTables>. But now I make one new field in my query.

    Thanks,

    Friday, December 19, 2008 1:49 AM
  • There isn't a way to do this currently. Returning LINQ queries generating anonymous types is a "rough corner" case in C#. Things will probably improve with the introduction of dynamic in C# 4.0.

    For now, you'll have to either:
    1) Refactor your code to not return LINQ queries, or
    2) Explicitly define the type (with properties "field1", "field2", "field3Count")

            -Steve
    • Proposed as answer by Stephen ClearyMVP Wednesday, December 24, 2008 3:33 AM
    • Marked as answer by Guo Surfer Wednesday, December 24, 2008 8:19 AM
    Friday, December 19, 2008 3:16 AM
  • Thanks Steve.
    Friday, December 19, 2008 3:41 AM
  • How is this a rough edge?  Aren't you saying the whole query/anonymous type structure is unusable?  This comes almost directly from documented examples:

                IEnumerable filePaths = Directory.GetFiles(path, "*.csv").Select(p => new { Path = p, Date = System.IO.File.GetLastWriteTime(p) })
                    .OrderByDescending(x => x.Date);
                foreach (var item in filePaths)
                {
                    Console.WriteLine(item.Path);
                }
    

    Yet C# 2013 flags it as an error.

    'object' does not contain a definition for 'Path'


    Arthur Gardner

    Tuesday, November 18, 2014 5:29 PM