Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LINQ: How to declare IEnumerable[AnonymousType]?

Tags:

c#

.net

linq

This is my function:

    private IEnumerable<string> SeachItem(int[] ItemIds)     {         using (var reader = File.OpenText(Application.StartupPath + @"\temp\A_A.tmp"))         {             var myLine = from line in ReadLines(reader)                          where line.Length > 1                          let id = int.Parse(line.Split('\t')[1])                          where ItemIds.Contains(id)                          let m = Regex.Match(line, @"^\d+\t(\d+)\t.+?\t(item\\[^\t]+\.ddj)")                          where m.Success == true                          select new { Text = line, ItemId = id, Path = m.Groups[2].Value };             return myLine;         }     } 

I get a compile error,because "myLine" is not a IEnumerable[string] and I don't know how to write IEnumerable[Anonymous]

"Cannot implicitly convert type 'System.Collections.Generic.IEnumerable[AnonymousType#1]' to 'System.Collections.Generic.IEnumerable[string]'"

like image 906
Ivan Prodanov Avatar asked May 23 '09 16:05

Ivan Prodanov


People also ask

Can you use LINQ on IEnumerable?

All LINQ methods are extension methods to the IEnumerable<T> interface. That means that you can call any LINQ method on any object that implements IEnumerable<T> . You can even create your own classes that implement IEnumerable<T> , and those classes will instantly "inherit" all LINQ functionality!

When to use an anonymous type in LINQ?

Usually, an anonymous data type is used in the select clause of a LINQ expression to return a subset of properties from each object in the collection. In the following code example, we will see using an anonymous object in a LINQ query.

Can you project a query to an anonymous type?

In some cases, you might want to project a query to a new type, but the query would be your only use for the new type. Rather than create the type, you can project to an anonymous type.


2 Answers

You cannot declare IEnumerable<AnonymousType> because the type has no (known) name at build time. So if you want to use this type in a function declaration, make it a normal type. Or just modify your query to return a IENumerable<String> and stick with that type.

Or return IEnumerable<KeyValuePair<Int32, String>> using the following select statement.

select new KeyValuePair<Int32, String>(id, m.Groups[2].Value) 
like image 75
Daniel Brückner Avatar answered Sep 17 '22 13:09

Daniel Brückner


I am not necessarily recommending this... It is a kind of subversion of the type system but you could do this:

1) change your method signature to return IEnumerable (the non generic one)

2) add a cast by example helper:

public static class Extensions{     public static IEnumerable<T> CastByExample<T>(             this IEnumerable sequence,              T example) where T: class     {         foreach (Object o in sequence)             yield return o as T;     } } 

3) then call the method something like this:

var example = new { Text = "", ItemId = 0, Path = "" }; foreach (var x in SeachItem(ids).CastByExample(example)) {     // now you can access the properties of x      Console.WriteLine("{0},{1},{2}", x.Text, x.ItemId, x.Path); } 

And you are done.

The key to this is the fact that if you create an anonymous type with the same order, types and property names in two places the types will be reused. Knowing this you can use generics to avoid reflection.

Hope this helps Alex

like image 25
Alex James Avatar answered Sep 21 '22 13:09

Alex James